diff --git a/db/changes/10141-zoneDoCalc/00-ticket.sql b/db/changes/10141-zoneDoCalc/00-ticket.sql new file mode 100644 index 000000000..c116e5139 --- /dev/null +++ b/db/changes/10141-zoneDoCalc/00-ticket.sql @@ -0,0 +1,19 @@ +ALTER TABLE `vn`.`ticket` +ADD COLUMN `zonePrice` DECIMAL(10,2) NULL DEFAULT NULL AFTER `collectionFk`, +ADD COLUMN `zoneBonus` DECIMAL(10,2) NULL DEFAULT NULL AFTER `zonePrice`, +ADD COLUMN `zoneClosure` TIME NULL AFTER `zoneBonus`; + +CREATE TABLE vn.`zoneCalcTicket` ( + `zoneFk` int(11) NOT NULL PRIMARY KEY, + CONSTRAINT `zoneCalcTicketfk_1` FOREIGN KEY (`zoneFk`) REFERENCES `zone` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +DROP EVENT IF EXISTS vn.`zone_doCalc`; +CREATE DEFINER=`root`@`%` EVENT vn.`zone_doCalc` + ON SCHEDULE EVERY 15 SECOND STARTS '2020-01-31 11:32:30' + ON COMPLETION PRESERVE ENABLE + DO CALL util.procNoOverlap('vn.zone_doCalc'); + +DROP TABLE `vn`.`zoneConfig`; + +DROP procedure IF EXISTS vn.`zoneClosure_recalc`; \ No newline at end of file diff --git a/db/changes/10141-zoneDoCalc/01-ticket_doCalc.sql b/db/changes/10141-zoneDoCalc/01-ticket_doCalc.sql new file mode 100644 index 000000000..d7538ff84 --- /dev/null +++ b/db/changes/10141-zoneDoCalc/01-ticket_doCalc.sql @@ -0,0 +1,56 @@ +USE `vn`; +DROP procedure IF EXISTS `zone_doCalc`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `zone_doCalc`() +proc: BEGIN +/** + * Updates ticket fields related with zone + */ + DECLARE vDone BOOL; + DECLARE vTicketFk INT; + DECLARE vShipped DATE; + DECLARE vZoneFk INT; + + DECLARE cCur CURSOR FOR + SELECT t.id, t.shipped, t.zoneFk + FROM zoneCalcTicket zct + JOIN ticket t ON t.zoneFk = zct.zoneFk + WHERE shipped >= CURDATE(); + + DECLARE CONTINUE HANDLER FOR NOT FOUND + SET vDone = TRUE; + + OPEN cCur; + + myLoop: LOOP + SET vDone = FALSE; + FETCH cCur INTO vTicketFk, vShipped, vZoneFk; + + IF vDone THEN + LEAVE myLoop; + END IF; + + DROP TEMPORARY TABLE IF EXISTS tmp.zone; + CREATE TEMPORARY TABLE tmp.zone + (INDEX (id)) + ENGINE = MEMORY + SELECT vZoneFk id; + + CALL zone_getOptionsForShipment(vShipped, TRUE); + + UPDATE ticket t + LEFT JOIN tmp.zoneOption zo ON TRUE + SET zonePrice = zo.price, zoneBonus = zo.bonus, zoneClosure = zo.`hour` + WHERE t.id = vTicketFk; + + END LOOP; + + CLOSE cCur; + + DELETE FROM zoneCalcTicket; +END$$ + +DELIMITER ; + diff --git a/db/changes/10141-zoneDoCalc/01-zoneClosure_recalc.sql b/db/changes/10141-zoneDoCalc/01-zoneClosure_recalc.sql new file mode 100644 index 000000000..f015eb894 --- /dev/null +++ b/db/changes/10141-zoneDoCalc/01-zoneClosure_recalc.sql @@ -0,0 +1 @@ +USE `vn`; diff --git a/db/changes/10141-zoneDoCalc/02-procNoOverlap.sql b/db/changes/10141-zoneDoCalc/02-procNoOverlap.sql new file mode 100644 index 000000000..253264ce9 --- /dev/null +++ b/db/changes/10141-zoneDoCalc/02-procNoOverlap.sql @@ -0,0 +1,30 @@ +USE `util`; +DROP procedure IF EXISTS `procNoOverlap`; + +DELIMITER $$ +USE `util`$$ +CREATE PROCEDURE `procNoOverlap` (procName VARCHAR(255)) +SQL SECURITY INVOKER +proc: BEGIN +/** + * call procedure without overlap + */ + DECLARE vIsChanged BOOL; + + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION + BEGIN + DO RELEASE_LOCK(procName); + RESIGNAL; + END; + + IF !GET_LOCK(procName, 0) THEN + LEAVE proc; + END IF; + + CALL exec(CONCAT('CALL ', procName)); + + DO RELEASE_LOCK(procName); +END$$ + +DELIMITER ; + diff --git a/modules/agency/back/model-config.json b/modules/agency/back/model-config.json index 7638e3f6c..c9a49ffe9 100644 --- a/modules/agency/back/model-config.json +++ b/modules/agency/back/model-config.json @@ -11,7 +11,7 @@ "Zone": { "dataSource": "vn" }, - "ZoneClosure": { + "ZoneCalcTicket": { "dataSource": "vn" }, "ZoneEvent": { diff --git a/modules/agency/back/models/zone-calc-ticket.js b/modules/agency/back/models/zone-calc-ticket.js new file mode 100644 index 000000000..c3633e8f4 --- /dev/null +++ b/modules/agency/back/models/zone-calc-ticket.js @@ -0,0 +1,24 @@ +const app = require('vn-loopback/server/server'); + + +module.exports = Self => { + app.on('started', function() { + let models = ['Zone', 'ZoneEvent', 'ZoneExclusion']; + + for (let modelName of models) { + let Model = app.models[modelName]; + + Model.observe('after save', doCalc); + Model.observe('after delete', doCalc); + } + + async function doCalc(ctx) { + try { + await Self.create({zoneFk: ctx.instance.zoneFk || ctx.instance.id}); + } catch (err) { + if (err.code != 'ER_DUP_ENTRY') + throw err; + } + } + }); +}; diff --git a/modules/agency/back/models/zone-closure.json b/modules/agency/back/models/zone-calc-ticket.json similarity index 62% rename from modules/agency/back/models/zone-closure.json rename to modules/agency/back/models/zone-calc-ticket.json index 895374838..5083d08ed 100644 --- a/modules/agency/back/models/zone-closure.json +++ b/modules/agency/back/models/zone-calc-ticket.json @@ -1,23 +1,15 @@ { - "name": "ZoneClosure", + "name": "ZoneCalcTicket", "base": "VnModel", "options": { "mysql": { - "table": "zoneClosure" + "table": "zoneCalcTicket" } }, "properties": { "zoneFk": { "id": true, "type": "Number" - }, - "dated": { - "type": "Date", - "required": true - }, - "hour": { - "type": "date", - "required": true } }, "relations": { diff --git a/modules/agency/back/models/zone-closure.js b/modules/agency/back/models/zone-closure.js deleted file mode 100644 index 8b66e31ae..000000000 --- a/modules/agency/back/models/zone-closure.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = Self => { - Self.doRecalc = async function() { - try { - await Self.rawSql(` - CREATE EVENT zoneClosure_doRecalc - ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 15 SECOND - DO CALL zoneClosure_recalc; - `); - } catch (err) { - if (err.code != 'ER_EVENT_ALREADY_EXISTS') throw err; - } - }; -}; diff --git a/modules/agency/back/models/zone-event.js b/modules/agency/back/models/zone-event.js index 46b2df202..d4fad8e96 100644 --- a/modules/agency/back/models/zone-event.js +++ b/modules/agency/back/models/zone-event.js @@ -34,12 +34,4 @@ module.exports = Self => { }, { message: `You should mark at least one week day` }); - - Self.observe('after save', async function() { - await app.models.ZoneClosure.doRecalc(); - }); - - Self.observe('after delete', async function() { - await app.models.ZoneClosure.doRecalc(); - }); }; diff --git a/modules/agency/back/models/zone-exclusion.js b/modules/agency/back/models/zone-exclusion.js deleted file mode 100644 index 51998aab8..000000000 --- a/modules/agency/back/models/zone-exclusion.js +++ /dev/null @@ -1,11 +0,0 @@ -const app = require('vn-loopback/server/server'); - -module.exports = Self => { - Self.observe('after save', async function() { - await app.models.ZoneClosure.doRecalc(); - }); - - Self.observe('after delete', async function() { - await app.models.ZoneClosure.doRecalc(); - }); -}; diff --git a/modules/agency/back/models/zone.js b/modules/agency/back/models/zone.js index 9d715a8d8..0c3ac24f6 100644 --- a/modules/agency/back/models/zone.js +++ b/modules/agency/back/models/zone.js @@ -1,5 +1,3 @@ -const app = require('vn-loopback/server/server'); - module.exports = Self => { require('../methods/zone/clone')(Self); require('../methods/zone/getLeaves')(Self); @@ -9,12 +7,4 @@ module.exports = Self => { Self.validatesPresenceOf('agencyModeFk', { message: `Agency cannot be blank` }); - - Self.observe('after save', async function() { - await app.models.ZoneClosure.doRecalc(); - }); - - Self.observe('after delete', async function() { - await app.models.ZoneClosure.doRecalc(); - }); };