Merge branch 'dev' into 7683-productionControlDeadlock
gitea/salix/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Robert Ferrús 2024-07-23 07:16:28 +00:00
commit 2a70df151a
72 changed files with 604 additions and 673 deletions

View File

@ -24,7 +24,7 @@ module.exports = Self => {
try {
const options = {transaction: tx, userId: ctx.req.accessToken.userId};
const files = await Self.rawSql('SELECT name, checksum, keyValue FROM edi.fileConfig', null, options);
const files = await Self.rawSql('SELECT name, checksum, keyValue FROM edi.fileMultiConfig', null, options);
const updatableFiles = [];
for (const file of files) {
@ -54,7 +54,7 @@ module.exports = Self => {
const tables = await Self.rawSql(`
SELECT fileName, toTable, file
FROM edi.tableConfig
FROM edi.tableMultiConfig
WHERE file IN (?)`, [fileNames], options);
for (const table of tables) {
@ -85,7 +85,7 @@ module.exports = Self => {
for (const file of updatableFiles) {
console.log(`Updating file ${file.name} checksum...`);
await Self.rawSql(`
UPDATE edi.fileConfig
UPDATE edi.fileMultiConfig
SET checksum = ?
WHERE name = ?`,
[file.checksum, file.name], options);
@ -228,7 +228,7 @@ module.exports = Self => {
await Self.rawSql(sqlTemplate, [filePath], options);
await Self.rawSql(`
UPDATE edi.tableConfig
UPDATE edi.tableMultiConfig
SET updated = ?
WHERE fileName = ?
`, [Date.vnNew(), baseName], options);

View File

@ -37,6 +37,7 @@ module.exports = Self => {
});
const xmlString = response.data;
console.log('xmlString: ', xmlString);
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'text/xml');
const result = xmlDoc.getElementsByTagName('Mensaje')[0].textContent;

View File

@ -25,7 +25,7 @@
</mrw:Direccion>
<mrw:Nif><%= expeditionData.fi %></mrw:Nif>
<mrw:Nombre><%= expeditionData.clientName %></mrw:Nombre>
<mrw:Telefono><%= expeditionData.phone %></mrw:Telefono>
<mrw:Telefono><%= expeditionData.mobile %></mrw:Telefono>
<mrw:Observaciones><%= expeditionData.deliveryObservation %></mrw:Observaciones>
</mrw:DatosEntrega>
<mrw:DatosServicio>

View File

@ -47,7 +47,7 @@ module.exports = Self => {
co.code countryCode,
c.fi,
c.name clientName,
c.phone,
a.mobile,
DATE_FORMAT(t.shipped, '%d/%m/%Y') created,
t.shipped,
CONCAT( e.ticketFk, LPAD(e.counter, mc.counterWidth, '0')) reference,

View File

@ -3,7 +3,7 @@
"base": "VnModel",
"options": {
"mysql": {
"table": "salix.defaultViewConfig"
"table": "salix.defaultViewMultiConfig"
}
},
"properties": {

View File

@ -14,6 +14,9 @@
},
"itemFk": {
"type": "number"
},
"isChecked": {
"type": "boolean"
}
}
}

View File

@ -3,7 +3,7 @@
"base": "VnModel",
"options": {
"mysql": {
"table": "userConfig"
"table": "userMultiConfig"
}
},
"properties": {

View File

@ -10,9 +10,6 @@ SET foreign_key_checks = 0;
INSERT INTO util.config (id, environment, mockTime, mockUtcTime, mockEnabled)
VALUES (1, 'local', '2001-01-01 12:00:00', '2001-01-01 11:00:00', TRUE);
INSERT INTO util.binlogQueue (code,logName, `position`)
VALUES ('mylogger', 'bin.000001', 4);
/* #5483
INSERT INTO vn.entryConfig (defaultEntry, mailToNotify, inventorySupplierFk, maxLockTime, defaultSupplierFk)
VALUES(1, NULL, 1, 300, 1);

View File

@ -1516,23 +1516,23 @@ INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed
(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, '');
INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `itemFk`, `itemTypeFk`, `saleTotal`, `saleWaste`, `rate`)
INSERT INTO `bs`.`waste`(`buyerFk`, `year`, `week`, `itemFk`, `itemTypeFk`, `saleTotal`, `saleQuantity`, `saleInternalWaste`, `saleExternalWaste`)
VALUES
('CharlesXavier', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation', 1, 1, '1062', '51', '4.8'),
('CharlesXavier', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation Colombia', 2, 1, '35074', '687', '2.0'),
('CharlesXavier', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation Mini', 3, 1, '1777', '13', '0.7'),
('CharlesXavier', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Carnation Short', 4, 1, '3182', '59', '0.6'),
('CharlesXavier', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Crisantemo', 5, 1, '1747', '13', '0.7'),
('CharlesXavier', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Lilium Oriental', 6, 1, '7182', '59', '0.6'),
('CharlesXavier', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Alstroemeria', 7, 1, '1777', '13', '0.7'),
('CharlesXavier', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Cymbidium', 1, 1, '4181', '59', '0.6'),
('CharlesXavier', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Cymbidium', 2, 1, '7268', '59', '0.6'),
('DavidCharlesHaller', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Containers', 2, 1, '-74', '0', '0.0'),
('DavidCharlesHaller', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Packagings', 3, 1, '-7', '0', '0.0'),
('DavidCharlesHaller', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Freight', 4, 1, '1100', '0', '0.0'),
('HankPym', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Funeral Accessories', 5, 1, '848', '-187', '-22.1'),
('HankPym', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Miscellaneous Accessories', 6, 1, '186', '0', '0.0'),
('HankPym', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Adhesives', 7, 1, '277', '0', '0.0');
('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 1, 1, '1062', '51', '56.20', '56.20'),
('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 2, 1, '35074', '687', '53.12', '89.69'),
('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 3, 1, '1777', '13', '12.02', '53.12'),
('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 4, 1, '3182', '59', '51', '56.20'),
('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 5, 1, '1747', '13', '53.12', '53.12'),
('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 6, 1, '7182', '59', '51', '53.12'),
('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 7, 1, '1777', '13', '89.69', '89.69'),
('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 8, 1, '4181', '59', '53.12', '53.12'),
('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 9, 1, '7268', '59', '12.02', '56.20'),
('103', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 2, 1, '-74', '0', '51', '89.69'),
('103', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 3, 1, '-7', '0', '12.02', '53.12'),
('103', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 4, 1, '1100', '0', '51', '56.20'),
('103', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 5, 1, '848', '-187', '12.02', '89.69'),
('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'),
('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');
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
@ -1968,7 +1968,7 @@ INSERT INTO `vn`.`orderTicket`(`orderFk`, `ticketFk`)
(21, 21),
(22, 22);
INSERT INTO `vn`.`userConfig` (`userFk`, `warehouseFk`, `companyFk`)
INSERT INTO `vn`.`userMultiConfig` (`userFk`, `warehouseFk`, `companyFk`)
VALUES
(1, 1, 69),
(5, 1, 442),

View File

@ -1,31 +1,50 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`waste_addSales`()
BEGIN
DECLARE vWeek INT;
DECLARE vYear INT;
DECLARE vDateFrom DATE DEFAULT util.VN_CURDATE() - INTERVAL WEEKDAY(CURDATE()) DAY;
DECLARE vDateTo DATE DEFAULT vDateFrom + INTERVAL 6 DAY;
SELECT week, year
INTO vWeek, vYear
FROM vn.time
WHERE dated = util.VN_CURDATE();
CALL cache.last_buy_refresh(FALSE);
REPLACE bs.waste
SELECT *, 100 * mermas / total as porcentaje
FROM (
SELECT buyer,
year,
week,
family,
itemFk,
itemTypeFk,
floor(sum(value)) as total,
floor(sum(IF(typeFk = 'loses', value, 0))) as mermas
FROM vn.saleValue
where year = vYear and week = vWeek
GROUP BY family, itemFk
) sub
ORDER BY mermas DESC;
SELECT YEAR(t.shipped),
WEEK(t.shipped, 4),
it.workerFk,
it.id,
s.itemFk,
SUM(s.quantity),
SUM((b.buyingValue + b.freightValue + b.comissionValue + b.packageValue) * s.quantity) `value`,
SUM (
IF(
aw.`type` = 'internal',
(b.buyingValue + b.freightValue + b.comissionValue + b.packageValue) * s.quantity,
0
)
) internalWaste,
SUM (
IF(
aw.`type` = 'external',
(b.buyingValue + b.freightValue + b.comissionValue + b.packageValue) * s.quantity,
IF(c.code = 'manaClaim',
sc.value * s.quantity,
0
)
)
) externalWaste
FROM vn.sale s
JOIN vn.item i ON i.id = s.itemFk
JOIN vn.itemType it ON it.id = i.typeFk
JOIN vn.ticket t ON t.id = s.ticketFk
JOIN vn.address a FORCE INDEX (PRIMARY) ON a.id = t.addressFk
LEFT JOIN vn.addressWaste aw ON aw.addressFk = a.id
JOIN vn.warehouse w ON w.id = t.warehouseFk
JOIN cache.last_buy lb ON lb.item_id = i.id
AND lb.warehouse_id = w.id
JOIN vn.buy b ON b.id = lb.buy_id
LEFT JOIN vn.saleComponent sc ON sc.saleFk = s.id
LEFT JOIN vn.component c ON c.id = sc.componentFk
WHERE t.shipped BETWEEN vDateFrom AND vDateTo
AND w.isManaged
GROUP BY it.id, i.id;
END$$
DELIMITER ;

View File

@ -10,5 +10,5 @@ AS SELECT `q`.`name` AS `name`,
`c`.`ringInUse` AS `ringinuse`
FROM (
`pbx`.`queue` `q`
JOIN `pbx`.`queueConfig` `c` ON(`q`.`config` = `c`.`id`)
JOIN `pbx`.`queueMultiConfig` `c` ON(`q`.`config` = `c`.`id`)
)

View File

@ -28,6 +28,10 @@ BEGIN
DELETE FROM ticketDown WHERE created < util.yesterday();
DELETE FROM entryLog WHERE creationDate < v2Months;
DELETE IGNORE FROM expedition WHERE created < v26Months;
DELETE cs
FROM sms s
JOIN clientSms cs ON cs.smsFk = s.id
WHERE s.created < v18Months;
DELETE FROM sms WHERE created < v18Months;
DELETE FROM saleTracking WHERE created < v1Years;
DELETE FROM productionError WHERE dated < v1Years;

View File

@ -3,7 +3,8 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`collection_addWithR
vItemFk INT,
vQuantity INT,
vTicketFk INT,
vSaleGroupFk INT
vSaleGroupFk INT,
vSectorFk INT
)
BEGIN
/**
@ -67,7 +68,7 @@ BEGIN
SELECT LAST_INSERT_ID() INTO vSaleFk;
CALL sale_calculateComponent(vSaleFk, NULL);
CALL itemShelvingSale_addBySale(vSaleFk);
CALL itemShelvingSale_addBySale(vSaleFk, vSectorFk);
IF NOT EXISTS (SELECT TRUE FROM itemShelvingSale WHERE saleFk = vSaleFk LIMIT 1) THEN
SET vHasThrow = TRUE;

View File

@ -7,7 +7,7 @@ DECLARE vCompanyFk INT;
SELECT IFNULL(uc.companyFk, rc.defaultCompanyFk)
INTO vCompanyFk
FROM vn.routeConfig rc
LEFT JOIN userConfig uc ON uc.userFk = workerFk;
LEFT JOIN userMultiConfig uc ON uc.userFk = workerFk;
SELECT

View File

@ -1,5 +1,10 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`expeditionPallet_build`(IN vExpeditions JSON, IN vArcId INT, IN vWorkerFk INT, OUT vPalletFk INT)
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`expeditionPallet_build`(
vExpeditions JSON,
vArcId INT,
vWorkerFk INT,
OUT vPalletFk INT
)
BEGIN
/** Construye un pallet de expediciones.
*
@ -7,28 +12,22 @@ BEGIN
* en cuyo caso actualiza ese pallet.
*
* @param vExpeditions JSON_ARRAY con esta estructura [exp1, exp2, exp3, ...]
* @param vArcId INT Identificador de vn.arcRead
* @param vWorkerFk INT Identificador de vn.worker
* @param out vPalletFk Identificador de vn.expeditionPallet
* @param vArcId INT Identificador de arcRead
* @param vWorkerFk INT Identificador de worker
* @param out vPalletFk Identificador de expeditionPallet
*/
DECLARE vCounter INT;
DECLARE vExpeditionFk INT;
DECLARE vTruckFk INT;
DECLARE vPrinterFk INT;
DECLARE vExpeditionStateTypeFk INT;
DROP TEMPORARY TABLE IF EXISTS tExpedition;
CREATE TEMPORARY TABLE tExpedition
SELECT
e.id expeditionFk,
r.id routeFk,
ep.id palletFk
FROM
vn.expedition e,
vn.route r,
vn.expeditionPallet ep
LIMIT 0;
ALTER TABLE tExpedition ADD PRIMARY KEY (expeditionFk);
CREATE OR REPLACE TEMPORARY TABLE tExpedition (
expeditionFk INT,
routeFk INT,
palletFk INT,
PRIMARY KEY (expeditionFk)
);
SET vCounter = JSON_LENGTH(vExpeditions);
@ -39,9 +38,9 @@ BEGIN
INSERT IGNORE INTO tExpedition(expeditionFk, routeFk, palletFk)
SELECT vExpeditionFk, t.routeFk, es.palletFk
FROM vn.expedition e
LEFT JOIN vn.ticket t ON t.id = e.ticketFk
LEFT JOIN vn.expeditionScan es ON es.expeditionFk = e.id
FROM expedition e
LEFT JOIN ticket t ON t.id = e.ticketFk
LEFT JOIN expeditionScan es ON es.expeditionFk = e.id
WHERE e.id = vExpeditionFk;
END WHILE;
@ -52,40 +51,45 @@ BEGIN
WHERE palletFk > 0
GROUP BY palletFk
ORDER BY n DESC
LIMIT 100 ) sub
LIMIT 100
) sub
LIMIT 1;
IF vPalletFk IS NULL THEN
SELECT roadmapStopFk
INTO vTruckFk
SELECT roadmapStopFk INTO vTruckFk
FROM (
SELECT rm.roadmapStopFk, count(*) n
FROM vn.routesMonitor rm
FROM routesMonitor rm
JOIN tExpedition e ON e.routeFk = rm.routeFk
GROUP BY roadmapStopFk
ORDER BY n DESC
LIMIT 1) sub;
LIMIT 1
) sub;
IF vTruckFk IS NULL THEN
CALL util.throw ('TRUCK_NOT_AVAILABLE');
END IF;
INSERT INTO vn.expeditionPallet(truckFk)
VALUES(vTruckFk);
INSERT INTO expeditionPallet SET truckFk = vTruckFk;
SET vPalletFk = LAST_INSERT_ID();
END IF;
INSERT INTO vn.expeditionScan(expeditionFk, palletFk, workerFk)
INSERT INTO expeditionScan(expeditionFk, palletFk, workerFk)
SELECT expeditionFk, vPalletFk, vWorkerFk
FROM tExpedition
ON DUPLICATE KEY UPDATE palletFk = vPalletFk, workerFk = vWorkerFk;
SELECT printerFk INTO vPrinterFk
FROM vn.arcRead
WHERE id = vArcId;
SELECT id INTO vExpeditionStateTypeFk
FROM expeditionStateType
WHERE code = 'PALLETIZED';
CALL vn.report_print(
INSERT INTO expeditionState(expeditionFk, typeFk)
SELECT expeditionFk, vExpeditionStateTypeFk FROM tExpedition;
SELECT printerFk INTO vPrinterFk FROM arcRead WHERE id = vArcId;
CALL report_print(
'LabelPalletExpedition',
vPrinterFk,
account.myUser_getId(),
@ -93,7 +97,7 @@ BEGIN
'high'
);
UPDATE vn.expeditionPallet SET isPrint = TRUE WHERE id = vPalletFk;
UPDATE expeditionPallet SET isPrint = TRUE WHERE id = vPalletFk;
DROP TEMPORARY TABLE tExpedition;
END$$

View File

@ -216,7 +216,7 @@ BEGIN
i.transactionTypeSageFk,
@vTaxCodeGeneral := i.taxClassCodeFk
FROM tmp.ticketServiceTax tst
JOIN invoiceOutTaxConfig i ON i.taxClassCodeFk = tst.code
JOIN invoiceOutTaxMultiConfig i ON i.taxClassCodeFk = tst.code
WHERE i.isService
HAVING taxableBase
) sub;
@ -229,7 +229,7 @@ BEGIN
i.taxTypeSageFk ,
i.transactionTypeSageFk
FROM tmp.ticketTax tt
JOIN invoiceOutTaxConfig i ON i.taxClassCodeFk = tt.code
JOIN invoiceOutTaxMultiConfig i ON i.taxClassCodeFk = tt.code
WHERE !i.isService
GROUP BY tt.pgcFk
HAVING taxableBase

View File

@ -0,0 +1,28 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemMinimumQuantity_check`(
vSelf INT,
vItemFk INT,
vStarted DATE,
vEnded DATE,
vWarehouseFk INT
)
BEGIN
DECLARE vHasCollision BOOL;
IF vStarted IS NULL THEN
CALL util.throw('The field "started" cannot be null');
END IF;
SELECT COUNT(*) INTO vHasCollision
FROM itemMinimumQuantity
WHERE vItemFk = itemFk
AND ((vStarted <= ended OR ended IS NULL)
AND (vStarted >= `started` OR vEnded IS NULL))
AND (vWarehouseFk <=> warehouseFk)
AND vSelf <> id;
IF vHasCollision THEN
CALL util.throw('A line with the same configuration already exists');
END IF;
END$$
DELIMITER ;

View File

@ -44,7 +44,7 @@ BEGIN
LEAVE l;
END IF;
CALL itemShelvingSale_addBySale(vSaleFk);
CALL itemShelvingSale_addBySale(vSaleFk, NULL);
END LOOP;
CLOSE vSales;
END$$

View File

@ -1,6 +1,7 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelvingSale_addBySale`(
vSaleFk INT
vSaleFk INT,
vSectorFk INT
)
proc: BEGIN
/**
@ -8,6 +9,7 @@ proc: BEGIN
*
* @param vSaleFk Id de sale
* @param vItemShelvingSaleFk Id de reserva
* @param vSectorFk Id del sector del operator
*/
DECLARE vLastPickingOrder INT;
DECLARE vDone INT DEFAULT FALSE;
@ -30,6 +32,7 @@ proc: BEGIN
JOIN productionConfig pc
WHERE s.id = vSaleFk
AND NOT sc.isHideForPickers
AND (sc.id = vSectorFk OR vSectorFk IS NULL)
ORDER BY s.id,
p.pickingOrder >= vLastPickingOrder,
sh.priority DESC,

View File

@ -10,6 +10,7 @@ BEGIN
*/
DECLARE vDone BOOL DEFAULT FALSE;
DECLARE vSaleFk INT;
DECLARE vSectorFk INT;
DECLARE vSales CURSOR FOR
SELECT s.id
FROM sectorCollectionSaleGroup sc
@ -25,6 +26,10 @@ BEGIN
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
SELECT sectorFk INTO vSectorFk
FROM operator
WHERE workerFk = account.myUser_getId();
OPEN vSales;
l: LOOP
SET vDone = FALSE;
@ -34,7 +39,7 @@ BEGIN
LEAVE l;
END IF;
CALL itemShelvingSale_addBySale(vSaleFk);
CALL itemShelvingSale_addBySale(vSaleFk, vSectorFk);
END LOOP;
CLOSE vSales;
END$$

View File

@ -6,9 +6,10 @@ proc: BEGIN
*/
DECLARE vDone BOOL;
DECLARE vSaleFk INT;
DECLARE vSectorFk INT;
DECLARE vSales CURSOR FOR
SELECT DISTINCT saleFk FROM tSale;
SELECT DISTINCT saleFk, sectorFk FROM tSale;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET vDone = TRUE;
@ -26,24 +27,25 @@ proc: BEGIN
CREATE OR REPLACE TEMPORARY TABLE tSale
ENGINE = MEMORY
SELECT id, saleFk FROM itemShelvingSaleReserve;
SELECT id, saleFk, sectorFk FROM itemShelvingSaleReserve;
OPEN vSales;
myLoop: LOOP
SET vDone = FALSE;
FETCH vSales INTO vSaleFk;
FETCH vSales INTO vSaleFk, vSectorFk;
IF vDone THEN
LEAVE myLoop;
END IF;
CALL itemShelvingSale_addBySale (vSaleFk);
CALL itemShelvingSale_addBySale (vSaleFk, vSectorFk);
END LOOP;
CLOSE vSales;
DELETE iss FROM itemShelvingSaleReserve iss JOIN tSale s ON s.id = iss.id;
DELETE iss FROM itemShelvingSaleReserve iss
JOIN tSale s ON s.id = iss.id AND s.sectorFk = iss.sectorFk;
DROP TEMPORARY TABLE tSale;

View File

@ -1,13 +1,16 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelvingSale_reallocate`(
vItemShelvingFk INT(10),
vItemFk INT(10)
vItemFk INT(10),
vSectorFk INT
)
BEGIN
/**
* Elimina reservas de un itemShelving e intenta reservar en otra ubicación
*
* @param vItemShelvingFk Id itemShelving
* @param vItemFk Id del artículo
* @param vSectorFk Id del sector
*/
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
@ -17,18 +20,21 @@ BEGIN
START TRANSACTION;
SELECT id INTO vItemShelvingFk
FROM itemShelving
WHERE id = vItemShelvingFk
FOR UPDATE;
UPDATE itemShelving
SET visible = 0,
available = 0
WHERE id = vItemShelvingFk
AND itemFk = vItemFk;
INSERT INTO itemShelvingSaleReserve (saleFk)
SELECT iss.id
FROM itemShelvingSale iss
JOIN itemShelving ish ON ish.id = iss.itemShelvingFk
WHERE iss.itemShelvingFk = vItemShelvingFk
AND iss.itemFk = vItemFk
AND NOT iss.isPicked
FOR UPDATE;
INSERT INTO itemShelvingSaleReserve (saleFk, vSectorFk)
SELECT DISTINCT iss.saleFk
FROM itemShelvingSale iss
JOIN itemShelving ish ON ish.id = iss.itemShelvingFk

View File

@ -2,7 +2,8 @@ DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelvingSale_setQuantity`(
vItemShelvingSaleFk INT(10),
vQuantity DECIMAL(10,0),
vIsItemShelvingSaleEmpty BOOLEAN
vIsItemShelvingSaleEmpty BOOLEAN,
vSectorFk INT
)
BEGIN
/**
@ -14,6 +15,7 @@ BEGIN
* @param vQuantity Cantidad real que se ha cogido de la ubicación
* @param vIsItemShelvingSaleEmpty determina si la ubicación itemShelvingSale se ha
* quedado vacio tras el movimiento
* @param vSectorFk Id del sector
*/
DECLARE vSaleFk INT;
DECLARE vItemShelvingFk INT;
@ -29,6 +31,12 @@ BEGIN
RESIGNAL;
END;
IF vQuantity > vReservedQuantity
OR (vQuantity < vReservedQuantity AND NOT vIsItemShelvingSaleEmpty)
OR (vQuantity = vReservedQuantity AND vIsItemShelvingSaleEmpty) THEN
CALL util.throw('The quantity cannot be different from the reserved');
END IF;
IF (SELECT isPicked FROM itemShelvingSale WHERE id = vItemShelvingSaleFk) THEN
CALL util.throw('Reservation completed');
END IF;
@ -50,9 +58,8 @@ BEGIN
AND NOT iss.isPicked;
IF vQuantity > vReservedQuantity
OR (vQuantity < vReservedQuantity AND
(NOT vIsItemShelvingSaleEmpty OR vIsItemShelvingSaleEmpty IS NULL))
OR (vIsItemShelvingSaleEmpty IS NOT NULL AND vQuantity = vReservedQuantity) THEN
OR (vQuantity < vReservedQuantity AND NOT vIsItemShelvingSaleEmpty)
OR (vQuantity = vReservedQuantity AND vIsItemShelvingSaleEmpty) THEN
CALL util.throw('The quantity cannot be different from the reserved');
END IF;
@ -72,7 +79,7 @@ BEGIN
SET visible = GREATEST(0, visible - vQuantity)
WHERE id = vItemShelvingFk;
SELECT SUM(IF(isPicked, 0, quantity)), SUM(quantity)
SELECT SUM(IF(isPicked OR id = vItemShelvingSaleFk, 0, quantity)), SUM(quantity)
INTO vRemainingQuantity, vTotalQuantity
FROM itemShelvingSale
WHERE saleFk = vSaleFk;
@ -96,9 +103,9 @@ BEGIN
COMMIT;
IF vIsItemShelvingSaleEmpty AND vQuantity <> vReservedQuantity THEN
INSERT INTO itemShelvingSaleReserve (saleFk)
SELECT vSaleFk;
CALL itemShelvingSale_reallocate(vItemShelvingFk, vItemFk);
INSERT INTO itemShelvingSaleReserve (saleFk, vSectorFk)
SELECT vSaleFk, vSectorFk;
CALL itemShelvingSale_reallocate(vItemShelvingFk, vItemFk, vSectorFk);
END IF;
END$$
DELIMITER ;

View File

@ -42,7 +42,7 @@ BEGIN
END IF;
SELECT warehouseFk INTO vWarehouseFk
FROM userConfig
FROM userMultiConfig
WHERE userFk = account.myUser_getId();
IF NOT vWarehouseFk OR vWarehouseFk IS NULL THEN

View File

@ -1,6 +1,8 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_valuateInventory`(
vDated DATE
vDated DATE,
vItemTypeFk INT,
vItemCategoryFk INT
)
BEGIN
DECLARE vInventoried DATE;
@ -61,11 +63,14 @@ BEGIN
JOIN `entry` e ON e.id = b.entryFk
JOIN travel tr ON tr.id = e.travelFk
JOIN itemType t ON t.id = i.typeFk
JOIN itemCategory ic ON ic.id = t.categoryFk
JOIN warehouse w ON w.id = tr.warehouseInFk
WHERE tr.landed = vDateDayEnd
AND e.supplierFk = vInventorySupplierFk
AND w.valuatedInventory
AND t.isInventory
AND (t.id = vItemTypeFk OR vItemTypeFk IS NULL)
AND (ic.id = vItemCategoryFk OR vItemCategoryFk IS NULL)
GROUP BY tr.warehouseInFk, b.itemFk;
ELSE
INSERT INTO tInventory(warehouseFk, itemFk, quantity, warehouseInventory)
@ -78,11 +83,14 @@ BEGIN
JOIN `entry` e ON e.id = b.entryFk
JOIN travel tr ON tr.id = e.travelFk
JOIN itemType t ON t.id = i.typeFk
JOIN itemCategory ic ON ic.id = t.categoryFk
JOIN warehouse w ON w.id = tr.warehouseInFk
WHERE tr.landed = vInventoried
AND e.supplierFk = vInventorySupplierFk
AND w.valuatedInventory
AND t.isInventory
AND (t.id = vItemTypeFk OR vItemTypeFk IS NULL)
AND (ic.id = vItemCategoryFk OR vItemCategoryFk IS NULL)
GROUP BY tr.warehouseInFk, b.itemFk;
END IF;
@ -97,6 +105,7 @@ BEGIN
JOIN `entry` e ON e.id = b.entryFk
JOIN travel tr ON tr.id = e.travelFk
JOIN itemType t ON t.id = i.typeFk
JOIN itemCategory ic ON ic.id = t.categoryFk
JOIN warehouse w ON w.id = tr.warehouseInFk
WHERE tr.landed BETWEEN vInventoried AND vDateDayEnd
AND IF(tr.landed = util.VN_CURDATE(), tr.isReceived, TRUE)
@ -104,6 +113,8 @@ BEGIN
AND w.valuatedInventory
AND t.isInventory
AND e.supplierFk <> vInventorySupplierFk
AND (t.id = vItemTypeFk OR vItemTypeFk IS NULL)
AND (ic.id = vItemCategoryFk OR vItemCategoryFk IS NULL)
ON DUPLICATE KEY UPDATE tInventory.quantity = tInventory.quantity + (b.quantity * IF(vHasNotInventory, -1, 1));
-- Descontamos las salidas
@ -117,11 +128,14 @@ BEGIN
JOIN `entry` e ON e.id = b.entryFk
JOIN travel tr ON tr.id = e.travelFk
JOIN itemType t ON t.id = i.typeFk
JOIN itemCategory ic ON ic.id = t.categoryFk
JOIN warehouse w ON w.id = tr.warehouseOutFk
WHERE tr.shipped BETWEEN vInventoried AND vDateDayEnd
AND NOT e.isRaid
AND w.valuatedInventory
AND t.isInventory
AND (t.id = vItemTypeFk OR vItemTypeFk IS NULL)
AND (ic.id = vItemCategoryFk OR vItemCategoryFk IS NULL)
ON DUPLICATE KEY UPDATE tInventory.quantity = tInventory.quantity + (b.quantity * IF(vHasNotInventory,1,-1));
-- Descontamos las lineas de venta
@ -135,10 +149,13 @@ BEGIN
JOIN `client` c ON c.id = t.clientFk
JOIN item i ON i.id = s.itemFk
JOIN itemType it ON it.id = i.typeFk
JOIN itemCategory ic ON ic.id = it.categoryFk
JOIN warehouse w ON w.id = t.warehouseFk
WHERE t.shipped BETWEEN vInventoried AND vDateDayEnd
AND w.valuatedInventory
AND it.isInventory
AND (it.id = vItemTypeFk OR vItemTypeFk IS NULL)
AND (ic.id = vItemCategoryFk OR vItemCategoryFk IS NULL)
ON DUPLICATE KEY UPDATE tInventory.quantity = tInventory.quantity + s.quantity * IF(vHasNotInventory, 1, -1);
-- Volver a poner lo que esta aun en las estanterias
@ -153,11 +170,14 @@ BEGIN
JOIN `client` c ON c.id = t.clientFk
JOIN item i ON i.id = s.itemFk
JOIN itemType it ON it.id = i.typeFk
JOIN itemCategory ic ON ic.id = it.categoryFk
JOIN warehouse w ON w.id = t.warehouseFk
WHERE t.shipped BETWEEN vDated AND vDateDayEnd
AND NOT (s.isPicked OR t.isLabeled)
AND w.valuatedInventory
AND it.isInventory
AND (it.id = vItemTypeFk OR vItemTypeFk IS NULL)
AND (ic.id = vItemCategoryFk OR vItemCategoryFk IS NULL)
ON DUPLICATE KEY UPDATE tInventory.quantity = tInventory.quantity + s.quantity * IF(vHasNotInventory, 0, 1);
END IF;
@ -172,6 +192,7 @@ BEGIN
JOIN `entry` e ON e.id = b.entryFk
JOIN travel tr ON tr.id = e.travelFk
JOIN itemType t ON t.id = i.typeFk
JOIN itemCategory ic ON ic.id = t.categoryFk
JOIN warehouse wIn ON wIn.id = tr.warehouseInFk
JOIN warehouse wOut ON wOut.id = tr.warehouseOutFk
WHERE vDated >= tr.shipped AND vDated < tr.landed
@ -179,6 +200,8 @@ BEGIN
AND wIn.valuatedInventory
AND t.isInventory
AND e.isConfirmed
AND (t.id = vItemTypeFk OR vItemTypeFk IS NULL)
AND (ic.id = vItemCategoryFk OR vItemCategoryFk IS NULL)
ON DUPLICATE KEY UPDATE tInventory.quantity = tInventory.quantity + (b.quantity);
CALL buyUltimate(NULL, vDateDayEnd);
@ -204,7 +227,8 @@ BEGIN
ic.name itemCategoryName,
ti.cost,
ti.total,
ti.warehouseInventory
ti.warehouseInventory,
ic.display
FROM tInventory ti
JOIN warehouse w ON w.id = warehouseFk
JOIN item i ON i.id = ti.itemFk

View File

@ -1,14 +1,18 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`route_updateM3`(vRoute INT)
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`route_updateM3`(
vSelf INT
)
BEGIN
/**
* Actualiza el volumen de la ruta.
*
* @param vSelf Id ruta
*/
DECLARE vVolume DECIMAL(10,1)
DEFAULT (SELECT SUM(volume) FROM saleVolume WHERE routeFk = vSelf);
UPDATE vn.route r
LEFT JOIN (
SELECT routeFk, SUM(volume) AS m3
FROM saleVolume
WHERE routeFk = vRoute
) v ON v.routeFk = r.id
SET r.m3 = IFNULL(v.m3,0)
WHERE r.id =vRoute;
UPDATE `route`
SET m3 = IFNULL(vVolume, 0)
WHERE id = vSelf;
END$$
DELIMITER ;

View File

@ -4,5 +4,6 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`itemMinimumQuantity_b
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
CALL itemMinimumQuantity_check(NEW.id, NEW.itemFk, NEW.started, NEW.ended, NEW.warehouseFk);
END$$
DELIMITER ;

View File

@ -4,5 +4,6 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`itemMinimumQuantity_b
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
CALL itemMinimumQuantity_check(NEW.id, NEW.itemFk, NEW.started, NEW.ended, NEW.warehouseFk);
END$$
DELIMITER ;

View File

@ -8,13 +8,16 @@ BEGIN
SET NEW.editorFk = account.myUser_getId();
IF NOT (NEW.routeFk <=> OLD.routeFk) THEN
INSERT IGNORE INTO `vn`.`routeRecalc` (`routeFk`)
SELECT r.id
FROM vn.route r
WHERE r.isOk = FALSE
AND r.id IN (OLD.routeFk,NEW.routeFk)
AND r.created >= util.VN_CURDATE()
GROUP BY r.id;
IF NEW.isSigned THEN
CALL util.throw('A signed ticket cannot be rerouted');
END IF;
INSERT IGNORE INTO routeRecalc(routeFk)
SELECT id
FROM `route`
WHERE NOT isOk
AND id IN (OLD.routeFk, NEW.routeFk)
AND created >= util.VN_CURDATE()
GROUP BY id;
END IF;
IF NOT (DATE(NEW.shipped) <=> DATE(OLD.shipped)) THEN

View File

@ -0,0 +1,53 @@
ALTER TABLE bs.waste ADD buyerFk int(10) unsigned NOT NULL;
USE vn;
CREATE OR REPLACE TEMPORARY TABLE tBuyers
ENGINE = MEMORY
WITH tDistinctBuyers AS (
SELECT DISTINCT buyer
FROM bs.waste w
)
SELECT buyer, u.id
FROM tDistinctBuyers tdb
JOIN account.`user` u ON u.name = tdb.buyer COLLATE utf8mb3_unicode_ci;
UPDATE bs.waste w
JOIN tBuyers tb ON tb.buyer = w.buyer
SET w.buyerFk = tb.id;
DROP TEMPORARY TABLE tBuyers;
ALTER TABLE bs.waste
DROP PRIMARY KEY,
DROP COLUMN family,
DROP COLUMN rate,
DROP COLUMN buyer;
ALTER TABLE bs.waste CHANGE buyerFk buyerFk int(10) unsigned NOT NULL AFTER `week`;
ALTER TABLE bs.waste ADD CONSTRAINT waste_user_FK FOREIGN KEY (buyerFk) REFERENCES account.user(id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE bs.waste ADD saleQuantity int(11) DEFAULT NULL NULL;
ALTER TABLE bs.waste MODIFY COLUMN saleTotal decimal(10,2) DEFAULT NULL NULL;
ALTER TABLE bs.waste MODIFY COLUMN saleWaste decimal(10,2) DEFAULT NULL NULL;
ALTER TABLE bs.waste CHANGE saleWaste saleInternalWaste decimal(10,2) DEFAULT NULL NULL;
ALTER TABLE bs.waste ADD saleExternalWaste decimal(10,2) DEFAULT NULL NULL;
ALTER TABLE bs.waste CHANGE saleQuantity saleQuantity decimal(10,2) DEFAULT NULL NULL AFTER itemTypeFk;
ALTER TABLE bs.waste CHANGE itemFk itemFk int(11) DEFAULT 0 NOT NULL AFTER itemTypeFk;
CREATE OR REPLACE TEMPORARY TABLE tWasteUnique
SELECT *
FROM bs.waste
GROUP BY `year`, `week`, buyerFk, itemTypeFk, itemFk
HAVING COUNT(*) > 1;
DELETE w.* FROM bs.waste w
JOIN tWasteUnique twu ON twu.`year` = w.`year`
AND twu.`week` = w.`week`
AND twu.`buyerFk` = w.`buyerFk`
AND twu.`itemTypeFk` = w.`itemTypeFk`
AND twu.`itemFk` = w.`itemFk`;
INSERT INTO bs.waste
SELECT * FROM tWasteUnique;
ALTER TABLE bs.waste ADD CONSTRAINT waste_pk PRIMARY KEY (`year`, `week`, buyerFk, itemTypeFk, itemFk);
DROP TEMPORARY TABLE tWasteUnique;

View File

@ -16,6 +16,4 @@ INSERT IGNORE INTO account.roleInherit (`role`,`inheritsFrom`)
UPDATE salix.ACL
SET principalId='$authenticated'
WHERE id=264;
WHERE id=(SELECT id FROM salix.ACL WHERE model='StarredModule' and property='*' and `accessType`='*');

View File

@ -0,0 +1,11 @@
RENAME TABLE hedera.shelfConfig TO hedera.shelfMultiConfig ;
RENAME TABLE pbx.queueConfig TO pbx.queueMultiConfig ;
RENAME TABLE salix.defaultViewConfig TO salix.defaultViewMultiConfig;
RENAME TABLE edi.fileConfig TO edi.fileMultiConfig;
RENAME TABLE edi.imapConfig TO edi.imapMultiConfig;
RENAME TABLE edi.tableConfig TO edi.tableMultiConfig;
RENAME TABLE vn.invoiceOutTaxConfig TO vn.invoiceOutTaxMultiConfig;
RENAME TABLE vn.userConfig TO vn.userMultiConfig;
RENAME TABLE vn.conveyorConfig TO vn.conveyorMultiConfig;
GRANT SELECT ON TABLE hedera.shelfMultiConfig TO employee;

View File

@ -0,0 +1,3 @@
-- Place your SQL code here
ALTER TABLE vn.ticketSms__ DROP FOREIGN KEY IF EXISTS ticketSms_FK;
ALTER TABLE vn.ticketSms__ ADD CONSTRAINT ticketSms_FK FOREIGN KEY (smsFk) REFERENCES vn.sms(id) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,11 @@
ALTER TABLE IF EXISTS vn.sectorCollectionSaleGroup DROP FOREIGN KEY sectorCollectionSaleGroup_ibfk_3;
ALTER TABLE IF EXISTS vn.sectorCollectionSaleGroup DROP FOREIGN KEY sectorCollectionSaleGroup_ibfk_2;
ALTER TABLE IF EXISTS vn.sectorCollectionSaleGroup DROP KEY saleGroupFk;
ALTER TABLE IF EXISTS vn.sectorCollectionSaleGroup ADD CONSTRAINT sectorCollectionSaleGroup_saleGroup_FK
FOREIGN KEY (saleGroupFk) REFERENCES vn.saleGroup(id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE IF EXISTS vn.sectorCollectionSaleGroup ADD CONSTRAINT sectorCollectionSaleGroup_unique UNIQUE KEY (sectorCollectionFk,saleGroupFk);

View File

@ -0,0 +1,11 @@
-- Place your SQL code here
ALTER TABLE IF EXISTS vn.itemShelvingSaleReserve
ADD IF NOT EXISTS sectorFk int(11) NULL;
ALTER TABLE IF EXISTS vn.itemShelvingSaleReserve
DROP FOREIGN KEY IF EXISTS itemShelvingSaleReserve_sector_FK;
ALTER TABLE IF EXISTS vn.itemShelvingSaleReserve
ADD CONSTRAINT itemShelvingSaleReserve_sector_FK FOREIGN KEY (id)
REFERENCES vn.sector(id) ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -0,0 +1,3 @@
ALTER TABLE vn.itemShelvingSale MODIFY COLUMN IF EXISTS isPicked tinyint(1) DEFAULT 1 NOT NULL;

View File

@ -0,0 +1,2 @@
ALTER TABLE vn.state DROP FOREIGN KEY state_ibfk_1;
ALTER TABLE vn.state ADD CONSTRAINT state_ibfk_1 FOREIGN KEY (alertLevel) REFERENCES vn.alertLevel(id) ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -0,0 +1,8 @@
ALTER TABLE dipole.expedition_PrintOut ADD isChecked BOOL DEFAULT FALSE NOT NULL COMMENT 'Indica si la expedición ha sido revisada por un revisor';
DELETE FROM salix.ACL
WHERE model = 'Expedition_PrintOut';
INSERT INTO salix.ACL ( model, property, accessType, permission, principalType, principalId)
VALUES( 'Expedition_PrintOut', '*', '*', 'ALLOW', 'ROLE', 'production');

View File

@ -1,5 +1,4 @@
const UserError = require('vn-loopback/util/user-error');
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
module.exports = Self => {

View File

@ -10,7 +10,7 @@
auto-load="true"
url="Countries"
data="countries"
order="country">
order="name">
</vn-crud-model>
<vn-crud-model
auto-load="true"

View File

@ -1,6 +1,6 @@
module.exports = Self => {
Self.remoteMethodCtx('itemShelvingSaleSetQuantity', {
description: 'Set quanitity of a sale in itemShelvingSale',
description: 'Set quantity of a sale in itemShelvingSale',
accessType: 'WRITE',
accepts: [
{
@ -20,6 +20,12 @@ module.exports = Self => {
type: 'boolean',
required: true,
description: 'True if the shelvingFk is empty ',
},
{
arg: 'sectorFk',
type: 'number',
required: true,
description: 'Sector Id',
}
],
http: {
@ -28,14 +34,14 @@ module.exports = Self => {
}
});
Self.itemShelvingSaleSetQuantity = async(ctx, id, quantity, isItemShelvingSaleEmpty, options) => {
Self.itemShelvingSaleSetQuantity = async(ctx, id, quantity, isItemShelvingSaleEmpty, sectorFk, options) => {
const myOptions = {userId: ctx.req.accessToken.userId};
if (typeof options == 'object')
Object.assign(myOptions, options);
await Self.rawSql(`CALL vn.itemShelvingSale_setQuantity(?, ?, ? )`,
[id, quantity, isItemShelvingSaleEmpty],
await Self.rawSql(`CALL vn.itemShelvingSale_setQuantity(?, ?, ?, ?)`,
[id, quantity, isItemShelvingSaleEmpty, sectorFk],
myOptions);
};
};

View File

@ -27,28 +27,42 @@ module.exports = Self => {
});
Self.getWasteByItem = async(buyer, family, options) => {
const models = Self.app.models;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const user = await models.VnUser.findOne({
fields: ['id'],
where: {name: buyer}
});
const itemType = await models.ItemType.findOne({
fields: ['id'],
where: {name: family}
}, options);
const date = Date.vnNew();
date.setHours(0, 0, 0, 0);
const wastes = await Self.rawSql(`
SELECT *, 100 * dwindle / total AS percentage
SELECT *, 100 * dwindle / total percentage
FROM (
SELECT buyer,
ws.family,
ws.itemFk,
sum(ws.saleTotal) AS total,
sum(ws.saleWaste) AS dwindle
FROM bs.waste ws
WHERE buyer = ? AND family = ?
AND year = YEAR(TIMESTAMPADD(WEEK,-1, ?))
AND week = WEEK(TIMESTAMPADD(WEEK,-1, ?), 1)
GROUP BY buyer, itemFk
SELECT u.name buyer,
it.name family,
w.itemFk,
SUM(w.saleTotal) total,
SUM(w.saleInternalWaste + w.saleExternalWaste) dwindle
FROM bs.waste w
JOIN account.user u ON u.id = w.buyerFk
JOIN vn.itemType it ON it.id = w.itemTypeFk
WHERE w.buyerFk = ? AND w.itemTypeFk = ?
AND w.year = YEAR(TIMESTAMPADD(WEEK, -1, ?))
AND w.week = WEEK(TIMESTAMPADD(WEEK, -1, ?), 1)
GROUP BY w.buyerFk, w.itemFk
) sub
ORDER BY family, percentage DESC`, [buyer, family, date, date], myOptions);
ORDER BY family, percentage DESC
`, [user.id, itemType.id, date, date], myOptions);
const details = [];

View File

@ -22,31 +22,37 @@ module.exports = Self => {
const date = Date.vnNew();
date.setHours(0, 0, 0, 0);
const wastes = await Self.rawSql(`
SELECT *, 100 * dwindle / total AS percentage
SELECT *, 100 * dwindle / total percentage
FROM (
SELECT buyer,
ws.family,
sum(ws.saleTotal) AS total,
sum(ws.saleWaste) AS dwindle
FROM bs.waste ws
SELECT u.name buyer,
it.name family,
w.itemFk,
SUM(w.saleTotal) total,
SUM(w.saleInternalWaste + w.saleExternalWaste) dwindle
FROM bs.waste w
JOIN account.user u ON u.id = w.buyerFk
JOIN vn.itemType it ON it.id = w.itemTypeFk
WHERE year = YEAR(TIMESTAMPADD(WEEK, -1, ?))
AND week = WEEK(TIMESTAMPADD(WEEK, -1, ?), 1)
GROUP BY buyer, family
GROUP BY buyerFk, itemTypeFk
) sub
ORDER BY percentage DESC`, [date, date], myOptions);
ORDER BY percentage DESC
`, [date, date], myOptions);
const wastesTotal = await Self.rawSql(`
SELECT *, 100 * dwindle / total AS percentage
SELECT *, 100 * dwindle / total percentage
FROM (
SELECT buyer,
sum(ws.saleTotal) AS total,
sum(ws.saleWaste) AS dwindle
FROM bs.waste ws
WHERE year = YEAR(TIMESTAMPADD(WEEK,-1, ?))
AND week = WEEK(TIMESTAMPADD(WEEK,-1, ?), 1)
GROUP BY buyer
SELECT u.name buyer,
SUM(w.saleTotal) total,
SUM(w.saleInternalWaste + w.saleExternalWaste) dwindle
FROM bs.waste w
JOIN account.user u ON u.id = w.buyerFk
WHERE w.year = YEAR(TIMESTAMPADD(WEEK, -1, ?))
AND w.week = WEEK(TIMESTAMPADD(WEEK, -1, ?), 1)
GROUP BY w.buyerFk
) sub
ORDER BY percentage DESC`, [date, date], myOptions);
ORDER BY percentage DESC
`, [date, date], myOptions);
const details = [];

View File

@ -6,13 +6,13 @@ describe('Item getWasteByItem()', () => {
const options = {transaction: tx};
try {
const result = await models.Item.getWasteByItem('CharlesXavier', 'Cymbidium', options);
const result = await models.Item.getWasteByItem('buyer', 'Crisantemo', options);
const length = result.length;
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
expect(anyResult.buyer).toEqual('CharlesXavier');
expect(anyResult.family).toEqual('Cymbidium');
expect(anyResult.buyer).toEqual('buyer');
expect(anyResult.family).toEqual('Crisantemo');
expect(anyResult.lines.length).toBeGreaterThanOrEqual(2);
await tx.rollback();

View File

@ -11,9 +11,9 @@ describe('Item getWasteByWorker()', () => {
const length = result.length;
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
expect(anyResult.buyer).toMatch(/(CharlesXavier|HankPym|DavidCharlesHaller)/);
expect(anyResult.buyer).toMatch(/(buyer|it)/);
expect(anyResult.total).toBeGreaterThanOrEqual(1000);
expect(anyResult.lines.length).toBeGreaterThanOrEqual(3);
expect(anyResult.lines.length).toBeGreaterThanOrEqual(1);
await tx.rollback();
} catch (e) {

View File

@ -2,9 +2,10 @@ const {models} = require('vn-loopback/server/server');
describe('itemMinimumQuantity model', () => {
const itemFk = 5;
const quantity = 100;
const warehouseFk = 60;
beforeAll(async() => {
beforeEach(async() => {
await models.ItemMinimumQuantity.destroyAll({where: {itemFk: itemFk}});
});
@ -12,7 +13,7 @@ describe('itemMinimumQuantity model', () => {
it('should create a new itemMinimumQuantity record', async() => {
const newRecord = {
itemFk: itemFk,
quantity: 100,
quantity: quantity,
started: Date.vnNew(),
ended: new Date(Date.vnNew().setFullYear(Date.vnNew().getFullYear() + 1)),
warehouseFk: warehouseFk
@ -27,7 +28,7 @@ describe('itemMinimumQuantity model', () => {
it('should read an existing itemMinimumQuantity record', async() => {
const newRecord = {
itemFk: itemFk,
quantity: 100,
quantity: quantity,
started: Date.vnNew(),
ended: new Date(Date.vnNew().setFullYear(Date.vnNew().getFullYear() + 2)),
warehouseFk: warehouseFk
@ -44,7 +45,7 @@ describe('itemMinimumQuantity model', () => {
it('should update an existing itemMinimumQuantity record', async() => {
const newRecord = {
itemFk: itemFk,
quantity: 100,
quantity: quantity,
started: Date.vnNew(),
ended: new Date(Date.vnNew().setFullYear(Date.vnNew().getFullYear() + 3)),
warehouseFk: warehouseFk
@ -67,7 +68,7 @@ describe('itemMinimumQuantity model', () => {
it('should enforce unique constraint on itemFk, started, ended, and warehouseFk', async() => {
const newRecord = {
itemFk: itemFk,
quantity: 100,
quantity: quantity,
started: Date.vnNew(),
ended: Date.vnNew().setFullYear(Date.vnNew().getFullYear() + 5),
warehouseFk: warehouseFk
@ -78,14 +79,14 @@ describe('itemMinimumQuantity model', () => {
await models.ItemMinimumQuantity.create(newRecord);
} catch (e) {
expect(e).toBeDefined();
expect(e.code).toContain('ER_DUP_ENTRY');
expect(e.code).toContain('ER_SIGNAL_EXCEPTION');
}
});
it('should allow null values for ended and warehouseFk', async() => {
const newRecord = {
itemFk: itemFk,
quantity: 100,
quantity: quantity,
started: Date.vnNew(),
ended: null,
warehouseFk: null

View File

@ -1,121 +1,2 @@
<vn-crud-model
vn-id="model"
url="Items/getBalance"
filter="$ctrl.filter"
data="sales"
auto-load="false">
</vn-crud-model>
<vn-crud-model
auto-load="true"
url="Warehouses"
data="warehouses"
order="name"
vn-id="warehouse-model">
</vn-crud-model>
<vn-vertical>
<vn-card class="vn-pa-lg vn-w-lg">
<vn-vertical>
<vn-horizontal>
<vn-autocomplete
vn-focus
data="warehouses"
show-field="name"
value-field="id"
initial-data="$ctrl.warehouseFk"
ng-model="$ctrl.warehouseFk"
label="Select warehouse">
</vn-autocomplete>
<vn-check
ng-class="{'table-check':$ctrl.showOld}"
label="Show what's before the inventory"
ng-model="$ctrl.showOld">
</vn-check>
<vn-date-picker
label="Since"
ng-model="$ctrl.date"
ng-show="$ctrl.showOld">
</vn-date-picker>
</vn-horizontal>
<vn-table model="model">
<vn-thead>
<vn-tr>
<vn-th shrink></vn-th>
<vn-th expand>Date</vn-th>
<vn-th number order="DESC" shrink>Id</vn-th>
<vn-th>State</vn-th>
<vn-th>Reference</vn-th>
<vn-th expand>Client</vn-th>
<vn-th number>In</vn-th>
<vn-th number>Out</vn-th>
<vn-th number>Balance</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr
ng-class="::{
'isIn': sale.invalue,
'balanceNegative': sale.balance < 0}"
ng-repeat="sale in sales"
vn-repeat-last
on-last="$ctrl.scrollToLine(sale.lastPreparedLineFk)"
ng-attr-id="vnItemDiary-{{::sale.lineFk}}">
<vn-td shrink>
<a ui-sref="claim.card.summary({id: sale.claimFk})">
<vn-icon icon="icon-claims"
ng-show="sale.claimFk"
vn-tooltip="{{::$ctrl.$t('Claim')}}: {{::sale.claimFk}}">
</vn-icon>
</a>
</vn-td>
<vn-td expand>
<span class="chip"
ng-class="::{warning: $ctrl.today == sale.shipped}">
{{::sale.shipped | date:'dd/MM/yyyy' }}
</span>
</vn-td>
<vn-td number shrink>
<span class="link"
ng-click="$ctrl.showDescriptor($event, sale)"
name="origin">
{{::sale.origin | dashIfEmpty}}
</span>
</vn-td>
<vn-td>{{::sale.stateName | dashIfEmpty}}</vn-td>
<vn-td>{{::sale.reference | dashIfEmpty}}</vn-td>
<vn-td class="truncate" expand>
<span ng-class="::{'warning chip': sale.highlighted}">
<span ng-if="::!sale.isTicket">
{{::sale.name | dashIfEmpty}}
</span>
<span
ng-if="::sale.isTicket"
vn-click-stop="clientDescriptor.show($event, sale.clientFk)"
class="link">
{{::sale.name | dashIfEmpty}}
</span>
</span>
</vn-td>
<vn-td number class="in">{{::sale.invalue | dashIfEmpty}}</vn-td>
<vn-td number>{{::sale.out | dashIfEmpty}}</vn-td>
<vn-td number class="balance">
<span class="chip balanceSpan"
ng-class="::{message: sale.lineFk == sale.lastPreparedLineFk}">
{{::sale.balance | dashIfEmpty}}
</span>
</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
</vn-vertical>
<vn-card>
</vn-card>
</vn-vertical>
<vn-ticket-descriptor-popover
vn-id="ticket-descriptor">
</vn-ticket-descriptor-popover>
<vn-client-descriptor-popover
vn-id="clientDescriptor">
</vn-client-descriptor-popover>
<vn-entry-descriptor-popover
vn-id="entryDescriptor">
</vn-entry-descriptor-popover>

View File

@ -1,107 +1,21 @@
import ngModule from '../module';
import Section from 'salix/components/section';
import './style.scss';
class Controller extends Section {
constructor($element, $scope, $anchorScroll, $location) {
super($element, $scope);
this.$anchorScroll = $anchorScroll;
this.$location = $location;
let today = Date.vnNew();
today.setHours(0, 0, 0, 0);
this.today = today.toJSON();
constructor($element, $) {
super($element, $);
}
get item() {
return this._item;
}
set item(value) {
this._item = value;
this.filter = {
where: {itemFk: this.$params.id}
};
this.$.$applyAsync(() => {
if (this.$params.warehouseFk)
this.warehouseFk = this.$params.warehouseFk;
else if (value)
this.warehouseFk = this.vnConfig.warehouseFk;
if (this.$params.lineFk)
this.lineFk = this.$params.lineFk;
});
}
set warehouseFk(value) {
if (value && value != this._warehouseFk) {
this._warehouseFk = value;
this.card.warehouseFk = value;
this.filter.where.warehouseFk = this.warehouseFk;
this.$.model.refresh();
async $onInit() {
this.$state.go('item.card.summary', {id: this.$params.id});
window.location.href = await this.vnApp.getUrl(`item/${this.$params.id}/diary`);
}
}
get warehouseFk() {
return this._warehouseFk;
}
set date(value) {
this._date = value;
this.filter.where.date = value;
this.filter.where.warehouseFk = this.warehouseFk;
this.$.model.refresh();
}
get date() {
return this._date;
}
set showOld(value) {
this._showOld = value;
if (!this._showOld) this.date = null;
else this.date = new Date();
}
get showOld() {
return this._showOld;
}
scrollToLine(lineFk) {
this.$.$applyAsync(() => {
const hashFk = this.lineFk || lineFk;
const hash = `vnItemDiary-${hashFk}`;
this.$location.hash(hash);
this.$anchorScroll();
});
}
showDescriptor(event, sale) {
let descriptor = 'entryDescriptor';
if (sale.isTicket)
descriptor = 'ticketDescriptor';
this.$[descriptor].show(event.target, sale.origin);
}
$onDestroy() {
if (this.$state.getCurrentPath()[2].state.name === 'item')
this.card.reload();
}
}
Controller.$inject = ['$element', '$scope', '$anchorScroll', '$location'];
ngModule.vnComponent('vnItemDiary', {
template: require('./index.html'),
controller: Controller,
bindings: {
item: '<'
},
require: {
card: '?^vnItemCard'
}
});

View File

@ -1,99 +0,0 @@
import './index.js';
import crudModel from 'core/mocks/crud-model';
describe('Item', () => {
describe('Component vnItemDiary', () => {
let $scope;
let controller;
beforeEach(ngModule('item'));
beforeEach(inject(($componentController, $rootScope) => {
$scope = $rootScope.$new();
const $element = angular.element('<vn-item-diary></vn-item-diary>');
controller = $componentController('vnItemDiary', {$element, $scope});
controller.$.model = crudModel;
controller.$params = {id: 1};
controller.card = {};
}));
describe('set item()', () => {
it('should set warehouseFk property based on itemType warehouseFk', () => {
jest.spyOn(controller.$, '$applyAsync');
controller.vnConfig = {warehouseFk: 1};
controller.item = {id: 1};
expect(controller.$.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
$scope.$apply();
expect(controller.warehouseFk).toEqual(1);
expect(controller.item.id).toEqual(1);
});
it(`should set warehouseFk property based on url query warehouseFk`, () => {
jest.spyOn(controller.$, '$applyAsync');
controller.$params.warehouseFk = 4;
controller.item = {id: 1, itemType: {warehouseFk: 1}};
expect(controller.$.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
$scope.$apply();
expect(controller.warehouseFk).toEqual(4);
expect(controller.item.id).toEqual(1);
});
});
describe('scrollToLine ()', () => {
it('should assign $location then call anchorScroll using controller value', () => {
jest.spyOn(controller, '$anchorScroll');
controller.lineFk = 1;
controller.scrollToLine('invalidValue');
$scope.$apply();
expect(controller.$location.hash()).toEqual(`vnItemDiary-${1}`);
expect(controller.$anchorScroll).toHaveBeenCalledWith();
});
it('should assign $location then call anchorScroll using received value', () => {
jest.spyOn(controller, '$anchorScroll');
controller.lineFk = undefined;
controller.scrollToLine(1);
$scope.$apply();
expect(controller.$location.hash()).toEqual(`vnItemDiary-${1}`);
expect(controller.$anchorScroll).toHaveBeenCalledWith();
});
});
describe('showDescriptor ()', () => {
it('should call to the entryDescriptor show() method', () => {
controller.$.entryDescriptor = {};
controller.$.entryDescriptor.show = jest.fn();
const $event = new Event('click');
const target = document.createElement('div');
target.dispatchEvent($event);
const data = {id: 1, origin: 1};
controller.showDescriptor($event, data);
expect(controller.$.entryDescriptor.show).toHaveBeenCalledWith($event.target, data.origin);
});
it('should call to the ticketDescriptor show() method', () => {
controller.$.ticketDescriptor = {};
controller.$.ticketDescriptor.show = jest.fn();
const $event = new Event('click');
const target = document.createElement('div');
target.dispatchEvent($event);
const data = {id: 1, origin: 1, isTicket: true};
controller.showDescriptor($event, data);
expect(controller.$.ticketDescriptor.show).toHaveBeenCalledWith($event.target, data.origin);
});
});
});
});

View File

@ -1,5 +0,0 @@
In: Entrada
Out: Salida
Visible quantity: Cantidad visible
Ticket/Entry: Ticket/Entrada
Show what's before the inventory: Mostrar lo anterior al inventario

View File

@ -1,33 +0,0 @@
@import "variables";
vn-item-diary {
& > vn-vertical {
display: block;
}
vn-horizontal {
justify-content: center;
}
vn-autocomplete > div {
width: 400px;
}
.balanceNegative .balance {
color: $color-alert;
}
.isIn .in {
color: $color-success;
font-weight: bold;
}
.isToday .date {
color: white;
background-color: $color-main;
}
.truncate {
max-width: 250px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.table-check{
justify-content: center;
}
}

View File

@ -48,7 +48,7 @@ module.exports = Self => {
LEFT JOIN vn.expeditionStateType est ON est.id = e.stateTypeFk
JOIN vn.agencyMode am ON am.id = r.agencyModeFk
JOIN vn.agency ag ON ag.id = am.agencyFk
LEFT JOIN vn.userConfig uc ON uc.userFk = account.myUser_getId()
LEFT JOIN vn.userMultiConfig uc ON uc.userFk = account.myUser_getId()
WHERE t.routeFk = ?
GROUP BY t.addressFk, e.itemPackingTypeFk
) sub

View File

@ -27,11 +27,8 @@ module.exports = Self => {
const deletedExpeditions = [];
for (let expeditionId of expeditionIds) {
const filter = {
fields: [],
where: {
id: expeditionId
},
try {
const expedition = await models.Expedition.findById(expeditionId, {
include: [
{
relation: 'agencyMode',
@ -40,27 +37,23 @@ module.exports = Self => {
}
}
]
};
const expedition = await models.Expedition.findOne(filter);
});
const {code} = expedition.agencyMode();
let isDeleted = true;
if (code?.toLowerCase()?.includes('mrw')) {
if (code?.toLowerCase()?.includes('mrw') && expedition.externalId) {
const result = await models.MrwConfig.cancelShipment(expeditionId);
isDeleted = result;
if (!result) throw new Error('not deleted');
}
if (code?.toLowerCase()?.substring(0, 10) == 'viaexpress') {
const result = await models.ViaexpressConfig.deleteExpedition(expeditionId);
if (result !== 'true') isDeleted = false;
if (result !== 'true') throw new Error('not deleted');
}
if (!isDeleted)
notDeletedExpeditions.push(expeditionId);
else {
const deletedExpedition = await models.Expedition.destroyById(expeditionId);
deletedExpeditions.push(deletedExpedition);
} catch (e) {
notDeletedExpeditions.push(expeditionId);
}
}

View File

@ -71,7 +71,8 @@ module.exports = Self => {
JSON_ARRAYAGG(
JSON_OBJECT(
'ticketId', ticketFk,
'reason', reason
'reason', reason,
'clientId', clientFk
)
)
)errors
@ -83,7 +84,8 @@ module.exports = Self => {
IF(hasErrorDeleted, 'Eliminado', NULL),
IF(hasErrorItemTaxCountry, 'Impuesto no informado', NULL),
IF(hasErrorAddress, 'Sin dirección', NULL),
IF(hasErrorInfoTaxAreaWorld, 'Datos exportaciones', NULL)) reason
IF(hasErrorInfoTaxAreaWorld, 'Datos exportaciones', NULL)) reason,
clientFk
FROM (
SELECT t.id ticketFk,
SUM(NOT c.hasToInvoice) hasErrorToInvoice,
@ -93,7 +95,8 @@ module.exports = Self => {
SUM(a.id IS NULL) hasErrorAddress,
SUM(ios.code IS NOT NULL
AND(ad.customsAgentFk IS NULL
OR ad.incotermsFk IS NULL)) hasErrorInfoTaxAreaWorld
OR ad.incotermsFk IS NULL)) hasErrorInfoTaxAreaWorld,
t.clientFk clientFk
FROM ticket t
LEFT JOIN address ad ON ad.id = t.addressFk
JOIN sale s ON s.ticketFk = t.id

View File

@ -51,23 +51,23 @@ module.exports = Self => {
fields: ['id']
});
async function setLocation(ticketId) {
async function setLocation() {
await models.Delivery.create({
ticketFk: ticketId,
ticketFk: ticket.id,
longitude: location.Longitude,
latitude: location.Latitude,
dated: signedTime || new Date()
}, myOptions);
}
async function hasSignDms(ticketId) {
async function hasSignDms() {
const hasTicketDms = await Self.rawSql(`
SELECT d.id
FROM ticketDms td
JOIN dms d ON d.id = td.dmsFk
WHERE td.ticketFk = ?
AND d.dmsTypeFk = ?
`, [ticketId, dmsTypeTicket.id], myOptions);
`, [ticket.id, dmsTypeTicket.id], myOptions);
if (hasTicketDms.length) return true;
}
@ -133,9 +133,9 @@ module.exports = Self => {
if (await ticket.isSigned)
throw new UserError('Ticket is already signed');
if (location) await setLocation(ticketId);
if (!await hasSignDms(ticketId) && !isSignUploaded)
await createGestDoc(ticketId);
if (location) await setLocation();
if (!await hasSignDms() && !isSignUploaded)
await createGestDoc();
if (isSignUploaded)
await models.TicketDms.create({ticketFk: ticket.id, dmsFk: dms[0].id}, myOptions);
await ticket.updateAttribute('isSigned', true, myOptions);

View File

@ -165,8 +165,8 @@ module.exports = Self => {
const sql = ParameterizedSQL.join(stmts, ';');
const days = await conn.executeStmt(sql, myOptions);
let previousWorkerFk = days[index][0].workerFk;
let previousReceiver = days[index][0].receiver;
let previousWorkerFk = days[index][0]?.workerFk;
let previousReceiver = days[index][0]?.receiver;
const workerTimeControlConfig = await models.WorkerTimeControlConfig.findOne(null, myOptions);

View File

@ -61,7 +61,7 @@ module.exports = Self => {
const url = `${salix.url}worker/${args.workerId}/time-control?timestamp=${timestamp}`;
ctx.args.url = url;
await models.WorkerTimeControl.updateMailState(ctx, ctx.workerId, myOptions);
await models.WorkerTimeControl.updateMailState(ctx, ctx.args.workerId, myOptions);
return Self.sendTemplate(ctx, 'weekly-hour-record');
};

View File

@ -380,7 +380,6 @@ class Controller extends Section {
updateWorkerTimeControlMail(state, reason) {
const params = {
workerId: this.worker.id,
year: this.date.getFullYear(),
week: this.weekNumber,
state
@ -389,7 +388,7 @@ class Controller extends Section {
if (reason)
params.reason = reason;
const query = `WorkerTimeControls/updateWorkerTimeControlMail`;
const query = `WorkerTimeControls/${this.worker.id}/updateMailState`;
this.$http.post(query, params).then(() => {
this.getMailStates(this.date);
this.getWeekData();

View File

@ -201,7 +201,7 @@ describe('Component vnWorkerTimeControl', () => {
controller.date = today;
controller.weekNumber = 1;
$httpBackend.expect('POST', 'WorkerTimeControls/updateWorkerTimeControlMail').respond();
$httpBackend.expect('POST', 'WorkerTimeControls/1/updateMailState').respond();
controller.isSatisfied();
$httpBackend.flush();
@ -236,7 +236,7 @@ describe('Component vnWorkerTimeControl', () => {
controller.weekNumber = 1;
controller.reason = 'reason';
$httpBackend.expect('POST', 'WorkerTimeControls/updateWorkerTimeControlMail').respond();
$httpBackend.expect('POST', 'WorkerTimeControls/1/updateMailState').respond();
controller.isSatisfied();
$httpBackend.flush();

View File

@ -42,7 +42,7 @@ fixtures:
- ACL
- fieldAcl
- module
- defaultViewConfig
- defaultViewMultiConfig
vn:
- alertLevel
- bookingPlanner
@ -363,7 +363,7 @@ localFixtures:
- travelConfig
- travelRecalc
- travelThermograph
- userConfig
- userMultiConfig
- vehicle
- wagonConfig
- wagonType

View File

@ -1,11 +1,13 @@
SELECT *, 100 * dwindle / total AS percentage
SELECT *, 100 * dwindle / total `percentage`
FROM (
SELECT buyer,
sum(saleTotal) as total,
sum(saleWaste) as dwindle
SELECT u.name buyer,
SUM(saleTotal) total,
SUM(w.saleInternalWaste + w.saleExternalWaste) dwindle
FROM bs.waste w
JOIN vn.time t ON w.year = t.year AND w.week = t.week
WHERE t.dated = DATE_ADD(CURDATE(), INTERVAL -1 WEEK)
GROUP BY buyer
JOIN account.user u ON u.id = w.buyerFk
JOIN vn.itemType it ON it.id = w.itemTypeFk
WHERE w.year = YEAR(util.VN_CURDATE() - INTERVAL 1 WEEK)
AND w.week = WEEK(util.VN_CURDATE() - INTERVAL 1 WEEK, 4)
GROUP BY buyerFk
) sub
ORDER BY percentage DESC;
ORDER BY `percentage` DESC;

View File

@ -7,6 +7,7 @@
<div v-for="ticket in tickets" class="grid-block vn-px-ml">
<p v-if="ticket.ticketId"><b>{{ $t('ticketId') }}:</b> {{ticket.ticketId}}</p>
<p v-if="ticket.reason"><b>{{ $t('reason') }}:</b> {{ticket.reason}}</p>
<p v-if="ticket.clientId"><b>{{ $t('clientId')}}</b>{{ticket.clientId}}</p>
<hr>
</div>
</div>

View File

@ -2,3 +2,4 @@ subject: Nightly ticket closing process report
title: Nightly ticket closing process report
reason: Reason
ticketId: Ticket
clientId: Client

View File

@ -2,3 +2,4 @@ subject: Informe proceso de cierre de tickets nocturno
title: Informe proceso de cierre de tickets nocturno
reason: Motivo
ticketId: Ticket
clientId: Cliente

View File

@ -0,0 +1,16 @@
subject: Bank Direct Debit Request
title: SEPA CORE Direct Debit
description:
dear: Dear Customer
instructions: <p>Given the excellent relationship between our two companies
and to facilitate the payment processes of our invoices, we suggest the use
of the SEPA CORE direct debit system.</p>
<p>This service involves issuing our receipts to your company in an automated
and electronic manner, which represents a substantial reduction in costs for you
in terms of fees and bank charges.</p>
<p>If you accept our proposal, on the due date of each payment, it will be automatically
debited from your account through your bank.</p>
<p>This system is based on the electronic transmission of data; the handling of
physical documents has been eliminated.</p>
<p>We appreciate your cooperation,</p>
conclusion: Thank you for your attention!

View File

@ -9,9 +9,7 @@ description:
forma automatizada y electrónicamente, lo que supone para usted una reducción
sustancial de costos en términos de honorarios y gastos bancarios.</p>
<p>En caso de que acepte nuestra propuesta, a la fecha de vencimiento de cada efecto,
se debitará a su cuenta automáticamente a través de su entidad bancaria.
Por tanto, le pedimos que firme y envíe a su banco la autorización original adjunta,
debidamente cumplimentada, y nos devuelva una fotocopia de dicha autorización.</p>
se debitará a su cuenta automáticamente a través de su entidad bancaria.</p>
<p>Este sistema se basa en la transmisión electrónica de datos;
el manejo de documentos físicos ha sido eliminado.</p>
<p>Le agradecemos su cooperación,</p>

View File

@ -14,11 +14,7 @@ description:
et commissions bancaires.</p>
<p>Dans le cas où vous accepteriez notre proposition, à
léchéance de chaque effet, votre compte sera débité
automatiquement par votre Banque.
Ainsi, nous vous demandons de signer et envoyer à votre
Banque l'original de l'autorisation pour débit en annexe,
dûment remplie, et de nous retourner une photocopie de la
dite autorisation.</p>
automatiquement par votre Banque.</p>
<p>Ce système étant basé sur la transmission de données de
manière électronique, le maniement de documents
physiques á été éliminé</p>

View File

@ -0,0 +1,46 @@
reportName: direct-debit-order
title: SEPA CORE Direct Debit Order
description: By signing this direct debit order, the debtor authorizes (A) the creditor
to send instructions to the debtor's bank to debit their account and (B) the bank to debit
their account according to the creditor's instructions. As part of their rights,
the debtor is entitled to a refund by their bank under the terms and conditions
of the contract signed with the bank. The refund request must be made within
eight weeks of the debit. You can obtain additional information about your rights
from your financial institution.
documentCopy: You must take a signed copy of this document to your Bank for registration to avoid returns.
mandatoryFields: ALL FIELDS MUST BE COMPLETED.
sendOrder: ONCE THIS DIRECT DEBIT ORDER IS SIGNED, IT MUST BE SENT TO THE CREDITOR
FOR SAFEGUARDING AND IT IS RECOMMENDED TO PROVIDE A COPY TO YOUR BANK.
supplier:
toCompleteBySupplier: To be completed by the creditor
orderReference: Direct debit order reference
identifier: Creditor identifier
name: Creditor's name
street: Address
location: Postal Code - City - Province
country: Country
client:
toCompleteByClient: To be completed by the debtor
name: Debtor's name(s)
fiscalId: NIF
street: Debtor's address
location: Postal Code - City - Province
country: Debtor's country
swift: Swift BIC
accountNumber: IBAN
accountHolder: "(Account holder(s))"
accountNumberFormat: In {0}, the IBAN consists of {1} characters always starting with {2}
paymentType: Payment type
recurrent: Recurrent
unique: Unique
signLocation: Date - City
sign: Debtor's signature and stamp
order: Direct Debit Order {0}
Francia: France
España: Spain
Portugal: Portugal
instructions:
title: Instructions
accountFields: Fill in the fields related to the bank account
signDocument: Sign and stamp the document. For it to be valid, the stamp must show the CIF/NIF. If not, the request must be accompanied by an account ownership certificate.
thanks: Thank you for your cooperation!

View File

@ -1,13 +1,12 @@
const vnReport = require('../../../core/mixins/vn-report.js');
const db = require('../../../core/database');
module.exports = {
name: 'sepa-core',
mixins: [vnReport],
async serverPrefetch() {
this.client = await this.findOneFromDef('client', [this.companyId, this.companyId, this.id]);
this.client = await this.findOneFromDef('client', [this.id]);
this.checkMainEntity(this.client);
const suppliers = await this.rawSqlFromDef('supplier', [this.companyId, this.companyId, this.id]);
const suppliers = await this.rawSqlFromDef('supplier', [this.companyId, this.id]);
this.supplier = {
...suppliers[0],
accountDetailValue: suppliers.map(val => val?.accountDetailValue)
@ -23,16 +22,5 @@ module.exports = {
type: Number,
required: true
}
},
methods: {
getSupplierCif() {
return db.findOne(`
SELECT DISTINCT ad.value
FROM supplierAccount sa
JOIN accountDetail ad ON ad.supplierAccountFk = sa.id
JOIN accountDetailType adt ON adt.id = ad.accountDetailTypeFk AND adt.id = 3
WHERE sa.supplierFk = ?`) [this.companyId];
}
}
};

View File

@ -1,19 +1,14 @@
SELECT
c.id,
m.code mandateCode,
SELECT c.id,
c.socialName,
c.street,
c.postcode,
c.city,
c.fi,
p.name AS province,
p.name province,
ct.name country,
ct.code AS countryCode,
ct.ibanLength AS ibanLength
ct.code countryCode,
ct.ibanLength ibanLength
FROM client c
JOIN country ct ON ct.id = c.countryFk
LEFT JOIN mandate m ON m.clientFk = c.id
AND m.companyFk = ? AND m.finished IS NULL
LEFT JOIN province p ON p.id = c.provinceFk
WHERE (m.companyFk = ? OR m.companyFk IS NULL) AND c.id = ?
ORDER BY m.created DESC LIMIT 1
JOIN province p ON p.id = c.provinceFk
WHERE c.id = ?

View File

@ -1,29 +1,24 @@
SELECT
m.code mandateCode,
SELECT m.code mandateCode,
s.name,
s.street,
sc.name country,
s.postCode,
s.city,
sp.name province,
s.nif,
sa.supplierFk,
be.name bankName,
ad.value accountDetailValue
FROM
client c
LEFT JOIN mandate m ON m.clientFk = c.id AND m.companyFk = ? AND m.finished IS NULL
LEFT JOIN supplier s ON s.id = m.companyFk
FROM client c
JOIN mandate m ON m.clientFk = c.id
JOIN mandateType mt ON mt.id = m.mandateTypeFk
JOIN supplier s ON s.id = m.companyFk
LEFT JOIN country sc ON sc.id = s.countryFk
LEFT JOIN province sp ON sp.id = s.provinceFk
LEFT JOIN province p ON p.id = c.provinceFk
LEFT JOIN supplierAccount sa ON sa.supplierFk = s.id
LEFT JOIN bankEntity be ON sa.bankEntityFk = be.id
LEFT JOIN accountDetail ad ON ad.supplierAccountFk = sa.id
JOIN accountDetailType adt ON adt.id = ad.accountDetailTypeFk AND adt.id = 3
WHERE
(m.companyFk = ? OR m.companyFk IS NULL)
AND (c.id = ? OR (c.id IS NULL AND c.countryFk = sa.countryFk))
GROUP BY ad.value
ORDER BY
m.created DESC;
JOIN supplierAccount sa ON sa.supplierFk = s.id
JOIN accountDetail ad ON ad.supplierAccountFk = sa.id
JOIN accountDetailType adt ON adt.id = ad.accountDetailTypeFk
WHERE m.companyFk = ?
AND m.finished IS NULL
AND c.id = ?
AND mt.name = 'CORE'
AND adt.description = 'Referencia Remesas'
GROUP BY m.id, ad.value
ORDER BY m.created DESC