#7919 delete if ticketRefund #3091
|
@ -19,8 +19,15 @@ module.exports = Self => {
|
|||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
const [info, info2, [{'@vCollectionFk': collectionFk}]] = await Self.rawSql(
|
||||
'CALL vn.collection_getAssigned(?, @vCollectionFk);SELECT @vCollectionFk', [userId], myOptions);
|
||||
|
||||
const randStr = Math.random().toString(36).substring(3);
|
||||
const result = await Self.rawSql(`
|
||||
CALL vn.collection_getAssigned(?, @vCollectionFk);
|
||||
SELECT @vCollectionFk ?
|
||||
`, [userId, randStr], myOptions);
|
||||
|
||||
const collectionFk = result.find(item => item[0]?.[randStr] !== undefined)?.[0]?.[randStr];
|
||||
|
||||
if (!collectionFk) throw new UserError('There are not picking tickets');
|
||||
await Self.rawSql('CALL vn.collection_printSticker(?, NULL)', [collectionFk], myOptions);
|
||||
|
||||
|
|
|
@ -72,9 +72,9 @@ describe('Renew Token', () => {
|
|||
}
|
||||
|
||||
expect(error).toBeDefined();
|
||||
const query = 'SELECT * FROM util.debug';
|
||||
|
||||
const debugLog = await models.Application.rawSql(query, null);
|
||||
const query = 'SELECT * FROM util.debug WHERE variable = "renewToken"';
|
||||
const debugLog = await models.Application.rawSql(query);
|
||||
|
||||
expect(debugLog.length).toEqual(1);
|
||||
});
|
||||
|
|
|
@ -5,100 +5,139 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`collection_getAssigne
|
|||
)
|
||||
BEGIN
|
||||
/**
|
||||
* Comprueba si existen colecciones libres que se ajustan al perfil del usuario
|
||||
* y le asigna la más antigua.
|
||||
* Añade un registro al semillero de colecciones y hace la reserva para la colección
|
||||
* Comprueba si existen colecciones libres que se ajustan
|
||||
* al perfil del usuario y le asigna la más antigua.
|
||||
* Añade un registro al semillero de colecciones.
|
||||
*
|
||||
* @param vUserFk Id de usuario
|
||||
* @param vCollectionFk Id de colección
|
||||
*/
|
||||
DECLARE vHasTooMuchCollections BOOL;
|
||||
DECLARE vItemPackingTypeFk VARCHAR(1);
|
||||
DECLARE vWarehouseFk INT;
|
||||
DECLARE vLockName VARCHAR(215);
|
||||
DECLARE vLockTime INT DEFAULT 30;
|
||||
DECLARE vDone BOOL DEFAULT FALSE;
|
||||
DECLARE vCollectionWorker INT;
|
||||
DECLARE vMaxNotAssignedCollectionLifeTime TIME;
|
||||
|
||||
DECLARE vCollections CURSOR FOR
|
||||
WITH collections AS (
|
||||
SELECT tc.collectionFk,
|
||||
SUM(sv.volume) volume,
|
||||
c.saleTotalCount,
|
||||
c.itemPackingTypeFk,
|
||||
c.trainFk,
|
||||
c.warehouseFk,
|
||||
c.wagons
|
||||
FROM vn.ticketCollection tc
|
||||
JOIN vn.collection c ON c.id = tc.collectionFk
|
||||
JOIN vn.saleVolume sv ON sv.ticketFk = tc.ticketFk
|
||||
WHERE c.workerFk IS NULL
|
||||
AND sv.shipped >= util.VN_CURDATE()
|
||||
GROUP BY tc.collectionFk
|
||||
) SELECT c.collectionFk
|
||||
FROM collections c
|
||||
JOIN vn.operator o
|
||||
WHERE o.workerFk = vUserFk
|
||||
AND (c.saleTotalCount <= o.linesLimit OR o.linesLimit IS NULL)
|
||||
AND (c.itemPackingTypeFk = o.itemPackingTypeFk OR o.itemPackingTypeFk IS NULL)
|
||||
AND o.numberOfWagons = c.wagons
|
||||
AND o.trainFk = c.trainFk
|
||||
AND o.warehouseFk = c.warehouseFk;
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
|
||||
-- Si hay colecciones sin terminar, sale del proceso
|
||||
|
||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||
BEGIN
|
||||
IF vLockName IS NOT NULL THEN
|
||||
DO RELEASE_LOCK(vLockName);
|
||||
END IF;
|
||||
|
||||
ROLLBACK;
|
||||
RESIGNAL;
|
||||
END;
|
||||
|
||||
-- Si hay colecciones sin terminar, sale del proceso
|
||||
CALL collection_get(vUserFk);
|
||||
|
||||
SELECT (pc.maxNotReadyCollections - COUNT(*)) <= 0,
|
||||
pc.collection_assign_lockname
|
||||
INTO vHasTooMuchCollections,
|
||||
vLockName
|
||||
FROM tmp.collection c
|
||||
JOIN productionConfig pc;
|
||||
SELECT (pc.maxNotReadyCollections - COUNT(*)) <= 0, pc.maxNotAssignedCollectionLifeTime
|
||||
INTO vHasTooMuchCollections, vMaxNotAssignedCollectionLifeTime
|
||||
FROM productionConfig pc
|
||||
LEFT JOIN tmp.collection ON TRUE;
|
||||
|
||||
DROP TEMPORARY TABLE tmp.collection;
|
||||
|
||||
IF vHasTooMuchCollections THEN
|
||||
CALL util.throw('There are pending collections');
|
||||
END IF;
|
||||
|
||||
SELECT warehouseFk, itemPackingTypeFk
|
||||
INTO vWarehouseFk, vItemPackingTypeFk
|
||||
FROM operator
|
||||
WHERE workerFk = vUserFk;
|
||||
|
||||
SET vLockName = CONCAT_WS('/',
|
||||
vLockName,
|
||||
vWarehouseFk,
|
||||
vItemPackingTypeFk
|
||||
);
|
||||
|
||||
IF NOT GET_LOCK(vLockName, vLockTime) THEN
|
||||
CALL util.throw(CONCAT('Cannot get lock: ', vLockName));
|
||||
CALL util.throw('Hay colecciones pendientes');
|
||||
END IF;
|
||||
|
||||
-- Se eliminan las colecciones sin asignar que estan obsoletas
|
||||
|
||||
INSERT INTO ticketTracking(stateFk, ticketFk)
|
||||
SELECT s.id, tc.ticketFk
|
||||
FROM collection c
|
||||
FROM `collection` c
|
||||
JOIN ticketCollection tc ON tc.collectionFk = c.id
|
||||
JOIN state s ON s.code = 'PRINTED_AUTO'
|
||||
JOIN productionConfig pc
|
||||
JOIN `state` s ON s.code = 'PRINTED_AUTO'
|
||||
WHERE c.workerFk IS NULL
|
||||
AND TIMEDIFF(util.VN_NOW(), c.created) > pc.maxNotAssignedCollectionLifeTime;
|
||||
AND TIMEDIFF(util.VN_NOW(), c.created) > vMaxNotAssignedCollectionLifeTime;
|
||||
|
||||
DELETE c
|
||||
FROM collection c
|
||||
JOIN productionConfig pc
|
||||
WHERE c.workerFk IS NULL
|
||||
AND TIMEDIFF(util.VN_NOW(), c.created) > pc.maxNotAssignedCollectionLifeTime;
|
||||
DELETE FROM `collection`
|
||||
WHERE workerFk IS NULL
|
||||
AND TIMEDIFF(util.VN_NOW(), created) > vMaxNotAssignedCollectionLifeTime;
|
||||
|
||||
-- Se añade registro al semillero
|
||||
INSERT INTO collectionHotbed
|
||||
SET userFk = vUserFk;
|
||||
|
||||
INSERT INTO collectionHotbed(userFk) VALUES(vUserFk);
|
||||
|
||||
-- Comprueba si hay colecciones disponibles que se ajustan a su configuracion
|
||||
SELECT MIN(c.id) INTO vCollectionFk
|
||||
FROM collection c
|
||||
JOIN operator o ON (o.itemPackingTypeFk = c.itemPackingTypeFk
|
||||
OR c.itemPackingTypeFk IS NULL)
|
||||
AND o.numberOfWagons = c.wagons
|
||||
AND o.trainFk = c.trainFk
|
||||
AND o.warehouseFk = c.warehouseFk
|
||||
AND c.workerFk IS NULL
|
||||
WHERE o.workerFk = vUserFk;
|
||||
|
||||
IF vCollectionFk IS NULL THEN
|
||||
CALL collection_new(vUserFk, vCollectionFk);
|
||||
OPEN vCollections;
|
||||
l: LOOP
|
||||
SET vDone = FALSE;
|
||||
FETCH vCollections INTO vCollectionFk;
|
||||
|
||||
IF vDone THEN
|
||||
LEAVE l;
|
||||
END IF;
|
||||
|
||||
UPDATE collection
|
||||
BEGIN
|
||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||
BEGIN
|
||||
ROLLBACK;
|
||||
SET vCollectionFk = NULL;
|
||||
RESIGNAL;
|
||||
END;
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
SELECT workerFk INTO vCollectionWorker
|
||||
FROM `collection`
|
||||
WHERE id = vCollectionFk FOR UPDATE;
|
||||
|
||||
IF vCollectionWorker IS NULL THEN
|
||||
UPDATE `collection`
|
||||
SET workerFk = vUserFk
|
||||
WHERE id = vCollectionFk;
|
||||
|
||||
CALL itemShelvingSale_addByCollection(vCollectionFk);
|
||||
COMMIT;
|
||||
LEAVE l;
|
||||
END IF;
|
||||
|
||||
DO RELEASE_LOCK(vLockName);
|
||||
ROLLBACK;
|
||||
END;
|
||||
END LOOP;
|
||||
CLOSE vCollections;
|
||||
|
||||
IF vCollectionFk IS NULL THEN
|
||||
CALL collection_new(vUserFk, vCollectionFk);
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
SELECT workerFk INTO vCollectionWorker
|
||||
FROM `collection`
|
||||
WHERE id = vCollectionFk FOR UPDATE;
|
||||
|
||||
IF vCollectionWorker IS NULL THEN
|
||||
UPDATE `collection`
|
||||
SET workerFk = vUserFk
|
||||
WHERE id = vCollectionFk;
|
||||
END IF;
|
||||
|
||||
COMMIT;
|
||||
END IF;
|
||||
CALL itemShelvingSale_addByCollection(vCollectionFk);
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,3 +1,3 @@
|
|||
ALTER TABLE vn.clientObservation
|
||||
ADD COLUMN observationTypeFk TINYINT(3) UNSIGNED NOT NULL,
|
||||
ADD CONSTRAINT clientObservationTypeFk FOREIGN KEY (observationTypeFk) REFERENCES vn.observationType(id);
|
||||
ALTER TABLE vn.clientObservation DROP COLUMN IF EXISTS observationTypeFk;
|
||||
ALTER TABLE vn.clientObservation ADD COLUMN IF NOT EXISTS observationTypeFk TINYINT(3) UNSIGNED NULL;
|
||||
ALTER TABLE vn.clientObservation ADD CONSTRAINT clientObservationTypeFk FOREIGN KEY IF NOT EXISTS (observationTypeFk) REFERENCES vn.observationType(id);
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
/*
|
||||
UPDATE vn.sale
|
||||
SET originalQuantity = quantity
|
||||
WHERE originalQuantity IS NULL
|
||||
*/
|
||||
|
|
|
@ -1 +1 @@
|
|||
-- ALTER TABLE vn.sale MODIFY COLUMN originalQuantity decimal(10,2) DEFAULT 0.00 NOT NULL COMMENT 'Se utiliza para notificar a través de rocket los cambios de quantity';
|
||||
ALTER TABLE vn.sale MODIFY COLUMN originalQuantity decimal(10,2) DEFAULT 0.00 NOT NULL COMMENT 'Se utiliza para notificar a través de rocket los cambios de quantity';
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
ALTER TABLE vn.sector ADD isOnReservationMode tinyint(1) DEFAULT FALSE NULL;
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE `vn`.`ticketConfig`
|
||||
ADD COLUMN `closureDaysAgo` int(11) NOT NULL DEFAULT 2 COMMENT 'Number of days to look back for ticket closure',
|
||||
ADD CONSTRAINT `closureDaysAgo_check` CHECK (`closureDaysAgo` > 0);
|
|
@ -59,6 +59,9 @@
|
|||
"isReserve": {
|
||||
"type": "boolean",
|
||||
"required": true
|
||||
},
|
||||
"isOnReservationMode": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -53,8 +53,9 @@ module.exports = Self => {
|
|||
JOIN province p ON p.id = c.provinceFk
|
||||
JOIN country co ON co.id = p.countryFk
|
||||
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
|
||||
JOIN ticketConfig tc ON TRUE
|
||||
WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered'))
|
||||
AND DATE(t.shipped) BETWEEN ? - INTERVAL 7 DAY AND util.dayEnd(?)
|
||||
AND t.shipped BETWEEN ? - INTERVAL tc.closureDaysAgo DAY AND util.dayEnd(?)
|
||||
AND t.refFk IS NULL
|
||||
GROUP BY t.id
|
||||
`, [toDate, toDate]);
|
||||
|
@ -108,6 +109,7 @@ module.exports = Self => {
|
|||
JOIN alertLevel al ON al.id = ts.alertLevel
|
||||
JOIN client c ON c.id = t.clientFk
|
||||
JOIN province p ON p.id = c.provinceFk
|
||||
JOIN ticketConfig tc ON TRUE
|
||||
LEFT JOIN autonomy a ON a.id = p.autonomyFk
|
||||
JOIN country co ON co.id = p.countryFk
|
||||
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
|
||||
|
@ -116,7 +118,7 @@ module.exports = Self => {
|
|||
LEFT JOIN vn.invoiceOutSerial ios ON ios.taxAreaFk = 'WORLD'
|
||||
AND ios.code = invoiceSerial(t.clientFk, t.companyFk, 'multiple')
|
||||
WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered'))
|
||||
AND DATE(t.shipped) BETWEEN ? - INTERVAL 2 DAY AND util.dayEnd(?)
|
||||
AND t.shipped BETWEEN ? - INTERVAL tc.closureDaysAgo DAY AND util.dayEnd(?)
|
||||
AND t.refFk IS NULL
|
||||
AND IFNULL(a.hasDailyInvoice, co.hasDailyInvoice)
|
||||
GROUP BY ticketFk
|
||||
|
@ -141,9 +143,10 @@ module.exports = Self => {
|
|||
JOIN alertLevel al ON al.id = ts.alertLevel
|
||||
JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||
JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
||||
JOIN ticketConfig tc ON TRUE
|
||||
LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id
|
||||
SET t.routeFk = NULL
|
||||
WHERE DATE(t.shipped) BETWEEN ? - INTERVAL 2 DAY AND util.dayEnd(?)
|
||||
WHERE t.shipped BETWEEN ? - INTERVAL tc.closureDaysAgo DAY AND util.dayEnd(?)
|
||||
AND al.code NOT IN ('DELIVERED', 'PACKED')
|
||||
AND NOT t.packages
|
||||
AND tob.id IS NULL
|
||||
|
|
|
@ -12,10 +12,7 @@ module.exports = async function(ctx, Self, tickets, options) {
|
|||
Object.assign(myOptions, options);
|
||||
|
||||
let tx;
|
||||
// if (!myOptions.transaction) {
|
||||
// tx = await Self.beginTransaction({});
|
||||
// myOptions.transaction = tx;
|
||||
// }
|
||||
// IMPORTANT: Due to its high cost in production, wrapping this process in a transaction may cause timeouts.
|
||||
|
||||
if (tickets.length == 0) return;
|
||||
|
||||
|
|
|
@ -50,9 +50,9 @@ describe('Ticket closure functionality', () => {
|
|||
|
||||
expect(ticketStateBefore.code).not.toBe(ticketStateAfter.code);
|
||||
|
||||
const ticketAfter = await models.TicketState.findById(ticketId, null, options);
|
||||
const ticketAfter = await models.Ticket.findById(ticketId, null, options);
|
||||
|
||||
expect(ticketAfter.refFk).toBeUndefined();
|
||||
expect(ticketAfter.refFk).toBeNull();
|
||||
});
|
||||
|
||||
it('should send Incoterms authorization email on first order', async() => {
|
||||
|
|
|
@ -87,7 +87,7 @@ module.exports = Self => {
|
|||
{
|
||||
relation: 'sector',
|
||||
scope: {
|
||||
fields: ['warehouseFk', 'description'],
|
||||
fields: ['warehouseFk', 'description', 'isOnReservationMode'],
|
||||
}
|
||||
}, {
|
||||
relation: 'printer',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "salix-back",
|
||||
"version": "24.42.0",
|
||||
"version": "24.44.0",
|
||||
"author": "Verdnatura Levante SL",
|
||||
"description": "Salix backend",
|
||||
"license": "GPL-3.0",
|
||||
|
|
Loading…
Reference in New Issue