diff --git a/CHANGELOG.md b/CHANGELOG.md
index 74109c7c4a..57848aa7f7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,89 @@
+# Version 24.38 - 2024-09-17
+
+### Added 🆕
+
+- chore: refs #7323 filter data by:jorgep
+- chore: refs #7323 fix test by:jorgep
+- chore: refs #7323 worker changes by:jorgep
+- chore: refs #7323 worker changes wip by:jorgep
+- chore: refs #7524 add select limit by:jorgep
+- feat(AccessToken&ACL): refs #7547 upgrade security by:alexm
+- feat: deleted code and redirect to Lilium by:Jon
+- feat: refs #4515 New throw buy_checkItem by:guillermo
+- feat: refs #6650 Added saleGroupLog by:guillermo
+- feat: refs #6650 new itemShelvingLog by:guillermo
+- feat: refs #6760 refs #actualiza campo nickname by:jgallego
+- feat: refs #7277 fdescribe by:jgallego
+- feat: refs #7277 fit by:jgallego
+- feat: refs #7277 refundInvoices by:jgallego
+- feat: refs #7277 test with warehouse by:jgallego
+- feat: refs #7277 traducciones by:jgallego
+- feat: refs #7277 transfer addressFk by:jgallego
+- feat: refs #7532 Requested changes by:guillermo
+- feat: refs #7564 Added proc by:guillermo
+- feat: refs #7564 Added ticket_setVolumeItemCost by:guillermo
+- feat: refs #7564 Added volume column by:guillermo
+- feat: refs #7564 Fix version by:guillermo
+- feat: refs #7564 Requested changes by:guillermo
+- feat: refs #7615 setDeleted by:robert
+- feat: refs #7650 Added no transfer lines to inventory entry and fixtures by:guillermo
+- feat: refs #7650 Fix tests by:guillermo
+- feat: refs #7747 Delete buyUltimate and buyUltimateFromInterval by:ivanm
+- feat: refs #7759 Changed defined only of vn objects by:guillermo
+- feat: refs #7759 Changed definer root to vn-admin by:guillermo
+- feat: refs #7759 Changed name by:guillermo
+- feat: refs #7759 Deleted version 11163-maroonEucalyptus by:guillermo
+- feat: refs #7759 Revoke routine grants vn by:guillermo
+- feat: refs #7811 Added comment by:guillermo
+- feat: refs #7811 Added new params in datasources.json by:guillermo
+- feat: refs #7898 Add column "floor" in vn.parking by:ivanm
+- feat: refs #7898 Modify default by:ivanm
+- feat: refs #7905 Added new method getBuysCsv by:guillermo
+- feat: refs #7905 Added param toCsv by:guillermo
+- feat: refs #7938 remove unnecessary insert in clientLog by:alexm
+- feat: refs #7953 pullinfo (7953-devToTest_2438) by:alexm
+- feat(salix): #7671 define isDestiny field in model by:Javier Segarra
+- feat(salix): refs #7896 update version and changelog (origin/7896_down_devToTest_2436) by:Javier Segarra
+- feat(salix): refs #7905 #7905 use getBuys toCSV flattened by:Javier Segarra
+- feat(ssalix): refs #7671 #7671 checkDates by:Javier Segarra
+- feat(ssalix): refs #7671 #7671 checkDates to present by:Javier Segarra
+- feat: ticket 215005 Changed acl show transferClient by:guillermo
+
+### Changed 📦
+
+- perf: refs #7671 improve showBadDates by:Javier Segarra
+- perf(salix): refs #7671 #7671 imrpove and revert where changes by:Javier Segarra
+- refactor: deleted e2e & added back descriptor and summary by:Jon
+
+### Fixed 🛠️
+
+- chore: refs #7323 fix test by:jorgep
+- feat: refs #7650 Added no transfer lines to inventory entry and fixtures by:guillermo
+- fix by:guillermo
+- fixes: refs #7760 collection problems by:Carlos Andrés
+- fix merge dev (7407-workerMedical) by:alexm
+- fix: refs #6727 No delete log tables data in clean procedures by:guillermo
+- fix: refs #6897 back and tests by:carlossa
+- fix: refs #6897 back by:carlossa
+- fix: refs #6897 fix filter by:carlossa
+- fix: refs #6897 fix json by:carlossa
+- fix: refs #6897 travel filter by:carlossa
+- fix: refs #6897 error test by:jgallego
+- fix: refs #7323 fetch from right source by:jorgep
+- fix: refs #7564 Deleted query by:guillermo
+- fix: refs #7759 Added user 'vn'@'localhost' & grants by:guillermo
+- fix: refs #7760 collection problems by:Carlos Andrés
+- fix: refs #7760 tmp.ticketIPT by:Carlos Andrés
+- fix: refs #7905 added comments to flatten.js by:guillermo
+- fix: refs ##7905 Handle error by:guillermo
+- fix(salix): refs #7905 #7905 use right fn to flatten data by:Javier Segarra
+- perf(salix): refs #7671 #7671 imrpove and revert where changes by:Javier Segarra
+- refs #6898 fix supplier remove by:carlossa
+- refs #7407 fix acls fixtures by:carlossa
+- test: fix connections e2e (7547-accessToken-security) by:alexm
+- test: refs #7277 fix test proposal by:Javier Segarra
+- test(salix): refs #7671 #7671 improve and revert where changes by:Javier Segarra
+
# Version 24.36 - 2024-09-03
### Added 🆕
diff --git a/back/methods/mrw-config/specs/createShipment.spec.js b/back/methods/mrw-config/specs/createShipment.spec.js
index 1ab77f608b..c8a5295f7c 100644
--- a/back/methods/mrw-config/specs/createShipment.spec.js
+++ b/back/methods/mrw-config/specs/createShipment.spec.js
@@ -12,9 +12,8 @@ const ticket1 = {
'addressFk': 1,
'agencyModeFk': 999
};
-
+let expedition;
const expedition1 = {
- 'id': 17,
'agencyModeFk': 999,
'ticketFk': 44,
'freightItemFk': 71,
@@ -47,7 +46,7 @@ describe('MRWConfig createShipment()', () => {
await createMrwConfig();
await models.Ticket.create(ticket1);
- await models.Expedition.create(expedition1);
+ expedition = await models.Expedition.create(expedition1);
});
afterAll(async() => {
@@ -93,7 +92,7 @@ describe('MRWConfig createShipment()', () => {
}
it('should create a shipment and return a base64Binary label', async() => {
- const {file} = await models.MrwConfig.createShipment(expedition1.id);
+ const {file} = await models.MrwConfig.createShipment(expedition.id);
expect(file).toEqual(mockBase64Binary);
});
@@ -101,7 +100,7 @@ describe('MRWConfig createShipment()', () => {
it('should fail if mrwConfig has no data', async() => {
let error;
await models.MrwConfig.destroyAll();
- await models.MrwConfig.createShipment(expedition1.id).catch(e => {
+ await models.MrwConfig.createShipment(expedition.id).catch(e => {
error = e;
}).finally(async() => {
expect(error.message).toEqual(`MRW service is not configured`);
@@ -126,7 +125,7 @@ describe('MRWConfig createShipment()', () => {
yesterday.setDate(yesterday.getDate() - 1);
await models.Ticket.updateAll({id: ticket1.id}, {shipped: yesterday});
- await models.MrwConfig.createShipment(expedition1.id).catch(e => {
+ await models.MrwConfig.createShipment(expedition.id).catch(e => {
error = e;
}).finally(async() => {
expect(error.message).toEqual(`This ticket has a shipped date earlier than today`);
@@ -136,7 +135,7 @@ describe('MRWConfig createShipment()', () => {
it('should send mail if you are past the dead line and is not notified today', async() => {
await models.MrwConfig.updateAll({id: 1}, {expeditionDeadLine: '10:00:00', notified: null});
- await models.MrwConfig.createShipment(expedition1.id);
+ await models.MrwConfig.createShipment(expedition.id);
const notification = await getLastNotification();
expect(notification.notificationFk).toEqual(filter.notificationFk);
@@ -144,7 +143,7 @@ describe('MRWConfig createShipment()', () => {
it('should send mail if you are past the dead line and it is notified from another day', async() => {
await models.MrwConfig.updateAll({id: 1}, {expeditionDeadLine: '10:00:00', notified: new Date()});
- await models.MrwConfig.createShipment(expedition1.id);
+ await models.MrwConfig.createShipment(expedition.id);
const notification = await getLastNotification();
expect(notification.notificationFk).toEqual(filter.notificationFk);
@@ -152,7 +151,7 @@ describe('MRWConfig createShipment()', () => {
it('should not send mail if you are past the dead line and it is notified', async() => {
await models.MrwConfig.updateAll({id: 1}, {expeditionDeadLine: '10:00:00', notified: Date.vnNew()});
- await models.MrwConfig.createShipment(expedition1.id);
+ await models.MrwConfig.createShipment(expedition.id);
const notification = await getLastNotification();
expect(notification).toEqual(null);
diff --git a/back/models/buyer.json b/back/models/buyer.json
index a17d3b5389..a1297eda3a 100644
--- a/back/models/buyer.json
+++ b/back/models/buyer.json
@@ -15,6 +15,9 @@
"nickname": {
"type": "string",
"required": true
+ },
+ "display": {
+ "type": "boolean"
}
},
"acls": [
diff --git a/db/dump/dump.after.sql b/db/dump/dump.after.sql
index 7508a36a70..962d8e3f27 100644
--- a/db/dump/dump.after.sql
+++ b/db/dump/dump.after.sql
@@ -4,7 +4,9 @@ GRANT SELECT,
INSERT,
UPDATE,
DELETE,
+ DROP,
CREATE TEMPORARY TABLES,
EXECUTE,
+ EVENT,
TRIGGER
ON *.* TO 'vn'@'localhost';
diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql
index 6fbd342741..91de1dc050 100644
--- a/db/dump/fixtures.before.sql
+++ b/db/dump/fixtures.before.sql
@@ -179,12 +179,12 @@ INSERT INTO `vn`.`country`(`id`, `name`, `isUeeMember`, `code`, `currencyFk`, `i
(30,'Canarias', 1, 'IC', 1, 24, 4, 1, 2);
INSERT INTO `vn`.`warehouse`(`id`, `name`, `code`, `isComparative`, `isInventory`, `hasAvailable`, `isManaged`, `hasDms`, `hasComission`, `countryFk`, `hasProduction`, `isOrigin`, `isDestiny`)
- VALUES
- (1, 'Warehouse One', 'ALG', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
+ VALUES (1, 'Warehouse One', 'ALG', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
(2, 'Warehouse Two', NULL, 1, 1, 1, 1, 0, 1, 13, 1, 1, 0),
(3, 'Warehouse Three', NULL, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0),
(4, 'Warehouse Four', NULL, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1),
(5, 'Warehouse Five', NULL, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0),
+ (6, 'Warehouse six', 'VNH', 1, 1, 1, 1, 0, 0, 1, 1, 0, 0),
(13, 'Inventory', 'inv', 1, 1, 1, 0, 0, 0, 1, 0, 0, 0),
(60, 'Algemesi', NULL, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0);
@@ -335,21 +335,21 @@ INSERT INTO `vn`.`payDem`(`id`, `payDem`)
(2, 20),
(7, 0);
-INSERT INTO `vn`.`autonomy`(`id`, `name`, `countryFk`)
+INSERT INTO `vn`.`autonomy`(`id`, `name`, `countryFk`, `hasDailyInvoice`)
VALUES
- (1, 'Autonomy one', 1),
- (2, 'Autonomy two', 1),
- (3, 'Autonomy three', 2),
- (4, 'Autonomy four', 13);
+ (1, 'Autonomy one', 1, 1),
+ (2, 'Autonomy two', 1, 0),
+ (3, 'Autonomy three', 2, 0),
+ (4, 'Autonomy four', 13, 0);
INSERT INTO `vn`.`province`(`id`, `name`, `countryFk`, `autonomyFk`, `warehouseFk`)
VALUES
- (1, 'Province one', 1, 1, NULL),
- (2, 'Province two', 1, 1, NULL),
- (3, 'Province three', 30, 2, NULL),
- (4, 'Province four', 2, 3, NULL),
- (5, 'Province five', 13, 4, NULL);
+ (1, 'Province one', 1, 1, NULL),
+ (2, 'Province two', 1, 1, NULL),
+ (3, 'Province three', 30, 2, NULL),
+ (4, 'Province four', 2, 3, NULL),
+ (5, 'Province five', 13, 4, NULL);
INSERT INTO `vn`.`town`(`id`, `name`, `provinceFk`)
VALUES
@@ -361,11 +361,11 @@ INSERT INTO `vn`.`town`(`id`, `name`, `provinceFk`)
INSERT INTO `vn`.`postCode`(`code`, `townFk`, `geoFk`)
VALUES
- ('46000', 1, 6),
- ('46460', 2, 6),
- ('46680', 3, 6),
- ('46600', 4, 7),
- ('EC170150', 5, 8);
+ ('46000', 1, 6),
+ ('46460', 2, 6),
+ ('46680', 3, 6),
+ ('46600', 4, 7),
+ ('EC170150', 5, 8);
INSERT INTO `vn`.`clientType`(`code`, `type`)
VALUES
@@ -397,7 +397,7 @@ INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city
(1107, 'Hank Pym', '09854837G', 'ANT MAN', 'Hawk', 'ANTHILL, SAN FRANCISCO, CALIFORNIA', 'Gotham', 46460, 1111111111, 222222222, 1, 'HankPym@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, 19, 0, 'florist','normal'),
(1108, 'Charles Xavier', '22641921P', 'PROFESSOR X', 'Beast', '3800 VICTORY PKWY, CINCINNATI, OH 45207, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 5, 1, 300, 13, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, NULL, 0, 0, 19, 0, 'florist','normal'),
(1109, 'Bruce Banner', '16104829E', 'HULK', 'Black widow', 'SOMEWHERE IN NEW YORK', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, 9, 0, 'florist','normal'),
- (1110, 'Jessica Jones', '58282869H', 'JESSICA JONES', 'Luke Cage', 'NYCC 2015 POSTER', 'Gotham', 46460, 1111111111, 222222222, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, NULL, 0, 'florist','normal'),
+ (1110, 'Jessica Jones', '58282869H', 'JESSICA JONES', 'Luke Cage', 'NYCC 2015 POSTER', 'Gotham', 46460, 1111111111, 222222222, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, NULL, 1, 'florist','normal'),
(1111, 'Missing', NULL, 'MISSING MAN', 'Anton', 'THE SPACE, UNIVERSE FAR AWAY', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 0, 1, 0, NULL, 1, 0, NULL, 0, 'others','loses'),
(1112, 'Trash', NULL, 'GARBAGE MAN', 'Unknown name', 'NEW YORK CITY, UNDERGROUND', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 0, 1, 0, NULL, 1, 0, NULL, 0, 'others','loses');
@@ -821,10 +821,10 @@ INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `userFk`, `created`)
(12, 3, 19, util.VN_NOW()),
(13, 3, 19, util.VN_NOW()),
(14, 3, 19, util.VN_NOW()),
- (15, 2, 19, util.VN_NOW()),
+ (15, 10, 19, util.VN_NOW()),
(16, 3, 19, util.VN_NOW()),
(17, 2, 19, util.VN_NOW()),
- (18, 2, 19, util.VN_NOW()),
+ (37, 10, 19, util.VN_NOW()),
(19, 2, 19, util.VN_NOW()),
(20, 1, 19, DATE_ADD(util.VN_NOW(), INTERVAL +1 MONTH)),
(21, 1, 19, DATE_ADD(util.VN_NOW(), INTERVAL +1 MONTH)),
@@ -1031,19 +1031,20 @@ INSERT INTO `vn`.`expeditionStateType`(`id`, `description`, `code`)
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `freightItemFk`, `created`, `counter`, `workerFk`, `externalId`, `packagingFk`, `stateTypeFk`, `hostFk`)
VALUES
- (1, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, 'UR9000006041', 94, 1, 'pc1'),
- (2, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 18, 'UR9000006041', 94, 1, NULL),
- (3, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 3, 18, 'UR9000006041', 94, 2, NULL),
- (4, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 4, 18, 'UR9000006041', 94, 2, NULL),
- (5, 1, 2, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, NULL, 94, 3, NULL),
- (6, 7, 3, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), 1, 18, NULL, 94, 3, NULL),
- (7, 2, 4, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), 1, 18, NULL, 94, NULL,NULL),
- (8, 3, 5, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), 1, 18, NULL, 94, 1, NULL),
- (9, 3, 6, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, NULL, 94, 2, NULL),
- (10, 7, 7, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL),
- (11, 7, 8, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL),
- (12, 7, 9, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL),
- (13, 1, 10,71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL);
+ (1, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, 'UR9000006041', 94, 1, 'pc1'),
+ (2, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 18, 'UR9000006041', 94, 1, NULL),
+ (3, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 3, 18, 'UR9000006041', 94, 2, NULL),
+ (4, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 4, 18, 'UR9000006041', 94, 2, NULL),
+ (5, 1, 2, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, NULL, 94, 3, NULL),
+ (6, 7, 3, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), 1, 18, NULL, 94, 3, NULL),
+ (7, 2, 4, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), 1, 18, NULL, 94, NULL,NULL),
+ (8, 3, 5, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), 1, 18, NULL, 94, 1, NULL),
+ (9, 3, 6, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, NULL, 94, 2, NULL),
+ (10, 7, 7, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL),
+ (11, 7, 8, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL),
+ (12, 7, 9, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL),
+ (13, 1, 10, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL),
+ (14, 1, 37, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL);
INSERT INTO `vn`.`expeditionState`(`id`, `created`, `expeditionFk`, `typeFk`, `userFk`)
@@ -1478,7 +1479,8 @@ INSERT INTO `vn`.`ticketWeekly`(`ticketFk`, `weekDay`)
(2, 1),
(3, 2),
(5, 6),
- (15, 6);
+ (15, 6),
+ (17, 6);
INSERT INTO `vn`.`awb` (id, code, package, weight, created, amount, transitoryFk, taxFk)
VALUES
@@ -1494,16 +1496,16 @@ INSERT INTO `vn`.`awb` (id, code, package, weight, created, amount, transitoryFk
(10, '07546500856', 185, 2364, util.VN_CURDATE(), 5321, 442, 1);
INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseOutFk`, `agencyModeFk`, `m3`, `kg`,`ref`, `totalEntries`, `cargoSupplierFk`, `awbFK`)
- VALUES
- (1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), 1, 2, 1, 100.00, 1000, 'first travel', 1, 1, 1),
- (2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 150, 2000, 'second travel', 2, 2, 2),
- (3, util.VN_CURDATE(), util.VN_CURDATE(), 1, 2, 1, 0.00, 0.00, 'third travel', 1, 1, 3),
- (4, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 3, 1, 50.00, 500, 'fourth travel', 0, 2, 4),
- (5, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 3, 3, 1, 50.00, 500, 'fifth travel', 1, 1, 5),
- (6, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 50.00, 500, 'sixth travel', 1, 2, 6),
- (7, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 4, 1, 50.00, 500, 'seventh travel', 2, 1, 7),
- (8, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 1, 1, 50.00, 500, 'eight travel', 1, 2, 10),
- (10, DATE_ADD(util.VN_CURDATE(), INTERVAL + 5 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL + 5 DAY), 5, 1, 1, 50.00, 500, 'nineth travel', 1, 2, 10);
+ VALUES (1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), 1, 2, 1, 100.00, 1000, 'first travel', 1, 1, 1),
+ (2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 150.00, 2000, 'second travel', 2, 2, 2),
+ (3, util.VN_CURDATE(), util.VN_CURDATE(), 1, 2, 1, 0.00, 0.00, 'third travel', 1, 1, 3),
+ (4, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 3, 1, 50.00, 500, 'fourth travel', 0, 2, 4),
+ (5, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 3, 3, 1, 50.00, 500, 'fifth travel', 1, 1, 5),
+ (6, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 50.00, 500, 'sixth travel', 1, 2, 6),
+ (7, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 4, 1, 50.00, 500, 'seventh travel', 2, 1, 7),
+ (8, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 1, 1, 50.00, 500, 'eight travel', 1, 2, 10),
+ (10, DATE_ADD(util.VN_CURDATE(), INTERVAL +5 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL +5 DAY), 5, 1, 1, 50.00, 500, 'nineth travel', 1, 2, 10),
+ (11, util.VN_CURDATE() , util.VN_CURDATE() + INTERVAL 1 DAY, 6, 3, 0, 50.00, 500, 'eleventh travel', 1, 2, 4);
INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed`, `companyFk`, `invoiceNumber`, `reference`, `isExcludedFromAvailable`, `isRaid`, `evaNotes`)
VALUES
@@ -1516,7 +1518,8 @@ INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed
(7, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'IN2007', 'Movement 7', 0, 0, 'observation seven'),
(8, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'IN2008', 'Movement 8', 1, 1, ''),
(9, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL +2 DAY), 10, 0, 442, 'IN2009', 'Movement 9', 1, 1, ''),
- (10, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL +2 DAY), 10, 0, 442, 'IN2009', 'Movement 9', 1, 1, '');
+ (10, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL +2 DAY), 10, 0, 442, 'IN2009', 'Movement 10', 1, 1, ''),
+ (99, 69, '2000-12-01 00:00:00.000', 11, 0, 442, 'IN2009', 'Movement 99', 1, 1, '');
INSERT INTO `vn`.`entryConfig` (`defaultEntry`, `inventorySupplierFk`, `defaultSupplierFk`)
VALUES (2, 4, 1);
@@ -1539,7 +1542,7 @@ INSERT INTO `bs`.`waste`(`buyerFk`, `year`, `week`, `itemFk`, `itemTypeFk`, `sal
('103', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 6, 1, '186', '0', '51', '53.12', '56.20', '56.20', '56.20'),
('103', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 7, 1, '277', '0', '53.12', '56.20', '56.20', '56.20', '56.20');
-INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packagingFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`, `printedStickers`,`isChecked`,`isIgnored`,`weight`, `created`)
+INSERT INTO vn.buy(id,entryFk,itemFk,buyingValue,quantity,packagingFk,stickers,freightValue,packageValue,comissionValue,packing,grouping,groupingMode,location,price1,price2,price3,printedStickers,isChecked,isIgnored,weight,created)
VALUES
(1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'packing', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 2 MONTH),
(2, 2, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'packing', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 1 MONTH),
@@ -1555,7 +1558,8 @@ INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packagi
(12, 6, 4, 1.25, 0, 3, 1, 2.500, 2.500, 0.000, 10, 10, 'grouping', NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
(13, 7, 1, 50, 0, 3, 1, 2.000, 2.000, 0.000, 1, 1, 'packing', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 4, util.VN_CURDATE()),
(14, 7, 2, 5, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 'grouping', NULL, 0.00, 7.30, 7.00, 0, 1, 0, 4, util.VN_CURDATE()),
- (15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 'grouping', NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE());
+ (15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 'grouping', NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
+ (16, 99,1,50.0000, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'packing', NULL, 0.00, 99.60, 99.40, 0, 1, 0, 1.00, '2024-07-30 08:13:51.000');
INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_id`, `agency_id`, `address_id`, `company_id`, `note`, `source_app`, `confirmed`,`total`, `date_make`, `first_row_stamp`, `confirm_date`)
VALUES
@@ -3932,44 +3936,38 @@ INSERT INTO vn.medicalReview
(id, workerFk, centerFk, `date`, `time`, isFit, amount, invoice, remark)
VALUES(3, 9, 2, '2000-01-01', '8:00', 1, 150.0, NULL, NULL);
-INSERT INTO vn.payrollComponent
-(id, name, isSalaryAgreed, isVariable, isException)
- VALUES
- (1, 'Salario1', 1, 0, 0),
+INSERT INTO vn.stockBought (workerFk, bought, reserve, dated)
+ VALUES(35, 1.00, 1.00, '2001-01-01');
+
+INSERT INTO vn.auctionConfig (id,conversionCoefficient,warehouseFk)
+ VALUES (1,0.6,6);
+
+INSERT INTO vn.payrollComponent (id, name, isSalaryAgreed, isVariable, isException)
+ VALUES (1, 'Salario1', 1, 0, 0),
(2, 'Salario2', 1, 1, 0),
(3, 'Salario3', 1, 0, 1);
-
-INSERT INTO vn.workerIncome
-(debit, credit, incomeTypeFk, paymentDate, workerFk, concept)
- VALUES
- (1000.00, 900.00, 2, '2000-01-01', 1106, NULL),
+INSERT INTO vn.workerIncome (debit, credit, incomeTypeFk, paymentDate, workerFk, concept)
+ VALUES (1000.00, 900.00, 2, '2000-01-01', 1106, NULL),
(1001.00, 800.00, 2, '2000-01-01', 1106, NULL);
+INSERT INTO dipole.printer (id, description) VALUES(1, '');
-INSERT INTO dipole.printer (id, description)
-VALUES(1, '');
+INSERT INTO dipole.expedition_PrintOut (expeditionFk, ticketFk, addressFk, street, postalCode, city, shopName, isPrinted, created, printerFk, routeFk, parkingCode, truckName, clientFk, phone, province, agency, m3, workerCode, itemFk, quantity, longName, shelvingFk, comments)
+ VALUES(1, 1, 0, ' ', ' ', ' ', ' ', 0, '2001-01-01 00:00:00', 1, 0, ' ', ' ', 0, NULL, '', NULL, 0.000, NULL, 10, NULL, NULL, 'NCC', NULL);
-INSERT INTO dipole.expedition_PrintOut (expeditionFk, ticketFk, addressFk, street, postalCode, city, shopName, isPrinted, created, printerFk, routeFk, parkingCode,
-truckName, clientFk, phone, province, agency, m3, workerCode, itemFk, quantity, longName, shelvingFk, comments)
-VALUES(1, 1, 0, ' ', ' ', ' ', ' ', 0, '2001-01-01 00:00:00', 1, 0, ' ', ' ', 0, NULL, '', NULL, 0.000, NULL, 10, NULL, NULL, 'NCC', NULL);
+INSERT INTO vn.accountDetail (id, value, accountDetailTypeFk, supplierAccountFk)
+ VALUES (21, 'ES12345B12345678', 3, 241),
+ (35, 'ES12346B12345679', 3, 241);
-INSERT INTO vn.accountDetail
-(id, value, accountDetailTypeFk, supplierAccountFk)
-VALUES
- (21, 'ES12345B12345678', 3, 241),
- (35, 'ES12346B12345679', 3, 241);
+INSERT INTO vn.accountDetailType (id, description, code)
+ VALUES (1, 'IBAN', 'iban'),
+ (2, 'SWIFT', 'swift'),
+ (3, 'Referencia Remesas', 'remRef'),
+ (4, 'Referencia Transferencias', 'trnRef'),
+ (5, 'Referencia Nominas', 'payRef'),
+ (6, 'ABA', 'aba');
-INSERT INTO vn.accountDetailType
-(id, description, code)
-VALUES
- (1, 'IBAN', 'iban'),
- (2, 'SWIFT', 'swift'),
- (3, 'Referencia Remesas', 'remRef'),
- (4, 'Referencia Transferencias', 'trnRef'),
- (5, 'Referencia Nominas', 'payRef'),
- (6, 'ABA', 'aba');
-
-INSERT IGNORE INTO ormConfig
+INSERT IGNORE INTO ormConfig
SET id =1,
selectLimit = 1000;
diff --git a/db/routines/vn/procedures/itemShelvingSale_addBySale.sql b/db/routines/vn/procedures/itemShelvingSale_addBySale.sql
index fbb93c5248..aa50f0ed8c 100644
--- a/db/routines/vn/procedures/itemShelvingSale_addBySale.sql
+++ b/db/routines/vn/procedures/itemShelvingSale_addBySale.sql
@@ -75,6 +75,9 @@ proc: BEGIN
WHERE saleFk = vSaleFk;
IF vTotalReservedQuantity <> vSaleQuantity THEN
+ CALL util.debugAdd('itemShelvingSale_addBySale',
+ CONCAT(vSaleFk, ' - ', vSaleQuantity,' - ', vTotalReservedQuantity,'-', vOutStanding,'-', account.myUser_getId()));
+
UPDATE sale
SET quantity = vTotalReservedQuantity
WHERE id = vSaleFk;
@@ -93,7 +96,8 @@ proc: BEGIN
SET vOutStanding = vOutStanding - vReservedQuantity;
IF vReservedQuantity > 0 THEN
-
+ CALL util.debugAdd('itemShelvingSale_addBySale_reservedQuantity',
+ CONCAT(vSaleFk, ' - ', vReservedQuantity, ' - ', vOutStanding, account.myUser_getId()));
INSERT INTO itemShelvingSale(
itemShelvingFk,
saleFk,
diff --git a/db/routines/vn/procedures/item_getSimilar.sql b/db/routines/vn/procedures/item_getSimilar.sql
index 823625b973..b524e30a77 100644
--- a/db/routines/vn/procedures/item_getSimilar.sql
+++ b/db/routines/vn/procedures/item_getSimilar.sql
@@ -1,48 +1,64 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getSimilar`(
- vSelf INT,
- vWarehouseFk INT,
- vDated DATE,
- vShowType BOOL
+ vSelf INT,
+ vWarehouseFk INT,
+ vDated DATE,
+ vShowType BOOL,
+ vDaysInForward INT
)
BEGIN
/**
-* Propone articulos disponibles ordenados, con la cantidad
+* Propone articulos ordenados, con la cantidad
* de veces usado y segun sus caracteristicas.
*
* @param vSelf Id de artĂculo
* @param vWarehouseFk Id de almacen
* @param vDated Fecha
* @param vShowType Mostrar tipos
+* @param vDaysInForward DĂas de alcance para las ventas
*/
- DECLARE vAvailableCalcFk INT;
- DECLARE vVisibleCalcFk INT;
- DECLARE vTypeFk INT;
- DECLARE vPriority INT DEFAULT 1;
+ DECLARE vAvailableCalcFk INT;
+ DECLARE vPriority INT DEFAULT 1;
- CALL cache.available_refresh(vAvailableCalcFk, FALSE, vWarehouseFk, vDated);
- CALL cache.visible_refresh(vVisibleCalcFk, FALSE, vWarehouseFk);
+ CALL cache.available_refresh(vAvailableCalcFk, FALSE, vWarehouseFk, vDated);
- WITH itemTags AS (
- SELECT i.id,
- typeFk,
- tag5,
- value5,
- tag6,
- value6,
- tag7,
- value7,
- tag8,
- value8,
- t.name,
- it.value
+ WITH itemTags AS (
+ SELECT i.id,
+ typeFk,
+ tag5,
+ value5,
+ tag6,
+ value6,
+ tag7,
+ value7,
+ tag8,
+ value8,
+ t.name,
+ it.value
FROM vn.item i
LEFT JOIN vn.itemTag it ON it.itemFk = i.id
AND it.priority = vPriority
LEFT JOIN vn.tag t ON t.id = it.tagFk
WHERE i.id = vSelf
- )
- SELECT i.id itemFk,
+ ),
+ stock AS (
+ SELECT itemFk, SUM(visible) stock
+ FROM vn.itemShelvingStock
+ WHERE warehouseFk = vWarehouseFk
+ GROUP BY itemFk
+ ),
+ sold AS (
+ SELECT SUM(s.quantity) quantity, s.itemFk
+ FROM vn.sale s
+ JOIN vn.ticket t ON t.id = s.ticketFk
+ LEFT JOIN vn.itemShelvingSale iss ON iss.saleFk = s.id
+ WHERE t.shipped BETWEEN CURDATE() AND CURDATE() + INTERVAL vDaysInForward DAY
+ AND iss.saleFk IS NULL
+ AND t.warehouseFk = vWarehouseFk
+ GROUP BY s.itemFk
+ )
+ SELECT i.id itemFk,
+ CAST(sd.quantity AS INT) advanceable,
i.longName,
i.subName,
i.tag5,
@@ -64,13 +80,13 @@ BEGIN
WHEN b.groupingMode = 'packing' THEN b.packing
ELSE 1
END minQuantity,
- v.visible located,
+ sk.stock located,
b.price2
FROM vn.item i
+ LEFT JOIN sold sd ON sd.itemFk = i.id
JOIN cache.available a ON a.item_id = i.id
AND a.calc_id = vAvailableCalcFk
- LEFT JOIN cache.visible v ON v.item_id = i.id
- AND v.calc_id = vVisibleCalcFk
+ LEFT JOIN stock sk ON sk.itemFk = i.id
LEFT JOIN cache.last_buy lb ON lb.item_id = i.id
AND lb.warehouse_id = vWarehouseFk
LEFT JOIN vn.itemProposal ip ON ip.mateFk = i.id
@@ -80,20 +96,21 @@ BEGIN
LEFT JOIN vn.tag t ON t.id = it.tagFk
LEFT JOIN vn.buy b ON b.id = lb.buy_id
JOIN itemTags its
- WHERE a.available > 0
+ WHERE (a.available > 0 OR sd.quantity < sk.stock)
AND (i.typeFk = its.typeFk OR NOT vShowType)
AND i.id <> vSelf
- ORDER BY `counter` DESC,
- (t.name = its.name) DESC,
- (it.value = its.value) DESC,
- (i.tag5 = its.tag5) DESC,
- match5 DESC,
- (i.tag6 = its.tag6) DESC,
- match6 DESC,
- (i.tag7 = its.tag7) DESC,
- match7 DESC,
- (i.tag8 = its.tag8) DESC,
- match8 DESC
+ ORDER BY (a.available > 0) DESC,
+ `counter` DESC,
+ (t.name = its.name) DESC,
+ (it.value = its.value) DESC,
+ (i.tag5 = its.tag5) DESC,
+ match5 DESC,
+ (i.tag6 = its.tag6) DESC,
+ match6 DESC,
+ (i.tag7 = its.tag7) DESC,
+ match7 DESC,
+ (i.tag8 = its.tag8) DESC,
+ match8 DESC
LIMIT 100;
END$$
DELIMITER ;
diff --git a/db/routines/vn/procedures/productionControl.sql b/db/routines/vn/procedures/productionControl.sql
index 842a306b49..3bd53c3116 100644
--- a/db/routines/vn/procedures/productionControl.sql
+++ b/db/routines/vn/procedures/productionControl.sql
@@ -276,7 +276,8 @@ proc: BEGIN
JOIN productionConfig pc
SET hasPlantTray = TRUE
WHERE ic.code = 'plant'
- AND p.`depth` >= pc.minPlantTrayLength;
+ AND p.`depth` >= pc.minPlantTrayLength
+ AND pb.isOwn;
DROP TEMPORARY TABLE
tmp.productionTicket,
diff --git a/db/routines/vn/procedures/stockBought_calculate.sql b/db/routines/vn/procedures/stockBought_calculate.sql
new file mode 100644
index 0000000000..6eabe015c8
--- /dev/null
+++ b/db/routines/vn/procedures/stockBought_calculate.sql
@@ -0,0 +1,52 @@
+DELIMITER $$
+CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`stockBought_calculate`()
+BEGIN
+/**
+ * Inserts the purchase volume per buyer
+ * into stockBought according to the current date.
+ */
+ DECLARE vDated DATE;
+ SET vDated = util.VN_CURDATE();
+
+ CREATE OR REPLACE TEMPORARY TABLE tStockBought
+ SELECT workerFk, reserve
+ FROM stockBought
+ WHERE dated = vDated
+ AND reserve;
+
+ DELETE FROM stockBought WHERE dated = vDated;
+
+ INSERT INTO stockBought (workerFk, bought, dated)
+ SELECT it.workerFk,
+ ROUND(SUM(
+ (ac.conversionCoefficient *
+ (b.quantity / b.packing) *
+ buy_getVolume(b.id)
+ ) / (vc.trolleyM3 * 1000000)
+ ), 1),
+ vDated
+ FROM entry e
+ JOIN travel t ON t.id = e.travelFk
+ JOIN warehouse w ON w.id = t.warehouseInFk
+ JOIN buy b ON b.entryFk = e.id
+ JOIN item i ON i.id = b.itemFk
+ JOIN itemType it ON it.id = i.typeFk
+ JOIN auctionConfig ac
+ JOIN volumeConfig vc
+ WHERE t.shipped = vDated
+ AND t.warehouseInFk = ac.warehouseFk
+ GROUP BY it.workerFk;
+
+ UPDATE stockBought s
+ JOIN tStockBought ts ON ts.workerFk = s.workerFk
+ SET s.reserve = ts.reserve
+ WHERE s.dated = vDated;
+
+ INSERT INTO stockBought (workerFk, reserve, dated)
+ SELECT ts.workerFk, ts.reserve, vDated
+ FROM tStockBought ts
+ WHERE ts.workerFk NOT IN (SELECT workerFk FROM stockBought WHERE dated = vDated);
+
+ DROP TEMPORARY TABLE tStockBought;
+END$$
+DELIMITER ;
diff --git a/db/routines/vn/procedures/ticket_splitItemPackingType.sql b/db/routines/vn/procedures/ticket_splitItemPackingType.sql
index b5b77d2efc..407b8cdde1 100644
--- a/db/routines/vn/procedures/ticket_splitItemPackingType.sql
+++ b/db/routines/vn/procedures/ticket_splitItemPackingType.sql
@@ -10,6 +10,7 @@ BEGIN
*
* @param vSelf Id ticket
* @param vOriginalItemPackingTypeFk Tipo empaquetado al que se mantiene el ticket original
+ * @return table tmp.ticketIPT(ticketFk, itemPackingTypeFk)
*/
DECLARE vDone INT DEFAULT FALSE;
DECLARE vHasItemPackingType BOOL;
@@ -72,6 +73,16 @@ BEGIN
SET s.ticketFk = stm.ticketFk
WHERE stm.ticketFk;
+ CREATE OR REPLACE TEMPORARY TABLE tmp.ticketIPT(
+ ticketFk INT,
+ itemPackingTypeFk VARCHAR(1)
+ ) ENGINE=MEMORY
+ SELECT ticketFk, itemPackingTypeFk
+ FROM tSalesToMove
+ GROUP BY ticketFk
+ UNION
+ SELECT vSelf, vOriginalItemPackingTypeFk;
+
DROP TEMPORARY TABLE tSalesToMove;
END$$
DELIMITER ;
\ No newline at end of file
diff --git a/db/routines/vn/views/buyer.sql b/db/routines/vn/views/buyer.sql
index 4f668d35dc..e690dc16fb 100644
--- a/db/routines/vn/views/buyer.sql
+++ b/db/routines/vn/views/buyer.sql
@@ -2,10 +2,12 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost`
SQL SECURITY DEFINER
VIEW `vn`.`buyer`
AS SELECT DISTINCT `u`.`id` AS `userFk`,
- `u`.`nickname` AS `nickname`
+ `u`.`nickname` AS `nickname`,
+ `ic`.`display` AS `display`
FROM (
`account`.`user` `u`
JOIN `vn`.`itemType` `it` ON(`it`.`workerFk` = `u`.`id`)
+ JOIN `vn`.`itemCategory` `ic` ON(`ic`.`id` = `it`.`categoryFk`)
)
WHERE `u`.`active` <> 0
ORDER BY `u`.`nickname`
diff --git a/db/versions/11088-bronzeAspidistra/00-firstScript.sql b/db/versions/11088-bronzeAspidistra/00-firstScript.sql
index 751bbf7e32..5c56993fd7 100644
--- a/db/versions/11088-bronzeAspidistra/00-firstScript.sql
+++ b/db/versions/11088-bronzeAspidistra/00-firstScript.sql
@@ -1,10 +1,10 @@
ALTER TABLE vn.collectionWagonTicket DROP FOREIGN KEY IF EXISTS collectionWagonTicket_tray;
ALTER TABLE vn.wagonConfig DROP FOREIGN KEY IF EXISTS wagonConfig_wagonTypeColor_FK;
CREATE OR REPLACE TABLE vn.wagonTypeTray (
- id INT(11) UNSIGNED,
- wagonTypeFk INT(11) unsigned NULL,
+ id INT(11) UNSIGNED auto_increment,
+ wagonTypeFk INT(11) UNSIGNED NULL,
height INT(11) UNSIGNED NULL,
- wagonTypeColorFk int(11) unsigned NULL,
+ wagonTypeColorFk int(11) UNSIGNED NULL,
CONSTRAINT wagonTypeTray_pk PRIMARY KEY (id),
CONSTRAINT wagonTypeTray_wagonType_FK FOREIGN KEY (wagonTypeFk) REFERENCES vn.wagonType(id) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT wagonTypeTray_wagonTypeColor_FK FOREIGN KEY (wagonTypeColorFk) REFERENCES vn.wagonTypeColor(id)
@@ -14,6 +14,6 @@ DEFAULT CHARSET=utf8mb3
COLLATE=utf8mb3_unicode_ci;
ALTER TABLE vn.wagonConfig ADD IF NOT EXISTS defaultHeight INT UNSIGNED DEFAULT 0 NULL COMMENT 'Default height in cm for a base tray';
-ALTER TABLE vn.wagonConfig ADD IF NOT EXISTS defaultTrayColorFk int(11) unsigned NULL COMMENT 'Default color for a base tray';
+ALTER TABLE vn.wagonConfig ADD IF NOT EXISTS defaultTrayColorFk int(11) UNSIGNED NULL COMMENT 'Default color for a base tray';
ALTER TABLE vn.wagonConfig ADD CONSTRAINT wagonConfig_wagonTypeColor_FK FOREIGN KEY (defaultTrayColorFk) REFERENCES vn.wagonTypeColor(id);
ALTER TABLE vn.collectionWagonTicket ADD CONSTRAINT collectionWagonTicket_tray FOREIGN KEY (trayFk) REFERENCES vn.wagonTypeTray(id);
diff --git a/db/versions/11115-turquoiseRose/00-firstScript.sql b/db/versions/11115-turquoiseRose/00-firstScript.sql
new file mode 100644
index 0000000000..3982936fcf
--- /dev/null
+++ b/db/versions/11115-turquoiseRose/00-firstScript.sql
@@ -0,0 +1,30 @@
+-- Place your SQL code here
+-- vn.stockBought definition
+
+CREATE TABLE IF NOT EXISTS vn.stockBought (
+ id INT UNSIGNED auto_increment NOT NULL,
+ workerFk int(10) unsigned NOT NULL,
+ bought decimal(10,2) NOT NULL COMMENT 'purchase volume in m3 for the day',
+ reserve decimal(10,2) NULL COMMENT 'reserved volume in m3 for the day',
+ dated DATE NOT NULL DEFAULT current_timestamp(),
+ CONSTRAINT stockBought_pk PRIMARY KEY (id),
+ CONSTRAINT stockBought_unique UNIQUE KEY (workerFk,dated),
+ CONSTRAINT stockBought_worker_FK FOREIGN KEY (workerFk) REFERENCES vn.worker(id)
+)
+ENGINE=InnoDB
+DEFAULT CHARSET=utf8mb3
+COLLATE=utf8mb3_unicode_ci;
+
+
+INSERT IGNORE vn.stockBought (workerFk, bought, reserve, dated)
+ SELECT userFk, SUM(buyed), SUM(IFNULL(reserved,0)), dated
+ FROM vn.stockBuyed
+ WHERE userFk IS NOT NULL
+ AND buyed IS NOT NULL
+ GROUP BY userFk, dated;
+
+INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
+ VALUES ('StockBought','*','READ','ALLOW','ROLE','buyer'),
+ ('StockBought','*','WRITE','ALLOW','ROLE','buyer'),
+ ('Buyer','*','READ','ALLOW','ROLE','buyer');
+
diff --git a/db/versions/11229-salmonAsparagus/00-firstScript.sql b/db/versions/11229-salmonAsparagus/00-firstScript.sql
index d590ed958d..80547db38c 100644
--- a/db/versions/11229-salmonAsparagus/00-firstScript.sql
+++ b/db/versions/11229-salmonAsparagus/00-firstScript.sql
@@ -1,3 +1,2 @@
--- Place your SQL code here
-ALTER TABLE vn.productionConfig ADD minPlantTrayLength INT DEFAULT 53 NOT NULL
+ALTER TABLE vn.productionConfig ADD IF NOT EXISTS minPlantTrayLength INT DEFAULT 53 NOT NULL
COMMENT 'minimum length for plant tray restriction. Avoid to make collection of the ticket with this kind of item';
diff --git a/db/versions/11235-purpleCordyline/00-firstScript.sql b/db/versions/11235-purpleCordyline/00-firstScript.sql
new file mode 100644
index 0000000000..f3bb6ddab8
--- /dev/null
+++ b/db/versions/11235-purpleCordyline/00-firstScript.sql
@@ -0,0 +1,12 @@
+ALTER TABLE vn.collectionWagon DROP FOREIGN KEY IF EXISTS collectionWagon_FK_1;
+ALTER TABLE vn.collectionWagonTicket DROP FOREIGN KEY IF EXISTS collectionWagonTicket_FK_1;
+ALTER TABLE vn.wagonVolumetry DROP FOREIGN KEY IF EXISTS wagonVolumetry_FK_1;
+
+ALTER TABLE vn.wagon MODIFY COLUMN id int(11) unsigned auto_increment NOT NULL COMMENT '26 letras de alfabeto inglés';
+ALTER TABLE vn.collectionWagon MODIFY COLUMN wagonFk int(11) unsigned NOT NULL;
+ALTER TABLE vn.collectionWagonTicket MODIFY COLUMN wagonFk int(11) unsigned NOT NULL;
+ALTER TABLE vn.wagonVolumetry MODIFY COLUMN wagonFk int(11) unsigned NOT NULL;
+
+ALTER TABLE vn.collectionWagon ADD CONSTRAINT collectionWagon_FK_1 FOREIGN KEY (wagonFk) REFERENCES vn.wagon(id) ON DELETE RESTRICT ON UPDATE CASCADE;
+ALTER TABLE vn.collectionWagonTicket ADD CONSTRAINT collectionWagonTicket_FK_1 FOREIGN KEY (wagonFk) REFERENCES vn.wagon(id) ON DELETE RESTRICT ON UPDATE CASCADE;
+ALTER TABLE vn.wagonVolumetry ADD CONSTRAINT wagonVolumetry_FK_1 FOREIGN KEY (wagonFk) REFERENCES vn.wagon(id) ON DELETE RESTRICT ON UPDATE CASCADE;
diff --git a/e2e/paths/05-ticket/09_weekly.spec.js b/e2e/paths/05-ticket/09_weekly.spec.js
index 1caf91f9c0..370d422e63 100644
--- a/e2e/paths/05-ticket/09_weekly.spec.js
+++ b/e2e/paths/05-ticket/09_weekly.spec.js
@@ -19,7 +19,7 @@ describe('Ticket descriptor path', () => {
it('should count the amount of tickets in the turns section', async() => {
const result = await page.countElement(selectors.ticketsIndex.weeklyTicket);
- expect(result).toEqual(5);
+ expect(result).toEqual(6);
});
it('should go back to the ticket index then search and access a ticket summary', async() => {
@@ -106,7 +106,7 @@ describe('Ticket descriptor path', () => {
await page.doSearch();
const nResults = await page.countElement(selectors.ticketsIndex.searchWeeklyResult);
- expect(nResults).toEqual(5);
+ expect(nResults).toEqual(6);
});
it('should update the agency then remove it afterwards', async() => {
diff --git a/loopback/locale/en.json b/loopback/locale/en.json
index 1753d1d072..352e08826f 100644
--- a/loopback/locale/en.json
+++ b/loopback/locale/en.json
@@ -235,9 +235,10 @@
"Cannot add holidays on this day": "Cannot add holidays on this day",
"Cannot send mail": "Cannot send mail",
"CONSTRAINT `chkParkingCodeFormat` failed for `vn`.`parking`": "CONSTRAINT `chkParkingCodeFormat` failed for `vn`.`parking`",
- "This postcode already exists": "This postcode already exists",
"Original invoice not found": "Original invoice not found",
"There is already a tray with the same height": "There is already a tray with the same height",
"The height must be greater than 50cm": "The height must be greater than 50cm",
- "The maximum height of the wagon is 200cm": "The maximum height of the wagon is 200cm"
-}
+ "The maximum height of the wagon is 200cm": "The maximum height of the wagon is 200cm",
+ "This postcode already exists": "This postcode already exists",
+ "This buyer has already made a reservation for this date": "This buyer has already made a reservation for this date"
+}
\ No newline at end of file
diff --git a/loopback/locale/es.json b/loopback/locale/es.json
index 1093fe326e..49c44a4d83 100644
--- a/loopback/locale/es.json
+++ b/loopback/locale/es.json
@@ -366,16 +366,17 @@
"The invoices have been created but the PDFs could not be generated": "Se ha facturado pero no se ha podido generar el PDF",
"It has been invoiced but the PDF of refund not be generated": "Se ha facturado pero no se ha podido generar el PDF del abono",
"Payment method is required": "El método de pago es obligatorio",
- "Cannot send mail": "NĂŁo Ă© possĂvel enviar o email",
+ "Cannot send mail": "No se ha podido enviar el correo",
"CONSTRAINT `supplierAccountTooShort` failed for `vn`.`supplier`": "La cuenta debe tener exactamente 10 dĂgitos",
"The sale not exists in the item shelving": "La venta no existe en la estanterĂa del artĂculo",
- "The entry not have stickers": "La entrada no tiene etiquetas",
- "Too many records": "Demasiados registros",
"Original invoice not found": "Factura original no encontrada",
"The entry has no lines or does not exist": "La entrada no tiene lineas o no existe",
"Weight already set": "El peso ya está establecido",
"This ticket is not allocated to your department": "Este ticket no está asignado a tu departamento",
"There is already a tray with the same height": "Ya existe una bandeja con la misma altura",
"The height must be greater than 50cm": "La altura debe ser superior a 50cm",
- "The maximum height of the wagon is 200cm": "La altura máxima es 200cm"
+ "The maximum height of the wagon is 200cm": "La altura máxima es 200cm",
+ "The entry does not have stickers": "La entrada no tiene etiquetas",
+ "Too many records": "Demasiados registros",
+ "This buyer has already made a reservation for this date": "Este comprador ya ha hecho una reserva para esta fecha"
}
\ No newline at end of file
diff --git a/modules/account/back/models/mail-alias-account.js b/modules/account/back/models/mail-alias-account.js
index 61ca344e9d..0eee6a1239 100644
--- a/modules/account/back/models/mail-alias-account.js
+++ b/modules/account/back/models/mail-alias-account.js
@@ -1,5 +1,6 @@
const ForbiddenError = require('vn-loopback/util/forbiddenError');
+const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.rewriteDbError(function(err) {
diff --git a/modules/entry/back/methods/entry/print.js b/modules/entry/back/methods/entry/print.js
index 5b9de9a695..11abf07880 100644
--- a/modules/entry/back/methods/entry/print.js
+++ b/modules/entry/back/methods/entry/print.js
@@ -52,7 +52,7 @@ module.exports = Self => {
await merger.add(new Uint8Array(pdfBuffer[0]));
}
- if (!merger._doc) throw new UserError('The entry not have stickers');
+ if (!merger._doc) throw new UserError('The entry does not have stickers');
await Self.rawSql(`
UPDATE buy
diff --git a/modules/entry/back/methods/entry/specs/filter.spec.js b/modules/entry/back/methods/entry/specs/filter.spec.js
index c7156062a9..145da170ab 100644
--- a/modules/entry/back/methods/entry/specs/filter.spec.js
+++ b/modules/entry/back/methods/entry/specs/filter.spec.js
@@ -39,7 +39,7 @@ describe('Entry filter()', () => {
const result = await models.Entry.filter(ctx, options);
- expect(result.length).toEqual(11);
+ expect(result.length).toEqual(12);
await tx.rollback();
} catch (e) {
@@ -131,7 +131,7 @@ describe('Entry filter()', () => {
const result = await models.Entry.filter(ctx, options);
- expect(result.length).toEqual(10);
+ expect(result.length).toEqual(11);
await tx.rollback();
} catch (e) {
diff --git a/modules/entry/back/methods/stock-bought/getStockBought.js b/modules/entry/back/methods/stock-bought/getStockBought.js
new file mode 100644
index 0000000000..94e206eced
--- /dev/null
+++ b/modules/entry/back/methods/stock-bought/getStockBought.js
@@ -0,0 +1,60 @@
+module.exports = Self => {
+ Self.remoteMethod('getStockBought', {
+ description: 'Returns the stock bought for a given date',
+ accessType: 'READ',
+ accepts: [{
+ arg: 'workerFk',
+ type: 'number',
+ description: 'The id for a buyer',
+ },
+ {
+ arg: 'dated',
+ type: 'date',
+ description: 'The date to filter',
+ }
+ ],
+ returns: {
+ type: ['object'],
+ root: true
+ },
+ http: {
+ path: `/getStockBought`,
+ verb: 'GET'
+ }
+ });
+
+ Self.getStockBought = async(workerFk, dated = Date.vnNew()) => {
+ const models = Self.app.models;
+ const today = Date.vnNew();
+ dated.setHours(0, 0, 0, 0);
+ today.setHours(0, 0, 0, 0);
+
+ if (dated.getTime() === today.getTime())
+ await models.StockBought.rawSql(`CALL vn.stockBought_calculate()`);
+
+ const filter = {
+ where: {
+ dated: dated
+ },
+ include: [
+ {
+ relation: 'worker',
+ scope: {
+ include: [
+ {
+ relation: 'user',
+ scope: {
+ fields: ['id', 'name']
+ }
+ }
+ ]
+ }
+ }
+ ]
+ };
+
+ if (workerFk) filter.where.workerFk = workerFk;
+
+ return models.StockBought.find(filter);
+ };
+};
diff --git a/modules/entry/back/methods/stock-bought/getStockBoughtDetail.js b/modules/entry/back/methods/stock-bought/getStockBoughtDetail.js
new file mode 100644
index 0000000000..6f09f1f679
--- /dev/null
+++ b/modules/entry/back/methods/stock-bought/getStockBoughtDetail.js
@@ -0,0 +1,58 @@
+module.exports = Self => {
+ Self.remoteMethod('getStockBoughtDetail', {
+ description: 'Returns the detail of stock bought for a given date and a worker',
+ accessType: 'READ',
+ accepts: [{
+ arg: 'workerFk',
+ type: 'number',
+ description: 'The worker to filter',
+ required: true,
+ }, {
+ arg: 'dated',
+ type: 'string',
+ description: 'The date to filter',
+ }
+ ],
+ returns: {
+ type: ['object'],
+ root: true
+ },
+ http: {
+ path: `/getStockBoughtDetail`,
+ verb: 'GET'
+ }
+ });
+
+ Self.getStockBoughtDetail = async(workerFk, dated) => {
+ if (!dated) {
+ dated = Date.vnNew();
+ dated.setHours(0, 0, 0, 0);
+ }
+ return Self.rawSql(
+ `SELECT e.id entryFk,
+ i.id itemFk,
+ i.longName itemName,
+ b.quantity,
+ ROUND((ac.conversionCoefficient *
+ (b.quantity / b.packing) *
+ buy_getVolume(b.id)
+ ) / (vc.trolleyM3 * 1000000),
+ 2
+ ) volume,
+ b.packagingFk,
+ b.packing
+ FROM entry e
+ JOIN travel t ON t.id = e.travelFk
+ JOIN buy b ON b.entryFk = e.id
+ JOIN item i ON i.id = b.itemFk
+ JOIN itemType it ON it.id = i.typeFk
+ JOIN worker w ON w.id = it.workerFk
+ JOIN auctionConfig ac
+ JOIN volumeConfig vc
+ WHERE t.warehouseInFk = ac.warehouseFk
+ AND it.workerFk = ?
+ AND t.shipped = util.VN_CURDATE()`,
+ [workerFk]
+ );
+ };
+};
diff --git a/modules/entry/back/model-config.json b/modules/entry/back/model-config.json
index dc7fd86be2..85f5e8285b 100644
--- a/modules/entry/back/model-config.json
+++ b/modules/entry/back/model-config.json
@@ -25,5 +25,8 @@
},
"EntryType": {
"dataSource": "vn"
+ },
+ "StockBought": {
+ "dataSource": "vn"
}
}
\ No newline at end of file
diff --git a/modules/entry/back/models/stock-bought.js b/modules/entry/back/models/stock-bought.js
new file mode 100644
index 0000000000..ae52e7654c
--- /dev/null
+++ b/modules/entry/back/models/stock-bought.js
@@ -0,0 +1,10 @@
+const UserError = require('vn-loopback/util/user-error');
+module.exports = Self => {
+ require('../methods/stock-bought/getStockBought')(Self);
+ require('../methods/stock-bought/getStockBoughtDetail')(Self);
+ Self.rewriteDbError(function(err) {
+ if (err.code === 'ER_DUP_ENTRY')
+ return new UserError(`This buyer has already made a reservation for this date`);
+ return err;
+ });
+};
diff --git a/modules/entry/back/models/stock-bought.json b/modules/entry/back/models/stock-bought.json
new file mode 100644
index 0000000000..18c9f03478
--- /dev/null
+++ b/modules/entry/back/models/stock-bought.json
@@ -0,0 +1,34 @@
+{
+ "name": "StockBought",
+ "base": "VnModel",
+ "options": {
+ "mysql": {
+ "table": "stockBought"
+ }
+ },
+ "properties": {
+ "id": {
+ "type": "number",
+ "id": true
+ },
+ "workerFk": {
+ "type": "number"
+ },
+ "bought": {
+ "type": "number"
+ },
+ "reserve": {
+ "type": "number"
+ },
+ "dated": {
+ "type": "date"
+ }
+ },
+ "relations": {
+ "worker": {
+ "type": "belongsTo",
+ "model": "Worker",
+ "foreignKey": "workerFk"
+ }
+ }
+}
diff --git a/modules/invoiceOut/back/models/invoice-out.js b/modules/invoiceOut/back/models/invoice-out.js
index 47dbcbea4f..bab1fa3756 100644
--- a/modules/invoiceOut/back/models/invoice-out.js
+++ b/modules/invoiceOut/back/models/invoice-out.js
@@ -83,8 +83,10 @@ module.exports = Self => {
const invoiceOutSerial = await Self.app.models.InvoiceOutSerial.findById(serial);
if (invoiceOutSerial?.taxAreaFk == 'WORLD') {
const address = await Self.app.models.Address.findById(addressId);
- if (!address || !address.customsAgentFk || !address.incotermsFk)
- throw new UserError('The address of the customer must have information about Incoterms and Customs Agent');
+ if (!address?.customsAgentFk || !address.incotermsFk) {
+ throw new UserError(
+ 'The address of the customer must have information about Incoterms and Customs Agent');
+ }
}
return serial;
diff --git a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js
index 9460addfa9..738af52199 100644
--- a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js
+++ b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js
@@ -39,7 +39,7 @@ describe('SalesMonitor salesFilter()', () => {
const filter = {};
const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
- expect(result.length).toBeGreaterThan(10);
+ expect(result.length).toBeGreaterThan(9);
await tx.rollback();
} catch (e) {
@@ -146,13 +146,20 @@ describe('SalesMonitor salesFilter()', () => {
try {
const options = {transaction: tx};
+ const alertLevel = await models.AlertLevel.findOne({
+ where: {code: 'FREE'},
+ options
+ });
+
+ const alertLevelFree = alertLevel.id;
+
const ctx = {req: {accessToken: {userId: 9}}, args: {pending: false}};
const filter = {order: 'alertLevel ASC'};
const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
- const firstRow = result[0];
- expect(result.length).toEqual(15);
- expect(firstRow.alertLevel).not.toEqual(0);
+ result.forEach(row => {
+ expect(row.alertLevel).toBeGreaterThan(alertLevelFree);
+ });
await tx.rollback();
} catch (e) {
diff --git a/modules/ticket/back/methods/ticket-weekly/filter.js b/modules/ticket/back/methods/ticket-weekly/filter.js
index a43b5e270a..6c9ed4f8bb 100644
--- a/modules/ticket/back/methods/ticket-weekly/filter.js
+++ b/modules/ticket/back/methods/ticket-weekly/filter.js
@@ -38,13 +38,14 @@ module.exports = Self => {
Object.assign(myOptions, options);
const where = buildFilter(ctx.args, (param, value) => {
- switch (param) {
- case 'search':
- return {or: [
- {'t.id': value},
- {'c.id': value},
- {'c.name': {like: `%${value}%`}}
- ]};
+ if (param === 'search') {
+ return {
+ or: [
+ {'t.id': value},
+ {'c.id': value},
+ {'c.name': {like: `%${value}%`}}
+ ]
+ };
}
});
diff --git a/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js b/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js
index 453b7924f1..9b1ad52095 100644
--- a/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js
+++ b/modules/ticket/back/methods/ticket-weekly/specs/filter.spec.js
@@ -13,11 +13,11 @@ describe('ticket-weekly filter()', () => {
const ctx = {req: {accessToken: {userId: authUserId}}, args: {filter: filter}};
const result = await models.TicketWeekly.filter(ctx, null, options);
-
+ const totalRecords = await models.TicketWeekly.count();
const firstRow = result[0];
expect(firstRow.ticketFk).toEqual(2);
- expect(result.length).toEqual(4);
+ expect(result.length).toEqual(totalRecords);
await tx.rollback();
} catch (e) {
diff --git a/modules/ticket/back/methods/ticket/closeByAgency.js b/modules/ticket/back/methods/ticket/closeByAgency.js
deleted file mode 100644
index eb1aee3494..0000000000
--- a/modules/ticket/back/methods/ticket/closeByAgency.js
+++ /dev/null
@@ -1,79 +0,0 @@
-const closure = require('./closure');
-
-module.exports = Self => {
- Self.remoteMethodCtx('closeByAgency', {
- description: 'Makes the closure process by agency mode',
- accessType: 'WRITE',
- accepts: [
- {
- arg: 'agencyModeFk',
- type: ['number'],
- required: true,
- description: 'The agencies mode ids',
- },
- {
- arg: 'warehouseFk',
- type: 'number',
- description: 'The ticket warehouse id',
- required: true
- },
- {
- arg: 'to',
- type: 'date',
- description: 'Max closure date',
- required: true
- }
- ],
- returns: {
- type: 'object',
- root: true
- },
- http: {
- path: `/close-by-agency`,
- verb: 'POST'
- }
- });
-
- Self.closeByAgency = async ctx => {
- const args = ctx.args;
-
- const tickets = await Self.rawSql(`
- SELECT
- t.id,
- t.clientFk,
- t.companyFk,
- c.name clientName,
- c.email recipient,
- c.salesPersonFk,
- c.isToBeMailed,
- c.hasToInvoice,
- co.hasDailyInvoice,
- eu.email salesPersonEmail
- FROM expedition e
- JOIN ticket t ON t.id = e.ticketFk
- JOIN ticketState ts ON ts.ticketFk = t.id
- JOIN alertLevel al ON al.id = ts.alertLevel
- JOIN client c ON c.id = t.clientFk
- JOIN province p ON p.id = c.provinceFk
- JOIN country co ON co.id = p.countryFk
- LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
- WHERE al.code = 'PACKED'
- AND t.agencyModeFk IN(?)
- AND t.warehouseFk = ?
- AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY)
- AND util.dayEnd(?)
- AND t.refFk IS NULL
- GROUP BY e.ticketFk`, [
- args.agencyModeFk,
- args.warehouseFk,
- args.to,
- args.to
- ]);
-
- await closure(Self, tickets);
-
- return {
- message: 'Success'
- };
- };
-};
diff --git a/modules/ticket/back/methods/ticket/closeByRoute.js b/modules/ticket/back/methods/ticket/closeByRoute.js
deleted file mode 100644
index 58e130b8e8..0000000000
--- a/modules/ticket/back/methods/ticket/closeByRoute.js
+++ /dev/null
@@ -1,75 +0,0 @@
-const closure = require('./closure');
-const {Email} = require('vn-print');
-
-module.exports = Self => {
- Self.remoteMethodCtx('closeByRoute', {
- description: 'Makes the closure process by route',
- accessType: 'WRITE',
- accepts: [
- {
- arg: 'routeFk',
- type: 'number',
- required: true,
- description: 'The routes ids',
- },
- ],
- returns: {
- type: 'object',
- root: true
- },
- http: {
- path: `/close-by-route`,
- verb: 'POST'
- }
- });
-
- Self.closeByRoute = async ctx => {
- const args = ctx.args;
-
- const tickets = await Self.rawSql(`
- SELECT
- t.id,
- t.clientFk,
- t.companyFk,
- c.name clientName,
- c.email recipient,
- c.salesPersonFk,
- c.isToBeMailed,
- c.hasToInvoice,
- co.hasDailyInvoice,
- eu.email salesPersonEmail
- FROM expedition e
- JOIN ticket t ON t.id = e.ticketFk
- JOIN ticketState ts ON ts.ticketFk = t.id
- JOIN alertLevel al ON al.id = ts.alertLevel
- JOIN client c ON c.id = t.clientFk
- JOIN province p ON p.id = c.provinceFk
- JOIN country co ON co.id = p.countryFk
- LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
- WHERE al.code = 'PACKED'
- AND t.routeFk = ?
- AND t.refFk IS NULL
- GROUP BY e.ticketFk`, [args.routeFk]);
-
- await closure(Self, tickets);
-
- // Send route report to the agency
- const [agencyMail] = await Self.rawSql(`
- SELECT am.reportMail
- FROM route r
- JOIN agencyMode am ON am.id = r.agencyModeFk
- WHERE r.id = ?`, [args.routeFk]);
-
- if (agencyMail) {
- const email = new Email('driver-route', {
- id: args.routeFk,
- recipient: agencyMail
- });
- await email.send();
- }
-
- return {
- message: 'Success'
- };
- };
-};
diff --git a/modules/ticket/back/methods/ticket/closeByTicket.js b/modules/ticket/back/methods/ticket/closeByTicket.js
index 8884897c23..40fe048a50 100644
--- a/modules/ticket/back/methods/ticket/closeByTicket.js
+++ b/modules/ticket/back/methods/ticket/closeByTicket.js
@@ -23,11 +23,25 @@ module.exports = Self => {
}
});
- Self.closeByTicket = async ctx => {
+ Self.closeByTicket = async(ctx, options) => {
+ let tx;
+ const myOptions = {};
+
+ if (typeof options == 'object')
+ Object.assign(myOptions, options);
+
+ if (!myOptions.transaction) {
+ tx = await Self.beginTransaction({});
+ myOptions.transaction = tx;
+ }
+
+ const userId = ctx.req.accessToken.userId;
+ myOptions.userId = userId;
+
const args = ctx.args;
const tickets = await Self.rawSql(`
- SELECT
+ SELECT
t.id,
t.clientFk,
t.companyFk,
@@ -37,7 +51,8 @@ module.exports = Self => {
c.isToBeMailed,
c.hasToInvoice,
co.hasDailyInvoice,
- eu.email salesPersonEmail
+ eu.email salesPersonEmail,
+ t.addressFk
FROM expedition e
JOIN ticket t ON t.id = e.ticketFk
JOIN ticketState ts ON ts.ticketFk = t.id
@@ -49,9 +64,14 @@ module.exports = Self => {
WHERE al.code = 'PACKED'
AND t.id = ?
AND t.refFk IS NULL
- GROUP BY e.ticketFk`, [args.id]);
+ GROUP BY e.ticketFk`,
+ [args.id],
+ myOptions);
- await closure(Self, tickets);
+ await closure(ctx, Self, tickets, myOptions);
+
+ if (tx)
+ await tx.commit();
return {
message: 'Success'
diff --git a/modules/ticket/back/methods/ticket/closure.js b/modules/ticket/back/methods/ticket/closure.js
index 4622ba271f..a75596bac3 100644
--- a/modules/ticket/back/methods/ticket/closure.js
+++ b/modules/ticket/back/methods/ticket/closure.js
@@ -1,13 +1,22 @@
-/* eslint max-len: ["error", { "code": 150 }]*/
-
const Report = require('vn-print/core/report');
const Email = require('vn-print/core/email');
const smtp = require('vn-print/core/smtp');
const config = require('vn-print/core/config');
const storage = require('vn-print/core/storage');
-module.exports = async function(ctx, Self, tickets, reqArgs = {}) {
+module.exports = async function(ctx, Self, tickets, options) {
const userId = ctx.req.accessToken.userId;
+ const myOptions = {userId};
+
+ if (typeof options == 'object')
+ Object.assign(myOptions, options);
+
+ let tx;
+ if (!myOptions.transaction) {
+ tx = await Self.beginTransaction({});
+ myOptions.transaction = tx;
+ }
+
if (tickets.length == 0) return;
const failedtickets = [];
@@ -17,7 +26,7 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) {
await Self.rawSql(
`CALL vn.ticket_closeByTicket(?)`,
[ticket.id],
- {userId}
+ myOptions
);
const [invoiceOut] = await Self.rawSql(`
@@ -26,7 +35,7 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) {
JOIN invoiceOut io ON io.ref = t.refFk
JOIN company cny ON cny.id = io.companyFk
WHERE t.id = ?
- `, [ticket.id]);
+ `, [ticket.id], myOptions);
const mailOptions = {
overrideAttachments: true,
@@ -63,7 +72,7 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) {
await Self.rawSql(
'UPDATE invoiceOut SET hasPdf = true WHERE id = ?',
[invoiceOut.id],
- {userId},
+ myOptions
);
if (isToBeMailed) {
@@ -108,7 +117,9 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) {
WHERE t.clientFk = ?
AND NOT t.isDeleted
AND c.isVies
- `, [ticket.clientFk]);
+ `,
+ [ticket.clientFk],
+ myOptions);
if (firstOrder == 1) {
const args = {
@@ -127,20 +138,22 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) {
SELECT id
FROM sample
WHERE code = 'incoterms-authorization'
- `);
+ `,
+ null,
+ myOptions);
await Self.rawSql(`
INSERT INTO clientSample (clientFk, typeFk, companyFk) VALUES(?, ?, ?)
- `, [ticket.clientFk, sample.id, ticket.companyFk], {userId});
+ `,
+ [ticket.clientFk, sample.id, ticket.companyFk],
+ myOptions);
}
} catch (error) {
- // Domain not found
if (error.responseCode == 450) {
await invalidEmail(ticket);
continue;
}
- // Save tickets on a list of failed ids
failedtickets.push({
id: ticket.id,
stacktrace: error,
@@ -148,7 +161,6 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) {
}
}
- // Send email with failed tickets
if (failedtickets.length > 0) {
let body = 'This following tickets have failed:
';
@@ -164,11 +176,14 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) {
}).catch(err => console.error(err));
}
+ if (tx)
+ await tx.commit();
+
async function invalidEmail(ticket) {
await Self.rawSql(
`UPDATE client SET email = NULL WHERE id = ?`,
[ticket.clientFk],
- {userId},
+ myOptions
);
const body = `No se ha podido enviar el albarán ${ticket.id}
diff --git a/modules/ticket/back/methods/ticket/saveCmr.js b/modules/ticket/back/methods/ticket/saveCmr.js
index f8d0af8ef3..339ac1e38a 100644
--- a/modules/ticket/back/methods/ticket/saveCmr.js
+++ b/modules/ticket/back/methods/ticket/saveCmr.js
@@ -39,7 +39,7 @@ module.exports = Self => {
}, myOptions);
for (const ticketId of tickets) {
- const ticket = await models.Ticket.findById(ticketId, myOptions);
+ const ticket = await models.Ticket.findById(ticketId, null, myOptions);
if (ticket.cmrFk) {
const hasDmsCmr = await Self.rawSql(`
diff --git a/modules/ticket/back/methods/ticket/specs/closure.spec.js b/modules/ticket/back/methods/ticket/specs/closure.spec.js
new file mode 100644
index 0000000000..303c38233a
--- /dev/null
+++ b/modules/ticket/back/methods/ticket/specs/closure.spec.js
@@ -0,0 +1,119 @@
+const models = require('vn-loopback/server/server').models;
+const LoopBackContext = require('loopback-context');
+const smtp = require('vn-print/core/smtp');
+const Email = require('vn-print/core/email');
+const config = require('vn-print/core/config');
+const closure = require('../closure');
+
+describe('Ticket closure functionality', () => {
+ const userId = 19;
+ const companyFk = 442;
+ const activeCtx = {
+ getLocale: () => 'es',
+ accessToken: {userId: userId},
+ headers: {origin: 'http://localhost:5000'},
+ };
+ let ctx = {req: activeCtx};
+ let tx;
+ let options;
+
+ beforeEach(async() => {
+ LoopBackContext.getCurrentContext = () => ({
+ active: activeCtx,
+ });
+
+ tx = await models.Sale.beginTransaction({});
+ options = {transaction: tx};
+ });
+
+ afterEach(async() => {
+ await tx.rollback();
+ });
+
+ it('should successfully close a ticket and not invoiced', async() => {
+ const ticketId = 15;
+ const tickets = [{
+ id: ticketId,
+ clientFk: 1101,
+ companyFk,
+ addressFk: 1,
+ isToBeMailed: true,
+ recipient: 'some@email.com',
+ salesPersonFk: userId
+ }];
+
+ const ticketStateBefore = await models.TicketState.findById(ticketId, null, options);
+
+ await closure(ctx, models.Ticket, tickets, options);
+
+ const ticketStateAfter = await models.TicketState.findById(ticketId, null, options);
+
+ expect(ticketStateBefore.code).not.toBe(ticketStateAfter.code);
+
+ const ticketAfter = await models.TicketState.findById(ticketId, null, options);
+
+ expect(ticketAfter.refFk).toBeUndefined();
+ });
+
+ it('should send Incoterms authorization email on first order', async() => {
+ const ticketId = 37;
+ ctx.args = {
+ id: ticketId,
+ };
+
+ const ticket = await models.Ticket.findById(ticketId, null, options);
+ spyOn(Email.prototype, 'send').and.returnValue(Promise.resolve());
+
+ await models.Ticket.closeByTicket(ctx, options);
+
+ const sample = await models.Sample.findOne({
+ where: {code: 'incoterms-authorization'},
+ fields: ['id']
+ },
+ options);
+
+ const insertedSample = await models.ClientSample.findOne({
+ where: {
+ clientFk: ticket.clientFk,
+ typeFk: sample.id,
+ companyFk: companyFk
+ }
+ }, options);
+
+ expect(insertedSample.clientFk).toEqual(ticket.clientFk);
+ });
+
+ it('should report failed tickets and set client email to null', async() => {
+ const ticketId = 37;
+ const clientId = 1110;
+ const tickets = [{
+ id: ticketId,
+ clientFk: clientId,
+ companyFk,
+ addressFk: 1,
+ isToBeMailed: true,
+ recipient: 'invalid@example.com',
+ salesPersonFk: userId
+ }];
+
+ spyOn(Email.prototype, 'send').and.callFake(() => {
+ const error = new Error('Invalid email');
+ error.responseCode = 450;
+ return Promise.reject(error);
+ });
+
+ await closure(ctx, models.Ticket, tickets, options);
+
+ const client = await models.Client.findById(clientId, null, options);
+
+ expect(client.email).toBeNull();
+
+ const reportEmail = await smtp.send({
+ to: config.app.reportEmail,
+ subject: '[API] Nightly ticket closure report',
+ html: `This following tickets have failed:`
+ });
+
+ expect(reportEmail).not.toBeNull();
+ });
+});
diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js
index 72249fe5db..d0edb24e39 100644
--- a/modules/ticket/back/methods/ticket/specs/filter.spec.js
+++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js
@@ -21,7 +21,7 @@ describe('ticket filter()', () => {
}
});
- it('should return the tickets matching the problems on true', async() => {
+ it('should return at least one ticket matching the problems on true', async() => {
const tx = await models.Ticket.beginTransaction({});
try {
@@ -41,7 +41,15 @@ describe('ticket filter()', () => {
const filter = {};
const result = await models.Ticket.filter(ctx, filter, options);
- expect(result.length).toBeGreaterThan(3);
+ const hasProblemTicket = result.some(ticket =>
+ ticket.isFreezed === true ||
+ ticket.hasRisk === true ||
+ ticket.hasTicketRequest === true ||
+ (typeof ticket.hasRounding === 'string' && ticket.hasRounding.trim().length > 0) ||
+ (typeof ticket.itemShortage === 'string' && ticket.itemShortage.trim().length > 0)
+ );
+
+ expect(hasProblemTicket).toBe(true);
await tx.rollback();
} catch (e) {
@@ -71,7 +79,13 @@ describe('ticket filter()', () => {
const filter = {};
const result = await models.Ticket.filter(ctx, filter, options);
- expect(result.length).toEqual(11);
+ result.forEach(ticket => {
+ expect(ticket.isFreezed).toEqual(null);
+ expect(ticket.hasRisk).toEqual(null);
+ expect(ticket.hasTicketRequest).toEqual(null);
+ expect(ticket.itemShortage).toEqual(null);
+ expect(ticket.hasRounding).toEqual(null);
+ });
await tx.rollback();
} catch (e) {
diff --git a/modules/ticket/back/methods/ticket/specs/isEditableOrThrow.spec.js b/modules/ticket/back/methods/ticket/specs/isEditableOrThrow.spec.js
index 883b0de2ee..1a8025f097 100644
--- a/modules/ticket/back/methods/ticket/specs/isEditableOrThrow.spec.js
+++ b/modules/ticket/back/methods/ticket/specs/isEditableOrThrow.spec.js
@@ -65,7 +65,7 @@ describe('ticket isEditableOrThrow()', () => {
const options = {transaction: tx};
const ctx = {req: {accessToken: {userId: 1}}};
- await models.Ticket.isEditableOrThrow(ctx, 15, options);
+ await models.Ticket.isEditableOrThrow(ctx, 17, options);
await tx.rollback();
} catch (e) {
error = e;
diff --git a/modules/ticket/back/models/ticket-methods.js b/modules/ticket/back/models/ticket-methods.js
index 12161d5f53..7fe968b267 100644
--- a/modules/ticket/back/models/ticket-methods.js
+++ b/modules/ticket/back/models/ticket-methods.js
@@ -33,8 +33,6 @@ module.exports = function(Self) {
require('../methods/ticket/deliveryNoteCsvEmail')(Self);
require('../methods/ticket/closeAll')(Self);
require('../methods/ticket/closeByTicket')(Self);
- require('../methods/ticket/closeByAgency')(Self);
- require('../methods/ticket/closeByRoute')(Self);
require('../methods/ticket/getTicketsFuture')(Self);
require('../methods/ticket/merge')(Self);
require('../methods/ticket/getTicketsAdvance')(Self);
diff --git a/print/core/email.js b/print/core/email.js
index a0bcf91221..a673685bb0 100644
--- a/print/core/email.js
+++ b/print/core/email.js
@@ -33,7 +33,7 @@ class Email extends Component {
const attachments = [];
const getAttachments = async(componentPath, files) => {
for (const file of files) {
- const fileCopy = Object.assign({}, file);
+ const fileCopy = {...file};
const fileName = fileCopy.filename;
if (options.overrideAttachments && !fileName.includes('.png')) continue;