#2687 - Travel CloneWithEntries #1887
|
@ -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;
|
|
@ -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
|
||||
* @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 ;
|
|
@ -0,0 +1,15 @@
|
|||
DELIMITER $$
|
||||
$$
|
||||
|
||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
los cambios van dentro del create los cambios van dentro del create
jsegarra
commented
Exacto. 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 $$
jsegarra
commented
Corregido Corregido cddd8f7d94713f985c624ae9dfa1d839310dacf2
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `util`.`tx_commit`(IN tx BOOL)
|
||||
BEGIN
|
||||
/**
|
||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
falta * falta *
jsegarra
commented
Corregido 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 ;
|
|
@ -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
jgallego
commented
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 ;
|
|
@ -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 ;
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
no es una fecha, es un almacen
Corregido
fe714aef22
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;