Compare commits

..

8 Commits
dev ... beta

Author SHA1 Message Date
Alex Moreno e4289398f6 Merge branch 'master' of https://gitea.verdnatura.es/verdnatura/salix into beta
gitea/salix/pipeline/head This commit looks good Details
2025-01-14 07:59:57 +01:00
Alex Moreno d0e803421f Merge branch 'master' of https://gitea.verdnatura.es/verdnatura/salix into beta
gitea/salix/pipeline/head This commit looks good Details
2025-01-14 07:35:11 +01:00
Alex Moreno 53f33aa89c Merge branch 'master' of https://gitea.verdnatura.es/verdnatura/salix into beta
gitea/salix/pipeline/head This commit looks good Details
2025-01-13 14:49:53 +01:00
Alex Moreno 1ead6944fa Merge branch 'master' of https://gitea.verdnatura.es/verdnatura/salix into beta
gitea/salix/pipeline/head This commit looks good Details
2025-01-07 07:50:34 +01:00
Alex Moreno a6ba1ab773 Merge branch 'master' of https://gitea.verdnatura.es/verdnatura/salix into beta
gitea/salix/pipeline/head This commit looks good Details
2024-12-23 17:39:52 +01:00
Alex Moreno c9c36245e9 Merge branch 'master' of https://gitea.verdnatura.es/verdnatura/salix into beta
gitea/salix/pipeline/head This commit looks good Details
2024-12-18 12:08:27 +01:00
Juan Ferrer 2f64dafdec ci(Jenkinsfile): refs #8285 Don't run Database on beta branch
gitea/salix/pipeline/head This commit looks good Details
2024-12-11 14:13:56 +01:00
Juan Ferrer c0b12db2e0 Merge pull request 'refs #8257 master into beta' (!3289) from master into beta
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3289
2024-12-10 10:31:30 +00:00
58 changed files with 242 additions and 801 deletions

3
Jenkinsfile vendored
View File

