diff --git a/back/methods/dms/deleteTrashFiles.js b/back/methods/dms/deleteTrashFiles.js index 6f9a2a211..828f9658c 100644 --- a/back/methods/dms/deleteTrashFiles.js +++ b/back/methods/dms/deleteTrashFiles.js @@ -17,61 +17,50 @@ module.exports = Self => { }); Self.deleteTrashFiles = async options => { - let tx; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - if (!myOptions.transaction) { - tx = await Self.beginTransaction({}); - myOptions.transaction = tx; - } + if (process.env.NODE_ENV == 'test') + throw new UserError(`Action not allowed on the test environment`); - try { - if (process.env.NODE_ENV == 'test') - throw new UserError(`Action not allowed on the test environment`); + const models = Self.app.models; + const DmsContainer = models.DmsContainer; - const models = Self.app.models; - const DmsContainer = models.DmsContainer; + const trashDmsType = await models.DmsType.findOne({ + where: {code: 'trash'} + }, myOptions); - const trashDmsType = await models.DmsType.findOne({ - where: {code: 'trash'} - }, myOptions); + const date = new Date(); + date.setMonth(date.getMonth() - 4); - const date = new Date(); - date.setMonth(date.getMonth() - 4); - - const dmsToDelete = await models.Dms.find({ - where: { - and: [ - {dmsTypeFk: trashDmsType.id}, - {created: {lt: date}} - ] - } - }, myOptions); - - for (let dms of dmsToDelete) { - const pathHash = DmsContainer.getHash(dms.id); - const dmsContainer = await DmsContainer.container(pathHash); - const dstFile = path.join(dmsContainer.client.root, pathHash, dms.file); - try { - await fs.unlink(dstFile); - } catch (err) { - continue; - } - const dstFolder = path.join(dmsContainer.client.root, pathHash); - try { - await fs.rmdir(dstFolder); - } catch (err) {} - - await dms.destroy(myOptions); + const dmsToDelete = await models.Dms.find({ + where: { + and: [ + {dmsTypeFk: trashDmsType.id}, + {created: {lt: date}} + ] } - if (tx) await tx.commit(); - } catch (e) { - if (tx) await tx.rollback(); + }, myOptions); - throw e; + for (let dms of dmsToDelete) { + const pathHash = DmsContainer.getHash(dms.id); + const dmsContainer = await DmsContainer.container(pathHash); + const dstFile = path.join(dmsContainer.client.root, pathHash, dms.file); + try { + await fs.unlink(dstFile); + } catch (err) { + continue; + } + const dstFolder = path.join(dmsContainer.client.root, pathHash); + try { + await fs.rmdir(dstFolder); + } catch (err) { + continue; + } + + await dms.destroy(myOptions); } }; }; diff --git a/db/changes/10490-august/00-acl_receiptPdf.sql b/db/changes/10490-august/00-acl_receiptPdf.sql new file mode 100644 index 000000000..42f84b87d --- /dev/null +++ b/db/changes/10490-august/00-acl_receiptPdf.sql @@ -0,0 +1,3 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Receipt', 'receiptPdf', '*', 'ALLOW', 'ROLE', 'salesAssistant'); diff --git a/db/changes/10491-august/00-defaultPayDem_sameAs_production.sql b/db/changes/10491-august/00-defaultPayDem_sameAs_production.sql new file mode 100644 index 000000000..294247338 --- /dev/null +++ b/db/changes/10491-august/00-defaultPayDem_sameAs_production.sql @@ -0,0 +1,2 @@ +INSERT INTO `vn`.`payDem` (id,payDem) + VALUES (7,'0'); diff --git a/db/changes/10491-august/00-newSupplier_ACL.sql b/db/changes/10491-august/00-newSupplier_ACL.sql new file mode 100644 index 000000000..c88f3de3f --- /dev/null +++ b/db/changes/10491-august/00-newSupplier_ACL.sql @@ -0,0 +1,2 @@ +INSERT INTO `salix`.`ACL` (model,property,accessType,principalId) + VALUES ('Supplier','newSupplier','WRITE','administrative'); diff --git a/db/changes/10491-august/00-payMethodFk_Allow_Null.sql b/db/changes/10491-august/00-payMethodFk_Allow_Null.sql new file mode 100644 index 000000000..6d9931d3c --- /dev/null +++ b/db/changes/10491-august/00-payMethodFk_Allow_Null.sql @@ -0,0 +1 @@ +ALTER TABLE `vn`.`supplier` MODIFY COLUMN payMethodFk tinyint(3) unsigned NULL; \ No newline at end of file diff --git a/db/changes/10491-august/00-supplierActivityFk_Allow_Null.sql b/db/changes/10491-august/00-supplierActivityFk_Allow_Null.sql new file mode 100644 index 000000000..62aac0556 --- /dev/null +++ b/db/changes/10491-august/00-supplierActivityFk_Allow_Null.sql @@ -0,0 +1 @@ +ALTER TABLE `vn`.`supplier` MODIFY COLUMN supplierActivityFk varchar(45) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL NULL; \ No newline at end of file diff --git a/db/changes/10491-august/ticket_closeByTicket.sql b/db/changes/10491-august/00-ticket_closeByTicket.sql similarity index 85% rename from db/changes/10491-august/ticket_closeByTicket.sql rename to db/changes/10491-august/00-ticket_closeByTicket.sql index 25b04f629..f378b1146 100644 --- a/db/changes/10491-august/ticket_closeByTicket.sql +++ b/db/changes/10491-august/00-ticket_closeByTicket.sql @@ -1,7 +1,9 @@ drop procedure `vn`.`ticket_closeByTicket`; +DELIMITER $$ +$$ create - definer = root@localhost procedure `vn`.`ticket_closeByTicket`(IN vTicketFk int) + definer = `root`@`localhost` procedure `vn`.`ticket_closeByTicket`(IN vTicketFk int) BEGIN /** @@ -27,5 +29,7 @@ BEGIN CALL ticket_close(); DROP TEMPORARY TABLE tmp.ticket_close; -END; +END$$ +DELIMITER ; + diff --git a/db/changes/10491-august/delete.keep b/db/changes/10491-august/delete.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/db/changes/10500-november/00-ACL.sql b/db/changes/10500-november/00-ACL.sql new file mode 100644 index 000000000..0b726538c --- /dev/null +++ b/db/changes/10500-november/00-ACL.sql @@ -0,0 +1,5 @@ +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) +VALUES + ('ClaimRma', '*', 'READ', 'ALLOW', 'ROLE', 'claimManager'), + ('ClaimRma', '*', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'); + diff --git a/db/changes/10500-november/00-claim.sql b/db/changes/10500-november/00-claim.sql new file mode 100644 index 000000000..0b9879878 --- /dev/null +++ b/db/changes/10500-november/00-claim.sql @@ -0,0 +1 @@ +ALTER TABLE `vn`.`claim` ADD rma varchar(100) NULL ; \ No newline at end of file diff --git a/db/changes/10500-november/00-claimRma.sql b/db/changes/10500-november/00-claimRma.sql new file mode 100644 index 000000000..91e1ebaba --- /dev/null +++ b/db/changes/10500-november/00-claimRma.sql @@ -0,0 +1,7 @@ +CREATE TABLE `vn`.`claimRma` ( + id INT UNSIGNED auto_increment NOT NULL PRIMARY KEY, + code varchar(100) NOT NULL, + created timestamp DEFAULT current_timestamp() NOT NULL, + workerFk INTEGER UNSIGNED NOT NULL +) +ENGINE=InnoDB; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 7e59c1a54..5b769e285 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1380,13 +1380,6 @@ INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed (7, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'Movement 7', 0, 0, 'this is the note seven', 'observation seven'), (8, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'Movement 8', 1, 1, '', ''); -INSERT INTO `vn`.`claimRatio`(`clientFk`, `yearSale`, `claimAmount`, `claimingRate`, `priceIncreasing`, `packingRate`) - VALUES - (1101, 500, NULL, 0.00, 0.00, 1.00), - (1102, 1000, 2.00, 0.01, 0.05, 1.00), - (1103, 2000, 0.00, 0.00, 0.02, 1.00), - (1104, 2500, 150.00, 0.02, 0.10, 1.00); - INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `itemFk`, `itemTypeFk`, `saleTotal`, `saleWaste`, `rate`) VALUES ('CharlesXavier', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation', 1, 1, '1062', '51', '4.8'), @@ -1743,12 +1736,12 @@ INSERT INTO `vn`.`claimState`(`id`, `code`, `description`, `roleFk`, `priority`, ( 6, 'mana', 'Mana', 1, 4, 0), ( 7, 'lack', 'Faltas', 1, 2, 0); -INSERT INTO `vn`.`claim`(`id`, `ticketCreated`, `claimStateFk`, `clientFk`, `workerFk`, `responsibility`, `isChargedToMana`, `created`, `packages`) +INSERT INTO `vn`.`claim`(`id`, `ticketCreated`, `claimStateFk`, `clientFk`, `workerFk`, `responsibility`, `isChargedToMana`, `created`, `packages`, `rma`) VALUES - (1, util.VN_CURDATE(), 1, 1101, 18, 3, 0, util.VN_CURDATE(), 0), - (2, util.VN_CURDATE(), 2, 1101, 18, 3, 0, util.VN_CURDATE(), 1), - (3, util.VN_CURDATE(), 3, 1101, 18, 1, 1, util.VN_CURDATE(), 5), - (4, util.VN_CURDATE(), 3, 1104, 18, 5, 0, util.VN_CURDATE(), 10); + (1, util.VN_CURDATE(), 1, 1101, 18, 3, 0, util.VN_CURDATE(), 0, '02676A049183'), + (2, util.VN_CURDATE(), 2, 1101, 18, 3, 0, util.VN_CURDATE(), 1, NULL), + (3, util.VN_CURDATE(), 3, 1101, 18, 1, 1, util.VN_CURDATE(), 5, NULL), + (4, util.VN_CURDATE(), 3, 1104, 18, 5, 0, util.VN_CURDATE(), 10, NULL); INSERT INTO `vn`.`claimObservation` (`claimFk`, `workerFk`, `text`, `created`) VALUES @@ -1790,6 +1783,23 @@ INSERT INTO `vn`.`claimConfig`(`id`, `pickupContact`, `maxResponsibility`) (1, 'Contact description', 50), (2, 'Contact description', 30); +INSERT INTO `vn`.`claimRatio`(`clientFk`, `yearSale`, `claimAmount`, `claimingRate`, `priceIncreasing`, `packingRate`) + VALUES + (1101, 500, NULL, 0.00, 0.00, 1.00), + (1102, 1000, 2.00, 0.01, 0.05, 1.00), + (1103, 2000, 0.00, 0.00, 0.02, 1.00), + (1104, 2500, 150.00, 0.02, 0.10, 1.00); + +INSERT INTO vn.claimRma (`id`, `code`, `created`, `workerFk`) +VALUES + (1, '02676A049183', DEFAULT, 1106), + (2, '02676A049183', DEFAULT, 1106), + (3, '02676A049183', DEFAULT, 1107), + (4, '02676A049183', DEFAULT, 1107), + (5, '01837B023653', DEFAULT, 1106); + + + INSERT INTO `hedera`.`tpvMerchant`(`id`, `description`, `companyFk`, `bankFk`, `secretKey`) VALUES (1, 'Arkham Bank', 442, 1, 'h12387193H10238'), diff --git a/e2e/paths/13-supplier/03_fiscal_data.spec.js b/e2e/paths/13-supplier/03_fiscal_data.spec.js index 0238c8704..4f9581e32 100644 --- a/e2e/paths/13-supplier/03_fiscal_data.spec.js +++ b/e2e/paths/13-supplier/03_fiscal_data.spec.js @@ -31,7 +31,7 @@ describe('Supplier fiscal data path', () => { await page.clearInput(selectors.supplierFiscalData.taxNumber); await page.write(selectors.supplierFiscalData.taxNumber, 'Wrong tax number'); await page.clearInput(selectors.supplierFiscalData.account); - await page.write(selectors.supplierFiscalData.account, 'edited account number'); + await page.write(selectors.supplierFiscalData.account, '0123456789'); await page.autocompleteSearch(selectors.supplierFiscalData.sageWihholding, 'retencion estimacion objetiva'); await page.autocompleteSearch(selectors.supplierFiscalData.sageTaxType, 'operaciones no sujetas'); @@ -70,7 +70,7 @@ describe('Supplier fiscal data path', () => { it('should check the account was edited', async() => { const result = await page.waitToGetProperty(selectors.supplierFiscalData.account, 'value'); - expect(result).toEqual('edited account number'); + expect(result).toEqual('0123456789'); }); it('should check the sageWihholding was edited', async() => { diff --git a/modules/claim/back/methods/claim/getSummary.js b/modules/claim/back/methods/claim/getSummary.js index 8ab39eb45..ca376f853 100644 --- a/modules/claim/back/methods/claim/getSummary.js +++ b/modules/claim/back/methods/claim/getSummary.js @@ -47,7 +47,7 @@ module.exports = Self => { { relation: 'claimState', scope: { - fields: ['id', 'description'] + fields: ['id', 'code', 'description'] } }, { diff --git a/modules/claim/back/model-config.json b/modules/claim/back/model-config.json index e99a455ac..83d88039c 100644 --- a/modules/claim/back/model-config.json +++ b/modules/claim/back/model-config.json @@ -2,6 +2,9 @@ "Claim": { "dataSource": "vn" }, + "ClaimContainer": { + "dataSource": "claimStorage" + }, "ClaimBeginning": { "dataSource": "vn" }, @@ -41,7 +44,7 @@ "ClaimObservation": { "dataSource": "vn" }, - "ClaimContainer": { - "dataSource": "claimStorage" - } + "ClaimRma": { + "dataSource": "vn" + } } diff --git a/modules/claim/back/models/claim-rma.js b/modules/claim/back/models/claim-rma.js new file mode 100644 index 000000000..6a93613bd --- /dev/null +++ b/modules/claim/back/models/claim-rma.js @@ -0,0 +1,9 @@ +const LoopBackContext = require('loopback-context'); + +module.exports = Self => { + Self.observe('before save', async function(ctx) { + const changes = ctx.data || ctx.instance; + const loopBackContext = LoopBackContext.getCurrentContext(); + changes.workerFk = loopBackContext.active.accessToken.userId; + }); +}; diff --git a/modules/claim/back/models/claim-rma.json b/modules/claim/back/models/claim-rma.json new file mode 100644 index 000000000..e3849422c --- /dev/null +++ b/modules/claim/back/models/claim-rma.json @@ -0,0 +1,30 @@ +{ + "name": "ClaimRma", + "base": "VnModel", + "options": { + "mysql": { + "table": "claimRma" + } + }, + "properties": { + "id": { + "type": "number", + "id": true, + "description": "Identifier" + }, + "code": { + "type": "string", + "required": true + }, + "created": { + "type": "date" + } + }, + "relations": { + "worker": { + "type": "belongsTo", + "model": "Worker", + "foreignKey": "workerFk" + } + } +} diff --git a/modules/claim/back/models/claim.json b/modules/claim/back/models/claim.json index a3490ccf4..76125c483 100644 --- a/modules/claim/back/models/claim.json +++ b/modules/claim/back/models/claim.json @@ -46,6 +46,9 @@ }, "packages": { "type": "number" + }, + "rma": { + "type": "string" } }, "relations": { @@ -54,6 +57,12 @@ "model": "ClaimState", "foreignKey": "claimStateFk" }, + "claimRma": { + "type": "belongsTo", + "model": "ClaimRma", + "foreignKey": "rma", + "primaryKey": "code" + }, "client": { "type": "belongsTo", "model": "Client", diff --git a/modules/client/back/methods/client/checkDuplicated.js b/modules/client/back/methods/client/checkDuplicated.js index acaffbf42..522cd088f 100644 --- a/modules/client/back/methods/client/checkDuplicated.js +++ b/modules/client/back/methods/client/checkDuplicated.js @@ -25,10 +25,9 @@ module.exports = Self => { const client = await Self.app.models.Client.findById(id, myOptions); - const emails = client.email ? client.email.split(',') : null; - const findParams = []; - if (emails.length) { + if (client.email) { + const emails = client.email.split(','); for (let email of emails) findParams.push({email: email}); } diff --git a/modules/client/back/methods/receipt/receiptPdf.js b/modules/client/back/methods/receipt/receiptPdf.js new file mode 100644 index 000000000..f55e05040 --- /dev/null +++ b/modules/client/back/methods/receipt/receiptPdf.js @@ -0,0 +1,55 @@ +const {Report} = require('vn-print'); + +module.exports = Self => { + Self.remoteMethodCtx('receiptPdf', { + description: 'Returns the receipt pdf', + accepts: [ + { + arg: 'id', + type: 'number', + required: true, + description: 'The claim id', + http: {source: 'path'} + }, + { + arg: 'recipientId', + type: 'number', + description: 'The recipient id', + required: false + } + ], + returns: [ + { + arg: 'body', + type: 'file', + root: true + }, { + arg: 'Content-Type', + type: 'String', + http: {target: 'header'} + }, { + arg: 'Content-Disposition', + type: 'String', + http: {target: 'header'} + } + ], + http: { + path: '/:id/receipt-pdf', + verb: 'GET' + } + }); + + Self.receiptPdf = async(ctx, id) => { + const args = Object.assign({}, ctx.args); + const params = {lang: ctx.req.getLocale()}; + + delete args.ctx; + for (const param in args) + params[param] = args[param]; + + const report = new Report('receipt', params); + const stream = await report.toPdfStream(); + + return [stream, 'application/pdf', `filename="doc-${id}.pdf"`]; + }; +}; diff --git a/modules/client/back/models/receipt.js b/modules/client/back/models/receipt.js index 36a4a8952..b79102e6b 100644 --- a/modules/client/back/models/receipt.js +++ b/modules/client/back/models/receipt.js @@ -2,6 +2,7 @@ const LoopBackContext = require('loopback-context'); module.exports = function(Self) { require('../methods/receipt/filter')(Self); + require('../methods/receipt/receiptPdf')(Self); Self.validateBinded('amountPaid', isNotZero, { message: 'Amount cannot be zero', diff --git a/modules/client/front/balance/create/index.js b/modules/client/front/balance/create/index.js index c6a6e7ff9..935129574 100644 --- a/modules/client/front/balance/create/index.js +++ b/modules/client/front/balance/create/index.js @@ -144,12 +144,8 @@ class Controller extends Dialog { }) .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))) .then(() => { - if (this.viewReceipt) { - this.vnReport.show('receipt', { - receiptId: receiptId, - companyId: this.companyFk - }); - } + if (this.viewReceipt) + this.vnReport.show(`Receipts/${receiptId}/receipt-pdf`); }); } diff --git a/modules/client/front/balance/create/index.spec.js b/modules/client/front/balance/create/index.spec.js index 77fe32e0f..fa6b48ea4 100644 --- a/modules/client/front/balance/create/index.spec.js +++ b/modules/client/front/balance/create/index.spec.js @@ -85,6 +85,8 @@ describe('Client', () => { }); it('should make an http POST query and then call to the report show() method', () => { + const receiptId = 1; + jest.spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnReport, 'show'); window.open = jest.fn(); @@ -92,14 +94,12 @@ describe('Client', () => { controller.$params = {id: 1101}; controller.viewReceipt = true; - $httpBackend.expect('POST', `Clients/1101/createReceipt`).respond({id: 1}); + $httpBackend.expect('POST', `Clients/1101/createReceipt`).respond({id: receiptId}); controller.responseHandler('accept'); $httpBackend.flush(); - const expectedParams = {receiptId: 1, companyId: 442}; - expect(controller.vnApp.showSuccess).toHaveBeenCalled(); - expect(controller.vnReport.show).toHaveBeenCalledWith('receipt', expectedParams); + expect(controller.vnReport.show).toHaveBeenCalledWith(`Receipts/${receiptId}/receipt-pdf`); }); }); diff --git a/modules/route/back/methods/route/driverRoutePdf.js b/modules/route/back/methods/route/driverRoutePdf.js index 161eb71af..65748afad 100644 --- a/modules/route/back/methods/route/driverRoutePdf.js +++ b/modules/route/back/methods/route/driverRoutePdf.js @@ -6,9 +6,9 @@ module.exports = Self => { accepts: [ { arg: 'id', - type: 'number', + type: 'string', required: true, - description: 'The client id', + description: 'The route id', http: {source: 'path'} }, { diff --git a/modules/route/front/index/index.js b/modules/route/front/index/index.js index 6845bf73f..9258c8fac 100644 --- a/modules/route/front/index/index.js +++ b/modules/route/front/index/index.js @@ -39,10 +39,7 @@ export default class Controller extends Section { routes.push(route.id); const routesId = routes.join(','); - this.vnReport.show('driver-route', { - authorization: this.vnToken.token, - routeId: routesId - }); + this.vnReport.show(`Routes/${routesId}/driver-route-pdf`); } openClonationDialog() { diff --git a/modules/route/front/index/index.spec.js b/modules/route/front/index/index.spec.js index 37386bc38..05dd56433 100644 --- a/modules/route/front/index/index.spec.js +++ b/modules/route/front/index/index.spec.js @@ -49,14 +49,12 @@ describe('Component vnRouteIndex', () => { const data = controller.$.model.data; data[0].checked = true; data[2].checked = true; - const expectedParams = { - authorization: null, - routeId: '1,3' - }; + + const routeIds = '1,3'; controller.showRouteReport(); - expect(controller.vnReport.show).toHaveBeenCalledWith('driver-route', expectedParams); + expect(controller.vnReport.show).toHaveBeenCalledWith(`Routes/${routeIds}/driver-route-pdf`); }); }); diff --git a/modules/supplier/back/methods/supplier/filter.js b/modules/supplier/back/methods/supplier/filter.js index 3500afacd..0b473f7df 100644 --- a/modules/supplier/back/methods/supplier/filter.js +++ b/modules/supplier/back/methods/supplier/filter.js @@ -95,8 +95,8 @@ module.exports = Self => { pm.name AS payMethod, pd.payDem AS payDem FROM vn.supplier s - JOIN vn.payMethod pm ON pm.id = s.payMethodFk - JOIN vn.payDem pd ON pd.id = s.payDemFk` + LEFT JOIN vn.payMethod pm ON pm.id = s.payMethodFk + LEFT JOIN vn.payDem pd ON pd.id = s.payDemFk` ); stmt.merge(conn.makeSuffix(filter)); diff --git a/modules/supplier/back/methods/supplier/newSupplier.js b/modules/supplier/back/methods/supplier/newSupplier.js new file mode 100644 index 000000000..f4059a259 --- /dev/null +++ b/modules/supplier/back/methods/supplier/newSupplier.js @@ -0,0 +1,45 @@ +module.exports = Self => { + Self.remoteMethod('newSupplier', { + description: 'Creates a new supplier and returns it', + accessType: 'WRITE', + accepts: [{ + arg: 'params', + type: 'object', + http: {source: 'body'} + }], + returns: { + type: 'string', + root: true + }, + http: { + path: `/newSupplier`, + verb: 'POST' + } + }); + + Self.newSupplier = async params => { + const models = Self.app.models; + const myOptions = {}; + + if (typeof(params) == 'string') + params = JSON.parse(params); + + params.nickname = params.name; + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const supplier = await models.Supplier.create(params, myOptions); + + if (tx) await tx.commit(); + + return supplier; + } catch (e) { + if (tx) await tx.rollback(); + return params; + } + }; +}; diff --git a/modules/supplier/back/methods/supplier/specs/filter.spec.js b/modules/supplier/back/methods/supplier/specs/filter.spec.js index 1f74b10ff..2620bb687 100644 --- a/modules/supplier/back/methods/supplier/specs/filter.spec.js +++ b/modules/supplier/back/methods/supplier/specs/filter.spec.js @@ -10,7 +10,7 @@ describe('Supplier filter()', () => { let result = await app.models.Supplier.filter(ctx); - expect(result.length).toEqual(1); + expect(result.length).toBeGreaterThanOrEqual(1); expect(result[0].id).toEqual(1); }); diff --git a/modules/supplier/back/methods/supplier/specs/newSupplier.spec.js b/modules/supplier/back/methods/supplier/specs/newSupplier.spec.js new file mode 100644 index 000000000..8f22a4f20 --- /dev/null +++ b/modules/supplier/back/methods/supplier/specs/newSupplier.spec.js @@ -0,0 +1,30 @@ +const app = require('vn-loopback/server/server'); +const LoopBackContext = require('loopback-context'); + +describe('Supplier newSupplier()', () => { + const newSupp = { + name: 'TestSupplier-1' + }; + const administrativeId = 5; + + it('should create a new supplier containing only the name', async() => { + const activeCtx = { + accessToken: {userId: administrativeId}, + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + + let result = await app.models.Supplier.newSupplier(JSON.stringify(newSupp)); + + expect(result.name).toEqual('TestSupplier-1'); + expect(result.id).toEqual(443); + + const createdSupplier = await app.models.Supplier.findById(result.id); + + expect(createdSupplier.id).toEqual(result.id); + expect(createdSupplier.name).toEqual(result.name); + expect(createdSupplier.payDemFk).toEqual(7); + expect(createdSupplier.nickname).toEqual(result.name); + }); +}); diff --git a/modules/supplier/back/models/supplier.js b/modules/supplier/back/models/supplier.js index c9af7b297..44549c65c 100644 --- a/modules/supplier/back/models/supplier.js +++ b/modules/supplier/back/models/supplier.js @@ -10,6 +10,7 @@ module.exports = Self => { require('../methods/supplier/freeAgencies')(Self); require('../methods/supplier/campaignMetricsPdf')(Self); require('../methods/supplier/campaignMetricsEmail')(Self); + require('../methods/supplier/newSupplier')(Self); Self.validatesPresenceOf('name', { message: 'The social name cannot be empty' @@ -19,13 +20,17 @@ module.exports = Self => { message: 'The supplier name must be unique' }); - Self.validatesPresenceOf('city', { - message: 'City cannot be empty' - }); + if (this.city) { + Self.validatesPresenceOf('city', { + message: 'City cannot be empty' + }); + } - Self.validatesPresenceOf('nif', { - message: 'The nif cannot be empty' - }); + if (this.nif) { + Self.validatesPresenceOf('nif', { + message: 'The nif cannot be empty' + }); + } Self.validatesUniquenessOf('nif', { message: 'TIN must be unique' @@ -57,6 +62,9 @@ module.exports = Self => { } async function tinIsValid(err, done) { + if (!this.countryFk) + return done(); + const filter = { fields: ['code'], where: {id: this.countryFk} @@ -80,6 +88,7 @@ module.exports = Self => { }); async function hasSupplierAccount(err, done) { + if (!this.payMethodFk) return done(); const payMethod = await Self.app.models.PayMethod.findById(this.payMethodFk); const supplierAccount = await Self.app.models.SupplierAccount.findOne({where: {supplierFk: this.id}}); const hasIban = supplierAccount && supplierAccount.iban; @@ -92,6 +101,7 @@ module.exports = Self => { } Self.observe('before save', async function(ctx) { + if (ctx.isNewInstance) return; const loopbackContext = LoopBackContext.getCurrentContext(); const changes = ctx.data || ctx.instance; const orgData = ctx.currentInstance; @@ -101,7 +111,7 @@ module.exports = Self => { const isPayMethodChecked = changes.isPayMethodChecked || orgData.isPayMethodChecked; const hasChanges = orgData && changes; const isPayMethodCheckedChanged = hasChanges - && orgData.isPayMethodChecked != isPayMethodChecked; + && orgData.isPayMethodChecked != isPayMethodChecked; if (isNotFinancial && isPayMethodCheckedChanged) throw new UserError('You can not modify is pay method checked'); @@ -114,7 +124,7 @@ module.exports = Self => { const socialName = changes.name || orgData.name; const hasChanges = orgData && changes; const socialNameChanged = hasChanges - && orgData.socialName != socialName; + && orgData.socialName != socialName; if ((socialNameChanged) && !isAlpha(socialName)) throw new UserError('The social name has an invalid format'); diff --git a/modules/supplier/front/create/index.html b/modules/supplier/front/create/index.html new file mode 100644 index 000000000..446a16cb6 --- /dev/null +++ b/modules/supplier/front/create/index.html @@ -0,0 +1,29 @@ + + +
+ + + + + + + + + + + + +
diff --git a/modules/supplier/front/create/index.js b/modules/supplier/front/create/index.js new file mode 100644 index 000000000..c33367dac --- /dev/null +++ b/modules/supplier/front/create/index.js @@ -0,0 +1,23 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +class Controller extends Section { + constructor($element, $) { + super($element, $); + } + + onSubmit() { + this.$.watcher.submit().then( + json => { + this.$state.go(`supplier.card.fiscalData`, {id: json.data.id}); + } + ); + } +} + +Controller.$inject = ['$element', '$scope']; + +ngModule.vnComponent('vnSupplierCreate', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/supplier/front/index.js b/modules/supplier/front/index.js index ba2768854..9216d0781 100644 --- a/modules/supplier/front/index.js +++ b/modules/supplier/front/index.js @@ -20,3 +20,4 @@ import './address/create'; import './address/edit'; import './agency-term/index'; import './agency-term/create'; +import './create/index'; diff --git a/modules/supplier/front/index/index.html b/modules/supplier/front/index/index.html index 87e822eea..49f38cb1b 100644 --- a/modules/supplier/front/index/index.html +++ b/modules/supplier/front/index/index.html @@ -58,4 +58,7 @@ - \ No newline at end of file + + + + \ No newline at end of file diff --git a/modules/supplier/front/index/locale/es.yml b/modules/supplier/front/index/locale/es.yml index ad8a4f0bb..ce06f462c 100644 --- a/modules/supplier/front/index/locale/es.yml +++ b/modules/supplier/front/index/locale/es.yml @@ -2,4 +2,5 @@ Payment deadline: Plazo de pago Pay day: Dia de pago Account: Cuenta Pay method: Metodo de pago -Tax number: Nif \ No newline at end of file +Tax number: Nif +New supplier: Nuevo proveedor \ No newline at end of file diff --git a/modules/supplier/front/routes.json b/modules/supplier/front/routes.json index 61420b40d..75b8213cb 100644 --- a/modules/supplier/front/routes.json +++ b/modules/supplier/front/routes.json @@ -30,7 +30,7 @@ "abstract": true, "component": "vn-supplier", "description": "Suppliers" - }, + }, { "url": "/index?q", "state": "supplier.index", @@ -51,6 +51,13 @@ "params": { "supplier": "$ctrl.supplier" } + }, + { + "url": "/create", + "state": "supplier.create", + "component": "vn-supplier-create", + "acl": ["administrative"], + "description": "New supplier" }, { "url": "/basic-data", diff --git a/print/boot.js b/print/boot.js deleted file mode 100644 index d5c06264c..000000000 --- a/print/boot.js +++ /dev/null @@ -1,54 +0,0 @@ -const express = require('express'); -const path = require('path'); -const fs = require('fs'); - -const templatesPath = path.resolve(__dirname, './templates'); -const componentsPath = path.resolve(__dirname, './core/components'); - -module.exports = async app => { - global.appPath = __dirname; - - process.env.OPENSSL_CONF = '/etc/ssl/'; - - // Extended locale intl polyfill - const IntlPolyfill = require('intl'); - Intl.NumberFormat = IntlPolyfill.NumberFormat; - Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat; - - // Init database instance - require('./core/database').init(); - // Init SMTP Instance - require('./core/smtp').init(); - require('./core/mixins'); - require('./core/filters'); - require('./core/directives'); - // Init router - require('./core/router')(app); - - /** - * Serve component static files - */ - const componentsDir = fs.readdirSync(componentsPath); - componentsDir.forEach(componentName => { - const componentDir = path.join(componentsPath, '/', componentName); - const assetsDir = `${componentDir}/assets`; - - app.use(`/api/${componentName}/assets`, express.static(assetsDir)); - }); - - /** - * Serve static files - */ - const templatesDir = fs.readdirSync(templatesPath); - templatesDir.forEach(directory => { - const templateTypeDir = path.join(templatesPath, '/', directory); - const templates = fs.readdirSync(templateTypeDir); - - templates.forEach(templateName => { - const templateDir = path.join(templatesPath, '/', directory, '/', templateName); - const assetsDir = `${templateDir}/assets`; - - app.use(`/api/${templateName}/assets`, express.static(assetsDir)); - }); - }); -}; diff --git a/print/core/cluster.js b/print/core/cluster.js new file mode 100644 index 000000000..7a1a665d0 --- /dev/null +++ b/print/core/cluster.js @@ -0,0 +1,42 @@ +const {Cluster} = require('puppeteer-cluster'); +const log4js = require('log4js'); +const {cpus} = require('os'); + +module.exports = { + init() { + if (!this.pool) { + Cluster.launch({ + concurrency: Cluster.CONCURRENCY_CONTEXT, + maxConcurrency: cpus().length, + puppeteerOptions: { + args: [ + '--no-sandbox', + '--disable-setuid-sandbox', + '--no-zygote' + ] + } + }) + .then(cluster => { + this.pool = cluster; + + log4js.configure({ + appenders: { + out: {type: 'stdout'} + }, + categories: {default: {appenders: ['out'], level: 'info'}}, + }); + + const logger = log4js.getLogger(); + + cluster.on('taskerror', (err, data, willRetry) => { + if (willRetry) + logger.warn(`[Print] => ${err.message}\nThis job will be retried`); + else + logger.error(`[Print] => ${err.message}`); + }); + + cluster.on('queue', () => logger.info('Printing task initialized by pool')); + }); + } + } +}; diff --git a/print/core/database.js b/print/core/database.js index 0e81806f2..ddc0153bd 100644 --- a/print/core/database.js +++ b/print/core/database.js @@ -1,5 +1,4 @@ const mysql = require('mysql2'); -const config = require('./config.js'); const fs = require('fs-extra'); module.exports = { diff --git a/print/core/report.js b/print/core/report.js index 4dad566f3..c5182d1a8 100644 --- a/print/core/report.js +++ b/print/core/report.js @@ -2,7 +2,7 @@ const fs = require('fs'); const path = require('path'); const config = require('./config'); const Component = require('./component'); -const puppeteer = require('puppeteer'); +const Cluster = require('./cluster'); if (!process.env.OPENSSL_CONF) process.env.OPENSSL_CONF = '/etc/ssl/'; @@ -32,39 +32,30 @@ class Report extends Component { if (fs.existsSync(fullPath)) options = require(optionsPath); - const browser = await puppeteer.launch({ - headless: true, - args: [ - '--no-sandbox', - '--disable-setuid-sandbox', - '--single-process', - '--no-zygote' - ] + return new Promise(resolve => { + Cluster.pool.queue({}, async({page}) => { + await page.emulateMediaType('screen'); + await page.setContent(template); + + const element = await page.$('#pageFooter'); + + let footer = '\n'; + if (element) { + footer = await page.evaluate(el => { + const html = el.innerHTML; + el.remove(); + return html; + }, element); + } + + options.headerTemplate = '\n'; + options.footerTemplate = footer; + + const stream = await page.pdf(options); + + resolve(stream); + }); }); - - const page = (await browser.pages())[0]; - await page.emulateMediaType('screen'); - await page.setContent(template); - - const element = await page.$('#pageFooter'); - - let footer = '\n'; - if (element) { - footer = await page.evaluate(el => { - const html = el.innerHTML; - el.remove(); - return html; - }, element); - } - - options.headerTemplate = '\n'; - options.footerTemplate = footer; - - const buffer = await page.pdf(options); - - await browser.close(); - - return buffer; } /** diff --git a/print/index.js b/print/index.js index 484aba00e..2ed713897 100644 --- a/print/index.js +++ b/print/index.js @@ -7,10 +7,15 @@ const componentsPath = path.resolve(__dirname, './core/components'); module.exports = { async boot(app) { - // Init database instance + // Extended locale intl polyfill + const IntlPolyfill = require('intl'); + Intl.NumberFormat = IntlPolyfill.NumberFormat; + Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat; + // Init database instance require('./core/database').init(app.dataSources); require('./core/smtp').init(); + require('./core/cluster').init(); require('./core/mixins'); require('./core/filters'); diff --git a/print/package-lock.json b/print/package-lock.json index 8e55f5c1e..02c5fa77d 100644 --- a/print/package-lock.json +++ b/print/package-lock.json @@ -14,9 +14,10 @@ "js-yaml": "^3.13.1", "jsonexport": "^3.2.0", "juice": "^5.2.0", + "log4js": "^6.7.0", "mysql2": "^1.7.0", "nodemailer": "^4.7.0", - "puppeteer": "^18.0.5", + "puppeteer-cluster": "^0.23.0", "qrcode": "^1.4.2", "strftime": "^0.10.0", "vue": "^2.6.10", @@ -37,12 +38,14 @@ "node_modules/@types/node": { "version": "18.8.2", "license": "MIT", - "optional": true + "optional": true, + "peer": true }, "node_modules/@types/yauzl": { "version": "2.10.0", "license": "MIT", "optional": true, + "peer": true, "dependencies": { "@types/node": "*" } @@ -58,6 +61,7 @@ "node_modules/agent-base": { "version": "6.0.2", "license": "MIT", + "peer": true, "dependencies": { "debug": "4" }, @@ -138,7 +142,8 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/base64-js": { "version": "1.5.1", @@ -156,7 +161,8 @@ "url": "https://feross.org/support" } ], - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", @@ -168,6 +174,7 @@ "node_modules/bl": { "version": "4.1.0", "license": "MIT", + "peer": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -181,6 +188,7 @@ "node_modules/brace-expansion": { "version": "1.1.11", "license": "MIT", + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -203,6 +211,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -211,6 +220,7 @@ "node_modules/buffer-crc32": { "version": "0.2.13", "license": "MIT", + "peer": true, "engines": { "node": "*" } @@ -265,7 +275,8 @@ }, "node_modules/chownr": { "version": "1.1.4", - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/cliui": { "version": "6.0.0", @@ -303,7 +314,8 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/core-util-is": { "version": "1.0.2", @@ -312,6 +324,7 @@ "node_modules/cross-fetch": { "version": "3.1.5", "license": "MIT", + "peer": true, "dependencies": { "node-fetch": "2.6.7" } @@ -372,6 +385,14 @@ "node": ">= 4" } }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "engines": { + "node": ">=4.0" + } + }, "node_modules/debug": { "version": "4.3.4", "license": "MIT", @@ -417,7 +438,8 @@ }, "node_modules/devtools-protocol": { "version": "0.0.1045489", - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/dijkstrajs": { "version": "1.0.2", @@ -468,6 +490,7 @@ "node_modules/end-of-stream": { "version": "1.4.4", "license": "MIT", + "peer": true, "dependencies": { "once": "^1.4.0" } @@ -501,6 +524,7 @@ "node_modules/extract-zip": { "version": "2.0.1", "license": "BSD-2-Clause", + "peer": true, "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -534,6 +558,7 @@ "node_modules/fd-slicer": { "version": "1.1.0", "license": "MIT", + "peer": true, "dependencies": { "pend": "~1.2.0" } @@ -549,6 +574,11 @@ "node": ">=8" } }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" + }, "node_modules/forever-agent": { "version": "0.6.1", "license": "Apache-2.0", @@ -570,7 +600,8 @@ }, "node_modules/fs-constants": { "version": "1.0.0", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/fs-extra": { "version": "7.0.1", @@ -586,7 +617,8 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/function-bind": { "version": "1.1.1", @@ -609,6 +641,7 @@ "node_modules/get-stream": { "version": "5.2.0", "license": "MIT", + "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -629,6 +662,7 @@ "node_modules/glob": { "version": "7.2.3", "license": "ISC", + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -723,6 +757,7 @@ "node_modules/https-proxy-agent": { "version": "5.0.1", "license": "MIT", + "peer": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -757,7 +792,8 @@ "url": "https://feross.org/support" } ], - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/image-size": { "version": "0.7.5", @@ -772,6 +808,7 @@ "node_modules/inflight": { "version": "1.0.6", "license": "ISC", + "peer": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -976,6 +1013,21 @@ "version": "4.5.0", "license": "MIT" }, + "node_modules/log4js": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.0.tgz", + "integrity": "sha512-KA0W9ffgNBLDj6fZCq/lRbgR6ABAodRIDHrZnS48vOtfKa4PzWImb0Md1lmGCdO3n3sbCm/n1/WmrNlZ8kCI3Q==", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.3" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/long": { "version": "4.0.0", "license": "Apache-2.0" @@ -1021,6 +1073,7 @@ "node_modules/minimatch": { "version": "3.1.2", "license": "ISC", + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1030,7 +1083,8 @@ }, "node_modules/mkdirp-classic": { "version": "0.5.3", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/ms": { "version": "2.1.2", @@ -1092,6 +1146,7 @@ "node_modules/node-fetch": { "version": "2.6.7", "license": "MIT", + "peer": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -1131,6 +1186,7 @@ "node_modules/once": { "version": "1.4.0", "license": "ISC", + "peer": true, "dependencies": { "wrappy": "1" } @@ -1175,6 +1231,7 @@ "node_modules/path-is-absolute": { "version": "1.0.1", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -1192,7 +1249,8 @@ }, "node_modules/pend": { "version": "1.2.0", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/performance-now": { "version": "2.1.0", @@ -1234,13 +1292,15 @@ "node_modules/progress": { "version": "2.0.3", "license": "MIT", + "peer": true, "engines": { "node": ">=0.4.0" } }, "node_modules/proxy-from-env": { "version": "1.1.0", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/pseudomap": { "version": "1.0.2", @@ -1253,6 +1313,7 @@ "node_modules/pump": { "version": "3.0.0", "license": "MIT", + "peer": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -1269,6 +1330,7 @@ "version": "18.2.0", "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "https-proxy-agent": "5.0.1", "progress": "2.0.3", @@ -1279,9 +1341,21 @@ "node": ">=14.1.0" } }, + "node_modules/puppeteer-cluster": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/puppeteer-cluster/-/puppeteer-cluster-0.23.0.tgz", + "integrity": "sha512-108terIWDzPrQopmoYSPd5yDoy3FGJ2dNnoGMkGYPs6xtkdhgaECwpfZkzaRToMQPZibUOz0/dSSGgPEdXEhkQ==", + "dependencies": { + "debug": "^4.3.3" + }, + "peerDependencies": { + "puppeteer": ">=1.5.0" + } + }, "node_modules/puppeteer-core": { "version": "18.2.0", "license": "Apache-2.0", + "peer": true, "dependencies": { "cross-fetch": "3.1.5", "debug": "4.3.4", @@ -1396,9 +1470,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, "node_modules/rimraf": { "version": "3.0.2", "license": "ISC", + "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -1524,6 +1604,32 @@ "node": ">=0.10.0" } }, + "node_modules/streamroller": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", + "integrity": "sha512-CphIJyFx2SALGHeINanjFRKQ4l7x2c+rXYJ4BMq0gd+ZK0gi4VT8b+eHe2wi58x4UayBAKx4xtHpXT/ea1cz8w==", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/streamroller/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/strftime": { "version": "0.10.1", "license": "MIT", @@ -1583,6 +1689,7 @@ "node_modules/tar-fs": { "version": "2.1.1", "license": "MIT", + "peer": true, "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -1593,6 +1700,7 @@ "node_modules/tar-stream": { "version": "2.2.0", "license": "MIT", + "peer": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -1606,7 +1714,8 @@ }, "node_modules/through": { "version": "2.3.8", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/tough-cookie": { "version": "2.5.0", @@ -1621,7 +1730,8 @@ }, "node_modules/tr46": { "version": "0.0.3", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/tunnel-agent": { "version": "0.6.0", @@ -1640,6 +1750,7 @@ "node_modules/unbzip2-stream": { "version": "1.4.3", "license": "MIT", + "peer": true, "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -1891,11 +2002,13 @@ }, "node_modules/webidl-conversions": { "version": "3.0.1", - "license": "BSD-2-Clause" + "license": "BSD-2-Clause", + "peer": true }, "node_modules/whatwg-url": { "version": "5.0.0", "license": "MIT", + "peer": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -1956,11 +2069,13 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/ws": { "version": "8.9.0", "license": "MIT", + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -2026,6 +2141,7 @@ "node_modules/yauzl": { "version": "2.10.0", "license": "MIT", + "peer": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -2038,11 +2154,13 @@ }, "@types/node": { "version": "18.8.2", - "optional": true + "optional": true, + "peer": true }, "@types/yauzl": { "version": "2.10.0", "optional": true, + "peer": true, "requires": { "@types/node": "*" } @@ -2057,6 +2175,7 @@ }, "agent-base": { "version": "6.0.2", + "peer": true, "requires": { "debug": "4" } @@ -2107,10 +2226,12 @@ "version": "1.11.0" }, "balanced-match": { - "version": "1.0.2" + "version": "1.0.2", + "peer": true }, "base64-js": { - "version": "1.5.1" + "version": "1.5.1", + "peer": true }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -2120,6 +2241,7 @@ }, "bl": { "version": "4.1.0", + "peer": true, "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -2131,6 +2253,7 @@ }, "brace-expansion": { "version": "1.1.11", + "peer": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2138,13 +2261,15 @@ }, "buffer": { "version": "5.7.1", + "peer": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "buffer-crc32": { - "version": "0.2.13" + "version": "0.2.13", + "peer": true }, "camelcase": { "version": "5.3.1" @@ -2182,7 +2307,8 @@ } }, "chownr": { - "version": "1.1.4" + "version": "1.1.4", + "peer": true }, "cliui": { "version": "6.0.0", @@ -2211,13 +2337,15 @@ "version": "2.20.3" }, "concat-map": { - "version": "0.0.1" + "version": "0.0.1", + "peer": true }, "core-util-is": { "version": "1.0.2" }, "cross-fetch": { "version": "3.1.5", + "peer": true, "requires": { "node-fetch": "2.6.7" } @@ -2260,6 +2388,11 @@ "mimer": "^1.0.0" } }, + "date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==" + }, "debug": { "version": "4.3.4", "requires": { @@ -2279,7 +2412,8 @@ "version": "1.5.1" }, "devtools-protocol": { - "version": "0.0.1045489" + "version": "0.0.1045489", + "peer": true }, "dijkstrajs": { "version": "1.0.2" @@ -2322,6 +2456,7 @@ }, "end-of-stream": { "version": "1.4.4", + "peer": true, "requires": { "once": "^1.4.0" } @@ -2340,6 +2475,7 @@ }, "extract-zip": { "version": "2.0.1", + "peer": true, "requires": { "@types/yauzl": "^2.9.1", "debug": "^4.1.1", @@ -2358,6 +2494,7 @@ }, "fd-slicer": { "version": "1.1.0", + "peer": true, "requires": { "pend": "~1.2.0" } @@ -2369,6 +2506,11 @@ "path-exists": "^4.0.0" } }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" + }, "forever-agent": { "version": "0.6.1" }, @@ -2381,7 +2523,8 @@ } }, "fs-constants": { - "version": "1.0.0" + "version": "1.0.0", + "peer": true }, "fs-extra": { "version": "7.0.1", @@ -2392,7 +2535,8 @@ } }, "fs.realpath": { - "version": "1.0.0" + "version": "1.0.0", + "peer": true }, "function-bind": { "version": "1.1.1" @@ -2408,6 +2552,7 @@ }, "get-stream": { "version": "5.2.0", + "peer": true, "requires": { "pump": "^3.0.0" } @@ -2420,6 +2565,7 @@ }, "glob": { "version": "7.2.3", + "peer": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2478,6 +2624,7 @@ }, "https-proxy-agent": { "version": "5.0.1", + "peer": true, "requires": { "agent-base": "6", "debug": "4" @@ -2490,13 +2637,15 @@ } }, "ieee754": { - "version": "1.2.1" + "version": "1.2.1", + "peer": true }, "image-size": { "version": "0.7.5" }, "inflight": { "version": "1.0.6", + "peer": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -2642,6 +2791,18 @@ "lodash.uniq": { "version": "4.5.0" }, + "log4js": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.0.tgz", + "integrity": "sha512-KA0W9ffgNBLDj6fZCq/lRbgR6ABAodRIDHrZnS48vOtfKa4PzWImb0Md1lmGCdO3n3sbCm/n1/WmrNlZ8kCI3Q==", + "requires": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.3" + } + }, "long": { "version": "4.0.0" }, @@ -2668,12 +2829,14 @@ }, "minimatch": { "version": "3.1.2", + "peer": true, "requires": { "brace-expansion": "^1.1.7" } }, "mkdirp-classic": { - "version": "0.5.3" + "version": "0.5.3", + "peer": true }, "ms": { "version": "2.1.2" @@ -2717,6 +2880,7 @@ }, "node-fetch": { "version": "2.6.7", + "peer": true, "requires": { "whatwg-url": "^5.0.0" } @@ -2735,6 +2899,7 @@ }, "once": { "version": "1.4.0", + "peer": true, "requires": { "wrappy": "1" } @@ -2758,7 +2923,8 @@ "version": "4.0.0" }, "path-is-absolute": { - "version": "1.0.1" + "version": "1.0.1", + "peer": true }, "path-key": { "version": "2.0.1" @@ -2767,7 +2933,8 @@ "version": "1.0.7" }, "pend": { - "version": "1.2.0" + "version": "1.2.0", + "peer": true }, "performance-now": { "version": "2.1.0" @@ -2787,10 +2954,12 @@ } }, "progress": { - "version": "2.0.3" + "version": "2.0.3", + "peer": true }, "proxy-from-env": { - "version": "1.1.0" + "version": "1.1.0", + "peer": true }, "pseudomap": { "version": "1.0.2" @@ -2800,6 +2969,7 @@ }, "pump": { "version": "3.0.0", + "peer": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -2810,6 +2980,7 @@ }, "puppeteer": { "version": "18.2.0", + "peer": true, "requires": { "https-proxy-agent": "5.0.1", "progress": "2.0.3", @@ -2817,8 +2988,17 @@ "puppeteer-core": "18.2.0" } }, + "puppeteer-cluster": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/puppeteer-cluster/-/puppeteer-cluster-0.23.0.tgz", + "integrity": "sha512-108terIWDzPrQopmoYSPd5yDoy3FGJ2dNnoGMkGYPs6xtkdhgaECwpfZkzaRToMQPZibUOz0/dSSGgPEdXEhkQ==", + "requires": { + "debug": "^4.3.3" + } + }, "puppeteer-core": { "version": "18.2.0", + "peer": true, "requires": { "cross-fetch": "3.1.5", "debug": "4.3.4", @@ -2897,8 +3077,14 @@ "supports-preserve-symlinks-flag": "^1.0.0" } }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, "rimraf": { "version": "3.0.2", + "peer": true, "requires": { "glob": "^7.1.3" } @@ -2962,6 +3148,28 @@ "tweetnacl": "~0.14.0" } }, + "streamroller": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", + "integrity": "sha512-CphIJyFx2SALGHeINanjFRKQ4l7x2c+rXYJ4BMq0gd+ZK0gi4VT8b+eHe2wi58x4UayBAKx4xtHpXT/ea1cz8w==", + "requires": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "dependencies": { + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } + } + }, "strftime": { "version": "0.10.1" }, @@ -2996,6 +3204,7 @@ }, "tar-fs": { "version": "2.1.1", + "peer": true, "requires": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -3005,6 +3214,7 @@ }, "tar-stream": { "version": "2.2.0", + "peer": true, "requires": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -3014,7 +3224,8 @@ } }, "through": { - "version": "2.3.8" + "version": "2.3.8", + "peer": true }, "tough-cookie": { "version": "2.5.0", @@ -3024,7 +3235,8 @@ } }, "tr46": { - "version": "0.0.3" + "version": "0.0.3", + "peer": true }, "tunnel-agent": { "version": "0.6.0", @@ -3037,6 +3249,7 @@ }, "unbzip2-stream": { "version": "1.4.3", + "peer": true, "requires": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -3197,10 +3410,12 @@ } }, "webidl-conversions": { - "version": "3.0.1" + "version": "3.0.1", + "peer": true }, "whatwg-url": { "version": "5.0.0", + "peer": true, "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -3241,10 +3456,12 @@ } }, "wrappy": { - "version": "1.0.2" + "version": "1.0.2", + "peer": true }, "ws": { "version": "8.9.0", + "peer": true, "requires": {} }, "xtend": { @@ -3281,6 +3498,7 @@ }, "yauzl": { "version": "2.10.0", + "peer": true, "requires": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" diff --git a/print/package.json b/print/package.json index ed1df5037..a6c53a28f 100755 --- a/print/package.json +++ b/print/package.json @@ -18,9 +18,10 @@ "js-yaml": "^3.13.1", "jsonexport": "^3.2.0", "juice": "^5.2.0", + "log4js": "^6.7.0", "mysql2": "^1.7.0", "nodemailer": "^4.7.0", - "puppeteer": "^18.0.5", + "puppeteer-cluster": "^0.23.0", "qrcode": "^1.4.2", "strftime": "^0.10.0", "vue": "^2.6.10", diff --git a/print/templates/reports/driver-route/locale/es.yml b/print/templates/reports/driver-route/locale/es.yml index 3fb6b6885..8f986b0d2 100644 --- a/print/templates/reports/driver-route/locale/es.yml +++ b/print/templates/reports/driver-route/locale/es.yml @@ -20,6 +20,6 @@ phone: Teléfono warehouse: Almacén salesPerson: Comercial import: Importe -route: Ruta +route: Ruta routeId: Ruta {0} -ticket: Ticket \ No newline at end of file +ticket: Ticket