#2687 - Travel CloneWithEntries #1887

Merged
jsegarra merged 20 commits from 2687_travel_cloneWithEntries into dev 2024-01-24 10:55:20 +00:00
7 changed files with 224 additions and 112 deletions

View File

@ -0,0 +1,3 @@
GRANT EXECUTE ON PROCEDURE util.tx_commit TO guest;
GRANT EXECUTE ON PROCEDURE util.tx_rollback TO guest;
GRANT EXECUTE ON PROCEDURE util.tx_start TO guest;

View File

@ -0,0 +1,85 @@
DROP PROCEDURE IF EXISTS vn.travel_cloneWithEntries;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`travel_cloneWithEntries`(
IN vTravelFk INT,
IN vDateStart DATE,
IN vDateEnd DATE,
IN vWarehouseOutFk INT,
IN vWarehouseInFk INT,
IN vRef VARCHAR(255),
IN vAgencyModeFk INT,
OUT vNewTravelFk INT)
BEGIN
/**
* Clona un travel junto con sus entradas y compras
* @param vTravelFk travel plantilla a clonar
* @param vDateStart fecha del shipment del nuevo travel
* @param vDateEnd fecha del landing del nuevo travel
* @param vWarehouseOutFk warehouse del salida del nuevo travel
jsegarra marked this conversation as resolved Outdated

no es una fecha, es un almacen

no es una fecha, es un almacen

Corregido fe714aef22
Nota: está también comentado como fecha en el structure.sql

Corregido fe714aef220bff5b10a06631cf131a1e7e5119ac Nota: está también comentado como fecha en el structure.sql

GRANT EXECUTE ON PROCEDURE util.tx_commit TO guest;
GRANT EXECUTE ON PROCEDURE util.tx_rollback TO guest;
GRANT EXECUTE ON PROCEDURE util.tx_start TO guest;

`GRANT EXECUTE ON PROCEDURE util.tx_commit TO guest;` `GRANT EXECUTE ON PROCEDURE util.tx_rollback TO guest;` `GRANT EXECUTE ON PROCEDURE util.tx_start TO guest;`
* @param vWarehouseInFk warehouse de landing del nuevo travel
* @param vRef referencia del nuevo travel
* @param vAgencyModeFk del nuevo travel
* @param vNewTravelFk id del nuevo travel
*/
DECLARE vNewEntryFk INT;
DECLARE vEvaNotes VARCHAR(255);
DECLARE vDone BOOL;
DECLARE vAuxEntryFk INT;
DECLARE vTx BOOLEAN DEFAULT !@@in_transaction;
DECLARE vRsEntry CURSOR FOR
SELECT e.id
FROM entry e
JOIN travel t ON t.id = e.travelFk
WHERE e.travelFk = vTravelFk;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
CALL util.tx_rollback(vTx);
RESIGNAL;
END;
CALL util.tx_start(vTx);
INSERT INTO travel (shipped, landed, warehouseInFk, warehouseOutFk, agencyModeFk, `ref`, isDelivered, isReceived, m3, cargoSupplierFk, kg,clonedFrom)
SELECT vDateStart, vDateEnd, vWarehouseInFk, vWarehouseOutFk, vAgencyModeFk, vRef, isDelivered, isReceived, m3,cargoSupplierFk, kg,vTravelFk
FROM travel
WHERE id = vTravelFk;
SET vNewTravelFk = LAST_INSERT_ID();
SET vDone = FALSE;
SET @isModeInventory = TRUE;
OPEN vRsEntry;
l: LOOP
SET vDone = FALSE;
FETCH vRsEntry INTO vAuxEntryFk;
IF vDone THEN
LEAVE l;
END IF;
CALL entry_cloneHeader(vAuxEntryFk, vNewEntryFk, vNewTravelFk);
CALL entry_copyBuys(vAuxEntryFk, vNewEntryFk);
SELECT evaNotes INTO vEvaNotes
FROM entry
WHERE id = vAuxEntryFk;
UPDATE entry
SET evaNotes = vEvaNotes
WHERE id = vNewEntryFk;
END LOOP;
SET @isModeInventory = FALSE;
CLOSE vRsEntry;
CALL util.tx_commit(vTx);
END$$
DELIMITER ;

