diff --git a/db/changes/10340-summer/00-ACL.sql b/db/changes/10340-summer/00-ACL.sql
index fd92b3c1c..2824aae2a 100644
--- a/db/changes/10340-summer/00-ACL.sql
+++ b/db/changes/10340-summer/00-ACL.sql
@@ -3,5 +3,7 @@ DELETE FROM `salix`.`ACL` WHERE id = 188;
UPDATE `salix`.`ACL` tdms SET tdms.accessType = '*'
WHERE tdms.id = 165;
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
- VALUES ('InvoiceOut', 'createManualInvoice', 'WRITE', 'ALLOW', 'ROLE', 'invoicing');
+ VALUES
+ ('InvoiceOut', 'createManualInvoice', 'WRITE', 'ALLOW', 'ROLE', 'invoicing'),
+ ('InvoiceOut', 'globalInvoicing', 'WRITE', 'ALLOW', 'ROLE', 'invoicing');
diff --git a/loopback/locale/en.json b/loopback/locale/en.json
index d4de6e55b..1781e0975 100644
--- a/loopback/locale/en.json
+++ b/loopback/locale/en.json
@@ -110,5 +110,6 @@
"nickname": "nickname",
"State": "State",
"regular": "regular",
- "reserved": "reserved"
+ "reserved": "reserved",
+ "Global invoicing failed": "[Global invoicing] Wasn't able to invoice some of the clients"
}
\ No newline at end of file
diff --git a/loopback/locale/es.json b/loopback/locale/es.json
index 92cd8d343..9c8f15a94 100644
--- a/loopback/locale/es.json
+++ b/loopback/locale/es.json
@@ -203,6 +203,6 @@
"This ticket is already invoiced": "Este ticket ya está facturado",
"A ticket with an amount of zero can't be invoiced": "No se puede facturar un ticket con importe cero",
"A ticket with a negative base can't be invoiced": "No se puede facturar un ticket con una base negativa",
- "Not invoiceable": "Not invoiceable",
- "Not invoiceable 1101": "Not invoiceable 1101"
+ "Global invoicing failed": "[Facturación global] No se han podido facturar algunos clientes",
+ "Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes"
}
\ No newline at end of file
diff --git a/modules/invoiceOut/back/methods/invoiceOut/globalInvoicing.js b/modules/invoiceOut/back/methods/invoiceOut/globalInvoicing.js
index df79a6c09..450736902 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/globalInvoicing.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/globalInvoicing.js
@@ -42,9 +42,9 @@ module.exports = Self => {
});
Self.globalInvoicing = async(ctx, options) => {
- const models = Self.app.models;
const args = ctx.args;
const invoicesIds = [];
+ const failedClients = [];
let tx;
const myOptions = {};
@@ -81,7 +81,7 @@ module.exports = Self => {
const minShipped = new Date();
minShipped.setFullYear(minShipped.getFullYear() - 1);
- // Liquidacion de cubos y carros
+ // Packaging liquidation
const vIsAllInvoiceable = false;
const clientsWithPackaging = await getClientsWithPackaging(ctx, myOptions);
for (let client of clientsWithPackaging) {
@@ -93,77 +93,70 @@ module.exports = Self => {
], myOptions);
}
- const company = await models.Company.findById(args.companyFk, null, myOptions);
const invoiceableClients = await getInvoiceableClients(ctx, myOptions);
if (!invoiceableClients.length) return;
for (let client of invoiceableClients) {
- // esto es para los que no tienen rol de invoicing??
- /* const [clientTax] = await Self.rawSql('SELECT vn.clientTaxArea(?, ?) AS taxArea', [
- client.id,
- args.companyFk
- ], myOptions);
- const clientTaxArea = clientTax.taxArea;
- if (clientTaxArea != 'WORLD' && company.code === 'VNL' && hasRole('invoicing')) {
- // Exit process??
- console.log(clientTaxArea);
- throw new UserError('Not invoiceable ' + client.id);
- }
- */
- if (client.hasToInvoiceByAddress) {
- await Self.rawSql('CALL ticketToInvoiceByAddress(?, ?, ?, ?)', [
- minShipped,
- args.maxShipped,
- client.addressFk,
- args.companyFk
- ], myOptions);
- } else {
- await Self.rawSql('CALL invoiceFromClient(?, ?, ?)', [
- args.maxShipped,
+ try {
+ if (client.hasToInvoiceByAddress) {
+ await Self.rawSql('CALL ticketToInvoiceByAddress(?, ?, ?, ?)', [
+ minShipped,
+ args.maxShipped,
+ client.addressFk,
+ args.companyFk
+ ], myOptions);
+ } else {
+ await Self.rawSql('CALL invoiceFromClient(?, ?, ?)', [
+ args.maxShipped,
+ client.id,
+ args.companyFk
+ ], myOptions);
+ }
+
+ // Make invoice
+ const isSpanishCompany = await getIsSpanishCompany(args.companyFk, myOptions);
+
+ // Validates ticket nagative base
+ const hasAnyNegativeBase = await getNegativeBase(myOptions);
+ if (hasAnyNegativeBase && isSpanishCompany)
+ continue;
+
+ query = `SELECT invoiceSerial(?, ?, ?) AS serial`;
+ const [invoiceSerial] = await Self.rawSql(query, [
client.id,
- args.companyFk
+ args.companyFk,
+ 'G'
], myOptions);
- }
+ const serialLetter = invoiceSerial.serial;
- // Make invoice
+ query = `CALL invoiceOut_new(?, ?, NULL, @invoiceId)`;
+ await Self.rawSql(query, [
+ serialLetter,
+ args.invoiceDate
+ ], myOptions);
- const isSpanishCompany = await getIsSpanishCompany(args.companyFk, myOptions);
+ const [newInvoice] = await Self.rawSql(`SELECT @invoiceId id`, null, myOptions);
+ if (newInvoice.id) {
+ await Self.rawSql('CALL invoiceOutBooking(?)', [newInvoice.id], myOptions);
- // Validates ticket nagative base
- const hasAnyNegativeBase = await getNegativeBase(myOptions);
- if (hasAnyNegativeBase && isSpanishCompany)
+ invoicesIds.push(newInvoice.id);
+ }
+ } catch (e) {
+ failedClients.push({
+ id: client.id,
+ stacktrace: e
+ });
continue;
-
- query = `SELECT invoiceSerial(?, ?, ?) AS serial`;
- const [invoiceSerial] = await Self.rawSql(query, [
- client.id,
- args.companyFk,
- 'G'
- ], myOptions);
- const serialLetter = invoiceSerial.serial;
-
- query = `CALL invoiceOut_new(?, ?, NULL, @invoiceId)`;
- await Self.rawSql(query, [
- serialLetter,
- args.invoiceDate
- ], myOptions);
-
- const [newInvoice] = await Self.rawSql(`SELECT @invoiceId id`, null, myOptions);
- if (newInvoice.id) {
- await Self.rawSql('CALL invoiceOutBooking(?)', [newInvoice.id], myOptions);
-
- invoicesIds.push(newInvoice.id);
}
-
- // IMPRIMIR PDF ID 3?
}
- // Print invoice to network printer
+ if (failedClients.length > 0)
+ await notifyFailures(ctx, failedClients, myOptions);
if (tx) await tx.commit();
- // Print invoices
+ // Print invoices PDF
for (let invoiceId of invoicesIds)
await Self.createPdf(ctx, invoiceId);
@@ -243,4 +236,28 @@ module.exports = Self => {
args.companyFk
], options);
}
+
+ async function notifyFailures(ctx, failedClients, options) {
+ const models = Self.app.models;
+ const userId = ctx.req.accessToken.userId;
+ const $t = ctx.req.__; // $translate
+
+ const worker = await models.EmailUser.findById(userId, null, options);
+ const subject = $t('Global invoicing failed');
+ let body = $t(`Wasn't able to invoice the following clients`) + ':
';
+
+ for (client of failedClients) {
+ body += `ID: ${client.id}
+
${client.stacktrace}
`;
+ }
+
+ await Self.rawSql(`
+ INSERT INTO vn.mail (sender, replyTo, sent, subject, body)
+ VALUES (?, ?, FALSE, ?, ?)`, [
+ worker.email,
+ worker.email,
+ subject,
+ body
+ ], options);
+ }
};
diff --git a/modules/invoiceOut/front/index/global-invoicing/index.html b/modules/invoiceOut/front/index/global-invoicing/index.html
index fd26afab9..9fd412d0e 100644
--- a/modules/invoiceOut/front/index/global-invoicing/index.html
+++ b/modules/invoiceOut/front/index/global-invoicing/index.html
@@ -14,6 +14,14 @@
data="companies"
order="code">
+