From 8ae5a0de0f0b0e99cc8621d8ad03521cdfc063d8 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 4 May 2023 12:03:47 +0200 Subject: [PATCH 01/11] refs #5513 adding backs and models --- .../231601/00-buyConfig_travelConfig.sql | 27 +++++++ .../back/methods/entry/addFromPackaging.js | 72 +++++++++++++++++++ modules/entry/back/model-config.json | 3 + modules/entry/back/models/buy-config.json | 18 +++++ modules/entry/back/models/entry.js | 1 + .../methods/supplier/getItemsPackaging.js | 51 +++++++++++++ modules/supplier/back/models/supplier.js | 1 + modules/travel/back/model-config.json | 3 + modules/travel/back/models/travel-config.json | 49 +++++++++++++ 9 files changed, 225 insertions(+) create mode 100644 db/changes/231601/00-buyConfig_travelConfig.sql create mode 100644 modules/entry/back/methods/entry/addFromPackaging.js create mode 100644 modules/entry/back/models/buy-config.json create mode 100644 modules/supplier/back/methods/supplier/getItemsPackaging.js create mode 100644 modules/travel/back/models/travel-config.json diff --git a/db/changes/231601/00-buyConfig_travelConfig.sql b/db/changes/231601/00-buyConfig_travelConfig.sql new file mode 100644 index 000000000..7643b9387 --- /dev/null +++ b/db/changes/231601/00-buyConfig_travelConfig.sql @@ -0,0 +1,27 @@ +CREATE TABLE `vn`.`buyConfig` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `showLastBuy` int(11) NOT NULL DEFAULT 6 COMMENT 'Meses desde la última compra', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +CREATE TABLE `vn`.`travelConfig` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `warehouseInFk` smallint(6) unsigned NOT NULL DEFAULT 8 COMMENT 'Warehouse de origen', + `warehouseOutFk` smallint(6) unsigned NOT NULL DEFAULT 60 COMMENT 'Warehouse destino', + `agencyFk` int(11) NOT NULL DEFAULT 1378 COMMENT 'Agencia por defecto', + `companyFk` smallint(5) unsigned NOT NULL DEFAULT 442 COMMENT 'Compañía por defecto', + PRIMARY KEY (`id`), + KEY `travelConfig_FK` (`warehouseInFk`), + KEY `travelConfig_FK_1` (`warehouseOutFk`), + KEY `travelConfig_FK_2` (`agencyFk`), + KEY `travelConfig_FK_3` (`companyFk`), + CONSTRAINT `travelConfig_FK` FOREIGN KEY (`warehouseInFk`) REFERENCES `warehouse` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `travelConfig_FK_1` FOREIGN KEY (`warehouseOutFk`) REFERENCES `warehouse` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `travelConfig_FK_2` FOREIGN KEY (`agencyFk`) REFERENCES `agencyMode` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `travelConfig_FK_3` FOREIGN KEY (`companyFk`) REFERENCES `company` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Entry', 'addFromPackaging', 'WRITE', 'ALLOW', 'ROLE', 'production'), + ('Supplier', 'getItemsPackaging', 'READ', 'ALLOW', 'ROLE', 'production'); diff --git a/modules/entry/back/methods/entry/addFromPackaging.js b/modules/entry/back/methods/entry/addFromPackaging.js new file mode 100644 index 000000000..4eaf0fcbd --- /dev/null +++ b/modules/entry/back/methods/entry/addFromPackaging.js @@ -0,0 +1,72 @@ +module.exports = Self => { + Self.remoteMethodCtx('addFromPackaging', { + description: 'Create a receipt or return entry for a supplier with a specific travel', + accessType: 'WRITE', + accepts: [{ + arg: 'supplier', + type: 'number', + required: true, + description: 'The supplier id', + }, + { + arg: 'isTravelReception', + type: 'boolean', + required: true, + description: 'Indicates if the travel associated with the entry is a return or receipt travel' + }], + returns: { + type: 'object', + root: true + }, + http: { + path: `/addFromPackaging`, + verb: 'POST' + } + }); + + Self.addFromPackaging = async(ctx, options) => { + const args = ctx.args; + 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; + } + + try { + const travelConfig = await models.TravelConfig.findOne({}, myOptions); + + const today = new Date(); + const yesterday = new Date(today); + yesterday.setDate(today.getDate() - 1); + const tomorrow = new Date(today); + tomorrow.setDate(today.getDate() + 1); + + const travel = await models.Travel.create({ + shipmentHour: args.isTravelReception ? yesterday : today, + landingHour: args.isTravelReception ? today : tomorrow, + agencyFk: travelConfig.agencyFk, + warehouseInFk: travelConfig.warehouseOutFk, + warehouseOutFk: travelConfig.warehouseInFk + }, myOptions); + + const entry = await models.Entry.create({ + supplierFk: args.supplier, + travelFk: travel.id, + companyFk: travelConfig.companyFk + }, myOptions); + + if (tx) await tx.commit(); + + return {travel, entry}; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/entry/back/model-config.json b/modules/entry/back/model-config.json index ad5a9063e..ca4472c8c 100644 --- a/modules/entry/back/model-config.json +++ b/modules/entry/back/model-config.json @@ -5,6 +5,9 @@ "Buy": { "dataSource": "vn" }, + "BuyConfig": { + "dataSource": "vn" + }, "ItemMatchProperties": { "dataSource": "vn" }, diff --git a/modules/entry/back/models/buy-config.json b/modules/entry/back/models/buy-config.json new file mode 100644 index 000000000..f48fec22a --- /dev/null +++ b/modules/entry/back/models/buy-config.json @@ -0,0 +1,18 @@ +{ + "name": "BuyConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "buyConfig" + } + }, + "properties": { + "id": { + "type": "number", + "id": true + }, + "showLastBuy": { + "type": "number" + } + } +} diff --git a/modules/entry/back/models/entry.js b/modules/entry/back/models/entry.js index 1980f964c..36944471f 100644 --- a/modules/entry/back/models/entry.js +++ b/modules/entry/back/models/entry.js @@ -8,6 +8,7 @@ module.exports = Self => { require('../methods/entry/importBuysPreview')(Self); require('../methods/entry/lastItemBuys')(Self); require('../methods/entry/entryOrderPdf')(Self); + require('../methods/entry/addFromPackaging')(Self); Self.observe('before save', async function(ctx, options) { if (ctx.isNewInstance) return; diff --git a/modules/supplier/back/methods/supplier/getItemsPackaging.js b/modules/supplier/back/methods/supplier/getItemsPackaging.js new file mode 100644 index 000000000..c54be5ee8 --- /dev/null +++ b/modules/supplier/back/methods/supplier/getItemsPackaging.js @@ -0,0 +1,51 @@ +module.exports = Self => { + Self.remoteMethod('getItemsPackaging', { + description: 'Returns the list of items from the supplier of type packing', + accessType: 'READ', + accepts: [{ + arg: 'id', + type: 'number', + required: true, + description: 'The supplier id', + http: {source: 'path'} + }, { + arg: 'entry', + type: 'number', + required: true, + description: 'The entry id', + }], + returns: { + type: 'object', + root: true + }, + http: { + path: `/:id/getItemsPackaging`, + verb: 'GET' + } + }); + Self.getItemsPackaging = async(id, entry) => { + const [result] = await Self.rawSql(` + WITH entryTmp AS( + SELECT i.id, SUM(b.quantity) quantity + FROM vn.entry e + JOIN vn.buy b ON b.entryFk = e.id + JOIN vn.supplier s ON s.id = e.supplierFk + JOIN vn.item i ON i.id = b.itemFk + WHERE e.id = ? AND e.supplierFk = ? + GROUP BY i.id + ) SELECT i.id, i.name, et.quantity, SUM(b.quantity) quantityTotal + FROM vn.buy b + JOIN vn.item i ON i.id = b.itemFk + JOIN vn.entry e ON e.id = b.entryFk + JOIN vn.supplier s ON s.id = e.supplierFk + JOIN vn.buyConfig bc ON bc.showLastBuy + JOIN vn.travel t ON t.id = e.travelFk + LEFT JOIN entryTmp et ON et.id = i.id + WHERE e.supplierFk = ? + AND (i.family ='EMB' OR i.family = 'CONT') + AND b.created > (CURRENT_DATE() - INTERVAL bc.showLastBuy MONTH) + GROUP BY b.itemFk + ORDER BY et.quantity DESC, quantityTotal DESC`, [entry, id, id]); + return result; + }; +}; diff --git a/modules/supplier/back/models/supplier.js b/modules/supplier/back/models/supplier.js index ae3eb4bcc..373ec36b1 100644 --- a/modules/supplier/back/models/supplier.js +++ b/modules/supplier/back/models/supplier.js @@ -11,6 +11,7 @@ module.exports = Self => { require('../methods/supplier/campaignMetricsPdf')(Self); require('../methods/supplier/campaignMetricsEmail')(Self); require('../methods/supplier/newSupplier')(Self); + require('../methods/supplier/getItemsPackaging')(Self); Self.validatesPresenceOf('name', { message: 'The social name cannot be empty' diff --git a/modules/travel/back/model-config.json b/modules/travel/back/model-config.json index 34321ba78..ed5c071b3 100644 --- a/modules/travel/back/model-config.json +++ b/modules/travel/back/model-config.json @@ -14,6 +14,9 @@ "TravelThermograph": { "dataSource": "vn" }, + "TravelConfig": { + "dataSource": "vn" + }, "Temperature": { "dataSource": "vn" } diff --git a/modules/travel/back/models/travel-config.json b/modules/travel/back/models/travel-config.json new file mode 100644 index 000000000..360c0b81a --- /dev/null +++ b/modules/travel/back/models/travel-config.json @@ -0,0 +1,49 @@ +{ + "name": "TravelConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "travelConfig" + } + }, + "properties": { + "id": { + "type": "number", + "id": true + }, + "warehouseInFk": { + "type": "number" + }, + "warehouseOutFk": { + "type": "number" + }, + "agencyFk": { + "type": "number" + }, + "companyFk": { + "type": "number" + } + }, + "relations": { + "warehouseIn": { + "type": "belongsTo", + "model": "Warehouse", + "foreignKey": "warehouseInFk" + }, + "warehouseOut": { + "type": "belongsTo", + "model": "Warehouse", + "foreignKey": "warehouseOutFk" + }, + "agency": { + "type": "belongsTo", + "model": "AgencyMode", + "foreignKey": "agencyFk" + }, + "company": { + "type": "belongsTo", + "model": "Company", + "foreignKey": "companyFk" + } + } +} From 5cdec35ed49a21f3fc14713a0d57ffd292df3939 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 4 May 2023 14:30:10 +0200 Subject: [PATCH 02/11] refs #5513 addFromPackaging.spec.js --- db/dump/fixtures.sql | 8 ++- .../back/methods/entry/addFromPackaging.js | 8 +-- .../entry/specs/addFromPackaging.spec.js | 49 +++++++++++++++++++ 3 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 modules/entry/back/methods/entry/specs/addFromPackaging.spec.js diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index e69974d08..76fba5b04 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2863,6 +2863,10 @@ INSERT INTO `vn`.`wagonTypeTray` (`id`, `typeFk`, `height`, `colorFk`) (2, 1, 50, 2), (3, 1, 0, 3); +INSERT INTO `vn`.`travelConfig` (id, warehouseInFk, warehouseOutFk, agencyFk, companyFk) + VALUES + (1, 1, 1, 1, 442); - - +INSERT INTO `vn`.`buyConfig` (id, showLastBuy) + VALUES + (1, 6); diff --git a/modules/entry/back/methods/entry/addFromPackaging.js b/modules/entry/back/methods/entry/addFromPackaging.js index 4eaf0fcbd..9ba855303 100644 --- a/modules/entry/back/methods/entry/addFromPackaging.js +++ b/modules/entry/back/methods/entry/addFromPackaging.js @@ -48,9 +48,9 @@ module.exports = Self => { tomorrow.setDate(today.getDate() + 1); const travel = await models.Travel.create({ - shipmentHour: args.isTravelReception ? yesterday : today, - landingHour: args.isTravelReception ? today : tomorrow, - agencyFk: travelConfig.agencyFk, + shipped: args.isTravelReception ? yesterday : today, + landed: args.isTravelReception ? today : tomorrow, + agencyModeFk: travelConfig.agencyFk, warehouseInFk: travelConfig.warehouseOutFk, warehouseOutFk: travelConfig.warehouseInFk }, myOptions); @@ -63,7 +63,7 @@ module.exports = Self => { if (tx) await tx.commit(); - return {travel, entry}; + return entry; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/entry/back/methods/entry/specs/addFromPackaging.spec.js b/modules/entry/back/methods/entry/specs/addFromPackaging.spec.js new file mode 100644 index 000000000..42d33ae61 --- /dev/null +++ b/modules/entry/back/methods/entry/specs/addFromPackaging.spec.js @@ -0,0 +1,49 @@ +const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); + +describe('entry addFromPackaging()', () => { + const supplier = 442; + const today = new Date(); + const yesterday = new Date(today); + yesterday.setDate(today.getDate() - 1); + + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 49}, + http: { + req: { + headers: {origin: 'http://localhost'}, + }, + }, + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx, + }); + }); + + it('should create a receipt travel', async() => { + const ctx = {args: {isTravelReception: true, supplier}}; + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; + + try { + const entry = await models.Entry.addFromPackaging(ctx, options); + const travelConfig = await models.TravelConfig.findOne({}, options); + const travel = await models.Travel.findOne({order: 'id DESC'}, options); + + expect(new Date(travel.shipped).getDate()).toEqual(yesterday.getDate()); + expect(new Date(travel.landed).getDate()).toEqual(today.getDate()); + expect(travel.agencyModeFk).toEqual(travelConfig.agencyFk); + expect(travel.warehouseInFk).toEqual(travelConfig.warehouseOutFk); + expect(travel.warehouseOutFk).toEqual(travelConfig.warehouseInFk); + expect(entry.supplierFk).toEqual(supplier); + expect(entry.travelFk).toEqual(travel.id); + expect(entry.companyFk).toEqual(travelConfig.companyFk); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); From d21b949ffbf6d3b19f4b1f8aade5f51fa28dec38 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 8 May 2023 09:18:53 +0200 Subject: [PATCH 03/11] refs #5513 fix getItemsPackaging --- db/dump/fixtures.sql | 2 +- modules/supplier/back/methods/supplier/getItemsPackaging.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 76fba5b04..48d72b7cf 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -905,7 +905,7 @@ INSERT INTO `vn`.`itemFamily`(`code`, `description`) INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`, `comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`, `isFloramondo`, `genericFk`, `itemPackingTypeFk`, `hasMinPrice`, `packingShelve`, `weightByPiece`) VALUES - (1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT', 0, NULL, 'V', 0, 15,3), + (1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'EMB', 0, NULL, 'V', 0, 15,3), (2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT', 0, NULL, 'H', 0, 10,2), (3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT', 0, NULL, NULL, 0, 5,5), (4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT', 0, NULL, NULL, 0, NULL,NULL), diff --git a/modules/supplier/back/methods/supplier/getItemsPackaging.js b/modules/supplier/back/methods/supplier/getItemsPackaging.js index c54be5ee8..cae32a701 100644 --- a/modules/supplier/back/methods/supplier/getItemsPackaging.js +++ b/modules/supplier/back/methods/supplier/getItemsPackaging.js @@ -25,7 +25,7 @@ module.exports = Self => { }); Self.getItemsPackaging = async(id, entry) => { const [result] = await Self.rawSql(` - WITH entryTmp AS( + WITH entryTmp AS ( SELECT i.id, SUM(b.quantity) quantity FROM vn.entry e JOIN vn.buy b ON b.entryFk = e.id @@ -43,7 +43,7 @@ module.exports = Self => { LEFT JOIN entryTmp et ON et.id = i.id WHERE e.supplierFk = ? AND (i.family ='EMB' OR i.family = 'CONT') - AND b.created > (CURRENT_DATE() - INTERVAL bc.showLastBuy MONTH) + AND b.created > (util.VN_CURDATE() - INTERVAL bc.showLastBuy MONTH) GROUP BY b.itemFk ORDER BY et.quantity DESC, quantityTotal DESC`, [entry, id, id]); return result; From 372b9a2ce289df25812770774e0b0382eafcacd3 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 8 May 2023 09:46:56 +0200 Subject: [PATCH 04/11] refs #5513 test getItemsPackaging --- .../methods/supplier/specs/getItemsPackaging.spec.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 modules/supplier/back/methods/supplier/specs/getItemsPackaging.spec.js diff --git a/modules/supplier/back/methods/supplier/specs/getItemsPackaging.spec.js b/modules/supplier/back/methods/supplier/specs/getItemsPackaging.spec.js new file mode 100644 index 000000000..fe8a5a489 --- /dev/null +++ b/modules/supplier/back/methods/supplier/specs/getItemsPackaging.spec.js @@ -0,0 +1,12 @@ +const app = require('vn-loopback/server/server'); + +describe('Supplier getItemsPackaging()', () => { + it('should return a summary the list of items from a determinate supplier', async() => { + const item = await app.models.Supplier.getItemsPackaging(1, 1); + + expect(item.id).toEqual(1); + expect(item.name).toEqual('Ranged weapon longbow 2m'); + expect(item.quantity).toEqual(5000); + expect(item.quantityTotal).toEqual(5100); + }); +}); From 9760e5021216e1712e27dd2970139c74158ce4ce Mon Sep 17 00:00:00 2001 From: alexandre Date: Fri, 12 May 2023 08:46:12 +0200 Subject: [PATCH 05/11] refs #5513 minor fixes --- db/changes/231601/00-buyConfig_travelConfig.sql | 2 +- db/dump/fixtures.sql | 4 ++-- modules/supplier/back/methods/supplier/getItemsPackaging.js | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/db/changes/231601/00-buyConfig_travelConfig.sql b/db/changes/231601/00-buyConfig_travelConfig.sql index 7643b9387..40fc057de 100644 --- a/db/changes/231601/00-buyConfig_travelConfig.sql +++ b/db/changes/231601/00-buyConfig_travelConfig.sql @@ -1,6 +1,6 @@ CREATE TABLE `vn`.`buyConfig` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `showLastBuy` int(11) NOT NULL DEFAULT 6 COMMENT 'Meses desde la última compra', + `monthsAgo` int(11) NOT NULL DEFAULT 6 COMMENT 'Meses desde la última compra', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 48d72b7cf..661a90faa 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2863,10 +2863,10 @@ INSERT INTO `vn`.`wagonTypeTray` (`id`, `typeFk`, `height`, `colorFk`) (2, 1, 50, 2), (3, 1, 0, 3); -INSERT INTO `vn`.`travelConfig` (id, warehouseInFk, warehouseOutFk, agencyFk, companyFk) +INSERT INTO `vn`.`travelConfig` (`id`, `warehouseInFk`, `warehouseOutFk`, `agencyFk`, `companyFk`) VALUES (1, 1, 1, 1, 442); -INSERT INTO `vn`.`buyConfig` (id, showLastBuy) +INSERT INTO `vn`.`buyConfig` (`id`, `monthsAgo`) VALUES (1, 6); diff --git a/modules/supplier/back/methods/supplier/getItemsPackaging.js b/modules/supplier/back/methods/supplier/getItemsPackaging.js index cae32a701..ced2f016f 100644 --- a/modules/supplier/back/methods/supplier/getItemsPackaging.js +++ b/modules/supplier/back/methods/supplier/getItemsPackaging.js @@ -38,12 +38,12 @@ module.exports = Self => { JOIN vn.item i ON i.id = b.itemFk JOIN vn.entry e ON e.id = b.entryFk JOIN vn.supplier s ON s.id = e.supplierFk - JOIN vn.buyConfig bc ON bc.showLastBuy + JOIN vn.buyConfig bc ON bc.monthsAgo JOIN vn.travel t ON t.id = e.travelFk LEFT JOIN entryTmp et ON et.id = i.id WHERE e.supplierFk = ? - AND (i.family ='EMB' OR i.family = 'CONT') - AND b.created > (util.VN_CURDATE() - INTERVAL bc.showLastBuy MONTH) + AND i.family IN ('EMB', 'CONT') + AND b.created > (util.VN_CURDATE() - INTERVAL bc.monthsAgo MONTH) GROUP BY b.itemFk ORDER BY et.quantity DESC, quantityTotal DESC`, [entry, id, id]); return result; From 37b29201578b47b548679e1caaf5ba9647ea0bf2 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 18 May 2023 14:49:40 +0200 Subject: [PATCH 06/11] refs #5513 moved sql --- db/changes/232201/.gitkeep | 0 .../232201/00-buyConfig_travelConfig.sql | 27 +++++++++++++++++++ 2 files changed, 27 insertions(+) delete mode 100644 db/changes/232201/.gitkeep create mode 100644 db/changes/232201/00-buyConfig_travelConfig.sql diff --git a/db/changes/232201/.gitkeep b/db/changes/232201/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/db/changes/232201/00-buyConfig_travelConfig.sql b/db/changes/232201/00-buyConfig_travelConfig.sql new file mode 100644 index 000000000..40fc057de --- /dev/null +++ b/db/changes/232201/00-buyConfig_travelConfig.sql @@ -0,0 +1,27 @@ +CREATE TABLE `vn`.`buyConfig` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `monthsAgo` int(11) NOT NULL DEFAULT 6 COMMENT 'Meses desde la última compra', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +CREATE TABLE `vn`.`travelConfig` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `warehouseInFk` smallint(6) unsigned NOT NULL DEFAULT 8 COMMENT 'Warehouse de origen', + `warehouseOutFk` smallint(6) unsigned NOT NULL DEFAULT 60 COMMENT 'Warehouse destino', + `agencyFk` int(11) NOT NULL DEFAULT 1378 COMMENT 'Agencia por defecto', + `companyFk` smallint(5) unsigned NOT NULL DEFAULT 442 COMMENT 'Compañía por defecto', + PRIMARY KEY (`id`), + KEY `travelConfig_FK` (`warehouseInFk`), + KEY `travelConfig_FK_1` (`warehouseOutFk`), + KEY `travelConfig_FK_2` (`agencyFk`), + KEY `travelConfig_FK_3` (`companyFk`), + CONSTRAINT `travelConfig_FK` FOREIGN KEY (`warehouseInFk`) REFERENCES `warehouse` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `travelConfig_FK_1` FOREIGN KEY (`warehouseOutFk`) REFERENCES `warehouse` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `travelConfig_FK_2` FOREIGN KEY (`agencyFk`) REFERENCES `agencyMode` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `travelConfig_FK_3` FOREIGN KEY (`companyFk`) REFERENCES `company` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Entry', 'addFromPackaging', 'WRITE', 'ALLOW', 'ROLE', 'production'), + ('Supplier', 'getItemsPackaging', 'READ', 'ALLOW', 'ROLE', 'production'); From 1fd51c191f5d9d51e1e67f3a13984702f2f5aea6 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 30 May 2023 13:47:09 +0200 Subject: [PATCH 07/11] refs #5513 minor fixes --- modules/supplier/back/methods/supplier/getItemsPackaging.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/supplier/back/methods/supplier/getItemsPackaging.js b/modules/supplier/back/methods/supplier/getItemsPackaging.js index ced2f016f..8ef80529b 100644 --- a/modules/supplier/back/methods/supplier/getItemsPackaging.js +++ b/modules/supplier/back/methods/supplier/getItemsPackaging.js @@ -24,7 +24,7 @@ module.exports = Self => { } }); Self.getItemsPackaging = async(id, entry) => { - const [result] = await Self.rawSql(` + return Self.rawSql(` WITH entryTmp AS ( SELECT i.id, SUM(b.quantity) quantity FROM vn.entry e @@ -46,6 +46,5 @@ module.exports = Self => { AND b.created > (util.VN_CURDATE() - INTERVAL bc.monthsAgo MONTH) GROUP BY b.itemFk ORDER BY et.quantity DESC, quantityTotal DESC`, [entry, id, id]); - return result; }; }; From 576a5f050ee7d5ee90af917f0f82e134f535f0fa Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 30 May 2023 13:48:56 +0200 Subject: [PATCH 08/11] refs #5513 fix back test --- .../back/methods/supplier/specs/getItemsPackaging.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/supplier/back/methods/supplier/specs/getItemsPackaging.spec.js b/modules/supplier/back/methods/supplier/specs/getItemsPackaging.spec.js index fe8a5a489..0fb01f5b5 100644 --- a/modules/supplier/back/methods/supplier/specs/getItemsPackaging.spec.js +++ b/modules/supplier/back/methods/supplier/specs/getItemsPackaging.spec.js @@ -2,7 +2,7 @@ const app = require('vn-loopback/server/server'); describe('Supplier getItemsPackaging()', () => { it('should return a summary the list of items from a determinate supplier', async() => { - const item = await app.models.Supplier.getItemsPackaging(1, 1); + const [item] = await app.models.Supplier.getItemsPackaging(1, 1); expect(item.id).toEqual(1); expect(item.name).toEqual('Ranged weapon longbow 2m'); From 15b5f10a93fde2b5ca4559d07bb45188ee2456fe Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 5 Jun 2023 09:10:19 +0200 Subject: [PATCH 09/11] refs #5513 addFromBuy back added --- .../00-buyConfig_travelConfig.sql | 1 + .../entry/back/methods/entry/addFromBuy.js | 107 ++++++++++++++++++ .../methods/entry/specs/addFromBuy.spec.js | 51 +++++++++ modules/entry/back/models/buy.json | 50 ++++++++ modules/entry/back/models/entry.js | 1 + 5 files changed, 210 insertions(+) rename db/changes/{232201 => 232401}/00-buyConfig_travelConfig.sql (96%) create mode 100644 modules/entry/back/methods/entry/addFromBuy.js create mode 100644 modules/entry/back/methods/entry/specs/addFromBuy.spec.js diff --git a/db/changes/232201/00-buyConfig_travelConfig.sql b/db/changes/232401/00-buyConfig_travelConfig.sql similarity index 96% rename from db/changes/232201/00-buyConfig_travelConfig.sql rename to db/changes/232401/00-buyConfig_travelConfig.sql index 40fc057de..0f73ddc8c 100644 --- a/db/changes/232201/00-buyConfig_travelConfig.sql +++ b/db/changes/232401/00-buyConfig_travelConfig.sql @@ -24,4 +24,5 @@ CREATE TABLE `vn`.`travelConfig` ( INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Entry', 'addFromPackaging', 'WRITE', 'ALLOW', 'ROLE', 'production'), + ('Entry', 'addFromBuy', 'WRITE', 'ALLOW', 'ROLE', 'production'), ('Supplier', 'getItemsPackaging', 'READ', 'ALLOW', 'ROLE', 'production'); diff --git a/modules/entry/back/methods/entry/addFromBuy.js b/modules/entry/back/methods/entry/addFromBuy.js new file mode 100644 index 000000000..a40dd3412 --- /dev/null +++ b/modules/entry/back/methods/entry/addFromBuy.js @@ -0,0 +1,107 @@ + +module.exports = Self => { + Self.remoteMethodCtx('addFromBuy', { + description: 'Modify a field of a buy or creates a new one with default values', + accessType: 'WRITE', + accepts: [{ + arg: 'id', + type: 'number', + required: true, + description: 'The entry id', + http: {source: 'path'} + }, { + arg: 'item', + type: 'number', + required: true, + description: 'The item id', + }, { + arg: 'printedStickers', + type: 'number', + required: true, + description: 'The field to modify', + }], + returns: { + type: 'object', + root: true + }, + http: { + path: `/:id/addFromBuy`, + verb: 'POST' + } + }); + + Self.addFromBuy = async(ctx, options) => { + const args = ctx.args; + const models = Self.app.models; + const userId = ctx.req.accessToken.userId; + const myOptions = {userId}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + let buy = await models.Buy.findOne({where: {entryFk: args.id}}, myOptions); + if (buy) + await buy.updateAttribute('printedStickers', args.printedStickers); + else { + const userConfig = await models.UserConfig.findById(userId, {fields: ['warehouseFk']}, myOptions); + await Self.rawSql( + 'CALL vn.buyUltimate(?,?)', + [userConfig.warehouseFk, null], + myOptions + ); + let buyUltimate = await Self.rawSql( + `SELECT buyFk + FROM tmp.buyUltimate + WHERE itemFk = ?`, + [args.item], + myOptions + ); + buyUltimate = await models.Buy.findById(buyUltimate[0].buyFk, null, myOptions); + buy = await models.Buy.create({ + entryFk: args.id, + itemFk: args.item, + quantity: 0, + dispatched: buyUltimate.dispatched, + buyingValue: buyUltimate.buyingValue, + freightValue: buyUltimate.freightValue, + isIgnored: buyUltimate.isIgnored, + stickers: buyUltimate.stickers, + packing: buyUltimate.packing, + grouping: buyUltimate.grouping, + groupingMode: buyUltimate.groupingMode, + containerFk: buyUltimate.containerFk, + comissionValue: buyUltimate.comissionValue, + packageValue: buyUltimate.packageValue, + location: buyUltimate.location, + packageFk: buyUltimate.packageFk, + price1: buyUltimate.price1, + price2: buyUltimate.price2, + price3: buyUltimate.price3, + minPrice: buyUltimate.minPrice, + printedStickers: args.printedStickers, + workerFk: buyUltimate.workerFk, + isChecked: buyUltimate.isChecked, + isPickedOff: buyUltimate.isPickedOff, + created: buyUltimate.created, + ektFk: buyUltimate.ektFk, + weight: buyUltimate.weight, + deliveryFk: buyUltimate.deliveryFk, + itemOriginalFk: buyUltimate.itemOriginalFk + }, myOptions); + } + + if (tx) await tx.commit(); + return buy; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/entry/back/methods/entry/specs/addFromBuy.spec.js b/modules/entry/back/methods/entry/specs/addFromBuy.spec.js new file mode 100644 index 000000000..b6ed475b3 --- /dev/null +++ b/modules/entry/back/methods/entry/specs/addFromBuy.spec.js @@ -0,0 +1,51 @@ +const models = require('vn-loopback/server/server').models; + +describe('entry addFromBuy()', () => { + const ctx = {req: {accessToken: {userId: 18}}}; + + it('should change the printedStickers of an existent buy', async() => { + const id = 1; + const item = 1; + const buy = 1; + + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; + try { + const currentBuy = await models.Buy.findById(buy, {fields: ['printedStickers']}, options); + const printedStickers = currentBuy.printedStickers + 10; + ctx.args = {id, item, printedStickers}; + const newBuy = await models.Entry.addFromBuy(ctx, options); + + expect(newBuy.printedStickers).toEqual(printedStickers); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should create for an entry without a concrete item a new buy', async() => { + const id = 8; + const item = 1; + const printedStickers = 10; + + const tx = await models.Entry.beginTransaction({}); + const options = {transaction: tx}; + try { + const emptyBuy = await models.Buy.findOne({where: {entryFk: id}}, options); + ctx.args = {id, item, printedStickers}; + const newBuy = await models.Entry.addFromBuy(ctx, options); + + expect(emptyBuy).toEqual(null); + expect(newBuy.entryFk).toEqual(id); + expect(newBuy.printedStickers).toEqual(printedStickers); + expect(newBuy.itemFk).toEqual(item); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/entry/back/models/buy.json b/modules/entry/back/models/buy.json index 379e55427..af205533f 100644 --- a/modules/entry/back/models/buy.json +++ b/modules/entry/back/models/buy.json @@ -39,6 +39,9 @@ "packageValue": { "type": "number" }, + "price1": { + "type": "number" + }, "price2": { "type": "number" }, @@ -47,7 +50,44 @@ }, "weight": { "type": "number" + }, + "printedStickers": { + "type": "number" + }, + "dispatched": { + "type": "number" + }, + "isIgnored": { + "type": "boolean" + }, + "containerFk": { + "type": "number" + }, + "location": { + "type": "number" + }, + "minPrice": { + "type": "number" + }, + "isChecked": { + "type": "boolean" + }, + "isPickedOff": { + "type": "boolean" + }, + "created": { + "type": "date" + }, + "ektFk": { + "type": "number" + }, + "itemOriginalFk": { + "type": "number" + }, + "editorFk": { + "type": "number" } + }, "relations": { "entry": { @@ -64,6 +104,16 @@ "type": "belongsTo", "model": "Packaging", "foreignKey": "packageFk" + }, + "worker": { + "type": "belongsTo", + "model": "Worker", + "foreignKey": "workerFk" + }, + "delivery": { + "type": "belongsTo", + "model": "Delivery", + "foreignKey": "deliveryFk" } } } diff --git a/modules/entry/back/models/entry.js b/modules/entry/back/models/entry.js index 36944471f..0eabd70ee 100644 --- a/modules/entry/back/models/entry.js +++ b/modules/entry/back/models/entry.js @@ -9,6 +9,7 @@ module.exports = Self => { require('../methods/entry/lastItemBuys')(Self); require('../methods/entry/entryOrderPdf')(Self); require('../methods/entry/addFromPackaging')(Self); + require('../methods/entry/addFromBuy')(Self); Self.observe('before save', async function(ctx, options) { if (ctx.isNewInstance) return; From 36b021664020648d760bc5df5022aa976f7a0c5a Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 6 Jun 2023 07:40:38 +0200 Subject: [PATCH 10/11] refs #5513 changed tests description --- modules/entry/back/methods/entry/specs/addFromPackaging.spec.js | 2 +- .../back/methods/supplier/specs/getItemsPackaging.spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/entry/back/methods/entry/specs/addFromPackaging.spec.js b/modules/entry/back/methods/entry/specs/addFromPackaging.spec.js index 42d33ae61..1b0d4656f 100644 --- a/modules/entry/back/methods/entry/specs/addFromPackaging.spec.js +++ b/modules/entry/back/methods/entry/specs/addFromPackaging.spec.js @@ -21,7 +21,7 @@ describe('entry addFromPackaging()', () => { }); }); - it('should create a receipt travel', async() => { + it('should create an incoming travel', async() => { const ctx = {args: {isTravelReception: true, supplier}}; const tx = await models.Entry.beginTransaction({}); const options = {transaction: tx}; diff --git a/modules/supplier/back/methods/supplier/specs/getItemsPackaging.spec.js b/modules/supplier/back/methods/supplier/specs/getItemsPackaging.spec.js index 0fb01f5b5..8e4cc9145 100644 --- a/modules/supplier/back/methods/supplier/specs/getItemsPackaging.spec.js +++ b/modules/supplier/back/methods/supplier/specs/getItemsPackaging.spec.js @@ -1,7 +1,7 @@ const app = require('vn-loopback/server/server'); describe('Supplier getItemsPackaging()', () => { - it('should return a summary the list of items from a determinate supplier', async() => { + it('should return a summary of the list of items from a specific supplier', async() => { const [item] = await app.models.Supplier.getItemsPackaging(1, 1); expect(item.id).toEqual(1); From 7311e7927353497ee8382f1dd044ce4c2181d0dc Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 6 Jun 2023 15:07:54 +0200 Subject: [PATCH 11/11] fix(vn-model): rewriteMethod --- loopback/common/models/vn-model.js | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/loopback/common/models/vn-model.js b/loopback/common/models/vn-model.js index f469e893a..37328247b 100644 --- a/loopback/common/models/vn-model.js +++ b/loopback/common/models/vn-model.js @@ -1,6 +1,8 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const UserError = require('vn-loopback/util/user-error'); +const utils = require('loopback/lib/utils'); +const {util} = require('webpack'); module.exports = function(Self) { Self.ParameterizedSQL = ParameterizedSQL; @@ -164,23 +166,21 @@ module.exports = function(Self) { function rewriteMethod(methodName) { const realMethod = this[methodName]; - return async(data, options, cb) => { - if (options instanceof Function) { - cb = options; - options = null; - } + return function(...args) { + let cb; + const lastArg = args[args.length - 1]; + if (lastArg instanceof Function) { + cb = lastArg; + args.pop(); + } else + cb = utils.createPromiseCallback(); - try { - const result = await realMethod.call(this, data, options); - - if (cb) cb(null, result); - else return result; - } catch (err) { - let myErr = replaceErr(err, replaceErrFunc); - if (cb) cb(myErr); - else - throw myErr; - } + args.push(function(err, res) { + if (err) err = replaceErr(err, replaceErrFunc); + cb(err, res); + }); + realMethod.apply(this, args); + return cb.promise; }; }