View File

@ -0,0 +1,15 @@
DELIMITER $$
$$
jsegarra marked this conversation as resolved Outdated

los cambios van dentro del create

los cambios van dentro del create

Exacto.
He cogido un archivo creado por un compañero y he visto otro fallo. Había un salto de línea entre END y

Exacto. He cogido un archivo creado por un compañero y he visto otro fallo. Había un salto de línea entre END y $$

Corregido cddd8f7d94

Corregido cddd8f7d94713f985c624ae9dfa1d839310dacf2
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `util`.`tx_commit`(IN tx BOOL)
BEGIN
/**
jsegarra marked this conversation as resolved Outdated

falta *

falta *

Corregido 056dddd212

Corregido 056dddd21229f2c8911c0917555e24bea5a254ad
* Procedimiento para confirmar los cambios asociados a una transacción
*
* @param tx BOOL es true si existe transacción asociada
*/
IF tx THEN
COMMIT;
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,15 @@
DELIMITER $$
$$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `util`.`tx_rollback`(tx BOOL)
BEGIN
/**
jsegarra marked this conversation as resolved Outdated

pon una descripcion en cada uno para que la gente sepa que hace

pon una descripcion en cada uno para que la gente sepa que hace
* Procedimiento para deshacer los cambios asociados a una transacción
*
* @param tx BOOL es true si existe transacción asociada
*/
IF tx THEN
ROLLBACK;
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,17 @@
DELIMITER $$
$$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `util`.`tx_start`(tx BOOL)
BEGIN
/**
* Procedimiento para iniciar una transacción
*
* @param tx BOOL es true si existe transacción asociada
*/
IF tx THEN
START TRANSACTION;
END IF;
END$$
DELIMITER ;

View File