@ -200,6 +200,9 @@ pipeline {
}
parallel {
stage('Database') {
when {
not { branch 'beta' }
}
steps {
configFileProvider([
configFile(fileId: "config.${env.NODE_ENV}.ini",

View File

@ -158,13 +158,13 @@ INSERT INTO `account`.`mailForward`(`account`, `forwardTo`)
INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`, `hasToDownloadRate`)
INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
VALUES
(1, 'EUR', 'Euro', 1, FALSE),
(2, 'USD', 'Dollar USA', 1.4, TRUE),
(3, 'GBP', 'Libra', 1, TRUE),
(4, 'JPY', 'Yen Japones', 1, FALSE),
(5, 'CNY', 'Yuan Chino', 1.2, TRUE);
(1, 'EUR', 'Euro', 1),
(2, 'USD', 'Dollar USA', 1.4),
(3, 'GBP', 'Libra', 1),
(4, 'JPY', 'Yen Japones', 1),
(5, 'CNY', 'Yuan Chino', 1.2);
INSERT INTO `vn`.`country`(`id`, `name`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`, `continentFk`, `hasDailyInvoice`, `CEE`)
VALUES
@ -426,50 +426,50 @@ INSERT INTO `vn`.`clientConfig`(`id`, `riskTolerance`, `maxCreditRows`, `maxPric
(1, 200, 10, 0.25, 2, 4, 5, 300.00, 1, 1, 2);
INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `clientFk`, `agencyModeFk`, `longitude`, `latitude`, `isEqualizated`, `isDefaultAddress`, `customsAgentFk`)
INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `clientFk`, `agencyModeFk`, `longitude`, `latitude`, `isEqualizated`, `isDefaultAddress`)
VALUES
(1, 'Bruce Wayne', '1007 Mountain Drive, Gotham', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1101, 2, -74.1111111, 10.1111111, 0, 1, 1),
(2, 'Petter Parker', '20 Ingram Street', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1102, 2, -74.2222222, 10.2222222, 0, 1, NULL),
(3, 'Clark Kent', '344 Clinton Street', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1103, 2, -74.3333333, 10.3333333, 0, 1, NULL),
(4, 'Tony Stark', '10880 Malibu Point', 'Gotham', 46460, 1, 1111111111, 222222222, 1 , 1104, 2, -74.4444444, 10.4444444, 0, 1, NULL),
(5, 'Max Eisenhardt', 'Unknown Whereabouts', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1105, 2, NULL, NULL, 0, 1, NULL),
(6, 'DavidCharlesHaller', 'Evil hideout', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1106, 2, NULL, NULL, 0, 1, NULL),
(7, 'Hank Pym', 'Anthill', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1107, 2, NULL, NULL, 0, 1, NULL),
(8, 'Charles Xavier', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Gotham', 46460, 5, 1111111111, 222222222, 1, 1108, 2, NULL, NULL, 0, 1, NULL),
(9, 'Bruce Banner', 'Somewhere in New York', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 1, NULL),
(10, 'Jessica Jones', 'NYCC 2015 Poster', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1110, 2, NULL, NULL, 0, 1, NULL),
(11, 'Missing', 'The space', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1111, 10, NULL, NULL, 0, 1, NULL),
(12, 'Trash', 'New York city', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1112, 10, NULL, NULL, 0, 1, NULL),
(101, 'Somewhere in Thailand', 'address 01', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(102, 'Somewhere in Poland', 'address 02', 'Gotham', 46460, 1, 3333333333, 444444444, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(103, 'Somewhere in Japan', 'address 03', 'Gotham', 46460, 1, 3333333333, 444444444, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(104, 'Somewhere in Spain', 'address 04', 'Gotham', 46460, 1, 3333333333, 444444444, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(105, 'Somewhere in Potugal', 'address 05', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(106, 'Somewhere in UK', 'address 06', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(107, 'Somewhere in Valencia', 'address 07', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(108, 'Somewhere in Gotham', 'address 08', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(109, 'Somewhere in London', 'address 09', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(110, 'Somewhere in Algemesi', 'address 10', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(111, 'Somewhere in Carlet', 'address 11', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(112, 'Somewhere in Campanar', 'address 12', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(113, 'Somewhere in Malilla', 'address 13', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(114, 'Somewhere in France', 'address 14', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(115, 'Somewhere in Birmingham', 'address 15', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(116, 'Somewhere in Scotland', 'address 16', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(117, 'Somewhere in nowhere', 'address 17', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(118, 'Somewhere over the rainbow', 'address 18', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(119, 'Somewhere in Alberic', 'address 19', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(120, 'Somewhere in Montortal', 'address 20', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(121, 'the bat cave', 'address 21', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1101, 2, NULL, NULL, 0, 0, NULL),
(122, 'NY roofs', 'address 22', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1102, 2, NULL, NULL, 0, 0, NULL),
(123, 'The phone box', 'address 23', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1103, 2, -74.555555, 10.555555, 0, 0, NULL),
(124, 'Stark tower Gotham', 'address 24', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1104, 2, NULL, NULL, 0, 0, NULL),
(125, 'The plastic cell', 'address 25', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1105, 2, NULL, NULL, 0, 0, NULL),
(126, 'Many places', 'address 26', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1106, 2, NULL, NULL, 0, 0, NULL),
(127, 'Your pocket', 'address 27', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1107, 2, NULL, NULL, 0, 0, NULL),
(128, 'Cerebro', 'address 28', 'Gotham', 46460, 5, 1111111111, 222222222, 1, 1108, 2, NULL, NULL, 0, 0, NULL),
(129, 'Luke Cages Bar', 'address 29', 'Gotham', 'EC170150', 1, 1111111111, 222222222, 1, 1110, 2, NULL, NULL, 0, 0, NULL),
(130, 'Non valid address', 'address 30', 'Gotham', 46460, 1, 1111111111, 222222222, 0, 1101, 2, NULL, NULL, 0, 0, NULL);
(1, 'Bruce Wayne', '1007 Mountain Drive, Gotham', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1101, 2, -74.1111111, 10.1111111, 0, 1),
(2, 'Petter Parker', '20 Ingram Street', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1102, 2, -74.2222222, 10.2222222, 0, 1),
(3, 'Clark Kent', '344 Clinton Street', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1103, 2, -74.3333333, 10.3333333, 0, 1),
(4, 'Tony Stark', '10880 Malibu Point', 'Gotham', 46460, 1, 1111111111, 222222222, 1 , 1104, 2, -74.4444444, 10.4444444, 0, 1),
(5, 'Max Eisenhardt', 'Unknown Whereabouts', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1105, 2, NULL, NULL, 0, 1),
(6, 'DavidCharlesHaller', 'Evil hideout', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1106, 2, NULL, NULL, 0, 1),
(7, 'Hank Pym', 'Anthill', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1107, 2, NULL, NULL, 0, 1),
(8, 'Charles Xavier', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Gotham', 46460, 5, 1111111111, 222222222, 1, 1108, 2, NULL, NULL, 0, 1),
(9, 'Bruce Banner', 'Somewhere in New York', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 1),
(10, 'Jessica Jones', 'NYCC 2015 Poster', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1110, 2, NULL, NULL, 0, 1),
(11, 'Missing', 'The space', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1111, 10, NULL, NULL, 0, 1),
(12, 'Trash', 'New York city', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1112, 10, NULL, NULL, 0, 1),
(101, 'Somewhere in Thailand', 'address 01', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(102, 'Somewhere in Poland', 'address 02', 'Gotham', 46460, 1, 3333333333, 444444444, 1, 1109, 2, NULL, NULL, 0, 0),
(103, 'Somewhere in Japan', 'address 03', 'Gotham', 46460, 1, 3333333333, 444444444, 1, 1109, 2, NULL, NULL, 0, 0),
(104, 'Somewhere in Spain', 'address 04', 'Gotham', 46460, 1, 3333333333, 444444444, 1, 1109, 2, NULL, NULL, 0, 0),
(105, 'Somewhere in Potugal', 'address 05', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0),
(106, 'Somewhere in UK', 'address 06', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0),
(107, 'Somewhere in Valencia', 'address 07', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0),
(108, 'Somewhere in Gotham', 'address 08', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0),
(109, 'Somewhere in London', 'address 09', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(110, 'Somewhere in Algemesi', 'address 10', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(111, 'Somewhere in Carlet', 'address 11', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(112, 'Somewhere in Campanar', 'address 12', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(113, 'Somewhere in Malilla', 'address 13', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(114, 'Somewhere in France', 'address 14', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(115, 'Somewhere in Birmingham', 'address 15', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(116, 'Somewhere in Scotland', 'address 16', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(117, 'Somewhere in nowhere', 'address 17', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(118, 'Somewhere over the rainbow', 'address 18', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(119, 'Somewhere in Alberic', 'address 19', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(120, 'Somewhere in Montortal', 'address 20', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(121, 'the bat cave', 'address 21', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1101, 2, NULL, NULL, 0, 0),
(122, 'NY roofs', 'address 22', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1102, 2, NULL, NULL, 0, 0),
(123, 'The phone box', 'address 23', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1103, 2, -74.555555, 10.555555, 0, 0),
(124, 'Stark tower Gotham', 'address 24', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1104, 2, NULL, NULL, 0, 0),
(125, 'The plastic cell', 'address 25', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1105, 2, NULL, NULL, 0, 0),
(126, 'Many places', 'address 26', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1106, 2, NULL, NULL, 0, 0),
(127, 'Your pocket', 'address 27', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1107, 2, NULL, NULL, 0, 0),
(128, 'Cerebro', 'address 28', 'Gotham', 46460, 5, 1111111111, 222222222, 1, 1108, 2, NULL, NULL, 0, 0),
(129, 'Luke Cages Bar', 'address 29', 'Gotham', 'EC170150', 1, 1111111111, 222222222, 1, 1110, 2, NULL, NULL, 0, 0),
(130, 'Non valid address', 'address 30', 'Gotham', 46460, 1, 1111111111, 222222222, 0, 1101, 2, NULL, NULL, 0, 0);
INSERT INTO `vn`.`address`( `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `isActive`, `clientFk`, `agencyModeFk`, `isDefaultAddress`)
SELECT name, CONCAT(name, 'Street'), 'GOTHAM', 46460, 1, 1, id, 2, 1
@ -648,13 +648,13 @@ INSERT INTO `vn`.`invoiceOutSerial`
('X', 'Exportación global', 0, 'WORLD', 0, 'global'),
('N', 'Múltiple Intracomunitaria', 0, 'CEE', 1, 'multiple');
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`, `customsAgentFk`, `incotermsFk`)
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`)
VALUES
(1, 'E', 1026.24, util.VN_CURDATE(), 1101, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0, 1, 'FAS'),
(2, 'T', 121.36, util.VN_CURDATE(), 1102, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0, NULL, NULL),
(3, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0, NULL, NULL),
(4, 'T', 8.88, util.VN_CURDATE(), 1104, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0, NULL, NULL),
(5, 'A', 8.88, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1103, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 0, NULL, NULL);
(1, 'T', 1026.24, util.VN_CURDATE(), 1101, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
(2, 'T', 121.36, util.VN_CURDATE(), 1102, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
(3, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
(4, 'T', 8.88, util.VN_CURDATE(), 1104, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
(5, 'A', 8.88, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1103, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 0);
UPDATE `vn`.`invoiceOut` SET ref = 'T1111111' WHERE id = 1;
UPDATE `vn`.`invoiceOut` SET ref = 'T2222222' WHERE id = 2;
@ -694,22 +694,22 @@ INSERT INTO `vn`.`invoiceOutExpense`(`id`, `invoiceOutFk`, `amount`, `expenseFk`
(6, 4, 8.07, 2000000000, util.VN_CURDATE()),
(7, 5, 8.07, 2000000000, util.VN_CURDATE());
INSERT INTO `vn`.`zone`
(`id`, `name`, `hour`, `agencyModeFk`, `travelingDays`, `price`, `bonus`, `itemMaxSize`, `priceOptimum`)
VALUES
(1, 'Zone pickup A', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 1, 0, 1, 0, 100, 1),
(2, 'Zone pickup B', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 1, 0, 1, 0, 100, 1),
(3, 'Zone 247 A', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 7, 1, 2, 0, 100, 1),
(4, 'Zone 247 B', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 7, 1, 2, 0, 100, 1),
(5, 'Zone expensive A', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 8, 1, 1000, 0, 100, 500),
(6, 'Zone expensive B', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 8, 1, 1000, 0, 100, 500),
(7, 'Zone refund', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 23, 0, 1, 0, 100, 0.5),
(8, 'Zone others', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 10, 0, 1, 0, 100, 0.5),
(9, 'Zone superMan', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 2, 0, 1, 0, 100, 0.5),
(10, 'Zone teleportation', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 3, 0, 1, 0, 100, 0.5),
(11, 'Zone pickup C', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 1, 0, 1, 0, 100, 0.5),
(12, 'Zone entanglement', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 4, 0, 1, 0, 100, 0.5),
(13, 'Zone quantum break', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 5, 0, 1, 0, 100, 0.5);
INSERT INTO `vn`.`zone` (`id`, `name`, `hour`, `agencyModeFk`, `travelingDays`, `price`, `bonus`, `itemMaxSize`)
VALUES
(1, 'Zone pickup A', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 1, 0, 1, 0, 100),
(2, 'Zone pickup B', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 1, 0, 1, 0, 100),
(3, 'Zone 247 A', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 7, 1, 2, 0, 100),
(4, 'Zone 247 B', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 7, 1, 2, 0, 100),
(5, 'Zone expensive A', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 8, 1, 1000, 0, 100),
(6, 'Zone expensive B', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 8, 1, 1000, 0, 100),
(7, 'Zone refund', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 23, 0, 1, 0, 100),
(8, 'Zone others', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 10, 0, 1, 0, 100),
(9, 'Zone superMan', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 2, 0, 1, 0, 100),
(10, 'Zone teleportation', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 3, 0, 1, 0, 100),
(11, 'Zone pickup C', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 1, 0, 1, 0, 100),
(12, 'Zone entanglement', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 4, 0, 1, 0, 100),
(13, 'Zone quantum break', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 5, 0, 1, 0, 100);
INSERT INTO `vn`.`zoneWarehouse` (`id`, `zoneFk`, `warehouseFk`)
VALUES

View File

@ -1,8 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` EVENT `vn`.`client_setPackagesDiscountFactor`
ON SCHEDULE EVERY 1 DAY
STARTS '2024-10-18 03:00:00.000'
ON COMPLETION PRESERVE
ENABLE
DO CALL client_setPackagesDiscountFactor()$$
DELIMITER ;

View File

@ -231,19 +231,7 @@ BEGIN
SELECT tcc.warehouseFK,
tcc.itemFk,
c2.id,
z.inflation
* ROUND(
ic.cm3delivery
* (
(
zo.priceOptimum + (( zo.price - zo.priceOptimum) * 2 * ( 1 - c.packagesDiscountFactor))
)
- IFNULL(zo.bonus, 0)
)
/ (1000 * vc.standardFlowerBox),
4
) cost
z.inflation * ROUND(ic.cm3delivery * (IFNULL(zo.price,5000) - IFNULL(zo.bonus,0)) / (1000 * vc.standardFlowerBox) , 4) cost
FROM tmp.ticketComponentCalculate tcc
JOIN item i ON i.id = tcc.itemFk
JOIN tmp.zoneOption zo ON zo.zoneFk = vZoneFk
@ -251,7 +239,6 @@ BEGIN
JOIN agencyMode am ON am.id = z.agencyModeFk
JOIN vn.volumeConfig vc
JOIN vn.component c2 ON c2.code = 'delivery'
JOIN `client` c on c.id = vClientFk
LEFT JOIN itemCost ic ON ic.warehouseFk = tcc.warehouseFk
AND ic.itemFk = tcc.itemFk
HAVING cost <> 0;

View File

@ -1,25 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost`
PROCEDURE `vn`.`client_setPackagesDiscountFactor`()
BEGIN
/**
* Set the discount factor for the packages of the clients.
*/
UPDATE client c
JOIN (
SELECT t.clientFk,
LEAST((
SUM(t.packages) / COUNT(DISTINCT DATE(t.shipped))
) / cc.packagesOptimum, 1) discountFactor
FROM ticket t
JOIN clientConfig cc ON TRUE
WHERE t.shipped > util.VN_CURDATE() - INTERVAL cc.monthsToCalcOptimumPrice MONTH
AND t.packages
GROUP BY t.clientFk
) ca ON c.id = ca.clientFk
SET c.packagesDiscountFactor = ca.discountFactor;
END$$
DELIMITER ;

View File

@ -34,7 +34,6 @@ BEGIN
DECLARE vMaxShipped DATE;
DECLARE vDone BOOL;
DECLARE vTicketFk INT;
DECLARE vAddressFk INT;
DECLARE vCursor CURSOR FOR
SELECT id
FROM tmp.ticketToInvoice;
@ -49,13 +48,11 @@ BEGIN
DATE(vInvoiceDate) >= invoiceOut_getMaxIssued(
vSerial,
t.companyFk,
YEAR(vInvoiceDate)),
t.addressFk
YEAR(vInvoiceDate))
INTO vClientFk,
vCompanyFk,
vMaxShipped,
vIsCorrectInvoiceDate,
vAddressFk
vIsCorrectInvoiceDate
FROM tmp.ticketToInvoice tt
JOIN ticket t ON t.id = tt.id;
@ -108,9 +105,7 @@ BEGIN
clientFk,
dued,
companyFk,
siiTypeInvoiceOutFk,
customsAgentFk,
incotermsFk
siiTypeInvoiceOutFk
)
SELECT
1,
@ -123,12 +118,9 @@ BEGIN
vCplusCorrectingInvoiceTypeFk,
IF(vSerial = vSimplifiedSerial,
vCplusSimplifiedInvoiceTypeFk,
vCplusStandardInvoiceTypeFk)),
a.customsAgentFk,
a.incotermsFk
FROM client c
JOIN address a ON a.id = vAddressFk
WHERE c.id = vClientFk;
vCplusStandardInvoiceTypeFk))
FROM client
WHERE id = vClientFk;
SET vNewInvoiceId = LAST_INSERT_ID();

View File

@ -1,27 +1,26 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`zone_getAddresses`(
vSelf INT,
vLanded DATE,
vShipped DATE,
vDepartmentFk INT
)
BEGIN
/**
* Devuelve un listado de todos los clientes activos
* con consignatarios a los que se les puede
* entregar producto para esa zona.
* vender producto para esa zona.
*
* @param vSelf Id de zona
* @param vLanded Fecha de entrega
* @param vDepartmentFk Id de departamento | NULL para mostrar todos
* @param vShipped Fecha de envio
* @param vDepartmentFk Id de departamento
* @return Un select
*/
CALL zone_getPostalCode(vSelf);
WITH clientWithTicket AS (
SELECT DISTINCT clientFk
SELECT clientFk
FROM vn.ticket
WHERE landed BETWEEN vLanded AND util.dayEnd(vLanded)
AND NOT isDeleted
WHERE shipped BETWEEN vShipped AND util.dayEnd(vShipped)
)
SELECT c.id,
c.name,
@ -31,7 +30,7 @@ BEGIN
u.name username,
aai.invoiced,
cnb.lastShipped,
IF(cwt.clientFk, TRUE, FALSE) hasTicket
cwt.clientFk
FROM vn.client c
JOIN vn.worker w ON w.id = c.salesPersonFk
JOIN vn.workerDepartment wd ON wd.workerFk = w.id
@ -51,7 +50,7 @@ BEGIN
AND c.isActive
AND ct.code = 'normal'
AND bt.code <> 'worker'
AND (d.id = vDepartmentFk OR vDepartmentFk IS NULL)
AND (d.id = vDepartmentFk OR NOT vDepartmentFk)
GROUP BY c.id;
DROP TEMPORARY TABLE tmp.zoneNodes;

View File

@ -9,7 +9,7 @@ BEGIN
* @return tmp.zoneOption(zoneFk, hour, travelingDays, price, bonus, specificity) The computed options
*/
DECLARE vHour TIME DEFAULT TIME(util.VN_NOW());
DROP TEMPORARY TABLE IF EXISTS tLandings;
CREATE TEMPORARY TABLE tLandings
(INDEX (eventFk))
@ -30,7 +30,6 @@ BEGIN
TIME(IFNULL(e.`hour`, z.`hour`)) `hour`,
l.travelingDays,
IFNULL(e.price, z.price) price,
IFNULL(e.priceOptimum, z.priceOptimum) priceOptimum,
IFNULL(e.bonus, z.bonus) bonus,
l.landed,
vShipped shipped

View File

@ -1,9 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerManaExcluded_beforeInsert`
BEFORE INSERT ON `workerManaExcluded`
FOR EACH ROW
BEGIN
DELETE FROM workerMana
WHERE workerFk = NEW.workerFk;
END$$
DELIMITER ;

View File

@ -1,9 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerManaExcluded_beforeUpdate`
BEFORE UPDATE ON `workerManaExcluded`
FOR EACH ROW
BEGIN
DELETE FROM workerMana
WHERE workerFk = NEW.workerFk;
END$$
DELIMITER ;

View File

@ -1,10 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerMana_beforeInsert`
BEFORE INSERT ON `workerMana`
FOR EACH ROW
BEGIN
IF (SELECT EXISTS(SELECT TRUE FROM workerManaExcluded WHERE workerFk = NEW.workerFk)) THEN
CALL util.throw('Worker is excluded from mana');
END IF;
END$$
DELIMITER ;

View File

@ -1,10 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerMana_beforeUpdate`
BEFORE UPDATE ON `workerMana`
FOR EACH ROW
BEGIN
IF (SELECT EXISTS(SELECT TRUE FROM workerManaExcluded WHERE workerFk = NEW.workerFk)) THEN
CALL util.throw('Worker is excluded from mana');
END IF;
END$$
DELIMITER ;

View File

@ -3,12 +3,10 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerTimeControl_after
AFTER DELETE ON `workerTimeControl`
FOR EACH ROW
BEGIN
IF account.myUser_getId() IS NOT NULL THEN
INSERT INTO workerLog
SET `action` = 'delete',
`changedModel` = 'WorkerTimeControl',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
END IF;
INSERT INTO workerLog
SET `action` = 'delete',
`changedModel` = 'WorkerTimeControl',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
END$$
DELIMITER ;

View File

@ -1,15 +0,0 @@
ALTER TABLE vn.invoiceOut ADD COLUMN IF NOT EXISTS customsAgentFk INT(11) DEFAULT NULL AFTER siiTrascendencyInvoiceOutFk;
ALTER TABLE vn.invoiceOut ADD COLUMN IF NOT EXISTS incotermsFk varchar(3) DEFAULT NULL AFTER customsAgentFk;
ALTER TABLE vn.invoiceOut ADD CONSTRAINT invoiceOut_customsAgentFk FOREIGN KEY (customsAgentFk)
REFERENCES vn.customsAgent (id) ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE vn.invoiceOut ADD CONSTRAINT invoiceOut_incotermsFk FOREIGN KEY (incotermsFk)
REFERENCES vn.incoterms (`code`) ON DELETE RESTRICT ON UPDATE CASCADE;
UPDATE vn.invoiceOut io
JOIN vn.client c ON c.id = io.clientFk
JOIN vn.ticket t ON t.clientFk = c.id
JOIN vn.address a ON a.id = t.addressFk
SET io.customsAgentFk = a.customsAgentFk,
io.incotermsFk = a.incotermsFk;

View File

@ -1,8 +0,0 @@
CREATE TABLE IF NOT EXISTS vn.productionCountry(
countryFk MEDIUMINT(8) UNSIGNED NOT NULL,
volumeGrowthEstimatePercent DECIMAL(6, 2) COMMENT 'Porcentaje estimado de crecimiento del volumen',
PRIMARY KEY (countryFk),
CONSTRAINT productionCountryVolume_countryFK
FOREIGN KEY (countryFk) REFERENCES vn.country (id)
ON DELETE RESTRICT ON UPDATE CASCADE
) COMMENT = 'Datos de producción por país'

View File

@ -1,5 +0,0 @@
DELETE FROM vn.workerMana
WHERE workerFk IN (
SELECT workerFk
FROM vn.workerManaExcluded
);

View File

@ -1,5 +0,0 @@
ALTER TABLE `vn`.`zoneEvent`
ADD COLUMN `priceOptimum` DECIMAL(10,2) NULL COMMENT 'Precio mínimo que puede pagar un bulto'
AFTER `price`,
ADD CONSTRAINT `ck_zoneEvent_priceOptimum`
CHECK (priceOptimum <= price)

View File

@ -1,5 +0,0 @@
ALTER TABLE `vn`.`zone`
ADD COLUMN `priceOptimum` DECIMAL(10,2) NOT NULL COMMENT 'Precio mínimo que puede pagar un bulto'
AFTER `price`,
ADD CONSTRAINT `ck_zone_priceOptimum`
CHECK (priceOptimum <= price)

View File

@ -1,2 +0,0 @@
UPDATE `vn`.`zone`
SET `priceOptimum` = `price`;

View File

@ -1,3 +0,0 @@
ALTER TABLE `vn`.`client`
ADD COLUMN `packagesDiscountFactor` DECIMAL(4,3) NOT NULL DEFAULT 1.000
COMMENT 'Porcentaje de ajuste entre el numero de bultos medio del cliente, y el número medio óptimo para las zonas en las que compra';

View File

@ -1,3 +0,0 @@
ALTER TABLE `vn`.`clientConfig`
ADD COLUMN `packagesOptimum` INT UNSIGNED NOT NULL DEFAULT 20 COMMENT 'Numero de bultos por cliente/dia para conseguir el precio optimo',
ADD COLUMN `monthsToCalcOptimumPrice` TINYINT UNSIGNED NOT NULL DEFAULT 3 COMMENT 'Número de meses a usar para el cálculo de client.packagesDiscountFactor';

View File

@ -1,3 +0,0 @@
ALTER TABLE `vn`.`entry`
ADD COLUMN `initialTemperature` decimal(10,2) DEFAULT NULL COMMENT 'Temperatura de como lo recibimos del proveedor ej. en colombia',
ADD COLUMN `finalTemperature` decimal(10,2) DEFAULT NULL COMMENT 'Temperatura final de como llega a nuestras instalaciones';

View File

@ -1,2 +0,0 @@
ALTER TABLE `vn`.`currency`
ADD COLUMN `hasToDownloadRate` TINYINT(1) NOT NULL DEFAULT 0 comment 'Si se guarda el tipo de cambio diariamente en referenceRate';

View File

@ -1,3 +0,0 @@
UPDATE `vn`.`currency`
SET `hasToDownloadRate` = TRUE
WHERE `code` IN ('USD', 'CNY', 'GBP');

View File

@ -1,2 +0,0 @@
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
VALUES ('VnUser','adminUser','WRITE','ALLOW','ROLE','sysadmin');

View File

@ -1,2 +0,0 @@
RENAME TABLE bi.f_tvc TO bi.f_tvc__;
ALTER TABLE bi.f_tvc__ COMMENT='@deprecated 2025-01-15';

View File

@ -1 +0,0 @@
CREATE INDEX ticket_landed_IDX USING BTREE ON vn.ticket (landed);

View File

@ -238,11 +238,25 @@ describe('Ticket Edit sale path', () => {
await page.waitToClick(selectors.globalItems.cancelButton);
});
it('should select the third sale and delete it', async() => {
it('should select the third sale and create a claim of it', async() => {
await page.accessToSearchResult('16');
await page.accessToSection('ticket.card.sale');
await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox);
await page.waitToClick(selectors.ticketSales.moreMenu);
await page.waitToClick(selectors.ticketSales.moreMenuCreateClaim);
await page.waitToClick(selectors.globalItems.acceptButton);
await page.waitForNavigation();
});
it('should search for a ticket then access to the sales section', async() => {
await page.goBack();
await page.goBack();
await page.loginAndModule('salesPerson', 'ticket');
await page.accessToSearchResult('16');
await page.accessToSection('ticket.card.sale');
});
it('should select the third sale and delete it', async() => {
await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox);
await page.waitToClick(selectors.ticketSales.deleteSaleButton);
await page.waitToClick(selectors.globalItems.acceptButton);

View File

@ -75,7 +75,7 @@ describe('Ticket Edit basic data path', () => {
const result = await page
.waitToGetProperty(selectors.ticketBasicData.stepTwoTotalPriceDif, 'innerText');
expect(result).toContain('-€111.75');
expect(result).toContain('-€228.25');
});
it(`should select a new reason for the changes made then click on finalize`, async() => {

View File

@ -211,7 +211,7 @@
"Name should be uppercase": "Name should be uppercase",
"You cannot update these fields": "You cannot update these fields",
"CountryFK cannot be empty": "Country cannot be empty",
"No tickets to invoice": "There are no tickets to invoice that meet the invoicing requirements",
"No tickets to invoice": "There are no tickets to invoice that meet the invoicing requirements",
"You are not allowed to modify the alias": "You are not allowed to modify the alias",
"You already have the mailAlias": "You already have the mailAlias",
"This machine is already in use.": "This machine is already in use.",
@ -247,11 +247,9 @@
"ticketLostExpedition": "The ticket [{{ticketId}}]({{{ticketUrl}}}) has the following lost expedition:{{ expeditionId }}",
"The raid information is not correct": "The raid information is not correct",
"Payment method is required": "Payment method is required",
"Price cannot be blank": "Price cannot be blank",
"There are tickets to be invoiced": "There are tickets to be invoiced",
"The address of the customer must have information about Incoterms and Customs Agent": "The address of the customer must have information about Incoterms and Customs Agent",
"Sales already moved": "Sales already moved",
"Holidays to past days not available": "Holidays to past days not available",
"Incorrect delivery order alert on route": "Incorrect delivery order alert on route: {{ route }} zone: {{ zone }}",
"Ticket has been delivered out of order": "The ticket {{ticket}} {{{fullUrl}}} has been delivered out of order."
}
"Price cannot be blank": "Price cannot be blank",
"There are tickets to be invoiced": "There are tickets to be invoiced",
"The address of the customer must have information about Incoterms and Customs Agent": "The address of the customer must have information about Incoterms and Customs Agent"
}

View File

@ -390,11 +390,13 @@
"The web user's email already exists": "El correo del usuario web ya existe",
"Sales already moved": "Ya han sido transferidas",
"The raid information is not correct": "La información de la redada no es correcta",
"No trips found because input coordinates are not connected": "No se encontraron rutas porque las coordenadas de entrada no están conectadas",
"This request is not supported": "Esta solicitud no es compatible",
"Invalid options or too many coordinates": "Opciones invalidas o demasiadas coordenadas",
"No address has coordinates": "Ninguna dirección tiene coordenadas",
"An item type with the same code already exists": "Un tipo con el mismo código ya existe",
"Holidays to past days not available": "Las vacaciones a días pasados no están disponibles",
"All tickets have a route order": "Todos los tickets tienen orden de ruta",
"There are tickets to be invoiced": "La zona tiene tickets por facturar",
"Incorrect delivery order alert on route": "Alerta de orden de entrega incorrecta en ruta: {{ route }} zona: {{ zone }}",
"Ticket has been delivered out of order": "El ticket {{ticket}} {{{fullUrl}}} no ha sigo entregado en su orden.",
"Price cannot be blank": "El precio no puede estar en blanco"
}
"Price cannot be blank": "Price cannot be blank",
"There are tickets to be invoiced": "La zona tiene tickets por facturar"
}

View File

@ -362,11 +362,9 @@
"The invoices have been created but the PDFs could not be generated": "La facture a été émise mais le PDF n'a pas pu être généré",
"It has been invoiced but the PDF of refund not be generated": "Il a été facturé mais le PDF de remboursement n'a pas été généré",
"Cannot send mail": "Impossible d'envoyer le mail",
"Original invoice not found": "Facture originale introuvable",
"The quantity claimed cannot be greater than the quantity of the line": "Le montant réclamé ne peut pas être supérieur au montant de la ligne",
"You do not have permission to modify the booked field": "Vous n'avez pas la permission de modifier le champ comptabilisé",
"Original invoice not found": "Facture originale introuvable",
"The quantity claimed cannot be greater than the quantity of the line": "Le montant réclamé ne peut pas être supérieur au montant de la ligne",
"You do not have permission to modify the booked field": "Vous n'avez pas la permission de modifier le champ comptabilisé",
"ticketLostExpedition": "Le ticket [{{ticketId}}]({{{ticketUrl}}}) a l'expédition perdue suivante : {{expeditionId}}",
"The web user's email already exists": "L'email de l'internaute existe déjà",
"Incorrect delivery order alert on route": "Alerte de bon de livraison incorrect sur l'itinéraire: {{ route }} zone : {{ zone }}",
"Ticket has been delivered out of order": "Le ticket {{ticket}} {{{fullUrl}}} a été livré hors ordre."
}
"The web user's email already exists": "L'email de l'internaute existe déjà"
}

View File

@ -365,7 +365,5 @@
"Cannot send mail": "Não é possível enviar o email",
"The quantity claimed cannot be greater than the quantity of the line": "O valor reclamado não pode ser superior ao valor da linha",
"ticketLostExpedition": "O ticket [{{ticketId}}]({{{ticketUrl}}}) tem a seguinte expedição perdida: {{expeditionId}}",
"The web user's email already exists": "O e-mail do utilizador da web já existe.",
"Incorrect delivery order alert on route": "Alerta de ordem de entrega incorreta na rota: {{ route }} zona: {{ zone }}",
"Ticket has been delivered out of order": "O ticket {{ticket}} {{{fullUrl}}} foi entregue fora de ordem."
}
"The web user's email already exists": "O e-mail do utilizador da web já existe."
}

View File

@ -52,14 +52,6 @@ module.exports = function(Self) {
arg: 'customsAgentFk',
type: 'number'
},
{
arg: 'longitude',
type: 'number'
},
{
arg: 'latitude',
type: 'number'
},
{
arg: 'isActive',
type: 'boolean'

View File

@ -1,7 +1,7 @@
const models = require('vn-loopback/server/server').models;
describe('Address updateAddress', () => {
const clientId = 1102;
const addressId = 2;
const clientId = 1101;
const addressId = 1;
const provinceId = 5;
const incotermsId = 'FAS';
const customAgentOneId = 1;

View File

@ -94,7 +94,7 @@ module.exports = Self => {
AND r1.started = r2.maxStarted
) r ON r.clientFk = c.id
LEFT JOIN workerDepartment wd ON wd.workerFk = u.id
LEFT JOIN department dp ON dp.id = wd.departmentFk
JOIN department dp ON dp.id = wd.departmentFk
WHERE
d.created = ?
AND d.amount > 0

View File

@ -19,9 +19,6 @@
},
"created": {
"type": "date"
},
"workerFk": {
"type": "number"
}
},
"relations": {
@ -36,4 +33,4 @@
"foreignKey": "workerFk"
}
}
}
}

View File

@ -119,16 +119,6 @@ module.exports = Self => {
arg: 'invoiceAmount',
type: 'number',
description: `The invoice amount`
},
{
arg: 'initialTemperature',
type: 'number',
description: 'Initial temperature value'
},
{
arg: 'finalTemperature',
type: 'number',
description: 'Final temperature value'
}
],
returns: {
@ -180,10 +170,6 @@ module.exports = Self => {
case 'invoiceInFk':
param = `e.${param}`;
return {[param]: value};
case 'initialTemperature':
return {'e.initialTemperature': {lte: value}};
case 'finalTemperature':
return {'e.finalTemperature': {gte: value}};
}
});
filter = mergeFilters(ctx.args.filter, {where});
@ -218,8 +204,6 @@ module.exports = Self => {
e.gestDocFk,
e.invoiceInFk,
e.invoiceAmount,
e.initialTemperature,
e.finalTemperature,
t.landed,
s.name supplierName,
s.nickname supplierAlias,

View File

@ -68,12 +68,6 @@
},
"invoiceAmount": {
"type": "number"
},
"initialTemperature": {
"type": "number"
},
"finalTemperature": {
"type": "number"
}
},
"relations": {

View File

@ -13,114 +13,66 @@ module.exports = Self => {
}
});
Self.exchangeRateUpdate = async(options = {}) => {
Self.exchangeRateUpdate = async() => {
const response = await axios.get('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml');
const xmlData = response.data;
const doc = new DOMParser({errorHandler: {warning: () => {}}})?.parseFromString(xmlData, 'text/xml');
const cubes = doc?.getElementsByTagName('Cube');
if (!cubes || cubes.length === 0)
throw new UserError('No cubes found. Exiting the method.');
const models = Self.app.models;
const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
const maxDateRecord = await models.ReferenceRate.findOne({order: 'dated DESC'});
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const response = await axios.get('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml');
const xmlData = response.data;
const doc = new DOMParser({errorHandler: {warning: () => {}}})
.parseFromString(xmlData, 'text/xml');
const cubes = doc?.getElementsByTagName('Cube');
if (!cubes || cubes.length === 0)
throw new UserError('No cubes found. Exiting the method.');
const currencies = await models.Currency.find({where: {hasToDownloadRate: true}}, myOptions);
const maxDateRecord = await models.ReferenceRate.findOne({order: 'dated DESC'}, myOptions);
const maxDate = maxDateRecord?.dated ? new Date(maxDateRecord.dated) : null;
let lastProcessedDate = maxDate;
for (const cube of Array.from(cubes)) {
if (cube.nodeType === doc.ELEMENT_NODE && cube.attributes.getNamedItem('time')) {
const xmlDate = new Date(cube.getAttribute('time'));
const xmlDateWithoutTime = new Date(
xmlDate.getFullYear(),
xmlDate.getMonth(),
xmlDate.getDate()
);
if (!maxDate || xmlDateWithoutTime > maxDate) {
if (lastProcessedDate && xmlDateWithoutTime > lastProcessedDate) {
for (const currency of currencies) {
await fillMissingDates(
models, currency, lastProcessedDate, xmlDateWithoutTime, myOptions
);
}
}
}
const maxDate = maxDateRecord?.dated ? new Date(maxDateRecord.dated) : null;
for (const cube of Array.from(cubes)) {
if (cube.nodeType === doc.ELEMENT_NODE && cube.attributes.getNamedItem('time')) {
const xmlDate = new Date(cube.getAttribute('time'));
const xmlDateWithoutTime = new Date(xmlDate.getFullYear(), xmlDate.getMonth(), xmlDate.getDate());
if (!maxDate || maxDate < xmlDateWithoutTime) {
for (const rateCube of Array.from(cube.childNodes)) {
if (rateCube.nodeType === doc.ELEMENT_NODE) {
const currencyCode = rateCube.getAttribute('currency');
const rate = rateCube.getAttribute('rate');
const currency = currencies.find(c => c.code === currencyCode);
if (currency) {
if (['USD', 'CNY', 'GBP'].includes(currencyCode)) {
const currency = await models.Currency.findOne({where: {code: currencyCode}});
if (!currency) throw new UserError(`Currency not found for code: ${currencyCode}`);
const existingRate = await models.ReferenceRate.findOne({
where: {currencyFk: currency.id, dated: xmlDateWithoutTime}
}, myOptions);
where: {currencyFk: currency.id, dated: xmlDate}
});
if (existingRate) {
if (existingRate.value !== rate)
await existingRate.updateAttributes({value: rate}, myOptions);
await existingRate.updateAttributes({value: rate});
} else {
await models.ReferenceRate.create({
currencyFk: currency.id,
dated: xmlDateWithoutTime,
dated: xmlDate,
value: rate
}, myOptions);
});
}
const monday = 1;
if (xmlDateWithoutTime.getDay() === monday) {
const saturday = new Date(xmlDateWithoutTime);
saturday.setDate(xmlDateWithoutTime.getDate() - 2);
const sunday = new Date(xmlDateWithoutTime);
sunday.setDate(xmlDateWithoutTime.getDate() - 1);
for (const date of [saturday, sunday]) {
await models.ReferenceRate.upsertWithWhere(
{currencyFk: currency.id, dated: date},
{currencyFk: currency.id, dated: date, value: rate}
);
}
}
}
}
}
lastProcessedDate = xmlDateWithoutTime;
}
}
if (tx) await tx.commit();
} catch (error) {
if (tx) await tx.rollback();
throw error;
}
};
async function getLastValidRate(models, currencyId, date, myOptions) {
return models.ReferenceRate.findOne({
where: {currencyFk: currencyId, dated: {lt: date}},
order: 'dated DESC'
}, myOptions);
}
async function fillMissingDates(models, currency, startDate, endDate, myOptions) {
const cursor = new Date(startDate);
cursor.setDate(cursor.getDate() + 1);
while (cursor < endDate) {
const existingRate = await models.ReferenceRate.findOne({
where: {currencyFk: currency.id, dated: cursor}
}, myOptions);
if (!existingRate) {
const lastValid = await getLastValidRate(models, currency.id, cursor, myOptions);
if (lastValid) {
await models.ReferenceRate.create({
currencyFk: currency.id,
dated: new Date(cursor),
value: lastValid.value
}, myOptions);
}
}
cursor.setDate(cursor.getDate() + 1);
}
}
};

View File

@ -1,190 +1,52 @@
describe('exchangeRateUpdate functionality', function() {
const axios = require('axios');
const models = require('vn-loopback/server/server').models;
let tx; let options;
function formatYmd(d) {
const mm = (d.getMonth() + 1).toString().padStart(2, '0');
const dd = d.getDate().toString().padStart(2, '0');
return `${d.getFullYear()}-${mm}-${dd}`;
}
afterEach(async() => {
await tx.rollback();
beforeEach(function() {
spyOn(axios, 'get').and.returnValue(Promise.resolve({
data: `<Cube>
<Cube time='2024-04-12'>
<Cube currency='USD' rate='1.1'/>
<Cube currency='CNY' rate='1.2'/>
</Cube>
</Cube>`
}));
});
beforeEach(async() => {
tx = await models.Sale.beginTransaction({});
options = {transaction: tx};
spyOn(axios, 'get').and.returnValue(Promise.resolve({data: ''}));
});
it('should process XML data and create rates', async function() {
const d1 = Date.vnNew();
const d4 = Date.vnNew();
d4.setDate(d4.getDate() + 1);
const xml = `<Cube>
<Cube time='${formatYmd(d1)}'>
<Cube currency='USD' rate='1.1'/>
<Cube currency='CNY' rate='1.2'/>
</Cube>
<Cube time='${formatYmd(d4)}'>
<Cube currency='USD' rate='1.3'/>
</Cube>
</Cube>`;
axios.get.and.returnValue(Promise.resolve({data: xml}));
it('should process XML data and update or create rates in the database', async function() {
spyOn(models.ReferenceRate, 'findOne').and.returnValue(Promise.resolve(null));
spyOn(models.ReferenceRate, 'create').and.returnValue(Promise.resolve());
await models.InvoiceIn.exchangeRateUpdate(options);
expect(models.ReferenceRate.create).toHaveBeenCalledTimes(3);
await models.InvoiceIn.exchangeRateUpdate();
expect(models.ReferenceRate.create).toHaveBeenCalledTimes(2);
});
it('should handle no data', async function() {
it('should not create or update rates when no XML data is available', async function() {
axios.get.and.returnValue(Promise.resolve({}));
spyOn(models.ReferenceRate, 'create');
let e;
let thrownError = null;
try {
await models.InvoiceIn.exchangeRateUpdate(options);
} catch (err) {
e = err;
await models.InvoiceIn.exchangeRateUpdate();
} catch (error) {
thrownError = error;
}
expect(e.message).toBe('No cubes found. Exiting the method.');
expect(models.ReferenceRate.create).not.toHaveBeenCalled();
expect(thrownError.message).toBe('No cubes found. Exiting the method.');
});
it('should handle errors', async function() {
it('should handle errors gracefully', async function() {
axios.get.and.returnValue(Promise.reject(new Error('Network error')));
let e;
let error;
try {
await models.InvoiceIn.exchangeRateUpdate(options);
} catch (err) {
e = err;
await models.InvoiceIn.exchangeRateUpdate();
} catch (e) {
error = e;
}
expect(e).toBeDefined();
expect(e.message).toBe('Network error');
});
it('should update existing rate', async function() {
const existingRate = await models.ReferenceRate.findOne({
order: 'id DESC'
}, options);
if (!existingRate) return fail('No ReferenceRate records in DB');
const currency = await models.Currency.findById(existingRate.currencyFk, null, options);
const xml = `<Cube>
<Cube time='${formatYmd(existingRate.dated)}'>
<Cube currency='${currency.code}' rate='2.22'/>
</Cube>
</Cube>`;
axios.get.and.returnValue(Promise.resolve({data: xml}));
await models.InvoiceIn.exchangeRateUpdate(options);
const updatedRate = await models.ReferenceRate.findById(existingRate.id, null, options);
expect(updatedRate.value).toBeCloseTo('2.22');
});
it('should not update if same rate', async function() {
const existingRate = await models.ReferenceRate.findOne({order: 'id DESC'}, options);
if (!existingRate) return fail('No existing ReferenceRate in DB');
const currency = await models.Currency.findById(existingRate.currencyFk, null, options);
const oldValue = existingRate.value;
const xml = `<Cube>
<Cube time='${formatYmd(existingRate.dated)}'>
<Cube currency='${currency.code}' rate='${oldValue}'/>
</Cube>
</Cube>`;
axios.get.and.returnValue(Promise.resolve({data: xml}));
await models.InvoiceIn.exchangeRateUpdate(options);
const updatedRate = await models.ReferenceRate.findById(existingRate.id, null, options);
expect(updatedRate.value).toBe(oldValue);
});
it('should backfill missing dates', async function() {
const lastRate = await models.ReferenceRate.findOne({order: 'dated DESC'}, options);
if (!lastRate) return fail('No existing ReferenceRate data in DB');
const currency = await models.Currency.findById(lastRate.currencyFk, null, options);
const d1 = new Date(lastRate.dated);
d1.setDate(d1.getDate() + 1);
const d4 = new Date(lastRate.dated);
d4.setDate(d4.getDate() + 4);
const xml = `<Cube>
<Cube time='${formatYmd(d1)}'>
<Cube currency='${currency.code}' rate='1.0'/>
</Cube>
<Cube time='${formatYmd(d4)}'>
<Cube currency='${currency.code}' rate='2.0'/>
</Cube>
</Cube>`;
axios.get.and.returnValue(Promise.resolve({data: xml}));
const beforeCount = await models.ReferenceRate.count({}, options);
await models.InvoiceIn.exchangeRateUpdate(options);
const afterCount = await models.ReferenceRate.count({}, options);
expect(afterCount - beforeCount).toBe(4);
});
it('should create entries for day1 and day2 from the feed, and not backfill day3', async function() {
const lastRate = await models.ReferenceRate.findOne({order: 'dated DESC'}, options);
if (!lastRate) return fail('No existing ReferenceRate data in DB');
const currency = await models.Currency.findById(lastRate.currencyFk, null, options);
if (!currency) return fail(`No currency for ID ${lastRate.currencyFk}`);
const day1 = new Date(lastRate.dated);
day1.setDate(day1.getDate() + 1);
const day2 = new Date(lastRate.dated);
day2.setDate(day2.getDate() + 2);
const day3 = new Date(lastRate.dated);
day3.setDate(day3.getDate() + 3);
const xml = `<Cube>
<Cube time='${formatYmd(day1)}'>
<Cube currency='${currency.code}' rate='1.1'/>
</Cube>
<Cube time='${formatYmd(day2)}'>
<Cube currency='${currency.code}' rate='2.2'/>
</Cube>
</Cube>`;
axios.get.and.returnValue(Promise.resolve({data: xml}));
await models.InvoiceIn.exchangeRateUpdate(options);
const day3Record = await models.ReferenceRate.findOne({
where: {currencyFk: currency.id, dated: day3}
}, options);
expect(day3Record).toBeNull();
const day1Record = await models.ReferenceRate.findOne({
where: {currencyFk: currency.id, dated: day1}
}, options);
const day2Record = await models.ReferenceRate.findOne({
where: {currencyFk: currency.id, dated: day2}
}, options);
expect(day1Record.value).toBeCloseTo('1.1');
expect(day2Record.value).toBeCloseTo('2.2');
expect(error).toBeDefined();
expect(error.message).toBe('Network error');
});
});

View File

@ -74,8 +74,7 @@ module.exports = Self => {
AND t.companyFk = ?
AND NOT t.isDeleted
GROUP BY IF(c.hasToInvoiceByAddress, a.id, c.id)
HAVING SUM(t.totalWithVat) > 0
ORDER BY c.id`;
HAVING SUM(t.totalWithVat) > 0;`;
const addresses = await Self.rawSql(query, [
minShipped,

View File

@ -79,12 +79,6 @@ module.exports = Self => {
type: 'date',
description: 'The due date filter',
http: {source: 'query'}
},
{
arg: 'customsAgentFk',
type: 'integer',
description: 'The customsAgent id',
http: {source: 'query'}
}
],
returns: {
@ -126,7 +120,6 @@ module.exports = Self => {
case 'companyFk':
case 'issued':
case 'dued':
case 'customsAgentFk':
param = `i.${param}`;
return {[param]: value};
}
@ -146,14 +139,11 @@ module.exports = Self => {
i.dued,
i.clientFk,
i.hasPdf,
i.customsAgentFk,
c.socialName AS clientSocialName,
co.code AS companyCode,
ca.fiscalName AS customsAgentName
co.code AS companyCode
FROM invoiceOut i
LEFT JOIN client c ON c.id = i.clientFk
LEFT JOIN company co ON co.id = i.companyFk
LEFT JOIN customsAgent ca ON ca.id = i.customsAgentFk`
LEFT JOIN company co ON co.id = i.companyFk`
);
stmt.merge(conn.makeSuffix(filter));

View File

@ -66,11 +66,6 @@
"model": "Ticket",
"foreignKey": "refFk",
"primaryKey": "ref"
},
"customsAgentFk": {
"type": "belongsTo",
"model": "CustomsAgent",
"foreignKey": "customsAgentFk"
}
}
}

View File

@ -8,7 +8,7 @@ module.exports = Self => {
arg: 'id',
type: 'number',
required: true,
description: 'The route id',
description: 'The client id',
http: {source: 'path'}
}, {
arg: 'replyTo',
@ -31,13 +31,26 @@ module.exports = Self => {
});
Self.driverRouteEmail = async(ctx, id) => {
const {agencyMode} = await Self.findById(id, {
fields: ['agencyModeFk'],
const models = Self.app.models;
const {workerFk, agencyMode} = await Self.findById(id, {
fields: ['workerFk', 'agencyModeFk'],
include: {relation: 'agencyMode'}
});
const {reportMail} = agencyMode();
let user;
let account;
if (workerFk) {
user = await models.VnUser.findById(workerFk, {
fields: ['active', 'id'],
include: {relation: 'emailUser'}
});
account = await models.Account.findById(workerFk);
}
if (user?.active && account) ctx.args.recipient = user.emailUser().email;
else ctx.args.recipient = reportMail;
ctx.args.recipient = reportMail;
if (!ctx.args.recipient) throw new UserError('An email is necessary');
return Self.sendTemplate(ctx, 'driver-route');
};

View File

@ -28,7 +28,6 @@ module.exports = Self => {
delete args.ctx;
if (!args.name) throw new UserError('The social name cannot be empty');
if (args.name !== args.name.toUpperCase()) throw new UserError('Social name should be uppercase');
const data = {...args, ...{nickname: args.name}};
const supplier = await models.Supplier.create(data, myOptions);

View File

@ -30,7 +30,7 @@ module.exports = Self => {
Object.assign(myOptions, options);
const query =
`SELECT DISTINCT u.id, u.nickname, w.firstName, w.lastName
`SELECT DISTINCT u.id, u.nickname
FROM itemType it
JOIN worker w ON w.id = it.workerFk
JOIN account.user u ON u.id = w.id`;

View File

@ -28,6 +28,7 @@ module.exports = Self => {
verb: 'POST'
}
});
Self.saveSign = async(ctx, tickets, location, signedTime, options) => {
const models = Self.app.models;
const myOptions = {userId: ctx.req.accessToken.userId};
@ -110,12 +111,6 @@ module.exports = Self => {
scope: {
fields: ['id']
}
},
{
relation: 'zone',
scope: {
fields: ['id', 'zoneFk,', 'name']
}
}]
}, myOptions);
@ -156,28 +151,6 @@ module.exports = Self => {
await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [ticketId, stateCode], myOptions);
if (stateCode == 'DELIVERED' && ticket.priority) {
const orderState = await models.State.findOne({
where: {code: 'DELIVERED'},
fields: ['id']
}, myOptions);
const ticketIncorrect = await Self.rawSql(`
SELECT t.id
FROM ticket t
JOIN ticketState ts ON ts.ticketFk = t.id
JOIN state s ON s.code = ts.code
WHERE t.routeFk = ?
AND s.\`order\` < ?
AND priority <(SELECT t.priority
FROM ticket t
WHERE t.id = ?)`
, [ticket.routeFk, orderState.id, ticket.id], myOptions);
if (ticketIncorrect?.length > 0)
await sendMail(ctx, ticket.routeFk, ticket.id, ticket.zone().name);
}
if (ticket?.address()?.province()?.country()?.code != 'ES' && ticket.$cmrFk) {
await models.Ticket.saveCmr(ctx, [ticketId], myOptions);
externalTickets.push(ticketId);
@ -190,25 +163,4 @@ module.exports = Self => {
}
await models.Ticket.sendCmrEmail(ctx, externalTickets);
};
async function sendMail(ctx, route, ticket, zoneName) {
const $t = ctx.req.__;
const url = await Self.app.models.Url.getUrl();
const sendTo = 'repartos@verdnatura.es';
const fullUrl = `${url}route/${route}/summary`;
const emailSubject = $t('Incorrect delivery order alert on route', {
route,
zone: zoneName
});
const emailBody = $t('Ticket has been delivered out of order', {
ticket,
fullUrl
});
await Self.app.models.Mail.create({
receiver: sendTo,
subject: emailSubject,
body: emailBody
});
}
};

View File

@ -1,20 +1,12 @@
const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('Ticket saveSign()', () => {
let ctx = {req: {
getLocale: () => {
return 'en';
},
__: () => {},
accessToken: {userId: 9}
}
};
beforeEach(() => {
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: ctx
});
});
}};
it(`should throw error if the ticket's alert level is lower than 2`, async() => {
const tx = await models.TicketDms.beginTransaction({});
@ -59,46 +51,4 @@ describe('Ticket saveSign()', () => {
expect(ticketTrackingAfter.name).toBe('Entregado en parte');
});
it('should send an email to notify that the delivery order is not correct', async() => {
const tx = await models.Ticket.beginTransaction({});
const ticketFk = 8;
const priority = 5;
const stateFk = 10;
const stateTicketFk = 2;
const expeditionFk = 11;
const expeditionStateFK = 2;
let mailCountBefore;
let mailCountAfter;
spyOn(models.Dms, 'uploadFile').and.returnValue([{id: 1}]);
const options = {transaction: tx};
const tickets = [ticketFk];
const expedition = await models.Expedition.findById(expeditionFk, null, options);
expedition.updateAttribute('stateTypeFk', expeditionStateFK, options);
const ticket = await models.Ticket.findById(ticketFk, null, options);
ticket.updateAttribute('priority', priority, options);
const filter = {where: {
ticketFk: ticketFk,
stateFk: stateTicketFk}
};
try {
const ticketTracking = await models.TicketTracking.findOne(filter, options);
ticketTracking.updateAttribute('stateFk', stateFk, options);
mailCountBefore = await models.Mail.count(options);
await models.Ticket.saveSign(ctx, tickets, null, null, options);
mailCountAfter = await models.Mail.count(options);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
expect(mailCountAfter).toBeGreaterThan(mailCountBefore);
});
});

View File

@ -1,64 +0,0 @@
const {models} = require('vn-loopback/server/server');
describe('ticketService model ', () => {
const originalTicketFk = 1;
const refundTicketFk = 11;
let tx;
let opts;
let ticketService;
beforeEach(async() => {
tx = await models.Sale.beginTransaction({});
opts = {transaction: tx};
ticketService = await models.TicketService.create({
ticketFk: refundTicketFk,
description: 'test',
quantity: 1,
price: 100,
taxClassFk: 1,
ticketServiceTypeFk: 1
}, opts);
});
afterEach(async() => {
await tx.rollback();
});
describe('TicketService', () => {
it('should allow updating description and quantity for non-refund tickets', async() => {
await ticketService.updateAttributes({
ticketServiceTypeFk: 2,
quantity: 5
}, opts);
const updated = await models.TicketService.findById(ticketService.id, null, opts);
expect(updated.description).not.toBe('test');
expect(updated.quantity).toBe(5);
});
it('should only allow updating description for refund tickets', async() => {
await models.TicketRefund.create({
refundTicketFk,
originalTicketFk
}, opts);
await ticketService.updateAttributes({
ticketServiceTypeFk: 2
}, opts);
try {
await ticketService.updateAttributes({
ticketServiceTypeFk: 3,
quantity: 5
}, opts);
fail('Should have thrown error');
} catch (e) {
expect(e.message).toBe('Only description can be modified in refund tickets');
}
});
});
});

View File

@ -10,18 +10,9 @@ module.exports = Self => {
const isLocked = await models.Ticket.isLocked(ticketId);
if (isLocked)
throw new UserError(`The current ticket can't be modified`);
const isRefund = await models.TicketRefund.findOne({
where: {refundTicketFk: ticketId}
}, {
transaction: ctx.options.transaction
});
if (isRefund && ctx.data && Object.keys(ctx.data).some(field => field !== 'ticketServiceTypeFk'))
throw new UserError('Only description can be modified in refund tickets');
}
if (changes?.ticketServiceTypeFk) {
if (changes && changes.ticketServiceTypeFk) {
const ticketServiceType = await models.TicketServiceType.findById(changes.ticketServiceTypeFk);
changes.description = ticketServiceType.name;
}

View File

@ -1,3 +1,4 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
const buildFilter = require('vn-loopback/util/filter').buildFilter;
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
@ -90,11 +91,6 @@ module.exports = Self => {
arg: 'landed',
type: 'date',
description: 'The landed date'
},
{
arg: 'awbFk',
type: 'number',
description: 'The awbFk id'
}
],
returns: {
@ -172,17 +168,14 @@ module.exports = Self => {
t.totalEntries,
t.isRaid,
t.daysInForward,
t.awbFk,
am.name agencyModeName,
a.code awbCode,
win.name warehouseInName,
wout.name warehouseOutName,
cnt.code continent
FROM travel t
JOIN agencyMode am ON am.id = t.agencyModeFk
JOIN warehouse win ON win.id = t.warehouseInFk
JOIN warehouse wout ON wout.id = t.warehouseOutFk
LEFT JOIN awb a ON a.id = t.awbFk
FROM vn.travel t
JOIN vn.agencyMode am ON am.id = t.agencyModeFk
JOIN vn.warehouse win ON win.id = t.warehouseInFk
JOIN vn.warehouse wout ON wout.id = t.warehouseOutFk
JOIN warehouse wo ON wo.id = t.warehouseOutFk
JOIN country c ON c.id = wo.countryFk
LEFT JOIN continent cnt ON cnt.id = c.continentFk) AS t`

View File

@ -41,9 +41,7 @@ module.exports = Self => {
* b.stickers)/1000000) AS DECIMAL(10,2)) m3,
TRUNCATE(SUM(b.stickers)/(COUNT( b.id) / COUNT( DISTINCT b.id)),0) hb,
CAST(SUM(b.freightValue*b.quantity) AS DECIMAL(10,2)) freightValue,
CAST(SUM(b.packageValue*b.quantity) AS DECIMAL(10,2)) packageValue,
e.initialTemperature,
e.finalTemperature
CAST(SUM(b.packageValue*b.quantity) AS DECIMAL(10,2)) packageValue
FROM vn.travel t
LEFT JOIN vn.entry e ON t.id = e.travelFk
LEFT JOIN vn.buy b ON b.entryFk = e.id

View File

@ -20,9 +20,6 @@
},
"ratio": {
"type": "number"
},
"hasToDownloadRate": {
"type": "boolean"
}
},
"acls": [

View File

@ -42,9 +42,6 @@
"price": {
"type": "number"
},
"priceOptimum": {
"type": "number"
},
"bonus": {
"type": "number"
},

View File

@ -28,9 +28,6 @@
"price": {
"type": "number"
},
"priceOptimum": {
"type": "number"
},
"bonus": {
"type": "number"
},

View File

@ -1,6 +1,6 @@
{
"name": "salix-back",
"version": "25.06.0",
"version": "25.02.0",
"author": "Verdnatura Levante SL",
"description": "Salix backend",
"license": "GPL-3.0",

View File

@ -1,9 +1,9 @@
WITH tickets AS(
SELECT id, addressFk, packages, refFk
FROM vn.ticket
WHERE refFk = ?
SELECT id, packages, addressFk, weight
FROM ticket
WHERE refFk= ?
), volume AS(
SELECT SUM(volume) volume, MAX(weight)weight
SELECT SUM(volume) volume
FROM tickets t
JOIN vn.saleVolume sv ON sv.ticketFk = t.id
), intrastat AS(
@ -12,14 +12,10 @@ SELECT GROUP_CONCAT(DISTINCT ir.description ORDER BY ir.description SEPARATOR '
JOIN vn.sale s ON t.id = s.ticketFk
JOIN vn.item i ON i.id = s.itemFk
JOIN vn.intrastat ir ON ir.id = i.intrastatFk
), totalPackages AS(
SELECT SUM(packages)packages
FROM tickets s
)
SELECT tp.packages,
io.incotermsFk,
)SELECT SUM(t.packages) packages,
a.incotermsFk,
ic.name incotermsName,
v.weight weight,
MAX(t.weight) weight,
ca.fiscalName customsAgentName,
ca.street customsAgentStreet,
ca.nif customsAgentNif,
@ -27,10 +23,9 @@ SELECT tp.packages,
ca.email customsAgentEmail,
CAST(v.volume AS DECIMAL (10,2)) volume,
i.intrastat
FROM vn.invoiceOut io
JOIN vn.incoterms ic ON ic.code = io.incotermsFk
LEFT JOIN vn.customsAgent ca ON ca.id = io.customsAgentFk
FROM tickets t
JOIN vn.address a ON a.id = t.addressFk
JOIN vn.incoterms ic ON ic.code = a.incotermsFk
LEFT JOIN vn.customsAgent ca ON ca.id = a.customsAgentFk
JOIN volume v
JOIN intrastat i
JOIN totalPackages tp
WHERE `ref` = (SELECT DISTINCT refFk FROM tickets)