diff --git a/back/methods/chat/sendQueued.js b/back/methods/chat/sendQueued.js
index c34642c7e..cf80817e5 100644
--- a/back/methods/chat/sendQueued.js
+++ b/back/methods/chat/sendQueued.js
@@ -10,7 +10,7 @@ module.exports = Self => {
},
http: {
path: `/sendQueued`,
- verb: 'POST'
+ verb: 'GET'
}
});
diff --git a/back/methods/dms/deleteTrashFiles.js b/back/methods/dms/deleteTrashFiles.js
index 9d16e9d81..7cfb9f8d1 100644
--- a/back/methods/dms/deleteTrashFiles.js
+++ b/back/methods/dms/deleteTrashFiles.js
@@ -1,3 +1,4 @@
+const UserError = require('vn-loopback/util/user-error');
const fs = require('fs-extra');
const path = require('path');
@@ -11,11 +12,11 @@ module.exports = Self => {
},
http: {
path: `/deleteTrashFiles`,
- verb: 'POST'
+ verb: 'GET'
}
});
- Self.deleteTrashFiles = async(options) => {
+ Self.deleteTrashFiles = async options => {
const tx = await Self.beginTransaction({});
const myOptions = {};
@@ -26,6 +27,9 @@ module.exports = Self => {
myOptions.transaction = tx;
try {
+ if (process.env.NODE_ENV == 'test')
+ throw new UserError(`Action not allowed on the test environment`);
+
const models = Self.app.models;
const DmsContainer = models.DmsContainer;
@@ -33,9 +37,15 @@ module.exports = Self => {
where: {code: 'trash'}
}, myOptions);
+ const date = new Date();
+ date.setMonth(date.getMonth() - 4);
+
const dmsToDelete = await models.Dms.find({
where: {
- dmsTypeFk: trashDmsType.id
+ and: [
+ {dmsTypeFk: trashDmsType.id},
+ {created: {lt: date}}
+ ]
}
}, myOptions);
@@ -43,14 +53,19 @@ module.exports = Self => {
const pathHash = DmsContainer.getHash(dms.id);
const dmsContainer = await DmsContainer.container(pathHash);
const dstFile = path.join(dmsContainer.client.root, pathHash, dms.file);
+ const dstFolder = path.join(dmsContainer.client.root, pathHash);
await fs.unlink(dstFile);
- await dms.destroy(myOptions);
+ try {
+ await fs.rmdir(dstFolder);
+ await dms.destroy(myOptions);
+ } catch (err) {
+ await dms.destroy(myOptions);
+ }
}
if (tx) await tx.commit();
-
} catch (e) {
if (tx) await tx.rollback();
-
+
throw e;
}
};
diff --git a/db/changes/10470-family/00-accountingType.sql b/db/changes/10470-family/00-accountingType.sql
index f3c092a34..964027e3a 100644
--- a/db/changes/10470-family/00-accountingType.sql
+++ b/db/changes/10470-family/00-accountingType.sql
@@ -1,2 +1,3 @@
ALTER TABLE `vn`.`accountingType` ADD daysInFuture INT NULL;
-ALTER TABLE `vn`.`accountingType` MODIFY COLUMN daysInFuture int(11) DEFAULT 0 NULL;
\ No newline at end of file
+ALTER TABLE `vn`.`accountingType` MODIFY COLUMN daysInFuture int(11) DEFAULT 0 NULL;
+UPDATE `vn`.`accountingType` SET daysInFuture=1 WHERE id=8;
\ No newline at end of file
diff --git a/db/changes/10471-family/00-chat.sql b/db/changes/10471-family/00-chat.sql
new file mode 100644
index 000000000..6f3c9d437
--- /dev/null
+++ b/db/changes/10471-family/00-chat.sql
@@ -0,0 +1,3 @@
+ALTER TABLE `vn`.`chat` MODIFY COLUMN message TEXT CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL NULL;
+ALTER TABLE `vn`.`chat` MODIFY COLUMN dated DATETIME DEFAULT NULL NULL;
+ALTER TABLE `vn`.`chat` ADD error TEXT NULL;
diff --git a/db/changes/10472-family/00-creditInsurance.sql b/db/changes/10472-family/00-creditInsurance.sql
new file mode 100644
index 000000000..4731cfb2a
--- /dev/null
+++ b/db/changes/10472-family/00-creditInsurance.sql
@@ -0,0 +1,3 @@
+ALTER TABLE `vn`.`creditInsurance`
+ ADD CONSTRAINT `creditInsurance_creditClassificationFk` FOREIGN KEY (`creditClassificationFk`)
+ REFERENCES `vn`.`creditClassification` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
\ No newline at end of file
diff --git a/db/changes/10480-june/00-aclZoneExclusionGeos.sql b/db/changes/10480-june/00-aclZoneExclusionGeos.sql
new file mode 100644
index 000000000..4c0f6c991
--- /dev/null
+++ b/db/changes/10480-june/00-aclZoneExclusionGeos.sql
@@ -0,0 +1,4 @@
+INSERT INTO `salix`.`ACL`(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
+ VALUES
+ ('ZoneExclusionGeo', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
+ ('ZoneExclusionGeo', '*', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss');
\ No newline at end of file
diff --git a/db/changes/10480-june/00-albaran_gestdoc.sql b/db/changes/10480-june/00-albaran_gestdoc.sql
new file mode 100644
index 000000000..a0ba93bd3
--- /dev/null
+++ b/db/changes/10480-june/00-albaran_gestdoc.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `vn2008`.`albaran_gestdoc` DROP FOREIGN KEY fk_albaran_gestdoc_gestdoc1;
+ALTER TABLE `vn2008`.`albaran_gestdoc` ADD CONSTRAINT albaran_gestdoc_FK FOREIGN KEY (gestdoc_id) REFERENCES `vn`.`dms`(id) ON DELETE CASCADE ON UPDATE CASCADE;
\ No newline at end of file
diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index 265968ec0..db60210bd 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -1351,7 +1351,7 @@ INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseO
(7, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 4, 1, 50.00, 500, 'seventh travel', 2, 1),
(8, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 1, 1, 50.00, 500, 'eight travel', 1, 2);
-INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed`, `companyFk`, `ref`,`isInventory`, `isRaid`, `notes`, `evaNotes`)
+INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed`, `companyFk`, `ref`,`isExcludedFromAvailable`, `isRaid`, `notes`, `evaNotes`)
VALUES
(1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 1, 442, 'Movement 1', 0, 0, '', ''),
(2, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 0, 442, 'Movement 2', 0, 0, 'this is the note two', 'observation two'),
@@ -2582,6 +2582,15 @@ INSERT INTO `vn`.`machineWorker` (`workerFk`, `machineFk`, `inTimed`, `outTimed`
(1106, 2, util.VN_CURDATE(), NULL),
(1106, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL +1 DAY));
+INSERT INTO `vn`.`zoneExclusion` (`id`, `zoneFk`, `dated`, `created`, `userFk`)
+VALUES
+ (1, 1, DATE_ADD(CURDATE(), INTERVAL (IF(DAYOFWEEK(CURDATE())<=7, 7, 14) - DAYOFWEEK(CURDATE())) DAY), CURDATE(), 100),
+ (2, 1, DATE_ADD(CURDATE(), INTERVAL (IF(DAYOFWEEK(CURDATE())<=8, 8, 15) - DAYOFWEEK(CURDATE())) DAY), CURDATE(), 100);
+
+INSERT INTO `vn`.`zoneExclusionGeo` (`zoneExclusionFk`, `geoFk`)
+ VALUES
+ (2, 1);
+
INSERT INTO `vn`.`mdbBranch` (`name`)
VALUES
('test'),
@@ -2614,4 +2623,4 @@ INSERT INTO `vn`.`workerTimeControlConfig` (`id`, `dayBreak`, `dayBreakDriver`,
INSERT INTO `vn`.`routeConfig` (`id`, `defaultWorkCenterFk`)
VALUES
- (1, 9);
\ No newline at end of file
+ (1, 9);
diff --git a/db/dump/structure.sql b/db/dump/structure.sql
index 719ec8fea..da7e77124 100644
--- a/db/dump/structure.sql
+++ b/db/dump/structure.sql
@@ -23,6 +23,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `account` /*!40100 DEFAULT CHARACTER SE
USE `account`;
+
--
-- Table structure for table `account`
--
@@ -7388,7 +7389,7 @@ proc: BEGIN
JOIN vn.warehouse w ON w.id = t.warehouseInFk
WHERE t.landed BETWEEN vInventoryDate AND vStartDate
AND t.warehouseInFk = vWarehouse
- AND NOT e.isInventory
+ AND NOT e.isExcludedFromAvailable
GROUP BY b.itemFk
) c
JOIN vn.item i ON i.id = c.item_id
@@ -27101,7 +27102,7 @@ CREATE TABLE `entry` (
`dated` datetime NOT NULL,
`ref` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`isBooked` tinyint(1) NOT NULL DEFAULT '0',
- `isInventory` tinyint(1) NOT NULL DEFAULT '0',
+ `isExcludedFromAvailable` tinyint(1) NOT NULL DEFAULT 0,
`notes` longtext COLLATE utf8_unicode_ci,
`isConfirmed` tinyint(1) NOT NULL DEFAULT '0',
`isOrdered` tinyint(1) NOT NULL DEFAULT '0',
@@ -59607,7 +59608,7 @@ BEGIN
WHERE tr.landed >= vDateInventory
AND vWarehouse = tr.warehouseInFk
AND b.itemFk = vItemId
- AND e.isInventory = FALSE
+ AND e.isExcludedFromAvailable = FALSE
AND e.isRaid = FALSE
UNION ALL
@@ -59642,7 +59643,7 @@ BEGIN
AND vWarehouse =tr.warehouseOutFk
AND s.id <> 4
AND b.itemFk = vItemId
- AND e.isInventory = FALSE
+ AND e.isExcludedFromAvailable = FALSE
AND w.isFeedStock = FALSE
AND e.isRaid = FALSE
UNION ALL
@@ -59896,7 +59897,7 @@ BEGIN
LEFT JOIN travel t ON t.id = e.travelFk
WHERE t.landed BETWEEN vDatedFrom AND vDatedTo
AND (vWarehouseFk IS NULL OR t.warehouseInFk = vWarehouseFk)
- AND !e.isInventory
+ AND !e.isExcludedFromAvailable
AND b.quantity != 0
AND (vItemFk IS NULL OR b.itemFk = vItemFk)
UNION ALL
@@ -59909,7 +59910,7 @@ BEGIN
LEFT JOIN travel t ON t.id = e.travelFk
WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo
AND (vWarehouseFk IS NULL OR t.warehouseOutFk = vWarehouseFk)
- AND !e.isInventory
+ AND !e.isExcludedFromAvailable
AND b.quantity != 0
AND (vItemFk IS NULL OR b.itemFk = vItemFk)
AND !e.isRaid
@@ -68727,7 +68728,7 @@ BEGIN
* Devuelve los tickets y la cantidad de lineas de venta que se pueden adelantar.
*
* @param vDated Fecha de los tickets que se quieren adelantar.
- * @param vWarehouseFk Almacén
+ * @param vWarehouseFk AlmacénitemEntryIn
*/
DECLARE vDateInventory DATE;
DECLARE vDateToAdvance DATE;
@@ -79992,7 +79993,7 @@ USE `vn`;
/*!50001 SET collation_connection = utf8mb4_unicode_ci */;
/*!50001 CREATE ALGORITHM=UNDEFINED */
/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
-/*!50001 VIEW `itemEntryIn` AS select `t`.`warehouseInFk` AS `warehouseInFk`,`t`.`landed` AS `landed`,`b`.`itemFk` AS `itemFk`,`b`.`quantity` AS `quantity`,`t`.`isReceived` AS `isReceived`,`e`.`isRaid` AS `isVirtualStock`,`e`.`id` AS `entryFk` from ((`buy` `b` join `entry` `e` on((`b`.`entryFk` = `e`.`id`))) join `travel` `t` on((`e`.`travelFk` = `t`.`id`))) where ((`e`.`isInventory` = 0) and (`b`.`quantity` <> 0)) */;
+/*!50001 VIEW `itemEntryIn` AS select `t`.`warehouseInFk` AS `warehouseInFk`,`t`.`landed` AS `landed`,`b`.`itemFk` AS `itemFk`,`b`.`quantity` AS `quantity`,`t`.`isReceived` AS `isReceived`,`e`.`isRaid` AS `isVirtualStock`,`e`.`id` AS `entryFk` from ((`buy` `b` join `entry` `e` on((`b`.`entryFk` = `e`.`id`))) join `travel` `t` on((`e`.`travelFk` = `t`.`id`))) where ((`e`.`isExcludedFromAvailable` = 0) and (`b`.`quantity` <> 0)) */;
/*!50001 SET character_set_client = @saved_cs_client */;
/*!50001 SET character_set_results = @saved_cs_results */;
/*!50001 SET collation_connection = @saved_col_connection */;
@@ -80011,7 +80012,7 @@ USE `vn`;
/*!50001 SET collation_connection = utf8mb4_unicode_ci */;
/*!50001 CREATE ALGORITHM=UNDEFINED */
/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
-/*!50001 VIEW `itemEntryOut` AS select `t`.`warehouseOutFk` AS `warehouseOutFk`,`t`.`shipped` AS `shipped`,`b`.`itemFk` AS `itemFk`,-(`b`.`quantity`) AS `quantity`,`t`.`isDelivered` AS `isDelivered`,`e`.`id` AS `entryFk` from ((`buy` `b` join `entry` `e` on((`b`.`entryFk` = `e`.`id`))) join `travel` `t` on((`e`.`travelFk` = `t`.`id`))) where ((`e`.`isInventory` = 0) and (`e`.`isRaid` = 0) and (`b`.`quantity` <> 0)) */;
+/*!50001 VIEW `itemEntryOut` AS select `t`.`warehouseOutFk` AS `warehouseOutFk`,`t`.`shipped` AS `shipped`,`b`.`itemFk` AS `itemFk`,-(`b`.`quantity`) AS `quantity`,`t`.`isDelivered` AS `isDelivered`,`e`.`id` AS `entryFk` from ((`buy` `b` join `entry` `e` on((`b`.`entryFk` = `e`.`id`))) join `travel` `t` on((`e`.`travelFk` = `t`.`id`))) where ((`e`.`isExcludedFromAvailable` = 0) and (`e`.`isRaid` = 0) and (`b`.`quantity` <> 0)) */;
/*!50001 SET character_set_client = @saved_cs_client */;
/*!50001 SET character_set_results = @saved_cs_results */;
/*!50001 SET collation_connection = @saved_col_connection */;
diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index e939838cb..37f7308a5 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -1102,7 +1102,7 @@ export default {
company: 'vn-entry-basic-data vn-autocomplete[ng-model="$ctrl.entry.companyFk"]',
ordered: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isOrdered"]',
confirmed: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isConfirmed"]',
- inventory: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isInventory"]',
+ inventory: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isExcludedFromAvailable"]',
raid: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isRaid"]',
booked: 'vn-entry-basic-data vn-check[ng-model="$ctrl.entry.isBooked"]',
save: 'vn-entry-basic-data button[type=submit]',
diff --git a/modules/entry/back/methods/entry/filter.js b/modules/entry/back/methods/entry/filter.js
index 13690d3ac..1ba4166dc 100644
--- a/modules/entry/back/methods/entry/filter.js
+++ b/modules/entry/back/methods/entry/filter.js
@@ -156,7 +156,7 @@ module.exports = Self => {
e.dated,
e.ref,
e.isBooked,
- e.isInventory,
+ e.isExcludedFromAvailable,
e.notes,
e.evaNotes AS observation,
e.isConfirmed,
diff --git a/modules/entry/back/models/entry.json b/modules/entry/back/models/entry.json
index d8bd079a2..c456859a5 100644
--- a/modules/entry/back/models/entry.json
+++ b/modules/entry/back/models/entry.json
@@ -24,7 +24,7 @@
"isBooked": {
"type": "boolean"
},
- "isInventory": {
+ "isExcludedFromAvailable": {
"type": "boolean"
},
"notes": {
diff --git a/modules/entry/front/basic-data/index.html b/modules/entry/front/basic-data/index.html
index a05630dd6..8787853a5 100644
--- a/modules/entry/front/basic-data/index.html
+++ b/modules/entry/front/basic-data/index.html
@@ -103,7 +103,7 @@
+ ng-model="$ctrl.entry.isExcludedFromAvailable">
+ ng-if="$ctrl.entry.isExcludedFromAvailable">
diff --git a/modules/entry/front/summary/index.html b/modules/entry/front/summary/index.html
index a95b2f18a..3dd9a4be5 100644
--- a/modules/entry/front/summary/index.html
+++ b/modules/entry/front/summary/index.html
@@ -91,7 +91,7 @@
diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index 05b223598..ec8244f49 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -12,7 +12,7 @@ module.exports = Self => {
},
http: {
path: `/downloadImages`,
- verb: 'POST'
+ verb: 'GET'
}
});
diff --git a/modules/zone/back/methods/zone/exclusionGeo.js b/modules/zone/back/methods/zone/exclusionGeo.js
new file mode 100644
index 000000000..5026c58c5
--- /dev/null
+++ b/modules/zone/back/methods/zone/exclusionGeo.js
@@ -0,0 +1,64 @@
+
+const UserError = require('vn-loopback/util/user-error');
+
+module.exports = Self => {
+ Self.remoteMethod('exclusionGeo', {
+ description: 'Exclude a geo from a zone',
+ accepts: [
+ {
+ arg: 'zoneFk',
+ type: 'number',
+ description: 'The zone id'
+ },
+ {
+ arg: 'date',
+ type: 'date',
+ description: 'The date to exclude'
+ },
+ {
+ arg: 'geoIds',
+ type: ['number'],
+ description: 'The geos id'
+ }
+
+ ],
+ returns: {
+ type: 'object',
+ root: true
+ },
+ http: {
+ path: `/exclusionGeo`,
+ verb: 'POST'
+ }
+ });
+
+ Self.exclusionGeo = async(zoneFk, date, geoIds, options) => {
+ const models = Self.app.models;
+ const myOptions = {};
+
+ if (typeof options == 'object')
+ Object.assign(myOptions, options);
+
+ if (!geoIds[0]) throw new UserError(`You must select a location`);
+
+ const newZoneExclusion = await models.ZoneExclusion.create({
+ zoneFk: zoneFk,
+ dated: date
+ }, myOptions);
+
+ const promises = [];
+
+ for (const geoId of geoIds) {
+ const newZoneExclusionGeo = await models.ZoneExclusionGeo.create({
+ zoneExclusionFk: newZoneExclusion.id,
+ geoFk: geoId
+ }, myOptions);
+
+ promises.push(newZoneExclusionGeo);
+ }
+
+ const newZoneExclusionGeos = await Promise.all(promises);
+
+ return newZoneExclusionGeos;
+ };
+};
diff --git a/modules/zone/back/methods/zone/getEventsFiltered.js b/modules/zone/back/methods/zone/getEventsFiltered.js
index 316652fa3..b7875785d 100644
--- a/modules/zone/back/methods/zone/getEventsFiltered.js
+++ b/modules/zone/back/methods/zone/getEventsFiltered.js
@@ -56,12 +56,23 @@ module.exports = Self => {
[zoneFk, started, ended, started, ended, started, ended, started, ended], myOptions);
query = `
- SELECT *
- FROM vn.zoneExclusion
- WHERE zoneFk = ?
- AND dated BETWEEN ? AND ?;`;
+ SELECT e.*
+ FROM vn.zoneExclusion e
+ LEFT JOIN vn.zoneExclusionGeo eg ON eg.zoneExclusionFk = e.id
+ WHERE e.zoneFk = ?
+ AND e.dated BETWEEN ? AND ?
+ AND eg.zoneExclusionFk IS NULL;`;
const exclusions = await Self.rawSql(query, [zoneFk, started, ended], myOptions);
- return {events, exclusions};
+ query = `
+ SELECT eg.*, e.zoneFk, e.dated, e.created, e.userFk
+ FROM vn.zoneExclusion e
+ LEFT JOIN vn.zoneExclusionGeo eg ON eg.zoneExclusionFk = e.id
+ WHERE e.zoneFk = ?
+ AND e.dated BETWEEN ? AND ?
+ AND eg.zoneExclusionFk IS NOT NULL;`;
+ const geoExclusions = await Self.rawSql(query, [zoneFk, started, ended], myOptions);
+
+ return {events, exclusions, geoExclusions};
};
};
diff --git a/modules/zone/back/methods/zone/specs/exclusionGeo.spec.js b/modules/zone/back/methods/zone/specs/exclusionGeo.spec.js
new file mode 100644
index 000000000..3a345f2ce
--- /dev/null
+++ b/modules/zone/back/methods/zone/specs/exclusionGeo.spec.js
@@ -0,0 +1,41 @@
+const models = require('vn-loopback/server/server').models;
+
+describe('zone exclusionGeo()', () => {
+ const zoneId = 1;
+ const today = new Date();
+
+ it(`should show an error when location isn't selected`, async() => {
+ const tx = await models.Zone.beginTransaction({});
+
+ try {
+ const options = {transaction: tx};
+ const geoIds = [];
+
+ await models.Zone.exclusionGeo(zoneId, today, geoIds, options);
+
+ await tx.rollback();
+ } catch (e) {
+ await tx.rollback();
+ error = e;
+ }
+
+ expect(error.message).toContain(`You must select a location`);
+ });
+
+ it('should create two exclusion by geo', async() => {
+ const tx = await models.Zone.beginTransaction({});
+
+ try {
+ const options = {transaction: tx};
+ const geoIds = [1, 2];
+ const result = await models.Zone.exclusionGeo(zoneId, today, geoIds, options);
+
+ expect(result.length).toEqual(2);
+
+ await tx.rollback();
+ } catch (e) {
+ await tx.rollback();
+ throw e;
+ }
+ });
+});
diff --git a/modules/zone/back/methods/zone/specs/updateExclusionGeo.spec.js b/modules/zone/back/methods/zone/specs/updateExclusionGeo.spec.js
new file mode 100644
index 000000000..9db2e24be
--- /dev/null
+++ b/modules/zone/back/methods/zone/specs/updateExclusionGeo.spec.js
@@ -0,0 +1,40 @@
+const models = require('vn-loopback/server/server').models;
+
+describe('zone updateExclusionGeo()', () => {
+ it(`should show an error when location isn't selected`, async() => {
+ const tx = await models.Zone.beginTransaction({});
+
+ try {
+ const options = {transaction: tx};
+ const zoneId = 1;
+ const geoIds = [];
+
+ await models.Zone.updateExclusionGeo(zoneId, geoIds, options);
+
+ await tx.rollback();
+ } catch (e) {
+ await tx.rollback();
+ error = e;
+ }
+
+ expect(error.message).toContain(`You must select a location`);
+ });
+
+ it('should delete all exclusion and then create two exclusion by geo for a zone', async() => {
+ const tx = await models.Zone.beginTransaction({});
+
+ try {
+ const options = {transaction: tx};
+ const zoneId = 2;
+ const geoIds = [1, 2];
+ const result = await models.Zone.updateExclusionGeo(zoneId, geoIds, options);
+
+ expect(result.length).toEqual(2);
+
+ await tx.rollback();
+ } catch (e) {
+ await tx.rollback();
+ throw e;
+ }
+ });
+});
diff --git a/modules/zone/back/methods/zone/updateExclusionGeo.js b/modules/zone/back/methods/zone/updateExclusionGeo.js
new file mode 100644
index 000000000..237e336e0
--- /dev/null
+++ b/modules/zone/back/methods/zone/updateExclusionGeo.js
@@ -0,0 +1,55 @@
+const UserError = require('vn-loopback/util/user-error');
+
+module.exports = Self => {
+ Self.remoteMethod('updateExclusionGeo', {
+ description: 'Update the geos excluded from a zone',
+ accepts: [
+ {
+ arg: 'zoneExclusionFk',
+ type: 'number',
+ description: 'The zoneExclusion id'
+ },
+ {
+ arg: 'geoIds',
+ type: ['number'],
+ description: 'The geos id'
+ }
+
+ ],
+ returns: {
+ type: 'object',
+ root: true
+ },
+ http: {
+ path: `/updateExclusionGeo`,
+ verb: 'POST'
+ }
+ });
+
+ Self.updateExclusionGeo = async(zoneExclusionFk, geoIds, options) => {
+ const models = Self.app.models;
+ const myOptions = {};
+
+ if (typeof options == 'object')
+ Object.assign(myOptions, options);
+
+ if (!geoIds[0]) throw new UserError(`You must select a location`);
+
+ await models.ZoneExclusionGeo.destroyAll({
+ zoneExclusionFk: zoneExclusionFk
+ }, myOptions);
+
+ const promises = [];
+
+ for (const geoId of geoIds) {
+ const params = {
+ zoneExclusionFk: zoneExclusionFk,
+ geoFk: geoId
+ };
+ const deletedZoneExclusionGeos = models.ZoneExclusionGeo.create(params, myOptions);
+ promises.push(deletedZoneExclusionGeos);
+ }
+
+ return Promise.all(promises);
+ };
+};
diff --git a/modules/zone/back/model-config.json b/modules/zone/back/model-config.json
index ee555f3f4..261a89902 100644
--- a/modules/zone/back/model-config.json
+++ b/modules/zone/back/model-config.json
@@ -23,6 +23,9 @@
"ZoneExclusion": {
"dataSource": "vn"
},
+ "ZoneExclusionGeo": {
+ "dataSource": "vn"
+ },
"ZoneGeo": {
"dataSource": "vn"
},
diff --git a/modules/zone/back/models/zone-exclusion-geo.json b/modules/zone/back/models/zone-exclusion-geo.json
new file mode 100644
index 000000000..816e4b650
--- /dev/null
+++ b/modules/zone/back/models/zone-exclusion-geo.json
@@ -0,0 +1,21 @@
+{
+ "name": "ZoneExclusionGeo",
+ "base": "VnModel",
+ "options": {
+ "mysql": {
+ "table": "zoneExclusionGeo"
+ }
+ },
+ "properties": {
+ "id": {
+ "id": true,
+ "type": "number"
+ },
+ "zoneExclusionFk": {
+ "type": "number"
+ },
+ "geoFk": {
+ "type": "number"
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/zone/back/models/zone.js b/modules/zone/back/models/zone.js
index ef1c8c5d9..6d5a6cdca 100644
--- a/modules/zone/back/models/zone.js
+++ b/modules/zone/back/models/zone.js
@@ -8,6 +8,8 @@ module.exports = Self => {
require('../methods/zone/deleteZone')(Self);
require('../methods/zone/includingExpired')(Self);
require('../methods/zone/getZoneClosing')(Self);
+ require('../methods/zone/exclusionGeo')(Self);
+ require('../methods/zone/updateExclusionGeo')(Self);
Self.validatesPresenceOf('agencyModeFk', {
message: `Agency cannot be blank`
diff --git a/modules/zone/front/calendar/index.js b/modules/zone/front/calendar/index.js
index a24d10aef..3bc7158ef 100644
--- a/modules/zone/front/calendar/index.js
+++ b/modules/zone/front/calendar/index.js
@@ -75,6 +75,17 @@ class Controller extends Component {
}
}
+ this.geoExclusions = {};
+ let geoExclusions = value.geoExclusions;
+
+ if (geoExclusions) {
+ for (let geoExclusion of geoExclusions) {
+ let stamp = toStamp(geoExclusion.dated);
+ if (!this.geoExclusions[stamp]) this.geoExclusions[stamp] = [];
+ this.geoExclusions[stamp].push(geoExclusion);
+ }
+ }
+
let events = value.events;
if (events) {
@@ -135,11 +146,13 @@ class Controller extends Component {
onSelection($event, $days, $type, $weekday) {
let $events = [];
let $exclusions = [];
+ let $geoExclusions = [];
for (let day of $days) {
let stamp = day.getTime();
$events = $events.concat(this.days[stamp] || []);
$exclusions = $exclusions.concat(this.exclusions[stamp] || []);
+ $geoExclusions = $geoExclusions.concat(this.geoExclusions[stamp] || []);
}
this.emit('selection', {
@@ -148,19 +161,23 @@ class Controller extends Component {
$type,
$weekday,
$events,
- $exclusions
+ $exclusions,
+ $geoExclusions
});
}
hasEvents(day) {
let stamp = day.getTime();
- return this.days[stamp] || this.exclusions[stamp];
+ return this.days[stamp] || this.exclusions[stamp] || this.geoExclusions[stamp];
}
getClass(day) {
let stamp = day.getTime();
- return this.exclusions[stamp] && !this.days[stamp]
- ? 'excluded' : '';
+ if (this.geoExclusions[stamp])
+ return 'geoExcluded';
+ else if (this.exclusions[stamp])
+ return 'excluded';
+ else return '';
}
}
Controller.$inject = ['$element', '$scope', 'vnWeekDays'];
diff --git a/modules/zone/front/calendar/index.spec.js b/modules/zone/front/calendar/index.spec.js
index be002925e..338f47917 100644
--- a/modules/zone/front/calendar/index.spec.js
+++ b/modules/zone/front/calendar/index.spec.js
@@ -15,6 +15,7 @@ describe('component vnZoneCalendar', () => {
controller.zone = {id: 1};
controller.days = [];
controller.exclusions = [];
+ controller.geoExclusions = [];
}));
describe('date() setter', () => {
@@ -57,7 +58,7 @@ describe('component vnZoneCalendar', () => {
});
describe('data() setter', () => {
- it('should set the events and exclusions and then call the refreshEvents() method', () => {
+ it('should set the events, exclusions and geoExclusions and then call the refreshEvents() method', () => {
jest.spyOn(controller, 'refreshEvents').mockReturnThis();
controller.data = {
@@ -66,13 +67,17 @@ describe('component vnZoneCalendar', () => {
}],
events: [{
dated: new Date()
- }]
+ }],
+ geoExclusions: [{
+ dated: new Date()
+ }],
};
expect(controller.refreshEvents).toHaveBeenCalledWith();
expect(controller.events).toBeDefined();
expect(controller.events.length).toEqual(1);
expect(controller.exclusions).toBeDefined();
+ expect(controller.geoExclusions).toBeDefined();
expect(Object.keys(controller.exclusions).length).toEqual(1);
});
});
@@ -122,7 +127,8 @@ describe('component vnZoneCalendar', () => {
$events: [],
$exclusions: [],
$type: 'day',
- $weekday: 1
+ $weekday: 1,
+ $geoExclusions: [],
}
);
});
@@ -151,5 +157,16 @@ describe('component vnZoneCalendar', () => {
expect(result).toEqual('excluded');
});
+
+ it('should return the className "geoExcluded" for a date with geo excluded', () => {
+ const dated = new Date();
+
+ controller.geoExclusions = [];
+ controller.geoExclusions[dated.getTime()] = true;
+
+ const result = controller.getClass(dated);
+
+ expect(result).toEqual('geoExcluded');
+ });
});
});
diff --git a/modules/zone/front/calendar/style.scss b/modules/zone/front/calendar/style.scss
index 25b6a87d1..38491af58 100644
--- a/modules/zone/front/calendar/style.scss
+++ b/modules/zone/front/calendar/style.scss
@@ -33,6 +33,9 @@ vn-zone-calendar {
&.excluded .day-number {
background-color: $color-alert;
}
+ &.geoExcluded .day-number {
+ background-color: $color-main;
+ }
}
}
}
diff --git a/modules/zone/front/events/index.html b/modules/zone/front/events/index.html
index e71a1ae26..46ba87dea 100644
--- a/modules/zone/front/events/index.html
+++ b/modules/zone/front/events/index.html
@@ -2,7 +2,7 @@
id="calendar"
vn-id="calendar"
data="data"
- on-selection="$ctrl.onSelection($days, $type, $weekday, $events, $exclusions)"
+ on-selection="$ctrl.onSelection($days, $type, $weekday, $events, $exclusions, $geoExclusions)"
on-step="$ctrl.refresh()"
class="vn-w-md">
@@ -98,7 +98,7 @@
fixed-bottom-right>
@@ -198,3 +198,80 @@
message="This item will be deleted"
question="Are you sure you want to continue?">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/zone/front/events/index.js b/modules/zone/front/events/index.js
index 0df16a42a..b86330126 100644
--- a/modules/zone/front/events/index.js
+++ b/modules/zone/front/events/index.js
@@ -1,5 +1,6 @@
import ngModule from '../module';
import Section from 'salix/components/section';
+import './style.scss';
class Controller extends Section {
constructor($element, $, vnWeekDays) {
@@ -20,6 +21,16 @@ class Controller extends Section {
return `Zones/${this.$params.id}/exclusions`;
}
+ get checked() {
+ const geos = this.$.model.data || [];
+ const checkedLines = [];
+ for (let geo of geos) {
+ if (geo.checked)
+ checkedLines.push(geo);
+ }
+ return checkedLines;
+ }
+
refresh() {
this.$.data = null;
this.$.$applyAsync(() => {
@@ -48,33 +59,56 @@ class Controller extends Section {
: this.$t('Everyday');
}
- onSelection(days, type, weekday, events, exclusions) {
+ onSelection(days, type, weekday, events, exclusions, exclusionGeos) {
if (this.editMode == 'include') {
if (events.length)
- this.edit(events[0]);
- else
- this.create(type, days, weekday);
- } else {
- if (exclusions.length)
- this.exclusionDelete(exclusions);
- else
- this.exclusionCreate(days);
+ return this.editInclusion(events[0]);
+ return this.createInclusion(type, days, weekday);
+ } else if (this.editMode == 'exclude') {
+ if (exclusions.length || exclusionGeos.length)
+ return this.editExclusion(exclusions[0] || {}, exclusionGeos);
+ return this.createExclusion(days);
}
}
+ editExclusion(exclusion, exclusionGeos) {
+ this.isNew = false;
+ this.excludeSelected = angular.copy(exclusion);
+ this.excludeSelected.type = exclusionGeos.length ?
+ 'specificLocations' : 'all';
+
+ this.exclusionGeos = new Set();
+ if (exclusionGeos.length) {
+ this.excludeSelected.id = exclusionGeos[0].zoneExclusionFk;
+ exclusionGeos.forEach(x => this.exclusionGeos.add(x.geoFk));
+ }
+
+ this.$.excludeDialog.show();
+ }
+
+ createExclusion(days) {
+ this.isNew = true;
+ this.excludeSelected = {
+ type: 'all',
+ dated: days[0]
+ };
+ this.exclusionGeos = new Set();
+ this.$.excludeDialog.show();
+ }
+
onEditClick(row, event) {
if (event.defaultPrevented) return;
- this.edit(row);
+ this.editInclusion(row);
}
- edit(row) {
+ editInclusion(row) {
this.isNew = false;
this.selected = angular.copy(row);
this.selected.wdays = this.vnWeekDays.fromSet(row.weekDays);
- this.$.dialog.show();
+ this.$.includeDialog.show();
}
- create(type, days, weekday) {
+ createInclusion(type, days, weekday) {
this.isNew = true;
if (type == 'weekday') {
@@ -92,7 +126,7 @@ class Controller extends Section {
};
}
- this.$.dialog.show();
+ this.$.includeDialog.show();
}
onIncludeResponse(response) {
@@ -132,6 +166,19 @@ class Controller extends Section {
}
}
+ onExcludeResponse(response) {
+ const type = this.excludeSelected.type;
+ switch (response) {
+ case 'accept': {
+ if (type == 'all')
+ return this.exclusionCreate();
+ return this.exclusionGeoCreate();
+ }
+ case 'delete':
+ return this.exclusionDelete(this.excludeSelected);
+ }
+ }
+
onDeleteClick(id, event) {
if (event.defaultPrevented) return;
event.preventDefault();
@@ -149,31 +196,121 @@ class Controller extends Section {
.then(() => this.refresh());
}
- exclusionCreate(days) {
- let exclusions = days.map(dated => {
- return {dated};
- });
+ exclusionCreate() {
+ const excludeSelected = this.excludeSelected;
+ const dated = excludeSelected.dated;
+ let req;
- this.$http.post(this.exclusionsPath, exclusions)
+ if (this.isNew)
+ req = this.$http.post(this.exclusionsPath, [{dated}]);
+ if (!this.isNew)
+ req = this.$http.put(`${this.exclusionsPath}/${excludeSelected.id}`, {dated});
+
+ return req.then(() => {
+ this.refresh();
+ });
+ }
+
+ exclusionGeoCreate() {
+ const excludeSelected = this.excludeSelected;
+ let req;
+ const geoIds = [];
+ this.exclusionGeos.forEach(id => geoIds.push(id));
+
+ if (this.isNew) {
+ const params = {
+ zoneFk: parseInt(this.$params.id),
+ date: excludeSelected.dated,
+ geoIds
+ };
+ req = this.$http.post(`Zones/exclusionGeo`, params);
+ } else {
+ const params = {
+ zoneExclusionFk: this.excludeSelected.id,
+ geoIds
+ };
+ req = this.$http.post(`Zones/updateExclusionGeo`, params);
+ }
+ return req.then(() => this.refresh());
+ }
+
+ exclusionDelete(exclusion) {
+ const path = `${this.exclusionsPath}/${exclusion.id}`;
+ return this.$http.delete(path)
.then(() => this.refresh());
}
- exclusionDelete(exclusions) {
- let reqs = [];
+ set excludeSearch(value) {
+ this._excludeSearch = value;
+ if (!value) this.onSearch();
+ }
- for (let exclusion of exclusions) {
- if (!exclusion.id) continue;
- let path = `${this.exclusionsPath}/${exclusion.id}`;
- reqs.push(this.$http.delete(path));
+ get excludeSearch() {
+ return this._excludeSearch;
+ }
+
+ onKeyDown(event) {
+ if (event.key == 'Enter') {
+ event.preventDefault();
+ this.onSearch();
+ }
+ }
+
+ onSearch() {
+ const params = {search: this._excludeSearch};
+ if (this.excludeSelected.type == 'specificLocations') {
+ this.$.model.applyFilter({}, params).then(() => {
+ const data = this.$.model.data;
+ this.getChecked(data);
+ this.$.treeview.data = data;
+ });
+ }
+ }
+
+ onFetch(item) {
+ const params = item ? {parentId: item.id} : null;
+ return this.$.model.applyFilter({}, params).then(() => {
+ const data = this.$.model.data;
+ this.getChecked(data);
+ return data;
+ });
+ }
+
+ onSort(a, b) {
+ if (b.selected !== a.selected) {
+ if (a.selected == null)
+ return 1;
+ if (b.selected == null)
+ return -1;
+ return b.selected - a.selected;
}
- this.$q.all(reqs)
- .then(() => this.refresh());
+ return a.name.localeCompare(b.name);
+ }
+
+ getChecked(data) {
+ for (let geo of data) {
+ geo.checked = this.exclusionGeos.has(geo.id);
+ if (geo.childs) this.getChecked(geo.childs);
+ }
+ }
+
+ onItemCheck(geoId, checked) {
+ if (checked)
+ this.exclusionGeos.add(geoId);
+ else
+ this.exclusionGeos.delete(geoId);
}
}
Controller.$inject = ['$element', '$scope', 'vnWeekDays'];
ngModule.vnComponent('vnZoneEvents', {
template: require('./index.html'),
- controller: Controller
+ controller: Controller,
+ bindings: {
+ zone: '<'
+ },
+ require: {
+ card: '^vnZoneCard'
+ }
});
diff --git a/modules/zone/front/events/index.spec.js b/modules/zone/front/events/index.spec.js
index ed2c91c31..b4ff800d6 100644
--- a/modules/zone/front/events/index.spec.js
+++ b/modules/zone/front/events/index.spec.js
@@ -1,4 +1,5 @@
import './index';
+import crudModel from 'core/mocks/crud-model';
describe('component vnZoneEvents', () => {
let $scope;
@@ -34,7 +35,8 @@ describe('component vnZoneEvents', () => {
const query = `Zones/getEventsFiltered?ended=${date}&started=${date}&zoneFk=${params.zoneFk}`;
const response = {
events: 'myEvents',
- exclusions: 'myExclusions'
+ exclusions: 'myExclusions',
+ geoExclusions: 'myGeoExclusions',
};
$httpBackend.whenGET(query).respond(response);
controller.refresh();
@@ -48,71 +50,129 @@ describe('component vnZoneEvents', () => {
});
describe('onSelection()', () => {
- it('should call the edit() method', () => {
- jest.spyOn(controller, 'edit').mockReturnThis();
+ it('should call the editInclusion() method', () => {
+ jest.spyOn(controller, 'editInclusion').mockReturnThis();
const weekday = {};
const days = [];
const type = 'EventType';
const events = [{name: 'Event'}];
const exclusions = [];
+ const exclusionsGeo = [];
controller.editMode = 'include';
- controller.onSelection(days, type, weekday, events, exclusions);
+ controller.onSelection(days, type, weekday, events, exclusions, exclusionsGeo);
- expect(controller.edit).toHaveBeenCalledWith({name: 'Event'});
+ expect(controller.editInclusion).toHaveBeenCalledWith({name: 'Event'});
});
- it('should call the create() method', () => {
- jest.spyOn(controller, 'create').mockReturnThis();
+ it('should call the createInclusion() method', () => {
+ jest.spyOn(controller, 'createInclusion').mockReturnThis();
const weekday = {dated: new Date()};
const days = [weekday];
const type = 'EventType';
const events = [];
const exclusions = [];
+ const exclusionsGeo = [];
controller.editMode = 'include';
- controller.onSelection(days, type, weekday, events, exclusions);
+ controller.onSelection(days, type, weekday, events, exclusions, exclusionsGeo);
- expect(controller.create).toHaveBeenCalledWith(type, days, weekday);
+ expect(controller.createInclusion).toHaveBeenCalledWith(type, days, weekday);
});
- it('should call the exclusionDelete() method', () => {
- jest.spyOn(controller, 'exclusionDelete').mockReturnThis();
+ it('should call the editExclusion() method with exclusions', () => {
+ jest.spyOn(controller, 'editExclusion').mockReturnThis();
const weekday = {};
const days = [];
const type = 'EventType';
const events = [];
- const exclusions = [{id: 1}];
- controller.editMode = 'delete';
- controller.onSelection(days, type, weekday, events, exclusions);
+ const exclusions = [{name: 'Exclusion'}];
+ const exclusionsGeo = [];
+ controller.editMode = 'exclude';
+ controller.onSelection(days, type, weekday, events, exclusions, exclusionsGeo);
- expect(controller.exclusionDelete).toHaveBeenCalledWith(exclusions);
+ expect(controller.editExclusion).toHaveBeenCalled();
});
- it('should call the exclusionCreate() method', () => {
- jest.spyOn(controller, 'exclusionCreate').mockReturnThis();
+ it('should call the editExclusion() method with exclusionsGeo', () => {
+ jest.spyOn(controller, 'editExclusion').mockReturnThis();
+
+ const weekday = {};
+ const days = [];
+ const type = 'EventType';
+ const events = [];
+ const exclusions = [];
+ const exclusionsGeo = [{name: 'GeoExclusion'}];
+ controller.editMode = 'exclude';
+ controller.onSelection(days, type, weekday, events, exclusions, exclusionsGeo);
+
+ expect(controller.editExclusion).toHaveBeenCalled();
+ });
+
+ it('should call the createExclusion() method', () => {
+ jest.spyOn(controller, 'createExclusion').mockReturnThis();
const weekday = {};
const days = [{dated: new Date()}];
const type = 'EventType';
const events = [];
const exclusions = [];
- controller.editMode = 'delete';
- controller.onSelection(days, type, weekday, events, exclusions);
+ const exclusionsGeo = [];
+ controller.editMode = 'exclude';
+ controller.onSelection(days, type, weekday, events, exclusions, exclusionsGeo);
- expect(controller.exclusionCreate).toHaveBeenCalledWith(days);
+ expect(controller.createExclusion).toHaveBeenCalledWith(days);
});
});
- describe('create()', () => {
- it('shoud set the selected property and then call the dialog show() method', () => {
- controller.$.dialog = {show: jest.fn()};
+ describe('editExclusion()', () => {
+ it('shoud set the excludeSelected.type = "specificLocations" and then call the excludeDialog show() method', () => {
+ controller.$.excludeDialog = {show: jest.fn()};
+
+ const exclusionGeos = [{id: 1}];
+ const exclusions = [];
+
+ controller.editExclusion(exclusions, exclusionGeos);
+
+ expect(controller.excludeSelected.type).toEqual('specificLocations');
+ expect(controller.$.excludeDialog.show).toHaveBeenCalledWith();
+ });
+
+ it('shoud set the excludeSelected.type = "all" and then call the excludeDialog show() method', () => {
+ controller.$.excludeDialog = {show: jest.fn()};
+
+ const exclusionGeos = [];
+ const exclusions = [{id: 1}];
+
+ controller.editExclusion(exclusions, exclusionGeos);
+
+ expect(controller.excludeSelected.type).toEqual('all');
+ expect(controller.$.excludeDialog.show).toHaveBeenCalledWith();
+ });
+ });
+
+ describe('createExclusion()', () => {
+ it('shoud set the excludeSelected property and then call the excludeDialog show() method', () => {
+ controller.$.excludeDialog = {show: jest.fn()};
+
+ const days = [new Date()];
+ controller.createExclusion(days);
+
+ expect(controller.excludeSelected).toBeDefined();
+ expect(controller.isNew).toBeTruthy();
+ expect(controller.$.excludeDialog.show).toHaveBeenCalledWith();
+ });
+ });
+
+ describe('createInclusion()', () => {
+ it('shoud set the selected property and then call the includeDialog show() method', () => {
+ controller.$.includeDialog = {show: jest.fn()};
const type = 'weekday';
const days = [new Date()];
const weekday = 1;
- controller.create(type, days, weekday);
+ controller.createInclusion(type, days, weekday);
const selection = controller.selected;
const firstWeekday = selection.wdays[weekday];
@@ -120,23 +180,23 @@ describe('component vnZoneEvents', () => {
expect(selection.type).toEqual('indefinitely');
expect(firstWeekday).toBeTruthy();
expect(controller.isNew).toBeTruthy();
- expect(controller.$.dialog.show).toHaveBeenCalledWith();
+ expect(controller.$.includeDialog.show).toHaveBeenCalledWith();
});
- it('shoud set the selected property with the first day and then call the dialog show() method', () => {
- controller.$.dialog = {show: jest.fn()};
+ it('shoud set the selected property with the first day and then call the includeDialog show() method', () => {
+ controller.$.includeDialog = {show: jest.fn()};
const type = 'nonListedType';
const days = [new Date()];
const weekday = 1;
- controller.create(type, days, weekday);
+ controller.createInclusion(type, days, weekday);
const selection = controller.selected;
expect(selection.type).toEqual('day');
expect(selection.dated).toEqual(days[0]);
expect(controller.isNew).toBeTruthy();
- expect(controller.$.dialog.show).toHaveBeenCalledWith();
+ expect(controller.$.includeDialog.show).toHaveBeenCalledWith();
});
});
@@ -180,6 +240,35 @@ describe('component vnZoneEvents', () => {
});
});
+ describe('onExcludeResponse()', () => {
+ it('should call the exclusionCreate() method', () => {
+ jest.spyOn(controller, 'exclusionCreate').mockReturnThis();
+
+ controller.excludeSelected = {type: 'all'};
+ controller.onExcludeResponse('accept');
+
+ expect(controller.exclusionCreate).toHaveBeenCalledWith();
+ });
+
+ it('should call the exclusionGeoCreate() method', () => {
+ jest.spyOn(controller, 'exclusionGeoCreate').mockReturnThis();
+
+ controller.excludeSelected = {type: 'specificLocations'};
+ controller.onExcludeResponse('accept');
+
+ expect(controller.exclusionGeoCreate).toHaveBeenCalledWith();
+ });
+
+ it('should call the exclusionDelete() method', () => {
+ jest.spyOn(controller, 'exclusionDelete').mockReturnThis();
+
+ controller.excludeSelected = {id: 1, type: 'all'};
+ controller.onExcludeResponse('delete');
+
+ expect(controller.exclusionDelete).toHaveBeenCalledWith(controller.excludeSelected);
+ });
+ });
+
describe('onDeleteResponse()', () => {
it('shoud make an HTTP DELETE query and then call the refresh() method', () => {
jest.spyOn(controller, 'refresh').mockReturnThis();
@@ -197,9 +286,10 @@ describe('component vnZoneEvents', () => {
it('shoud make an HTTP POST query and then call the refresh() method', () => {
jest.spyOn(controller, 'refresh').mockReturnThis();
- const dates = [new Date()];
+ controller.excludeSelected = {};
+ controller.isNew = true;
$httpBackend.expect('POST', `Zones/1/exclusions`).respond({id: 1});
- controller.exclusionCreate(dates);
+ controller.exclusionCreate();
$httpBackend.flush();
expect(controller.refresh).toHaveBeenCalledWith();
@@ -210,25 +300,41 @@ describe('component vnZoneEvents', () => {
it('shoud make an HTTP DELETE query once and then call the refresh() method', () => {
jest.spyOn(controller, 'refresh').mockReturnThis();
- const exclusions = [{id: 1}];
+ const exclusions = {id: 1};
const firstExclusionId = 1;
- $httpBackend.when('DELETE', `Zones/1/exclusions/${firstExclusionId}`).respond(200);
+ $httpBackend.expectDELETE(`Zones/1/exclusions/${firstExclusionId}`).respond(200);
controller.exclusionDelete(exclusions);
$httpBackend.flush();
expect(controller.refresh).toHaveBeenCalledWith();
});
+ });
- it('shoud make an HTTP DELETE query for every event and then call the refresh() method', () => {
- jest.spyOn(controller, 'refresh').mockReturnThis();
- jest.spyOn(controller.$http, 'delete').mockReturnValue(200);
+ describe('onSearch()', () => {
+ it('should call the applyFilter() method and then set the data', () => {
+ jest.spyOn(controller, 'getChecked').mockReturnValue([1, 2, 3]);
- const exclusions = [{id: 1}, {id: 2}, {id: 3}, {id: 4}];
- controller.exclusionDelete(exclusions);
- $scope.$apply();
+ controller.$.treeview = {};
+ controller.$.model = crudModel;
+ controller.excludeSelected = {type: 'specificLocations'};
+ controller._excludeSearch = 'es';
- expect(controller.$http.delete).toHaveBeenCalledTimes(4);
- expect(controller.refresh).toHaveBeenCalledWith();
+ controller.onSearch();
+ const treeviewData = controller.$.treeview.data;
+
+ expect(treeviewData).toBeDefined();
+ expect(treeviewData.length).toEqual(3);
+ });
+ });
+
+ describe('onFetch()', () => {
+ it('should call the applyFilter() method and then return the model data', () => {
+ jest.spyOn(controller, 'getChecked').mockReturnValue([1, 2, 3]);
+
+ controller.$.model = crudModel;
+ const result = controller.onFetch();
+
+ expect(result.length).toEqual(3);
});
});
});
diff --git a/modules/zone/front/events/locale/es.yml b/modules/zone/front/events/locale/es.yml
index eb581a719..1fb114720 100644
--- a/modules/zone/front/events/locale/es.yml
+++ b/modules/zone/front/events/locale/es.yml
@@ -4,3 +4,7 @@ Exclude: Excluir
Events: Eventos
Add event: Añadir evento
Edit event: Editar evento
+All: Todo
+Specific locations: Localizaciones concretas
+Locations where it is not distributed: Localizaciones en las que no se reparte
+You must select a location: Debes seleccionar una localización
diff --git a/modules/zone/front/events/style.scss b/modules/zone/front/events/style.scss
new file mode 100644
index 000000000..49a6e87a6
--- /dev/null
+++ b/modules/zone/front/events/style.scss
@@ -0,0 +1,11 @@
+@import "variables";
+
+ .width{
+ width: 600px
+ }
+
+ .treeview{
+ max-height: 300px;
+ overflow: auto;
+ }
+
diff --git a/modules/zone/front/location/style.scss b/modules/zone/front/location/style.scss
index 2316a2622..24d685a51 100644
--- a/modules/zone/front/location/style.scss
+++ b/modules/zone/front/location/style.scss
@@ -1,19 +1,21 @@
@import "variables";
-vn-treeview-child {
- .content > .vn-check:not(.indeterminate):not(.checked) {
- color: $color-alert;
+vn-zone-location {
+ vn-treeview-child {
+ .content > .vn-check:not(.indeterminate):not(.checked) {
+ color: $color-alert;
- & > .btn {
- border-color: $color-alert;
+ & > .btn {
+ border-color: $color-alert;
+ }
+ }
+ .content > .vn-check.checked {
+ color: $color-notice;
+
+ & > .btn {
+ background-color: $color-notice;
+ border-color: $color-notice
+ }
}
}
- .content > .vn-check.checked {
- color: $color-notice;
-
- & > .btn {
- background-color: $color-notice;
- border-color: $color-notice
- }
- }
-}
\ No newline at end of file
+}
diff --git a/modules/zone/front/routes.json b/modules/zone/front/routes.json
index e08f97314..7f67260da 100644
--- a/modules/zone/front/routes.json
+++ b/modules/zone/front/routes.json
@@ -85,10 +85,13 @@
"description": "Warehouses"
},
{
- "url": "/events",
+ "url": "/events?q",
"state": "zone.card.events",
"component": "vn-zone-events",
- "description": "Calendar"
+ "description": "Calendar",
+ "params": {
+ "zone": "$ctrl.zone"
+ }
},
{
"url": "/location?q",
diff --git a/package.json b/package.json
index cb66a79a3..13a7096d6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "salix-back",
- "version": "6.8.0",
+ "version": "8.6.0",
"author": "Verdnatura Levante SL",
"description": "Salix backend",
"license": "GPL-3.0",