feat: refs #7346 backTest checks new implementation
This commit is contained in:
parent
ccfb53891f
commit
340348a38e
|
@ -1,10 +1,10 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`invoiceSerial`(vClientFk INT, vCompanyFk INT, vType CHAR(15))
|
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`invoiceSerial`(vClientFk INT, vCompanyFk INT, vType CHAR(15))
|
||||||
RETURNS char(1) CHARSET utf8mb3 COLLATE utf8mb3_general_ci
|
RETURNS char(2) CHARSET utf8mb3 COLLATE utf8mb3_general_ci
|
||||||
DETERMINISTIC
|
DETERMINISTIC
|
||||||
BEGIN
|
BEGIN
|
||||||
/**
|
/**
|
||||||
* Obtiene la serie de de una factura
|
* Obtiene la serie de una factura
|
||||||
* dependiendo del area del cliente.
|
* dependiendo del area del cliente.
|
||||||
*
|
*
|
||||||
* @param vClientFk Id del cliente
|
* @param vClientFk Id del cliente
|
||||||
|
|
|
@ -31,7 +31,7 @@ module.exports = Self => {
|
||||||
}, {
|
}, {
|
||||||
arg: 'serialType',
|
arg: 'serialType',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Type of serial',
|
description: 'Invoice serial number type (see vn.invoiceOutSerial.type enum)',
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -44,12 +44,10 @@ module.exports = Self => {
|
||||||
verb: 'POST'
|
verb: 'POST'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.invoiceClient = async(ctx, options) => {
|
Self.invoiceClient = async(ctx, options) => {
|
||||||
const args = ctx.args;
|
const args = ctx.args;
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
options = typeof options == 'object'
|
options = typeof options === 'object' ? {...options} : {};
|
||||||
? Object.assign({}, options) : {};
|
|
||||||
options.userId = ctx.req.accessToken.userId;
|
options.userId = ctx.req.accessToken.userId;
|
||||||
|
|
||||||
let tx;
|
let tx;
|
||||||
|
@ -81,7 +79,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
const invoiceId = await models.Ticket.makeInvoice(
|
const invoiceId = await models.Ticket.makeInvoice(
|
||||||
ctx,
|
ctx,
|
||||||
serialType,
|
args.serialType,
|
||||||
args.companyFk,
|
args.companyFk,
|
||||||
args.invoiceDate,
|
args.invoiceDate,
|
||||||
null,
|
null,
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
|
describe('InvoiceOut clientsToInvoice()', () => {
|
||||||
|
const userId = 1;
|
||||||
|
const clientId = 1101;
|
||||||
|
const companyFk = 442;
|
||||||
|
const maxShipped = new Date();
|
||||||
|
maxShipped.setMonth(11);
|
||||||
|
maxShipped.setDate(31);
|
||||||
|
maxShipped.setHours(23, 59, 59, 999);
|
||||||
|
const invoiceDate = new Date();
|
||||||
|
const activeCtx = {
|
||||||
|
getLocale: () => {
|
||||||
|
return 'en';
|
||||||
|
},
|
||||||
|
accessToken: {userId: userId},
|
||||||
|
__: value => {
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
};
|
||||||
|
const ctx = {req: activeCtx};
|
||||||
|
|
||||||
|
it('should return a list of clients to invoice', async() => {
|
||||||
|
spyOn(models.InvoiceOut, 'rawSql').and.callFake(query => {
|
||||||
|
if (query.includes('ticketPackaging_add'))
|
||||||
|
return Promise.resolve(true);
|
||||||
|
else if (query.includes('SELECT c.id clientId')) {
|
||||||
|
return Promise.resolve([
|
||||||
|
{
|
||||||
|
clientId: clientId,
|
||||||
|
clientName: 'Test Client',
|
||||||
|
id: 1,
|
||||||
|
nickname: 'Address 1'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const tx = await models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const addresses = await models.InvoiceOut.clientsToInvoice(
|
||||||
|
ctx, clientId, invoiceDate, maxShipped, companyFk, options);
|
||||||
|
|
||||||
|
expect(addresses.length).toBeGreaterThan(0);
|
||||||
|
expect(addresses[0].clientId).toBe(clientId);
|
||||||
|
expect(addresses[0].clientName).toBe('Test Client');
|
||||||
|
expect(addresses[0].id).toBe(1);
|
||||||
|
expect(addresses[0].nickname).toBe('Address 1');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle errors and rollback transaction', async() => {
|
||||||
|
spyOn(models.InvoiceOut, 'rawSql').and.callFake(() => {
|
||||||
|
return Promise.reject(new Error('Test Error'));
|
||||||
|
});
|
||||||
|
|
||||||
|
const tx = await models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await models.InvoiceOut.clientsToInvoice(ctx, clientId, invoiceDate, maxShipped, companyFk, options);
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toBe('Test Error');
|
||||||
|
await tx.rollback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -3,14 +3,13 @@ const models = require('vn-loopback/server/server').models;
|
||||||
describe('InvoiceOut invoiceClient()', () => {
|
describe('InvoiceOut invoiceClient()', () => {
|
||||||
const userId = 1;
|
const userId = 1;
|
||||||
const clientId = 1101;
|
const clientId = 1101;
|
||||||
const addressId = 121;
|
const addressFk = 121;
|
||||||
const companyFk = 442;
|
const companyFk = 442;
|
||||||
const minShipped = Date.vnNew();
|
const minShipped = Date.vnNew();
|
||||||
minShipped.setFullYear(minShipped.getFullYear() - 1);
|
minShipped.setFullYear(minShipped.getFullYear() - 1);
|
||||||
minShipped.setMonth(1);
|
minShipped.setMonth(1);
|
||||||
minShipped.setDate(1);
|
minShipped.setDate(1);
|
||||||
minShipped.setHours(0, 0, 0, 0);
|
minShipped.setHours(0, 0, 0, 0);
|
||||||
const invoiceSerial = 'A';
|
|
||||||
const activeCtx = {
|
const activeCtx = {
|
||||||
getLocale: () => {
|
getLocale: () => {
|
||||||
return 'en';
|
return 'en';
|
||||||
|
@ -24,8 +23,8 @@ describe('InvoiceOut invoiceClient()', () => {
|
||||||
};
|
};
|
||||||
const ctx = {req: activeCtx};
|
const ctx = {req: activeCtx};
|
||||||
|
|
||||||
it('should make a global invoicing', async() => {
|
it('should make a global invoicing by address and verify billing status', async() => {
|
||||||
spyOn(models.InvoiceOut, 'makePdf').and.returnValue(new Promise(resolve => resolve(true)));
|
spyOn(models.InvoiceOut, 'makePdf').and.returnValue(Promise.resolve(true));
|
||||||
spyOn(models.InvoiceOut, 'invoiceEmail');
|
spyOn(models.InvoiceOut, 'invoiceEmail');
|
||||||
|
|
||||||
const tx = await models.InvoiceOut.beginTransaction({});
|
const tx = await models.InvoiceOut.beginTransaction({});
|
||||||
|
@ -34,20 +33,42 @@ describe('InvoiceOut invoiceClient()', () => {
|
||||||
try {
|
try {
|
||||||
ctx.args = {
|
ctx.args = {
|
||||||
clientId: clientId,
|
clientId: clientId,
|
||||||
addressId: addressId,
|
addressId: addressFk,
|
||||||
invoiceDate: Date.vnNew(),
|
invoiceDate: Date.vnNew(),
|
||||||
maxShipped: Date.vnNew(),
|
maxShipped: Date.vnNew(),
|
||||||
companyFk: companyFk,
|
companyFk: companyFk,
|
||||||
minShipped: minShipped
|
serialType: 'global'
|
||||||
};
|
};
|
||||||
|
|
||||||
const invoiceOutId = await models.InvoiceOut.invoiceClient(ctx, options);
|
const invoiceOutId = await models.InvoiceOut.invoiceClient(ctx, options);
|
||||||
|
|
||||||
const invoiceOut = await models.InvoiceOut.findById(invoiceOutId, null, options);
|
const invoiceOut = await models.InvoiceOut.findById(invoiceOutId, null, options);
|
||||||
const [firstTicket] = await models.Ticket.find({
|
|
||||||
|
expect(invoiceOutId).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
const allClientTickets = await models.Ticket.find({
|
||||||
|
where: {
|
||||||
|
clientFk: clientId,
|
||||||
|
or: [
|
||||||
|
{refFk: null},
|
||||||
|
{refFk: invoiceOut.ref}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
const billedTickets = await models.Ticket.find({
|
||||||
where: {refFk: invoiceOut.ref}
|
where: {refFk: invoiceOut.ref}
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
expect(invoiceOutId).toBeGreaterThan(0);
|
const allBilledTicketsHaveCorrectAddress = billedTickets.every(ticket => ticket.addressFk === addressFk);
|
||||||
expect(firstTicket.refFk).toContain(invoiceSerial);
|
|
||||||
|
expect(allBilledTicketsHaveCorrectAddress).toBe(true);
|
||||||
|
|
||||||
|
const addressTickets = allClientTickets.filter(ticket => ticket.addressFk === addressFk);
|
||||||
|
|
||||||
|
const allAddressTicketsBilled = addressTickets.every(ticket => ticket.refFk === invoiceOut.ref);
|
||||||
|
|
||||||
|
expect(allAddressTicketsBilled).toBe(true);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -55,4 +76,45 @@ describe('InvoiceOut invoiceClient()', () => {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 300000;
|
||||||
|
fit('should invoice all tickets regardless of address when hasToInvoiceByAddress is false', async() => {
|
||||||
|
spyOn(models.InvoiceOut, 'makePdf').and.returnValue(Promise.resolve(true));
|
||||||
|
spyOn(models.InvoiceOut, 'invoiceEmail');
|
||||||
|
|
||||||
|
const tx = await models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('Searching for client with ID:', clientId);
|
||||||
|
const client = await models.Client.findById(clientId, options);
|
||||||
|
console.log('Found client:', JSON.stringify(client, null, 2));
|
||||||
|
|
||||||
|
if (!client)
|
||||||
|
throw new Error(`Client with id ${clientId} not found`);
|
||||||
|
|
||||||
|
console.log('Client before update:', JSON.stringify(client, null, 2));
|
||||||
|
console.log('Current hasToInvoiceByAddress value:', client.hasToInvoiceByAddress);
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('Attempting to update hasToInvoiceByAddress');
|
||||||
|
await client.updateAttribute('hasToInvoiceByAddress', false, options);
|
||||||
|
console.log('Update successful');
|
||||||
|
} catch (updateError) {
|
||||||
|
console.error('Error updating hasToInvoiceByAddress:', updateError);
|
||||||
|
console.error('Error stack:', updateError.stack);
|
||||||
|
throw updateError;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Client after update:', JSON.stringify(client, null, 2));
|
||||||
|
console.log('New hasToInvoiceByAddress value:', client.hasToInvoiceByAddress);
|
||||||
|
|
||||||
|
console.log('Test completed successfully');
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Test failed:', e);
|
||||||
|
console.error('Error stack:', e.stack);
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue