#7277 - RefundInvoices #2904

Merged
jgallego merged 12 commits from 7277-RefundInvoices into dev 2024-09-05 09:07:25 +00:00
18 changed files with 535 additions and 271 deletions

View File

@ -15,9 +15,7 @@ describe('ticket assignCollection()', () => {
args: {}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: ctx.req
});
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({active: ctx.req});
options = {transaction: tx};
tx = await models.Sale.beginTransaction({});
@ -25,7 +23,7 @@ describe('ticket assignCollection()', () => {
});
afterEach(async() => {
await tx.rollback();
if (tx) await tx.rollback();
});
it('should throw an error when there is not picking tickets', async() => {

View File

@ -1922,7 +1922,7 @@ INSERT INTO `ACL` VALUES (746,'Claim','getSummary','READ','ALLOW','ROLE','claimV
INSERT INTO `ACL` VALUES (747,'CplusRectificationType','*','READ','ALLOW','ROLE','administrative',NULL);
INSERT INTO `ACL` VALUES (748,'SiiTypeInvoiceOut','*','READ','ALLOW','ROLE','salesPerson',NULL);
INSERT INTO `ACL` VALUES (749,'InvoiceCorrectionType','*','READ','ALLOW','ROLE','salesPerson',NULL);
INSERT INTO `ACL` VALUES (750,'InvoiceOut','transferInvoice','WRITE','ALLOW','ROLE','administrative',NULL);
INSERT INTO `ACL` VALUES (750,'InvoiceOut','transfer','WRITE','ALLOW','ROLE','administrative',NULL);
INSERT INTO `ACL` VALUES (751,'Application','executeProc','*','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (752,'Application','executeFunc','*','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (753,'NotificationSubscription','getList','READ','ALLOW','ROLE','employee',NULL);

View File

@ -0,0 +1,2 @@
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
VALUES ('InvoiceOut','refundAndInvoice','WRITE','ALLOW','ROLE','administrative');

View File

@ -230,10 +230,12 @@
"This workCenter is already assigned to this agency": "This workCenter is already assigned to this agency",
"You can only have one PDA": "You can only have one PDA",
"Incoterms and Customs agent are required for a non UEE member": "Incoterms and Customs agent are required for a non UEE member",
"It has been invoiced but the PDF could not be generated": "It has been invoiced but the PDF could not be generated",
"The invoices have been created but the PDFs could not be generated": "The invoices have been created but the PDFs could not be generated",
"It has been invoiced but the PDF of refund not be generated": "It has been invoiced but the PDF of refund not be generated",
"Cannot add holidays on this day": "Cannot add holidays on this day",
"Cannot send mail": "Cannot send mail",
"CONSTRAINT `chkParkingCodeFormat` failed for `vn`.`parking`": "CONSTRAINT `chkParkingCodeFormat` failed for `vn`.`parking`",
"This postcode already exists": "This postcode already exists"
}
"This postcode already exists": "This postcode already exists",
"Original invoice not found": "Original invoice not found"
}

View File

@ -363,12 +363,13 @@
"You can not use the same password": "No puedes usar la misma contraseña",
"This PDA is already assigned to another user": "Este PDA ya está asignado a otro usuario",
"You can only have one PDA": "Solo puedes tener un PDA",
"It has been invoiced but the PDF could not be generated": "Se ha facturado pero no se ha podido generar el PDF",
"The invoices have been created but the PDFs could not be generated": "Se ha facturado pero no se ha podido generar el PDF",
"It has been invoiced but the PDF of refund not be generated": "Se ha facturado pero no se ha podido generar el PDF del abono",
"Payment method is required": "El método de pago es obligatorio",
"Cannot send mail": "Não é possível enviar o email",
"CONSTRAINT `supplierAccountTooShort` failed for `vn`.`supplier`": "La cuenta debe tener exactamente 10 dígitos",
"The sale not exists in the item shelving": "La venta no existe en la estantería del artículo",
"The entry not have stickers": "La entrada no tiene etiquetas",
"Too many records": "Demasiados registros"
}
"Too many records": "Demasiados registros",
"Original invoice not found": "Factura original no encontrada"
}

View File

@ -358,7 +358,9 @@
"This workCenter is already assigned to this agency": "Ce centre de travail est déjà assigné à cette agence",
"Select ticket or client": "Choisissez un ticket ou un client",
"It was not able to create the invoice": "Il n'a pas été possible de créer la facture",
"It has been invoiced but the PDF could not be generated": "La facture a été émise mais le PDF n'a pas pu être généré",
"The invoices have been created but the PDFs could not be generated": "La facture a été émise mais le PDF n'a pas pu être généré",
"It has been invoiced but the PDF of refund not be generated": "Il a été facturé mais le PDF de remboursement n'a pas été généré",
"Cannot send mail": "Impossible d'envoyer le mail"
"Cannot send mail": "Impossible d'envoyer le mail",
"Original invoice not found": "Facture originale introuvable"
}

View File

@ -358,6 +358,8 @@
"This workCenter is already assigned to this agency": "Este centro de trabalho já está atribuído a esta agência",
"Select ticket or client": "Selecione um ticket ou cliente",
"It was not able to create the invoice": "Não foi possível criar a fatura",
"It has been invoiced but the PDF could not be generated": "Foi faturado, mas o PDF não pôde ser gerado",
"It has been invoiced but the PDF of refund not be generated": "Foi faturado mas não foi gerado o PDF do reembolso"
"The invoices have been created but the PDFs could not be generated": "Foi faturado, mas o PDF não pôde ser gerado",
"It has been invoiced but the PDF of refund not be generated": "Foi faturado mas não foi gerado o PDF do reembolso",
"Original invoice not found": "Fatura original não encontrada"
}

View File