@ -1,6 +1,5 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
const UserError = require('vn-loopback/util/user-error');
const loggable = require('vn-loopback/util/log');
module.exports = Self => {
Self.remoteMethodCtx('cloneWithEntries', {
@ -11,8 +10,9 @@ module.exports = Self => {
type: 'number',
required: true,
description: 'The original travel id',
http: {source: 'path'}
}],
http: {source: 'path'},
},
],
returns: {
type: 'object',
description: 'The new cloned travel id',
@ -24,61 +24,75 @@ module.exports = Self => {
}
});
Self.cloneWithEntries = async(ctx, id) => {
Self.cloneWithEntries = async(ctx, id, options) => {
const conn = Self.dataSource.connector;
const travel = await Self.findById(id, {
fields: [
'id',
'shipped',
'landed',
'warehouseInFk',
'warehouseOutFk',
'agencyModeFk',
'ref'
]
});
const started = Date.vnNew();
const ended = Date.vnNew();
const myOptions = {};
let tx = options?.transaction;
if (!travel)
throw new UserError('Travel not found');
try {
if (typeof options == 'object')
Object.assign(myOptions, options);
let stmts = [];
let stmt;
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
stmt = new ParameterizedSQL(
`CALL travel_cloneWithEntries(?, ?, ?, ?, ?, ?, ?, @vTravelFk)`, [
id,
started,
ended,
travel.warehouseOutFk,
travel.warehouseInFk,
travel.ref,
travel.agencyModeFk
]
);
stmts.push(stmt);
const newTravelIndex = stmts.push('SELECT @vTravelFk AS id') - 1;
const travel = await Self.findById(id, {
fields: [
'id',
'shipped',
'landed',
'warehouseInFk',
'warehouseOutFk',
'agencyModeFk',
'ref'
]
});
const started = Date.vnNew();
const ended = Date.vnNew();
const sql = ParameterizedSQL.join(stmts, ';');
const result = await conn.executeStmt(sql);
const [lastInsert] = result[newTravelIndex];
if (!travel)
throw new UserError('Travel not found');
if (!lastInsert.id)
throw new UserError('Unable to clone this travel');
let stmts = [];
let stmt;
stmt = new ParameterizedSQL(
`CALL travel_cloneWithEntries(?, ?, ?, ?, ?, ?, ?, @vTravelFk)`, [
id,
started,
ended,
travel.warehouseOutFk,
travel.warehouseInFk,
travel.ref,
travel.agencyModeFk
]
);
stmts.push(stmt);
const newTravelIndex = stmts.push('SELECT @vTravelFk AS id') - 1;
const newTravel = await Self.findById(lastInsert.id, {
fields: [
'id',
'shipped',
'landed',
'warehouseInFk',
'warehouseOutFk',
'agencyModeFk',
'ref'
]
});
const sql = ParameterizedSQL.join(stmts, ';');
const result = await conn.executeStmt(sql, myOptions);
const [lastInsert] = result[newTravelIndex];
return newTravel.id;
if (!lastInsert.id)
throw new UserError('Unable to clone this travel');
const newTravel = await Self.findById(lastInsert.id, {
fields: [
'id',
'shipped',
'landed',
'warehouseInFk',
'warehouseOutFk',
'agencyModeFk',
'ref'
]
}, myOptions);
return newTravel.id;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -5,73 +5,36 @@ describe('Travel cloneWithEntries()', () => {
const travelId = 5;
const currentUserId = 1102;
const ctx = {req: {accessToken: {userId: currentUserId}}};
let travelBefore;
let newTravelId;
// afterAll(async() => {
// try {
// const entries = await models.Entry.find({
// where: {
// travelFk: newTravelId
// }
// });
// const entriesId = entries.map(entry => entry.id);
// // Destroy all entries buys
// await models.Buy.destroyAll({
// where: {
// entryFk: {inq: entriesId}
// }
// });
// // Destroy travel entries
// await models.Entry.destroyAll({
// where: {
// travelFk: newTravelId
// }
// });
// // Destroy new travel
// await models.Travel.destroyById(newTravelId);
// // Restore original travel shipped & landed
// const travel = await models.Travel.findById(travelId);
// await travel.updateAttributes({
// shipped: travelBefore.shipped,
// landed: travelBefore.landed
// });
// } catch (error) {
// console.error(error);
// }
// });
it(`should clone the travel and the containing entries`, async() => {
pending('#2687 - Cannot make a data rollback because of the triggers');
const tx = await models.Travel.beginTransaction({
});
const warehouseThree = 3;
const agencyModeOne = 1;
const yesterday = Date.vnNew();
yesterday.setDate(yesterday.getDate() - 1);
try {
const options = {transaction: tx};
newTravelId = await models.Travel.cloneWithEntries(ctx, travelId, options);
const travelEntries = await models.Entry.find({
where: {
travelFk: newTravelId
}
}, options);
const newTravel = await models.Travel.findById(travelId);
travelBefore = await models.Travel.findById(travelId);
await travelBefore.updateAttributes({
shipped: yesterday,
landed: yesterday
});
expect(newTravelId).not.toEqual(travelId);
expect(newTravel.ref).toEqual('fifth travel');
expect(newTravel.warehouseInFk).toEqual(warehouseThree);
expect(newTravel.warehouseOutFk).toEqual(warehouseThree);
expect(newTravel.agencyModeFk).toEqual(agencyModeOne);
expect(travelEntries.length).toBeGreaterThan(0);
newTravelId = await models.Travel.cloneWithEntries(ctx, travelId);
const travelEntries = await models.Entry.find({
where: {
travelFk: newTravelId
}
});
await tx.rollback();
const travelRemoved = await models.Travel.findById(newTravelId, options);
const newTravel = await models.Travel.findById(travelId);
expect(newTravelId).not.toEqual(travelId);
expect(newTravel.ref).toEqual('fifth travel');
expect(newTravel.warehouseInFk).toEqual(warehouseThree);
expect(newTravel.warehouseOutFk).toEqual(warehouseThree);
expect(newTravel.agencyModeFk).toEqual(agencyModeOne);
expect(travelEntries.length).toBeGreaterThan(0);
expect(travelRemoved).toBeNull();
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
});
});