Merge pull request '#7019 fix(createManualInvoice): add throw error' (!2175) from 7019_fix_createManualInvoice into dev
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Reviewed-on: #2175 Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
This commit is contained in:
commit
86d8bc877a
|
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Fixed
|
||||
- (Worker -> time-control) Corrección de errores
|
||||
- (InvoiceOut -> Crear factura) Cuando falla al crear una factura, se devuelve un error
|
||||
|
||||
## [24.18.01] - 2024-05-07
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ describe('InvoiceOut manual invoice path', () => {
|
|||
await page.waitToClick(selectors.invoiceOutIndex.createInvoice);
|
||||
await page.waitForSelector(selectors.invoiceOutIndex.manualInvoiceForm);
|
||||
|
||||
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceClient, 'Max Eisenhardt');
|
||||
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceClient, 'Bruce Wayne');
|
||||
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceSerial, 'Global nacional');
|
||||
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceTaxArea, 'national');
|
||||
await page.waitToClick(selectors.invoiceOutIndex.saveInvoice);
|
||||
|
|
|
@ -353,5 +353,7 @@
|
|||
"This password can only be changed by the user themselves": "Esta contraseña solo puede ser modificada por el propio usuario",
|
||||
"They're not your subordinate": "No es tu subordinado/a.",
|
||||
"No results found": "No se han encontrado resultados",
|
||||
"InvoiceIn is already booked": "La factura recibida está contabilizada"
|
||||
}
|
||||
"InvoiceIn is already booked": "La factura recibida está contabilizada",
|
||||
"Select ticket or client": "Elija un ticket o un client",
|
||||
"It was not able to create the invoice": "No se pudo crear la factura"
|
||||
}
|
||||
|
|
|
@ -46,12 +46,11 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.createManualInvoice = async(ctx, options) => {
|
||||
Self.createManualInvoice = async(ctx, clientFk, ticketFk, maxShipped, serial, taxArea, reference, options) => {
|
||||
if (!clientFk && !ticketFk) throw new UserError(`Select ticket or client`);
|
||||
const models = Self.app.models;
|
||||
const args = ctx.args;
|
||||
|
||||
let tx;
|
||||
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||
let tx;
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
@ -61,18 +60,15 @@ module.exports = Self => {
|
|||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
const ticketId = args.ticketFk;
|
||||
let clientId = args.clientFk;
|
||||
let maxShipped = args.maxShipped;
|
||||
let companyId;
|
||||
let newInvoice;
|
||||
let query;
|
||||
try {
|
||||
if (ticketId) {
|
||||
const ticket = await models.Ticket.findById(ticketId, null, myOptions);
|
||||
if (ticketFk) {
|
||||
const ticket = await models.Ticket.findById(ticketFk, null, myOptions);
|
||||
const company = await models.Company.findById(ticket.companyFk, null, myOptions);
|
||||
|
||||
clientId = ticket.clientFk;
|
||||
clientFk = ticket.clientFk;
|
||||
maxShipped = ticket.shipped;
|
||||
companyId = ticket.companyFk;
|
||||
|
||||
|
@ -85,7 +81,7 @@ module.exports = Self => {
|
|||
throw new UserError(`A ticket with an amount of zero can't be invoiced`);
|
||||
|
||||
// Validates ticket nagative base
|
||||
const hasNegativeBase = await getNegativeBase(maxShipped, clientId, companyId, myOptions);
|
||||
const hasNegativeBase = await getNegativeBase(maxShipped, clientFk, companyId, myOptions);
|
||||
if (hasNegativeBase && company.code == 'VNL')
|
||||
throw new UserError(`A ticket with a negative base can't be invoiced`);
|
||||
} else {
|
||||
|
@ -95,7 +91,7 @@ module.exports = Self => {
|
|||
const company = await models.Ticket.findOne({
|
||||
fields: ['companyFk'],
|
||||
where: {
|
||||
clientFk: clientId,
|
||||
clientFk: clientFk,
|
||||
shipped: {lte: maxShipped}
|
||||
}
|
||||
}, myOptions);
|
||||
|
@ -103,7 +99,7 @@ module.exports = Self => {
|
|||
}
|
||||
|
||||
// Validate invoiceable client
|
||||
const isClientInvoiceable = await isInvoiceable(clientId, myOptions);
|
||||
const isClientInvoiceable = await isInvoiceable(clientFk, myOptions);
|
||||
if (!isClientInvoiceable)
|
||||
throw new UserError(`This client is not invoiceable`);
|
||||
|
||||
|
@ -114,27 +110,27 @@ module.exports = Self => {
|
|||
if (maxShipped >= tomorrow)
|
||||
throw new UserError(`Can't invoice to future`);
|
||||
|
||||
const maxInvoiceDate = await getMaxIssued(args.serial, companyId, myOptions);
|
||||
const maxInvoiceDate = await getMaxIssued(serial, companyId, myOptions);
|
||||
if (Date.vnNew() < maxInvoiceDate)
|
||||
throw new UserError(`Can't invoice to past`);
|
||||
|
||||
if (ticketId) {
|
||||
if (ticketFk) {
|
||||
query = `CALL invoiceOut_newFromTicket(?, ?, ?, ?, @newInvoiceId)`;
|
||||
await Self.rawSql(query, [
|
||||
ticketId,
|
||||
args.serial,
|
||||
args.taxArea,
|
||||
args.reference
|
||||
ticketFk,
|
||||
serial,
|
||||
taxArea,
|
||||
reference
|
||||
], myOptions);
|
||||
} else {
|
||||
query = `CALL invoiceOut_newFromClient(?, ?, ?, ?, ?, ?, @newInvoiceId)`;
|
||||
await Self.rawSql(query, [
|
||||
clientId,
|
||||
args.serial,
|
||||
clientFk,
|
||||
serial,
|
||||
maxShipped,
|
||||
companyId,
|
||||
args.taxArea,
|
||||
args.reference
|
||||
taxArea,
|
||||
reference
|
||||
], myOptions);
|
||||
}
|
||||
|
||||
|
@ -146,26 +142,27 @@ module.exports = Self => {
|
|||
throw e;
|
||||
}
|
||||
|
||||
if (newInvoice.id)
|
||||
await Self.createPdf(ctx, newInvoice.id);
|
||||
if (!newInvoice.id) throw new UserError('It was not able to create the invoice');
|
||||
|
||||
await Self.createPdf(ctx, newInvoice.id);
|
||||
|
||||
return newInvoice;
|
||||
};
|
||||
|
||||
async function isInvoiceable(clientId, options) {
|
||||
async function isInvoiceable(clientFk, options) {
|
||||
const models = Self.app.models;
|
||||
const query = `SELECT (hasToInvoice AND isTaxDataChecked) AS invoiceable
|
||||
FROM client
|
||||
WHERE id = ?`;
|
||||
const [result] = await models.InvoiceOut.rawSql(query, [clientId], options);
|
||||
const [result] = await models.InvoiceOut.rawSql(query, [clientFk], options);
|
||||
|
||||
return result.invoiceable;
|
||||
}
|
||||
|
||||
async function getNegativeBase(maxShipped, clientId, companyId, options) {
|
||||
async function getNegativeBase(maxShipped, clientFk, companyId, options) {
|
||||
const models = Self.app.models;
|
||||
await models.InvoiceOut.rawSql('CALL invoiceOut_exportationFromClient(?,?,?)',
|
||||
[maxShipped, clientId, companyId], options
|
||||
[maxShipped, clientFk, companyId], options
|
||||
);
|
||||
const query = 'SELECT vn.hasAnyNegativeBase() AS base';
|
||||
const [result] = await models.InvoiceOut.rawSql(query, [], options);
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
const {models} = require('vn-loopback/server/server');
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
describe('InvoiceOut createManualInvoice()', () => {
|
||||
const userId = 1;
|
||||
const ticketId = 16;
|
||||
const clientId = 1106;
|
||||
const activeCtx = {
|
||||
accessToken: {userId: userId},
|
||||
};
|
||||
const activeCtx = {accessToken: {userId: 1}};
|
||||
const ctx = {req: activeCtx};
|
||||
|
||||
it('should throw an error trying to invoice again', async() => {
|
||||
|
@ -18,13 +15,8 @@ describe('InvoiceOut createManualInvoice()', () => {
|
|||
|
||||
let error;
|
||||
try {
|
||||
ctx.args = {
|
||||
ticketFk: ticketId,
|
||||
serial: 'T',
|
||||
taxArea: 'CEE'
|
||||
};
|
||||
await models.InvoiceOut.createManualInvoice(ctx, options);
|
||||
await models.InvoiceOut.createManualInvoice(ctx, options);
|
||||
await createInvoice(ctx, options, undefined, ticketId);
|
||||
await createInvoice(ctx, options, undefined, ticketId);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
@ -47,17 +39,9 @@ describe('InvoiceOut createManualInvoice()', () => {
|
|||
let error;
|
||||
try {
|
||||
const ticket = await models.Ticket.findById(ticketId, null, options);
|
||||
await ticket.updateAttributes({
|
||||
totalWithVat: 0
|
||||
}, options);
|
||||
|
||||
ctx.args = {
|
||||
ticketFk: ticketId,
|
||||
serial: 'T',
|
||||
taxArea: 'CEE'
|
||||
};
|
||||
await models.InvoiceOut.createManualInvoice(ctx, options);
|
||||
await ticket.updateAttributes({totalWithVat: 0}, options);
|
||||
|
||||
await createInvoice(ctx, options, undefined, ticketId);
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
error = e;
|
||||
|
@ -75,13 +59,7 @@ describe('InvoiceOut createManualInvoice()', () => {
|
|||
|
||||
let error;
|
||||
try {
|
||||
ctx.args = {
|
||||
clientFk: clientId,
|
||||
serial: 'T',
|
||||
taxArea: 'CEE'
|
||||
};
|
||||
await models.InvoiceOut.createManualInvoice(ctx, options);
|
||||
|
||||
await createInvoice(ctx, options, clientId);
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
error = e;
|
||||
|
@ -103,16 +81,9 @@ describe('InvoiceOut createManualInvoice()', () => {
|
|||
let error;
|
||||
try {
|
||||
const client = await models.Client.findById(clientId, null, options);
|
||||
await client.updateAttributes({
|
||||
isTaxDataChecked: false
|
||||
}, options);
|
||||
await client.updateAttributes({isTaxDataChecked: false}, options);
|
||||
|
||||
ctx.args = {
|
||||
ticketFk: ticketId,
|
||||
serial: 'T',
|
||||
taxArea: 'CEE'
|
||||
};
|
||||
await models.InvoiceOut.createManualInvoice(ctx, options);
|
||||
await createInvoice(ctx, options, undefined, ticketId);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
@ -130,12 +101,7 @@ describe('InvoiceOut createManualInvoice()', () => {
|
|||
const options = {transaction: tx};
|
||||
|
||||
try {
|
||||
ctx.args = {
|
||||
ticketFk: ticketId,
|
||||
serial: 'T',
|
||||
taxArea: 'CEE'
|
||||
};
|
||||
const result = await models.InvoiceOut.createManualInvoice(ctx, options);
|
||||
const result = await createInvoice(ctx, options, undefined, ticketId);
|
||||
|
||||
expect(result.id).toEqual(jasmine.any(Number));
|
||||
|
||||
|
@ -146,3 +112,18 @@ describe('InvoiceOut createManualInvoice()', () => {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
function createInvoice(
|
||||
ctx,
|
||||
options,
|
||||
clientFk = undefined,
|
||||
ticketFk = undefined,
|
||||
maxShipped = undefined,
|
||||
serial = 'T',
|
||||
taxArea = 'CEE',
|
||||
reference = undefined
|
||||
) {
|
||||
return models.InvoiceOut.createManualInvoice(
|
||||
ctx, clientFk, ticketFk, maxShipped, serial, taxArea, reference, options
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue