Merge pull request 'feat: refs #7346' (!2864) from 7346 into dev
gitea/salix/pipeline/head This commit looks good Details

Reviewed-on: #2864
Reviewed-by: Javier Segarra <jsegarra@verdnatura.es>
This commit is contained in:
Javi Gallego 2024-08-22 09:30:27 +00:00
commit 24468ad338
16 changed files with 228 additions and 88 deletions

View File

@ -632,7 +632,7 @@ INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaF
('A', 'Global nacional', 1, 'NATIONAL', 0, 'global'), ('A', 'Global nacional', 1, 'NATIONAL', 0, 'global'),
('T', 'Española rapida', 1, 'NATIONAL', 0, 'quick'), ('T', 'Española rapida', 1, 'NATIONAL', 0, 'quick'),
('V', 'Intracomunitaria global', 0, 'CEE', 1, 'global'), ('V', 'Intracomunitaria global', 0, 'CEE', 1, 'global'),
('M', 'Múltiple nacional', 1, 'NATIONAL', 0, 'quick'), ('M', 'Múltiple nacional', 1, 'NATIONAL', 0, 'multiple'),
('R', 'Rectificativa', 1, 'NATIONAL', 0, NULL), ('R', 'Rectificativa', 1, 'NATIONAL', 0, NULL),
('E', 'Exportación rápida', 0, 'WORLD', 0, 'quick'); ('E', 'Exportación rápida', 0, 'WORLD', 0, 'quick');

View File

@ -1,26 +1,32 @@
DELIMITER $$ DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`invoiceSerial`(vClientFk INT, vCompanyFk INT, vType CHAR(1)) 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
* @param vCompanyFk Id de la empresa * @param vCompanyFk Id de la empresa
* @param vType Tipo de factura ["R", "M", "G"] * @param vType Tipo de factura ['global','multiple','quick']
* @return Serie de la factura * @return vSerie de la factura
*/ */
DECLARE vTaxArea VARCHAR(25); DECLARE vTaxArea VARCHAR(25) COLLATE utf8mb3_general_ci;
DECLARE vSerie CHAR(1); DECLARE vSerie CHAR(2);
IF (SELECT hasInvoiceSimplified FROM client WHERE id = vClientFk) THEN IF (SELECT hasInvoiceSimplified FROM client WHERE id = vClientFk) THEN
RETURN 'S'; RETURN 'S';
END IF; END IF;
SELECT clientTaxArea(vClientFk, vCompanyFk) INTO vTaxArea; SELECT addressTaxArea(defaultAddressFk, vCompanyFk) INTO vTaxArea
SELECT invoiceSerialArea(vType,vTaxArea) INTO vSerie; FROM client
WHERE id = vClientFk;
SELECT code INTO vSerie
FROM invoiceOutSerial
WHERE `type` = vType AND taxAreaFk = vTaxArea;
RETURN vSerie; RETURN vSerie;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -1,34 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`invoiceSerialArea`(vType CHAR(1), vTaxArea VARCHAR(25))
RETURNS char(1) CHARSET utf8mb3 COLLATE utf8mb3_unicode_ci
DETERMINISTIC
BEGIN
DECLARE vSerie CHAR(1);
IF vType = 'R' THEN
SELECT
CASE vTaxArea
WHEN 'CEE' THEN 'H'
WHEN 'WORLD' THEN 'E'
ELSE 'T'
END INTO vSerie;
-- Factura multiple
ELSEIF vType = 'M' THEN
SELECT
CASE vTaxArea
WHEN 'CEE' THEN 'H'
WHEN 'WORLD' THEN 'E'
ELSE 'M'
END INTO vSerie;
-- Factura global
ELSEIF vType = 'G' THEN
SELECT
CASE vTaxArea
WHEN 'CEE' THEN 'V'
WHEN 'WORLD' THEN 'X'
ELSE 'A'
END INTO vSerie;
END IF;
RETURN vSerie;
END$$
DELIMITER ;

View File

@ -97,7 +97,7 @@ BEGIN
AND (vCorrectingSerial = vSerial OR NOT hasAnyNegativeBase()) AND (vCorrectingSerial = vSerial OR NOT hasAnyNegativeBase())
THEN THEN
-- el trigger añade el siguiente Id_Factura correspondiente a la vSerial -- el trigger añade el siguiente ref correspondiente a la vSerial
INSERT INTO invoiceOut( INSERT INTO invoiceOut(
ref, ref,
serial, serial,

View File

@ -2,7 +2,7 @@ DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_close`() CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_close`()
BEGIN BEGIN
/** /**
* Realiza el cierre de todos los * Realiza el cierre de todos los
* tickets de la tabla tmp.ticket_close. * tickets de la tabla tmp.ticket_close.
* *
* @table tmp.ticket_close(ticketFk) Identificadores de los tickets a cerrar * @table tmp.ticket_close(ticketFk) Identificadores de los tickets a cerrar
@ -20,7 +20,7 @@ BEGIN
DECLARE cur CURSOR FOR DECLARE cur CURSOR FOR
SELECT ticketFk FROM tmp.ticket_close; SELECT ticketFk FROM tmp.ticket_close;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN
RESIGNAL; RESIGNAL;
@ -30,7 +30,7 @@ BEGIN
proc: LOOP proc: LOOP
SET vDone = FALSE; SET vDone = FALSE;
FETCH cur INTO vCurTicketFk; FETCH cur INTO vCurTicketFk;
IF vDone THEN IF vDone THEN
@ -47,12 +47,12 @@ BEGIN
c.hasToInvoice c.hasToInvoice
INTO vClientFk, INTO vClientFk,
vIsTaxDataChecked, vIsTaxDataChecked,
vCompanyFk, vCompanyFk,
vShipped, vShipped,
vHasDailyInvoice, vHasDailyInvoice,
vWithPackage, vWithPackage,
vHasToInvoice vHasToInvoice
FROM ticket t FROM ticket t
JOIN `client` c ON c.id = t.clientFk JOIN `client` c ON c.id = t.clientFk
JOIN province p ON p.id = c.provinceFk JOIN province p ON p.id = c.provinceFk
LEFT JOIN autonomy a ON a.id = p.autonomyFk LEFT JOIN autonomy a ON a.id = p.autonomyFk
@ -62,7 +62,7 @@ BEGIN
INSERT INTO ticketPackaging (ticketFk, packagingFk, quantity) INSERT INTO ticketPackaging (ticketFk, packagingFk, quantity)
(SELECT vCurTicketFk, p.id, COUNT(*) (SELECT vCurTicketFk, p.id, COUNT(*)
FROM expedition e FROM expedition e
JOIN packaging p ON p.id = e.packagingFk JOIN packaging p ON p.id = e.packagingFk
JOIN ticket t ON t.id = e.ticketFk JOIN ticket t ON t.id = e.ticketFk
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
@ -73,15 +73,15 @@ BEGIN
GROUP BY p.itemFk); GROUP BY p.itemFk);
-- No retornables o no catalogados -- No retornables o no catalogados
INSERT INTO sale (itemFk, ticketFk, concept, quantity, price, isPriceFixed) INSERT INTO sale (itemFk, ticketFk, concept, quantity, price, isPriceFixed)
(SELECT e.freightItemFk, vCurTicketFk, i.name, COUNT(*) AS amount, getSpecialPrice(e.freightItemFk, vClientFk), 1 (SELECT e.freightItemFk, vCurTicketFk, i.name, COUNT(*) AS amount, getSpecialPrice(e.freightItemFk, vClientFk), 1
FROM expedition e FROM expedition e
JOIN item i ON i.id = e.freightItemFk JOIN item i ON i.id = e.freightItemFk
LEFT JOIN packaging p ON p.itemFk = i.id LEFT JOIN packaging p ON p.itemFk = i.id
WHERE e.ticketFk = vCurTicketFk AND IFNULL(p.isPackageReturnable, 0) = 0 WHERE e.ticketFk = vCurTicketFk AND IFNULL(p.isPackageReturnable, 0) = 0
AND getSpecialPrice(e.freightItemFk, vClientFk) > 0 AND getSpecialPrice(e.freightItemFk, vClientFk) > 0
GROUP BY e.freightItemFk); GROUP BY e.freightItemFk);
IF(vHasDailyInvoice) AND vHasToInvoice THEN IF(vHasDailyInvoice) AND vHasToInvoice THEN
-- Facturacion rapida -- Facturacion rapida
@ -89,10 +89,10 @@ BEGIN
-- Facturar si está contabilizado -- Facturar si está contabilizado
IF vIsTaxDataChecked THEN IF vIsTaxDataChecked THEN
CALL invoiceOut_newFromClient( CALL invoiceOut_newFromClient(
vClientFk, vClientFk,
(SELECT invoiceSerial(vClientFk, vCompanyFk, 'M')), (SELECT invoiceSerial(vClientFk, vCompanyFk, 'multiple')),
vShipped, vShipped,
vCompanyFk, vCompanyFk,
NULL, NULL,
NULL, NULL,
vNewInvoiceId); vNewInvoiceId);

View File

@ -0,0 +1,4 @@
ALTER TABLE vn.invoiceOutSerial
MODIFY COLUMN `type` enum('global','quick','multiple') CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL NULL;
CREATE UNIQUE INDEX invoiceOutSerial_taxAreaFk_IDX USING BTREE ON vn.invoiceOutSerial (taxAreaFk,`type`);

View File

@ -0,0 +1,3 @@
UPDATE vn.invoiceOutSerial
SET `type`='multiple'
WHERE `description` LIKE '%Múltiple%';

View File

@ -46,7 +46,7 @@ module.exports = Self => {
} }
}); });
filter = mergeFilters(args.filter, {where}); const filter = mergeFilters(args.filter, {where});
const stmt = new ParameterizedSQL( const stmt = new ParameterizedSQL(
`SELECT i.serial, SUM(IF(i.isBooked, 0,1)) pending, COUNT(*) total `SELECT i.serial, SUM(IF(i.isBooked, 0,1)) pending, COUNT(*) total

View File

@ -75,7 +75,7 @@ module.exports = Self => {
AND c.isTaxDataChecked AND c.isTaxDataChecked
AND c.isActive AND c.isActive
AND NOT t.isDeleted AND NOT t.isDeleted
GROUP BY c.id, IF(c.hasToInvoiceByAddress, a.id, TRUE) GROUP BY IF(c.hasToInvoiceByAddress, a.id, c.id)
HAVING SUM(t.totalWithVat) > 0;`; HAVING SUM(t.totalWithVat) > 0;`;
const addresses = await Self.rawSql(query, [ const addresses = await Self.rawSql(query, [

View File

@ -28,6 +28,11 @@ module.exports = Self => {
type: 'number', type: 'number',
description: 'The company id to invoice', description: 'The company id to invoice',
required: true required: true
}, {
arg: 'serialType',
type: 'string',
description: 'Invoice serial number type (see vn.invoiceOutSerial.type enum)',
required: true
} }
], ],
returns: { returns: {
@ -39,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;
@ -74,10 +77,9 @@ module.exports = Self => {
], options); ], options);
} }
const invoiceType = 'G';
const invoiceId = await models.Ticket.makeInvoice( const invoiceId = await models.Ticket.makeInvoice(
ctx, ctx,
invoiceType, args.serialType,
args.companyFk, args.companyFk,
args.invoiceDate, args.invoiceDate,
null, null,

View File

@ -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();
}
});
});

View File

@ -1,16 +1,16 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
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';
@ -23,9 +23,14 @@ describe('InvoiceOut invoiceClient()', () => {
}; };
const ctx = {req: activeCtx}; const ctx = {req: activeCtx};
beforeAll(() => {
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: 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 +39,96 @@ 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);
const allBilledTicketsHaveCorrectAddress = billedTickets.every(ticket => ticket.addressFk === addressFk);
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();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('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 {
const client = await models.Client.findById(clientId, null, options);
await client.updateAttribute('hasToInvoiceByAddress', false, options);
ctx.args = {
clientId: clientId,
invoiceDate: Date.vnNew(),
maxShipped: Date.vnNew(),
companyFk: companyFk,
serialType: 'global'
};
const invoiceOutId = await models.InvoiceOut.invoiceClient(ctx, options);
const invoiceOut = await models.InvoiceOut.findById(invoiceOutId, null, options);
expect(invoiceOutId).toBeGreaterThan(0); expect(invoiceOutId).toBeGreaterThan(0);
expect(firstTicket.refFk).toContain(invoiceSerial);
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}
}, options);
const allTicketsBilled = allClientTickets.every(ticket => ticket.refFk === invoiceOut.ref);
expect(allTicketsBilled).toBe(true);
const billedAddresses = new Set(billedTickets.map(ticket => ticket.addressFk));
expect(billedAddresses.size).toBeGreaterThan(1);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {

View File

@ -20,6 +20,9 @@
}, },
"isCEE": { "isCEE": {
"type": "boolean" "type": "boolean"
},
"type": {
"type": "string"
} }
}, },
"relations": { "relations": {
@ -35,4 +38,4 @@
"principalId": "$everyone", "principalId": "$everyone",
"permission": "ALLOW" "permission": "ALLOW"
}] }]
} }

View File

@ -93,8 +93,8 @@ module.exports = Self => {
SUM(t.isDeleted) hasErrorDeleted, SUM(t.isDeleted) hasErrorDeleted,
SUM(itc.id IS NULL) hasErrorItemTaxCountry, SUM(itc.id IS NULL) hasErrorItemTaxCountry,
SUM(a.id IS NULL) hasErrorAddress, SUM(a.id IS NULL) hasErrorAddress,
SUM(ios.code IS NOT NULL SUM(ios.code IS NOT NULL
AND(ad.customsAgentFk IS NULL AND(ad.customsAgentFk IS NULL
OR ad.incotermsFk IS NULL)) hasErrorInfoTaxAreaWorld, OR ad.incotermsFk IS NULL)) hasErrorInfoTaxAreaWorld,
t.clientFk clientFk t.clientFk clientFk
FROM ticket t FROM ticket t
@ -113,24 +113,24 @@ module.exports = Self => {
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
LEFT JOIN itemTaxCountry itc ON itc.itemFk = i.id LEFT JOIN itemTaxCountry itc ON itc.itemFk = i.id
AND itc.countryFk = su.countryFk AND itc.countryFk = su.countryFk
LEFT JOIN vn.invoiceOutSerial ios ON ios.taxAreaFk = 'WORLD' LEFT JOIN vn.invoiceOutSerial ios ON ios.taxAreaFk = 'WORLD'
AND ios.code = invoiceSerial(t.clientFk, t.companyFk, 'M') AND ios.code = invoiceSerial(t.clientFk, t.companyFk, 'multiple')
WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered')) WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered'))
AND DATE(t.shipped) BETWEEN ? - INTERVAL 2 DAY AND util.dayEnd(?) AND DATE(t.shipped) BETWEEN ? - INTERVAL 2 DAY AND util.dayEnd(?)
AND t.refFk IS NULL AND t.refFk IS NULL
AND IFNULL(a.hasDailyInvoice, co.hasDailyInvoice) AND IFNULL(a.hasDailyInvoice, co.hasDailyInvoice)
GROUP BY ticketFk GROUP BY ticketFk
HAVING hasErrorToInvoice HAVING hasErrorToInvoice
OR hasErrorTaxDataChecked OR hasErrorTaxDataChecked
OR hasErrorDeleted OR hasErrorDeleted
OR hasErrorItemTaxCountry OR hasErrorItemTaxCountry
OR hasErrorAddress OR hasErrorAddress
OR hasErrorInfoTaxAreaWorld OR hasErrorInfoTaxAreaWorld
)sub )sub
)sub2 )sub2
) SELECT IF(errors = '{"tickets": null}', ) SELECT IF(errors = '{"tickets": null}',
'No errors', 'No errors',
util.notification_send('invoice-ticket-closure', errors, NULL)) util.notification_send('invoice-ticket-closure', errors, NULL))
FROM ticketNotInvoiceable`, [toDate, toDate]); FROM ticketNotInvoiceable`, [toDate, toDate]);
await closure(ctx, Self, tickets); await closure(ctx, Self, tickets);

View File

@ -95,7 +95,7 @@ module.exports = function(Self) {
FROM vn.ticket FROM vn.ticket
WHERE id IN (?) WHERE id IN (?)
`, [ticketsIds], myOptions); `, [ticketsIds], myOptions);
return models.Ticket.makeInvoice(ctx, 'R', companyId, Date.vnNew(), invoiceCorrection, myOptions); return models.Ticket.makeInvoice(ctx, 'quick', companyId, Date.vnNew(), invoiceCorrection, myOptions);
} }
}; };

View File

@ -3,7 +3,7 @@ const LoopBackContext = require('loopback-context');
describe('ticket makeInvoice()', () => { describe('ticket makeInvoice()', () => {
const userId = 19; const userId = 19;
const invoiceType = 'R'; const invoiceType = 'quick';
const companyFk = 442; const companyFk = 442;
const invoiceDate = Date.vnNew(); const invoiceDate = Date.vnNew();
const activeCtx = { const activeCtx = {