@ -47,12 +47,16 @@ module.exports = Self => {
Self.invoiceClient = async(ctx, options) => {
const args = ctx.args;
const models = Self.app.models;
options = typeof options === 'object' ? {...options} : {};
options.userId = ctx.req.accessToken.userId;
let tx;
if (!options.transaction)
tx = options.transaction = await Self.beginTransaction({});
const myOptions = {userId: ctx.req.accessToken.userId};
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
const minShipped = Date.vnNew();
minShipped.setFullYear(args.maxShipped.getFullYear() - 1);

View File

@ -0,0 +1,89 @@
module.exports = Self => {
Self.remoteMethodCtx('refundAndInvoice', {
description: 'Refund an invoice and create a new one',
accessType: 'WRITE',
accepts: [
{
arg: 'id',
type: 'number',
required: true,
description: 'Issued invoice id'
},
{
arg: 'cplusRectificationTypeFk',
type: 'number',
required: true
},
{
arg: 'siiTypeInvoiceOutFk',
type: 'number',
required: true
},
{
arg: 'invoiceCorrectionTypeFk',
type: 'number',
required: true
},
],
returns: {
type: 'object',
root: true
},
http: {
path: '/refundAndInvoice',
verb: 'post'
}
});
Self.refundAndInvoice = async(
ctx,
id,
cplusRectificationTypeFk,
siiTypeInvoiceOutFk,
invoiceCorrectionTypeFk,
options
) => {
const models = Self.app.models;
const myOptions = {userId: ctx.req.accessToken.userId};
let refundId;
if (typeof options == 'object')
Object.assign(myOptions, options);
let tx;
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const originalInvoice = await models.InvoiceOut.findById(id, myOptions);
const refundedTickets = await Self.refund(ctx, originalInvoice.ref, false, myOptions);
const invoiceCorrection = {
correctedFk: id,
cplusRectificationTypeFk,
siiTypeInvoiceOutFk,
invoiceCorrectionTypeFk
};
const ticketIds = refundedTickets.map(ticket => ticket.id);
refundId = await models.Ticket.invoiceTickets(ctx, ticketIds, invoiceCorrection, myOptions);
tx && await tx.commit();
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
if (tx) {
try {
await models.InvoiceOut.makePdfList(ctx, refundId);
} catch (e) {
throw new UserError('The invoices have been created but the PDFs could not be generated');
jsegarra marked this conversation as resolved
Review

Este texto no deberia tener traducción?

Este texto no deberia tener traducción?
}
}
return {refundId};
};
};

View File

@ -0,0 +1,105 @@
const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
const UserError = require('vn-loopback/util/user-error');
describe('InvoiceOut makePdfAndNotify()', () => {
const userId = 5;
const ctx = {
req: {
accessToken: {userId},
__: (key, obj) => `Translated: ${key}, ${JSON.stringify(obj)}`,
getLocale: () => 'es'
},
args: {}
};
const activeCtx = {accessToken: {userId}};
const id = 4;
const printerFk = 1;
beforeEach(() => {
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({active: activeCtx});
});
it('should generate PDF and send email when client is to be mailed', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
try {
await models.InvoiceOut.makePdfAndNotify(ctx, id, printerFk, options);
const invoice = await models.InvoiceOut.findById(id, {
fields: ['ref', 'clientFk'],
include: {
relation: 'client',
scope: {
fields: ['id', 'email', 'isToBeMailed', 'salesPersonFk']
}
}
}, options);
expect(invoice).toBeDefined();
expect(invoice.client().isToBeMailed).toBe(true);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should generate PDF and print when client is not to be mailed', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
try {
await models.InvoiceOut.makePdfAndNotify(ctx, id, null, options);
const invoice = await models.InvoiceOut.findById(id, {
fields: ['ref', 'clientFk'],
include: {
relation: 'client',
scope: {
fields: ['id', 'email', 'isToBeMailed', 'salesPersonFk']
}
}
}, options);
expect(invoice).toBeDefined();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should throw UserError when PDF generation fails', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
try {
await models.InvoiceOut.makePdfAndNotify(ctx, null, null, options);
await tx.rollback();
} catch (e) {
expect(e instanceof UserError).toBe(true);
expect(e.message).toContain('Error while generating PDF');
await tx.rollback();
}
});
it('should send message to salesperson when email fails', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
try {
spyOn(models.InvoiceOut, 'invoiceEmail').and.rejectWith(new Error('Test Error'));
await models.InvoiceOut.makePdfAndNotify(ctx, id, null, options);
await tx.rollback();
} catch (e) {
expect(e instanceof UserError).toBe(true);
expect(e.message).toContain('Error when sending mail to client');
await tx.rollback();
}
});
});

View File

@ -0,0 +1,46 @@
const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('InvoiceOut refundAndInvoice()', () => {
const userId = 5;
const ctx = {req: {accessToken: {userId}}};
const activeCtx = {accessToken: {userId}};
const id = 4;
const cplusRectificationTypeFk = 1;
const siiTypeInvoiceOutFk = 1;
const invoiceCorrectionTypeFk = 1;
beforeEach(() => {
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({active: activeCtx});
});
it('should refund an invoice and create a new invoice', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
try {
const result = await models.InvoiceOut.refundAndInvoice(
ctx,
id,
cplusRectificationTypeFk,
siiTypeInvoiceOutFk,
invoiceCorrectionTypeFk,
options
);
expect(result).toBeDefined();
expect(result.refundId).toBeDefined();
const invoicesAfter = await models.InvoiceOut.find({where: {id: result.refundId}}, options);
const ticketsAfter = await models.Ticket.find({where: {refFk: 'R10100001'}}, options);
expect(invoicesAfter.length).toBeGreaterThan(0);
expect(ticketsAfter.length).toBeGreaterThan(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -0,0 +1,135 @@
const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
const UserError = require('vn-loopback/util/user-error');
describe('InvoiceOut transfer()', () => {
const userId = 5;
let options;
let tx;
let ctx;
const activeCtx = {accessToken: {userId}};
const id = 4;
const newClientFk = 1101;
const cplusRectificationTypeFk = 1;
const siiTypeInvoiceOutFk = 1;
const invoiceCorrectionTypeFk = 1;
beforeEach(async() => {
ctx = {
req: {
accessToken: {userId: 1106},
headers: {origin: 'http://localhost'},
__: value => value,
getLocale: () => 'es'
},
args: {}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({active: activeCtx});
options = {transaction: tx};
tx = await models.Sale.beginTransaction({});
options.transaction = tx;
});
afterEach(async() => {
await tx.rollback();
});
it('should transfer an invoice to a new client and return the new invoice ID', async() => {
const makeInvoice = true;
const makePdfListMock = spyOn(models.InvoiceOut, 'makePdfList').and.returnValue();
const [result] = await models.InvoiceOut.transfer(
ctx,
id,
newClientFk,
cplusRectificationTypeFk,
siiTypeInvoiceOutFk,
invoiceCorrectionTypeFk,
makeInvoice,
options
);
const newInvoice = await models.InvoiceOut.findById(result, null, options);
expect(newInvoice.clientFk).toBe(newClientFk);
const transferredTickets = await models.Ticket.find({
where: {
refFk: newInvoice.ref,
clientFk: newClientFk
}
}, options);
expect(transferredTickets.length).toBeGreaterThan(0);
expect(makePdfListMock).toHaveBeenCalledWith(ctx, [result]);
});
it('should throw an error if original invoice is not found', async() => {
const makeInvoice = true;
try {
await models.InvoiceOut.transfer(
ctx,
'idNotExists',
newClientFk,
cplusRectificationTypeFk,
siiTypeInvoiceOutFk,
invoiceCorrectionTypeFk,
makeInvoice,
options
);
fail('Expected an error to be thrown');
} catch (e) {
expect(e).toBeInstanceOf(UserError);
expect(e.message).toBe('Original invoice not found');
}
});
it('should throw an error if the new client is the same as the original client', async() => {
const makeInvoice = true;
const originalInvoice = await models.InvoiceOut.findById(id, options);
try {
await models.InvoiceOut.transfer(
ctx,
id,
originalInvoice.clientFk,
cplusRectificationTypeFk,
siiTypeInvoiceOutFk,
invoiceCorrectionTypeFk,
makeInvoice,
options
);
fail('Expected an error to be thrown');
} catch (e) {
expect(e).toBeInstanceOf(UserError);
expect(e.message).toBe('Select a different client');
}
});
it('should not create a new invoice if makeInvoice is false', async() => {
const originalTickets = await models.Ticket.find({
where: {clientFk: newClientFk, refFk: null},
options
});
const result = await models.InvoiceOut.transfer(
ctx,
id,
newClientFk,
cplusRectificationTypeFk,
siiTypeInvoiceOutFk,
invoiceCorrectionTypeFk,
false,
options
);
expect(result).toBeUndefined();
const transferredTickets = await models.Ticket.find({
where: {clientFk: newClientFk, refFk: null}
}, options);
expect(transferredTickets.length).toBeGreaterThan(originalTickets.length);
});
});

View File

@ -1,116 +0,0 @@
const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('InvoiceOut transferInvoice()', () => {
const activeCtx = {
accessToken: {userId: 5},
http: {
req: {
headers: {origin: 'http://localhost'}
}
}
};
const ctx = {req: activeCtx};
beforeEach(() => {
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
});
it('should return the id of the created issued invoice', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
const id = 4;
const newClient = 1;
spyOn(models.InvoiceOut, 'makePdfList');
try {
const {clientFk: oldClient} = await models.InvoiceOut.findById(id, {fields: ['clientFk']});
const invoicesBefore = await models.InvoiceOut.find({}, options);
const result = await models.InvoiceOut.transferInvoice(
ctx,
id,
'T4444444',
newClient,
1,
1,
1,
true,
options);
const invoicesAfter = await models.InvoiceOut.find({}, options);
const rectificativeInvoice = invoicesAfter[invoicesAfter.length - 2];
const newInvoice = invoicesAfter[invoicesAfter.length - 1];
expect(result).toBeDefined();
expect(invoicesAfter.length - invoicesBefore.length).toEqual(2);
expect(rectificativeInvoice.clientFk).toEqual(oldClient);
expect(newInvoice.clientFk).toEqual(newClient);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should throw an error when it is the same client', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
spyOn(models.InvoiceOut, 'makePdfList');
try {
await models.InvoiceOut.transferInvoice(ctx, '1', 'T1111111', 1101, 1, 1, 1, true, options);
await tx.rollback();
} catch (e) {
expect(e.message).toBe(`Select a different client`);
await tx.rollback();
}
});
it('should throw an error when it is refund', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
spyOn(models.InvoiceOut, 'makePdfList');
try {
await models.InvoiceOut.transferInvoice(ctx, '1', 'T1111111', 1102, 1, 1, 1, true, options);
await tx.rollback();
} catch (e) {
expect(e.message).toContain(`This ticket is already a refund`);
await tx.rollback();
}
});
it('should throw an error when pdf failed', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
spyOn(models.InvoiceOut, 'makePdfList').and.returnValue(() => {
throw new Error('test');
});
try {
await models.InvoiceOut.transferInvoice(ctx, '1', 'T1111111', 1102, 1, 1, 1, true, options);
await tx.rollback();
} catch (e) {
expect(e.message).toContain(`It has been invoiced but the PDF could not be generated`);
await tx.rollback();
}
});
it('should not generate an invoice', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
spyOn(models.InvoiceOut, 'makePdfList');
let response;
try {
response = await models.InvoiceOut.transferInvoice(ctx, '1', 'T1111111', 1102, 1, 1, 1, false, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
expect(response).not.toBeDefined();
});
});

View File

@ -0,0 +1,122 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('transfer', {
description: 'Transfer an issued invoice to another client',
accessType: 'WRITE',
accepts: [
{
arg: 'id',
type: 'number',
required: true,
description: 'Issued invoice id'
},
{
arg: 'newClientFk',
type: 'number',
required: true
},
{
arg: 'cplusRectificationTypeFk',
type: 'number',
required: true
},
{
arg: 'siiTypeInvoiceOutFk',
type: 'number',
required: true
},
{
arg: 'invoiceCorrectionTypeFk',
type: 'number',
required: true
},
{
arg: 'makeInvoice',
type: 'boolean',
required: true
},
],
returns: {type: 'object', root: true},
http: {path: '/transfer', verb: 'post'}
});
Self.transfer = async(
ctx,
id,
newClientFk,
cplusRectificationTypeFk,
siiTypeInvoiceOutFk,
invoiceCorrectionTypeFk,
makeInvoice,
options
) => {
const models = Self.app.models;
let tx;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
const originalInvoice = await models.InvoiceOut.findById(id);
if (!originalInvoice)
throw new UserError('Original invoice not found');
Review

traducción?

traducción?
if (originalInvoice.clientFk === newClientFk)
throw new UserError('Select a different client');
let transferredInvoiceId;
try {
await Self.refundAndInvoice(
ctx,
id,
cplusRectificationTypeFk,
siiTypeInvoiceOutFk,
invoiceCorrectionTypeFk,
myOptions
);
const tickets = await models.Ticket.find({where: {refFk: originalInvoice.ref}}, myOptions);
const ticketIds = tickets.map(ticket => ticket.id);
const transferredTickets = await models.Ticket.cloneAll(ctx, ticketIds, false, false, myOptions);
const client = await models.Client.findById(newClientFk,
{fields: ['id', 'defaultAddressFk']}, myOptions);
const address = await models.Address.findById(client.defaultAddressFk,
{fields: ['id', 'nickname']}, myOptions);
const transferredTicketIds = transferredTickets.map(ticket => ticket.id);
await models.Ticket.updateAll(
{id: {inq: transferredTicketIds}},
{
clientFk: newClientFk,
addressFk: client.defaultAddressFk,
nickname: address.nickname
},
myOptions
);
if (makeInvoice)
transferredInvoiceId = await models.Ticket.invoiceTickets(ctx, transferredTicketIds, null, myOptions);
if (tx) await tx.commit();
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
if (transferredInvoiceId) {
try {
await models.InvoiceOut.makePdfList(ctx, transferredInvoiceId);
} catch (e) {
throw new UserError('The invoices have been created but the PDFs could not be generatedd');
jsegarra marked this conversation as resolved Outdated

traducción?

traducción?
}
}
return transferredInvoiceId;
};
};

View File

@ -1,131 +0,0 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('transferInvoice', {
description: 'Transfer an issued invoice to another client',
accessType: 'WRITE',
accepts: [
{
arg: 'id',
type: 'number',
required: true,
description: 'Issued invoice id'
},
{
arg: 'refFk',
type: 'string',
required: true
},
{
arg: 'newClientFk',
type: 'number',
required: true
},
{
arg: 'cplusRectificationTypeFk',
type: 'number',
required: true
},
{
arg: 'siiTypeInvoiceOutFk',
type: 'number',
required: true
},
{
arg: 'invoiceCorrectionTypeFk',
type: 'number',
required: true
},
{
arg: 'makeInvoice',
type: 'boolean',
required: true
},
],
returns: {
type: 'object',
root: true
},
http: {
path: '/transferInvoice',
verb: 'post'
}
});
Self.transferInvoice = async(
ctx,
id,
refFk,
newClientFk,
cplusRectificationTypeFk,
siiTypeInvoiceOutFk,
invoiceCorrectionTypeFk,
makeInvoice,
options
) => {
const models = Self.app.models;
const myOptions = {userId: ctx.req.accessToken.userId};
let invoiceId;
let refundId;
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
const {clientFk} = await models.InvoiceOut.findById(id);
if (clientFk == newClientFk)
throw new UserError(`Select a different client`);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const tickets = await models.Ticket.find({where: {refFk}}, myOptions);
const ticketsIds = tickets.map(ticket => ticket.id);
const refundTickets = await models.Ticket.cloneAll(ctx, ticketsIds, false, true, myOptions);
const clonedTickets = await models.Ticket.cloneAll(ctx, ticketsIds, false, false, myOptions);
const clonedTicketIds = [];
for (const clonedTicket of clonedTickets) {
await clonedTicket.updateAttribute('clientFk', newClientFk, myOptions);
clonedTicketIds.push(clonedTicket.id);
}
const invoiceCorrection = {
correctedFk: id,
cplusRectificationTypeFk,
siiTypeInvoiceOutFk,
invoiceCorrectionTypeFk
};
const refundTicketIds = refundTickets.map(ticket => ticket.id);
refundId = await models.Ticket.invoiceTickets(ctx, refundTicketIds, invoiceCorrection, myOptions);
if (makeInvoice)
invoiceId = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, null, myOptions);
tx && await tx.commit();
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
if (tx && makeInvoice) {
try {
await models.InvoiceOut.makePdfList(ctx, invoiceId);
} catch (e) {
throw new UserError('It has been invoiced but the PDF could not be generated');
}
try {
await models.InvoiceOut.makePdfList(ctx, refundId);
} catch (e) {
throw new UserError('It has been invoiced but the PDF of refund not be generated');
}
}
return invoiceId;
};
};

View File

@ -26,7 +26,8 @@ module.exports = Self => {
require('../methods/invoiceOut/getInvoiceDate')(Self);
require('../methods/invoiceOut/negativeBases')(Self);
require('../methods/invoiceOut/negativeBasesCsv')(Self);
require('../methods/invoiceOut/transferInvoice')(Self);
require('../methods/invoiceOut/transfer')(Self);
require('../methods/invoiceOut/refundAndInvoice')(Self);
Self.filePath = async function(id, options) {
const fields = ['ref', 'issued'];

View File

@ -138,7 +138,6 @@ class Controller extends Section {
transferInvoice() {
const params = {
id: this.invoiceOut.id,
jsegarra marked this conversation as resolved Outdated

duda, en Lilium, has quitado este param. porque aquí no?
En Lilium has dejado id

duda, en Lilium, has quitado este param. porque aquí no? En Lilium has dejado id
refFk: this.invoiceOut.ref,
newClientFk: this.clientId,
cplusRectificationTypeFk: this.cplusRectificationType,
siiTypeInvoiceOutFk: this.siiTypeInvoiceOut,
@ -155,7 +154,7 @@ class Controller extends Section {
return;
}
this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => {
this.$http.post(`InvoiceOuts/transfer`, params).then(res => {
const invoiceId = res.data;
this.vnApp.showSuccess(this.$t('Transferred invoice'));
this.$state.go('invoiceOut.card.summary', {id: invoiceId});

View File

@ -35,8 +35,11 @@ module.exports = Self => {
Self.cloneAll = async(ctx, ticketsIds, withWarehouse, negative, options) => {
const models = Self.app.models;
const myOptions = typeof options == 'object' ? {...options} : {};
let tx;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});