diff --git a/db/changes/10121-zoneClosure/00-zoneClosure.sql b/db/changes/10121-zoneClosure/00-zoneClosure.sql new file mode 100644 index 000000000..07db5b167 --- /dev/null +++ b/db/changes/10121-zoneClosure/00-zoneClosure.sql @@ -0,0 +1,5 @@ +CREATE TABLE `vn`.`zoneClosure` ( + `zoneFk` INT NOT NULL, + `dated` DATE NOT NULL, + `hour` TIME NOT NULL, + PRIMARY KEY (`zoneFk`, `dated`)); diff --git a/db/changes/10121-zoneClosure/00-zoneClosure_recalc.sql b/db/changes/10121-zoneClosure/00-zoneClosure_recalc.sql new file mode 100644 index 000000000..cb313cdec --- /dev/null +++ b/db/changes/10121-zoneClosure/00-zoneClosure_recalc.sql @@ -0,0 +1,50 @@ + +DROP procedure IF EXISTS vn.`zoneClosure_recalc`; + +DELIMITER $$ +CREATE DEFINER=`root`@`%` PROCEDURE vn.`zoneClosure_recalc`() +proc: BEGIN +/** + * Recalculates the delivery time (hour) for every zone in days + scope in future + */ + DECLARE vScope INT; + DECLARE vCounter INT DEFAULT 0; + DECLARE vShipped DATE DEFAULT CURDATE(); + + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION + BEGIN + DO RELEASE_LOCK('vn.zoneClosure_recalc'); + RESIGNAL; + END; + + IF NOT GET_LOCK('vn.zoneClosure_recalc', 0) THEN + LEAVE proc; + END IF; + + SELECT scope INTO vScope + FROM zoneConfig; + + DROP TEMPORARY TABLE IF EXISTS tmp.zone; + CREATE TEMPORARY TABLE tmp.zone + (INDEX (id)) + ENGINE = MEMORY + SELECT id FROM zone; + + TRUNCATE TABLE zoneClosure; + + REPEAT + CALL zone_getOptionsForShipment(vShipped); + INSERT INTO zoneClosure(zoneFk, dated, `hour`) + SELECT zoneFk, vShipped, `hour` FROM tmp.zoneOption; + + SET vCounter = vCounter + 1; + SET vShipped = TIMESTAMPADD(DAY, 1, vShipped); + UNTIL vCounter > vScope + END REPEAT; + + DROP TEMPORARY TABLE tmp.zone; + DO RELEASE_LOCK('vn.zoneClosure_recalc'); +END$$ + +DELIMITER ; + diff --git a/db/changes/10121-zoneClosure/00-zoneConfig.sql b/db/changes/10121-zoneClosure/00-zoneConfig.sql new file mode 100644 index 000000000..915fb8894 --- /dev/null +++ b/db/changes/10121-zoneClosure/00-zoneConfig.sql @@ -0,0 +1,11 @@ +CREATE TABLE `vn`.`zoneConfig` ( + `id` INT UNSIGNED NOT NULL, + `scope` INT UNSIGNED NOT NULL, + PRIMARY KEY (`id`)); + +ALTER TABLE `vn`.`zoneConfig` +CHANGE COLUMN `id` `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ; + +INSERT INTO `vn`.`zoneConfig` (`scope`) VALUES ('1'); + +INSERT INTO `bs`.`nightTask` (`order`, `schema`, `procedure`) VALUES ('100', 'vn', 'zoneClosure_recalc'); diff --git a/modules/agency/back/model-config.json b/modules/agency/back/model-config.json index cfdbb83d3..7638e3f6c 100644 --- a/modules/agency/back/model-config.json +++ b/modules/agency/back/model-config.json @@ -11,7 +11,7 @@ "Zone": { "dataSource": "vn" }, - "ZoneGeo": { + "ZoneClosure": { "dataSource": "vn" }, "ZoneEvent": { @@ -20,6 +20,9 @@ "ZoneExclusion": { "dataSource": "vn" }, + "ZoneGeo": { + "dataSource": "vn" + }, "ZoneIncluded": { "dataSource": "vn" }, diff --git a/modules/agency/back/models/zone-closure.js b/modules/agency/back/models/zone-closure.js new file mode 100644 index 000000000..8b66e31ae --- /dev/null +++ b/modules/agency/back/models/zone-closure.js @@ -0,0 +1,13 @@ +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-closure.json b/modules/agency/back/models/zone-closure.json new file mode 100644 index 000000000..895374838 --- /dev/null +++ b/modules/agency/back/models/zone-closure.json @@ -0,0 +1,30 @@ +{ + "name": "ZoneClosure", + "base": "VnModel", + "options": { + "mysql": { + "table": "zoneClosure" + } + }, + "properties": { + "zoneFk": { + "id": true, + "type": "Number" + }, + "dated": { + "type": "Date", + "required": true + }, + "hour": { + "type": "date", + "required": true + } + }, + "relations": { + "zone": { + "type": "belongsTo", + "model": "Zone", + "foreignKey": "zoneFk" + } + } +} \ No newline at end of file diff --git a/modules/agency/back/models/zone-event.js b/modules/agency/back/models/zone-event.js index 6af031a23..46b2df202 100644 --- a/modules/agency/back/models/zone-event.js +++ b/modules/agency/back/models/zone-event.js @@ -1,3 +1,5 @@ +const app = require('vn-loopback/server/server'); + module.exports = Self => { Self.validate('range', function(err) { if (this.type == 'range' @@ -32,4 +34,12 @@ 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 new file mode 100644 index 000000000..51998aab8 --- /dev/null +++ b/modules/agency/back/models/zone-exclusion.js @@ -0,0 +1,11 @@ +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 0c3ac24f6..9d715a8d8 100644 --- a/modules/agency/back/models/zone.js +++ b/modules/agency/back/models/zone.js @@ -1,3 +1,5 @@ +const app = require('vn-loopback/server/server'); + module.exports = Self => { require('../methods/zone/clone')(Self); require('../methods/zone/getLeaves')(Self); @@ -7,4 +9,12 @@ 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(); + }); };