From c78c154ab0161d4e35e10b2dd4aa528cd99f661f Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Tue, 11 Feb 2020 14:41:59 +0100 Subject: [PATCH 01/14] Added datalist --- front/core/components/datalist/index.js | 2 - .../order/back/methods/order/catalogFilter.js | 1 + modules/order/front/catalog/index.html | 13 ++-- modules/order/front/catalog/index.js | 74 +++++++++++-------- modules/order/front/catalog/index.spec.js | 55 ++++++++++++-- modules/order/front/locale/es.yml | 1 + 6 files changed, 102 insertions(+), 44 deletions(-) diff --git a/front/core/components/datalist/index.js b/front/core/components/datalist/index.js index d5feb18932..0964a14805 100644 --- a/front/core/components/datalist/index.js +++ b/front/core/components/datalist/index.js @@ -157,8 +157,6 @@ export default class Datalist extends Textfield { this.destroyList(); } else this.buildList(); - - this.emit('select', {selection}); }); } diff --git a/modules/order/back/methods/order/catalogFilter.js b/modules/order/back/methods/order/catalogFilter.js index 3814aa12d1..114cd27864 100644 --- a/modules/order/back/methods/order/catalogFilter.js +++ b/modules/order/back/methods/order/catalogFilter.js @@ -162,6 +162,7 @@ module.exports = Self => { `SELECT it.tagFk, it.itemFk, + it.value, t.name FROM tmp.ticketCalculateItem tci JOIN vn.itemTag it ON it.itemFk = tci.itemFk diff --git a/modules/order/front/catalog/index.html b/modules/order/front/catalog/index.html index 5cc72e3c8f..37767e81bb 100644 --- a/modules/order/front/catalog/index.html +++ b/modules/order/front/catalog/index.html @@ -85,12 +85,15 @@ - + show-field="value" + value-field="value" + label="Search tag"> @@ -101,7 +104,7 @@ style="cursor: pointer;"> - + { - // Add new tag filters - item.tags.forEach(itemTag => { - const alreadyAdded = newFilterList.findIndex(filter => { - return filter.field == itemTag.tagFk; - }); - - if (alreadyAdded == -1) { - newFilterList.push({ - name: itemTag.name, - field: itemTag.tagFk, - isTag: true - }); - } - }); - }); - - // Add default filters - Replaces tags with same name - this.defaultOrderFields.forEach(orderField => { - const index = newFilterList.findIndex(newfield => { - return newfield.name == orderField.name; - }); - - if (index > -1) - newFilterList[index] = orderField; - else - newFilterList.push(orderField); - }); - - this.orderFields = newFilterList; + this.buildTagsFilter(value); + this.buildOrderFilter(value); } get categoryId() { @@ -273,6 +244,45 @@ class Controller { this.$state.go(this.$state.current.name, params); } + + // Builds the tags filter + buildTagsFilter(items) { + const tagValues = []; + items.forEach(item => { + item.tags.forEach(itemTag => { + const alreadyAdded = tagValues.findIndex(tag => { + return tag.value == itemTag.value; + }); + + if (alreadyAdded == -1) + tagValues.push(itemTag); + }); + }); + this.tagValues = tagValues; + } + + // Builds the order filter + buildOrderFilter(items) { + const tags = []; + items.forEach(item => { + item.tags.forEach(itemTag => { + const alreadyAdded = tags.findIndex(tag => { + return tag.field == itemTag.tagFk; + }); + + if (alreadyAdded == -1) { + tags.push({ + name: itemTag.name, + field: itemTag.tagFk, + isTag: true + }); + } + }); + }); + let newFilterList = [].concat(this.defaultOrderFields); + newFilterList = newFilterList.concat(tags); + this.orderFields = newFilterList; + } } Controller.$inject = ['$http', '$scope', '$state', '$compile', '$transitions']; diff --git a/modules/order/front/catalog/index.spec.js b/modules/order/front/catalog/index.spec.js index dd9e132577..01da618009 100644 --- a/modules/order/front/catalog/index.spec.js +++ b/modules/order/front/catalog/index.spec.js @@ -37,16 +37,19 @@ describe('Order', () => { describe('items() setter', () => { it(`should return an object with order params`, () => { - let expectedResult = [{field: 'showOrder, price', name: 'Color'}]; - let unexpectedResult = [{tagFk: 5, name: 'Color'}]; - controller.items = [{id: 1, name: 'My Item', tags: [ + spyOn(controller, 'buildTagsFilter'); + spyOn(controller, 'buildOrderFilter').and.callThrough(); + const expectedResult = [{field: 'showOrder, price', name: 'Color and price'}]; + const items = [{id: 1, name: 'My Item', tags: [ {tagFk: 4, name: 'Length'}, {tagFk: 5, name: 'Color'} ]}]; + controller.items = items; - expect(controller.orderFields.length).toEqual(5); + expect(controller.orderFields.length).toEqual(6); expect(controller.orderFields).toEqual(jasmine.arrayContaining(expectedResult)); - expect(controller.orderFields).not.toEqual(jasmine.arrayContaining(unexpectedResult)); + expect(controller.buildTagsFilter).toHaveBeenCalledWith(items); + expect(controller.buildOrderFilter).toHaveBeenCalledWith(items); }); }); @@ -222,6 +225,48 @@ describe('Order', () => { expect(controller.$.model.addFilter).toHaveBeenCalledWith(null, expectedOrder); }); }); + + describe('buildTagsFilter()', () => { + it(`should create an array of non repeated tag values and then set the tagValues property`, () => { + const items = [ + { + id: 1, name: 'My Item 1', tags: [ + {tagFk: 4, name: 'Length', value: 1}, + {tagFk: 5, name: 'Color', value: 'red'} + ] + }, + { + id: 2, name: 'My Item 2', tags: [ + {tagFk: 4, name: 'Length', value: 1}, + {tagFk: 5, name: 'Color', value: 'blue'} + ] + }]; + controller.buildTagsFilter(items); + + expect(controller.tagValues.length).toEqual(3); + }); + }); + + describe('buildOrderFilter()', () => { + it(`should create an array of non repeated tags plus default filters and then set the orderFields property`, () => { + const items = [ + { + id: 1, name: 'My Item 1', tags: [ + {tagFk: 4, name: 'Length'}, + {tagFk: 5, name: 'Color'} + ] + }, + { + id: 2, name: 'My Item 2', tags: [ + {tagFk: 5, name: 'Color'}, + {tagFk: 6, name: 'Relevancy'} + ] + }]; + controller.buildOrderFilter(items); + + expect(controller.orderFields.length).toEqual(7); + }); + }); }); }); diff --git a/modules/order/front/locale/es.yml b/modules/order/front/locale/es.yml index 0ada37bfd0..565d4f2518 100644 --- a/modules/order/front/locale/es.yml +++ b/modules/order/front/locale/es.yml @@ -16,6 +16,7 @@ Item id: Id de artículo Order by: Ordenar por Order: Orden Price: Precio +Color and price: Color y precio Ascendant: Ascendente Descendant: Descendente Created from: Creado desde From df873b4ac06a98d8299ae8c9d046788a819900f1 Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Thu, 13 Feb 2020 11:05:00 +0100 Subject: [PATCH 02/14] added datalist to catalog filter --- e2e/helpers/selectors.js | 4 ++-- front/core/components/datalist/index.js | 2 +- front/core/components/datalist/style.scss | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100755 front/core/components/datalist/style.scss diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 99c78eea2f..d92bb5b14e 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -606,8 +606,8 @@ export default { plantRealmButton: 'vn-order-catalog > vn-side-menu vn-icon[icon="icon-plant"]', type: 'vn-autocomplete[data="$ctrl.itemTypes"]', itemId: 'vn-order-catalog > vn-side-menu vn-textfield[ng-model="$ctrl.itemId"]', - itemTagValue: 'vn-order-catalog > vn-side-menu vn-textfield[ng-model="$ctrl.value"]', - openTagSearch: 'vn-order-catalog > vn-side-menu > div > vn-vertical > vn-textfield[ng-model="$ctrl.value"] .append i', + itemTagValue: 'vn-order-catalog > vn-side-menu vn-datalist[ng-model="$ctrl.value"]', + openTagSearch: 'vn-order-catalog > vn-side-menu > div > vn-vertical > vn-datalist[ng-model="$ctrl.value"] .append i', tag: 'vn-order-catalog-search-panel vn-autocomplete[ng-model="filter.tagFk"]', tagValue: 'vn-order-catalog-search-panel vn-textfield[ng-model="filter.value"]', searchTagButton: 'vn-order-catalog-search-panel button[type=submit]', diff --git a/front/core/components/datalist/index.js b/front/core/components/datalist/index.js index 0964a14805..bf3cab9a18 100644 --- a/front/core/components/datalist/index.js +++ b/front/core/components/datalist/index.js @@ -3,6 +3,7 @@ import ArrayModel from '../array-model/array-model'; import CrudModel from '../crud-model/crud-model'; import {mergeWhere} from 'vn-loopback/util/filter'; import Textfield from '../textfield/textfield'; +import './style.scss'; export default class Datalist extends Textfield { constructor($element, $scope, $compile, $transclude) { @@ -12,7 +13,6 @@ export default class Datalist extends Textfield { this._selection = null; this.buildInput('text'); - this.input.setAttribute('autocomplete', 'off'); } diff --git a/front/core/components/datalist/style.scss b/front/core/components/datalist/style.scss new file mode 100755 index 0000000000..db4ed2bb09 --- /dev/null +++ b/front/core/components/datalist/style.scss @@ -0,0 +1,7 @@ +@import "effects"; + +vn-datalist { + input::-webkit-calendar-picker-indicator { + display: none + } +} \ No newline at end of file From d9ed7cda384703c47bc0bbaa5bb746a4ace465e5 Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Mon, 17 Feb 2020 07:22:55 +0100 Subject: [PATCH 03/14] Added form dialog --- modules/item/back/methods/item/getCard.js | 3 + modules/item/back/models/item.json | 112 +++++++++++----------- modules/item/front/basic-data/index.html | 46 ++++++++- modules/item/front/basic-data/index.js | 22 +++-- 4 files changed, 115 insertions(+), 68 deletions(-) diff --git a/modules/item/back/methods/item/getCard.js b/modules/item/back/methods/item/getCard.js index 9780c5601e..50ff22321d 100644 --- a/modules/item/back/methods/item/getCard.js +++ b/modules/item/back/methods/item/getCard.js @@ -55,6 +55,9 @@ module.exports = Self => { } }] } + }, + { + relation: 'taxClass' } ] }; diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json index d8d1cb64d1..dbaa3a4090 100644 --- a/modules/item/back/models/item.json +++ b/modules/item/back/models/item.json @@ -1,13 +1,13 @@ { "name": "Item", - "base": "Loggable", - "log": { - "model":"ItemLog", + "base": "Loggable", + "log": { + "model": "ItemLog", "showField": "id" - }, + }, "options": { "mysql": { - "table": "item" + "table": "item" } }, "properties": { @@ -125,55 +125,55 @@ } }, "relations": { - "itemType": { - "type": "belongsTo", - "model": "ItemType", - "foreignKey": "typeFk" - }, - "ink": { - "type": "belongsTo", - "model": "Ink", - "foreignKey": "inkFk" - }, - "origin": { - "type": "belongsTo", - "model": "Origin", - "foreignKey": "originFk" - }, - "producer": { - "type": "belongsTo", - "model": "Producer", - "foreignKey": "producerFk" - }, - "intrastat": { - "type": "belongsTo", - "model": "Intrastat", - "foreignKey": "intrastatFk" - }, - "expense": { - "type": "belongsTo", - "model": "Expense", - "foreignKey": "expenseFk" - }, - "tags": { - "type": "hasMany", - "model": "ItemTag", - "foreignKey": "itemFk" - }, - "itemBarcode": { - "type": "hasMany", - "model": "ItemBarcode", - "foreignKey": "itemFk" - }, - "taxes": { - "type": "hasMany", - "model": "ItemTaxCountry", - "foreignKey": "itemFk" - }, - "itemNiche": { - "type": "hasMany", - "model": "ItemNiche", - "foreignKey": "itemFk" - } + "itemType": { + "type": "belongsTo", + "model": "ItemType", + "foreignKey": "typeFk" + }, + "ink": { + "type": "belongsTo", + "model": "Ink", + "foreignKey": "inkFk" + }, + "origin": { + "type": "belongsTo", + "model": "Origin", + "foreignKey": "originFk" + }, + "producer": { + "type": "belongsTo", + "model": "Producer", + "foreignKey": "producerFk" + }, + "intrastat": { + "type": "belongsTo", + "model": "Intrastat", + "foreignKey": "intrastatFk" + }, + "expense": { + "type": "belongsTo", + "model": "Expense", + "foreignKey": "expenseFk" + }, + "tags": { + "type": "hasMany", + "model": "ItemTag", + "foreignKey": "itemFk" + }, + "itemBarcode": { + "type": "hasMany", + "model": "ItemBarcode", + "foreignKey": "itemFk" + }, + "taxes": { + "type": "hasMany", + "model": "ItemTaxCountry", + "foreignKey": "itemFk" + }, + "itemNiche": { + "type": "hasMany", + "model": "ItemNiche", + "foreignKey": "itemFk" + } } - } \ No newline at end of file +} \ No newline at end of file diff --git a/modules/item/front/basic-data/index.html b/modules/item/front/basic-data/index.html index bd0cec86de..16d37ff044 100644 --- a/modules/item/front/basic-data/index.html +++ b/modules/item/front/basic-data/index.html @@ -55,6 +55,13 @@
{{::id}}
{{::description}}
+ + + + - + @@ -134,3 +141,38 @@ + + + + +
New intrastat
+ + + + + + + + + + +
+ + + + +
\ No newline at end of file diff --git a/modules/item/front/basic-data/index.js b/modules/item/front/basic-data/index.js index 123aa59cdc..3c3d62c747 100644 --- a/modules/item/front/basic-data/index.js +++ b/modules/item/front/basic-data/index.js @@ -1,20 +1,22 @@ import ngModule from '../module'; +import Component from 'core/lib/component'; +class Controller extends Component { + showIntrastat(event) { + if (event.defaultPrevented) return; + event.preventDefault(); -class Controller { - constructor($scope, $timeout) { - this.$scope = $scope; - this.$timeout = $timeout; + this.newIntrastat = { + taxClassFk: this.item.taxClassFk + }; + this.$.intrastat.show(); } - $onChanges(data) { - this.$timeout(() => { - this.$scope.watcher.data = data.item.currentValue; - }); + onCustomAgentAccept() { + return this.$http.post(`CustomsAgents`, this.newCustomsAgent) + .then(res => this.address.customsAgentFk = res.data.id); } } -Controller.$inject = ['$scope', '$timeout']; - ngModule.component('vnItemBasicData', { template: require('./index.html'), bindings: { From 578556b1d553403d16ac679bc777275ba54d9e5e Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Mon, 17 Feb 2020 08:38:19 +0100 Subject: [PATCH 04/14] 2121 - Client balance fix balance on pagination --- modules/client/front/balance/index/index.html | 6 +-- modules/client/front/balance/index/index.js | 13 +++++- .../client/front/balance/index/index.spec.js | 43 +++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/modules/client/front/balance/index/index.html b/modules/client/front/balance/index/index.html index f42998bbd9..8cdb5c9712 100644 --- a/modules/client/front/balance/index/index.html +++ b/modules/client/front/balance/index/index.html @@ -85,9 +85,9 @@ {{::balance.bankFk}} - {{::balance.debit | currency: 'EUR':2}} - {{::balance.credit | currency: 'EUR':2}} - {{balance.balance | currency: 'EUR':2}} + {{::balance.debit | currency: 'EUR':2}} + {{::balance.credit | currency: 'EUR':2}} + {{balance.balance | currency: 'EUR':2}} { expect(expectedBalances[2].balance).toEqual(213.24); }); }); + + describe('balances() setter', () => { + it('should set the balances data and not call the getBalances() method', () => { + spyOn(controller, 'getBalances'); + controller.$.riskModel.data = null; + controller.balances = [{ + id: 1, + debit: 1000, + credit: null + }, { + id: 2, + debit: null, + credit: 500 + }, { + id: 3, + debit: null, + credit: 300 + }]; + + expect(controller.balances).toBeDefined(); + expect(controller.getBalances).not.toHaveBeenCalledWith(); + }); + + it('should set the balances data and then call the getBalances() method', () => { + spyOn(controller, 'getBalances'); + controller.balances = [{ + id: 1, + debit: 1000, + credit: null + }, { + id: 2, + debit: null, + credit: 500 + }, { + id: 3, + debit: null, + credit: 300 + }]; + + expect(controller.balances).toBeDefined(); + expect(controller.getBalances).toHaveBeenCalledWith(); + }); + }); }); }); From 03f0a415f9f0c79cbc217ed8925f73b531c2cb83 Mon Sep 17 00:00:00 2001 From: jgallego Date: Mon, 17 Feb 2020 12:01:11 +0100 Subject: [PATCH 05/14] zoneClosure fase 2 --- db/changes/10141-zoneDoCalc/00-ticket.sql | 4 +- .../01-zoneClosure_recalc.sql | 1 - .../10141-zoneDoCalc/02-insertPastTickets.sql | 62 +++++++ .../03-getOptionsForLanding.sql | 66 +++++++ .../10141-zoneDoCalc/03-rutasAnalyze.sql | 171 ++++++++++++++++++ db/changes/10141-zoneDoCalc/03-saleVolume.sql | 26 +++ .../10141-zoneDoCalc/03-viewSaleFreight__.sql | 24 +++ .../03-zone_geShippedWarehouse.sql | 41 +++++ .../10141-zoneDoCalc/03-zone_getAgency.sql | 42 +++++ .../10141-zoneDoCalc/03-zone_getAvailable.sql | 18 ++ .../10141-zoneDoCalc/03-zone_getWarehouse.sql | 41 +++++ 11 files changed, 493 insertions(+), 3 deletions(-) delete mode 100644 db/changes/10141-zoneDoCalc/01-zoneClosure_recalc.sql create mode 100644 db/changes/10141-zoneDoCalc/02-insertPastTickets.sql create mode 100644 db/changes/10141-zoneDoCalc/03-getOptionsForLanding.sql create mode 100644 db/changes/10141-zoneDoCalc/03-rutasAnalyze.sql create mode 100644 db/changes/10141-zoneDoCalc/03-saleVolume.sql create mode 100644 db/changes/10141-zoneDoCalc/03-viewSaleFreight__.sql create mode 100644 db/changes/10141-zoneDoCalc/03-zone_geShippedWarehouse.sql create mode 100644 db/changes/10141-zoneDoCalc/03-zone_getAgency.sql create mode 100644 db/changes/10141-zoneDoCalc/03-zone_getAvailable.sql create mode 100644 db/changes/10141-zoneDoCalc/03-zone_getWarehouse.sql diff --git a/db/changes/10141-zoneDoCalc/00-ticket.sql b/db/changes/10141-zoneDoCalc/00-ticket.sql index c116e51399..a756a11afe 100644 --- a/db/changes/10141-zoneDoCalc/00-ticket.sql +++ b/db/changes/10141-zoneDoCalc/00-ticket.sql @@ -3,9 +3,9 @@ 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` ( +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 + CONSTRAINT `zoneCalcTicketfk_1` FOREIGN KEY (`zoneFk`) REFERENCES `vn`.`zone` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; DROP EVENT IF EXISTS vn.`zone_doCalc`; diff --git a/db/changes/10141-zoneDoCalc/01-zoneClosure_recalc.sql b/db/changes/10141-zoneDoCalc/01-zoneClosure_recalc.sql deleted file mode 100644 index f015eb894b..0000000000 --- a/db/changes/10141-zoneDoCalc/01-zoneClosure_recalc.sql +++ /dev/null @@ -1 +0,0 @@ -USE `vn`; diff --git a/db/changes/10141-zoneDoCalc/02-insertPastTickets.sql b/db/changes/10141-zoneDoCalc/02-insertPastTickets.sql new file mode 100644 index 0000000000..4314e5d7d9 --- /dev/null +++ b/db/changes/10141-zoneDoCalc/02-insertPastTickets.sql @@ -0,0 +1,62 @@ +USE `vn`; +DROP procedure IF EXISTS `zone_doCalcInitialize`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `zone_doCalcInitialize`() +proc: BEGIN +/** + * Initialize ticket + */ + DECLARE vDone BOOL; + DECLARE vTicketFk INT; + DECLARE vLanded DATE; + DECLARE vZoneFk INT; + + DECLARE cCur CURSOR FOR + SELECT t.id, t.landed, t.zoneFk + FROM ticket t + WHERE (zonePrice IS NULL OR zoneBonus IS NULL OR zoneClosure IS NULL) + AND landed >= '2019-01-01' AND shipped >= '2019-01-01' + GROUP BY landed, zoneFk; + + DECLARE CONTINUE HANDLER FOR NOT FOUND + SET vDone = TRUE; + + OPEN cCur; + + myLoop: LOOP + SET vDone = FALSE; + FETCH cCur INTO vTicketFk, vLanded, 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_getOptionsForLanding(vLanded, TRUE); + + UPDATE ticket t + LEFT JOIN tmp.zoneOption zo ON TRUE + SET zonePrice = zo.price, zoneBonus = zo.bonus, zoneClosure = zo.`hour` + WHERE t.zoneFk = vZoneFk AND landed = vLanded; + + UPDATE ticket t + LEFT JOIN vn.zone z ON z.id = t.zoneFk + SET zonePrice = z.price, zoneBonus = z.bonus, zoneClosure = z.`hour` + WHERE t.zonePrice IS NULL AND z.id = vZoneFk + AND landed >= '2019-01-01' AND shipped >= '2019-01-01'; + + END LOOP; + + CLOSE cCur; + + DELETE FROM zoneCalcTicket; +END$$ + +DELIMITER ; \ No newline at end of file diff --git a/db/changes/10141-zoneDoCalc/03-getOptionsForLanding.sql b/db/changes/10141-zoneDoCalc/03-getOptionsForLanding.sql new file mode 100644 index 0000000000..e0f5f9a48b --- /dev/null +++ b/db/changes/10141-zoneDoCalc/03-getOptionsForLanding.sql @@ -0,0 +1,66 @@ +USE `vn`; +DROP procedure IF EXISTS `zone_getOptionsForLanding`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `zone_getOptionsForLanding`(vLanded DATE, vShowExpiredZones BOOLEAN) +BEGIN +/** + * Gets computed options for the passed zones and delivery date. + * + * @table tmp.zones(id) The zones ids + * @param vLanded The delivery date + * @return tmp.zoneOption The computed options + */ + DROP TEMPORARY TABLE IF EXISTS tmp.zoneOption; + CREATE TEMPORARY TABLE tmp.zoneOption + ENGINE = MEMORY + SELECT + zoneFk, + `hour`, + travelingDays, + price, + bonus, + TIMESTAMPADD(DAY, -travelingDays, vLanded) shipped + FROM ( + SELECT t.id zoneFk, + TIME(IFNULL(e.`hour`, z.`hour`)) `hour`, + IFNULL(e.travelingDays, z.travelingDays) travelingDays, + IFNULL(e.price, z.price) price, + IFNULL(e.bonus, z.bonus) bonus + FROM tmp.zone t + JOIN zone z ON z.id = t.id + JOIN zoneEvent e ON e.zoneFk = t.id + WHERE ( + e.`type` = 'day' + AND e.dated = vLanded + ) OR ( + e.`type` != 'day' + AND e.weekDays & (1 << WEEKDAY(vLanded)) + AND (e.`started` IS NULL OR vLanded >= e.`started`) + AND (e.`ended` IS NULL OR vLanded <= e.`ended`) + ) + ORDER BY + zoneFk, + CASE + WHEN e.`type` = 'day' + THEN 1 + WHEN e.`type` = 'range' + THEN 2 + ELSE 3 + END + ) t + GROUP BY zoneFk; + + DELETE t FROM tmp.zoneOption t + JOIN zoneExclusion e + ON e.zoneFk = t.zoneFk AND e.`dated` = vLanded; + + IF NOT vShowExpiredZones THEN + DELETE FROM tmp.zoneOption + WHERE shipped < CURDATE() + OR (shipped = CURDATE() AND CURTIME() > `hour`); + END IF; +END$$ + +DELIMITER ; \ No newline at end of file diff --git a/db/changes/10141-zoneDoCalc/03-rutasAnalyze.sql b/db/changes/10141-zoneDoCalc/03-rutasAnalyze.sql new file mode 100644 index 0000000000..313f2f797a --- /dev/null +++ b/db/changes/10141-zoneDoCalc/03-rutasAnalyze.sql @@ -0,0 +1,171 @@ +USE `vn`; +DROP procedure IF EXISTS `rutasAnalyze`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `rutasAnalyze`(vYear INT, vMonth INT) +BEGIN + +/* Analiza los costes de las rutas de reparto y lo almacena en la tabla Rutas_Master +* +* PAK 15/4/2019 +*/ + + DELETE FROM bi.rutasBoard + WHERE year = vYear AND month = vMonth; + + -- Rellenamos la tabla con los datos de las rutas VOLUMETRICAS, especialmente con los bultos "virtuales" + INSERT INTO bi.rutasBoard(year, + month, + warehouse_id, + Id_Ruta, + Id_Agencia, + km, + Dia, + Fecha, + Bultos, + Matricula, + Tipo, + Terceros) + SELECT YEAR(r.created), + MONTH(r.created), + GREATEST(1,a.warehouseFk), + r.id, + r.agencyModeFk, + r.kmEnd - r.kmStart, + DAYNAME(r.created), + r.created, + SUM(sv.volume / ebv.m3), + v.numberPlate, + IF(ISNULL(`r`.`cost`), 'P', 'A'), + r.cost + FROM vn.route r + JOIN vn.ticket t ON t.routeFk = r.id + LEFT JOIN vn.zone z ON z.id = t.zoneFk + LEFT JOIN vn.agencyMode am ON am.id = r.agencyModeFk + LEFT JOIN vn.agency a ON a.id = am.agencyFk + LEFT JOIN vn.vehicle v ON v.id = r.vehicleFk + JOIN vn.saleVolume sv ON sv.ticketFk = t.id + JOIN vn.expeditionBoxVol ebv ON ebv.boxFk = 71 + WHERE YEAR(r.created) = vYear AND MONTH(r.created) = vMonth + AND z.isVolumetric + GROUP BY r.id; + + -- Rellenamos la tabla con los datos de las rutas NO VOLUMETRICAS, especialmente con los bultos "virtuales" + INSERT INTO bi.rutasBoard(year, + month, + warehouse_id, + Id_Ruta, + Id_Agencia, + km, + Dia, + Fecha, + Bultos, + Matricula, + Tipo, + Terceros) + SELECT YEAR(r.created), + MONTH(r.created), + GREATEST(1,a.warehouseFk), + r.id, + r.agencyModeFk, + r.kmEnd - r.kmStart, + DAYNAME(r.created), + r.created, + SUM(t.packages), + v.numberPlate, + IF(ISNULL(`r`.`cost`), 'P', 'A'), + r.cost + FROM vn.route r + JOIN vn.ticket t ON t.routeFk = r.id + LEFT JOIN vn.zone z ON z.id = t.zoneFk + LEFT JOIN vn.agencyMode am ON am.id = r.agencyModeFk + LEFT JOIN vn.agency a ON a.id = am.agencyFk + LEFT JOIN vn.vehicle v ON v.id = r.vehicleFk + WHERE YEAR(r.created) = vYear AND MONTH(r.created) = vMonth + AND z.isVolumetric = FALSE + GROUP BY r.id + ON DUPLICATE KEY UPDATE Bultos = Bultos + VALUES(Bultos); + + -- Coste REAL de cada bulto "virtual", de acuerdo con el valor apuntado a mano en la ruta + UPDATE bi.rutasBoard r + INNER JOIN vn2008.Rutas_Master rm ON rm.año = r.year AND rm.mes = r.month AND rm.warehouse_id = r.warehouse_id + SET r.coste_bulto = IF(r.Tipo ='A', r.Terceros, r.km * rm.coste_km ) / r.Bultos + WHERE r.Bultos > 0 + AND rm.año = vYear + AND rm.mes = vMonth; + + -- Coste PRACTICO de cada bulto, de acuerdo con los componentes de tipo AGENCIA en cada linea de venta + UPDATE bi.rutasBoard r + JOIN ( + SELECT t.routeFk, sum(s.quantity * sc.value) practicoTotal + FROM vn.route r + JOIN vn.time tm ON tm.dated = r.created + JOIN vn.ticket t ON t.routeFk = r.id + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.saleComponent sc ON sc.saleFk = s.id + JOIN vn.`component` c ON c.id = sc.componentFk + JOIN vn.componentType ct ON ct.id = c.typeFk + WHERE ct.type = 'agencia' + AND tm.year = vYear + AND tm.month = vMonth + GROUP BY r.id + ) sub ON sub.routeFk = r.Id_Ruta + SET r.practico = sub.practicoTotal / r.Bultos; + + -- Coste TEORICO de una caja "virtual" para cada ruta, teniendo en cuenta que hay carros, pallets, etc + UPDATE bi.rutasBoard r + JOIN ( + SELECT t.routeFk, + SUM(t.zonePrice/ ebv.ratio)/ count(*) AS BultoTeoricoMedio + FROM vn.ticket t + JOIN vn.route r ON r.id = t.routeFk + JOIN vn.time tm ON tm.dated = r.created + JOIN vn.expedition e ON e.ticketFk = t.id + JOIN vn.expeditionBoxVol ebv ON ebv.boxFk = e.isBox + JOIN vn.address ad ON ad.id = t.addressFk + JOIN vn.client c ON c.id = ad.clientFk + LEFT JOIN vn.zone z ON z.id = t.zoneFk + WHERE tm.year = vYear + AND tm.month = vMonth + AND z.isVolumetric = FALSE + GROUP BY t.routeFk) sub ON r.Id_Ruta = sub.routeFk + SET r.teorico = sub.BultoTeoricoMedio; + + -- Coste VOLUMETRICO TEORICO de una caja "virtual" para cada ruta + UPDATE bi.rutasBoard r + JOIN ( + SELECT t.routeFk, + SUM(freight) AS BultoTeoricoMedio + FROM vn.ticket t + JOIN vn.route r ON r.id = t.routeFk + JOIN vn.time tm ON tm.dated = r.created + JOIN vn.saleVolume sf ON sf.ticketFk = t.id + JOIN vn.client c ON c.id = t.clientFk + JOIN vn.zone z ON z.id = t.zoneFk + WHERE tm.year = vYear + AND tm.month = vMonth + AND z.isVolumetric != FALSE + GROUP BY t.routeFk) sub ON r.Id_Ruta = sub.routeFk + SET r.teorico = sub.BultoTeoricoMedio / r.Bultos; + + -- La diferencia entre el teorico y el practico se deberia de cobrar en greuges, cada noche + UPDATE bi.rutasBoard r + JOIN ( + SELECT t.routeFk, + Sum(g.amount) AS greuge + FROM vn.ticket t + JOIN vn.route r ON r.id = t.routeFk + JOIN vn.time tm ON tm.dated = r.created + JOIN vn.greuge g ON g.ticketFk = t.id + JOIN vn.greugeType gt ON gt.id = g.greugeTypeFk + WHERE tm.year = vYear + AND tm.month = vMonth + AND gt.name = 'Diferencia portes' + GROUP BY t.routeFk) sub ON r.Id_Ruta = sub.routeFk + SET r.greuge = sub.greuge / r.Bultos; + +END$$ + +DELIMITER ; + diff --git a/db/changes/10141-zoneDoCalc/03-saleVolume.sql b/db/changes/10141-zoneDoCalc/03-saleVolume.sql new file mode 100644 index 0000000000..2ded49a8d3 --- /dev/null +++ b/db/changes/10141-zoneDoCalc/03-saleVolume.sql @@ -0,0 +1,26 @@ +USE `vn`; +CREATE + OR REPLACE ALGORITHM = UNDEFINED + DEFINER = `root`@`%` + SQL SECURITY DEFINER +VIEW `saleVolume` AS + SELECT + `s`.`ticketFk` AS `ticketFk`, + `s`.`id` AS `saleFk`, + IFNULL(ROUND(((((`i`.`compression` * (GREATEST(`i`.`density`, 167) / 167)) * `ic`.`cm3`) * `s`.`quantity`) / 1000), + 2), + 0) AS `litros`, + `t`.`routeFk` AS `routeFk`, + `t`.`shipped` AS `shipped`, + (((`s`.`quantity` * `ic`.`cm3`) * `i`.`compression`) / 1000000) AS `volume`, + ((((`s`.`quantity` * `ic`.`cm3`) * `i`.`compression`) * (GREATEST(`i`.`density`, 167) / 167)) / 1000000) AS `physicalWeight`, + (((`s`.`quantity` * `ic`.`cm3`) * `i`.`density`) / 1000000) AS `weight`, + (((`s`.`quantity` * `ic`.`cm3`) * `i`.`compression`) / 1000000) AS `physicalVolume`, + ((((`s`.`quantity` * `ic`.`cm3`) * `t`.`zonePrice`) * `i`.`compression`) / `cb`.`volume`) AS `freight` + FROM + ((((`sale` `s` + JOIN `item` `i` ON ((`i`.`id` = `s`.`itemFk`))) + JOIN `ticket` `t` ON ((`t`.`id` = `s`.`ticketFk`))) + JOIN `packaging` `cb` ON ((`cb`.`id` = '94'))) + JOIN `itemCost` `ic` ON (((`ic`.`itemFk` = `s`.`itemFk`) + AND (`ic`.`warehouseFk` = `t`.`warehouseFk`)))); diff --git a/db/changes/10141-zoneDoCalc/03-viewSaleFreight__.sql b/db/changes/10141-zoneDoCalc/03-viewSaleFreight__.sql new file mode 100644 index 0000000000..903c8b48ac --- /dev/null +++ b/db/changes/10141-zoneDoCalc/03-viewSaleFreight__.sql @@ -0,0 +1,24 @@ +DROP VIEW IF EXISTS `vn`.`saleFreight` ; +USE `vn`; +CREATE + OR REPLACE ALGORITHM = UNDEFINED + DEFINER = `root`@`%` + SQL SECURITY DEFINER +VIEW `saleFreight__` AS + SELECT + `s`.`ticketFk` AS `ticketFk`, + `t`.`clientFk` AS `clientFk`, + `t`.`routeFk` AS `routeFk`, + `s`.`id` AS `saleFk`, + `t`.`zoneFk` AS `zoneFk`, + `t`.`companyFk` AS `companyFk`, + `t`.`shipped` AS `shipped`, + `t`.`zonePrice` AS `price`, + ((((`s`.`quantity` * `r`.`cm3`) * `t`.`zonePrice`) * `i`.`compression`) / `cb`.`volume`) AS `freight` + FROM + ((((`vn`.`sale` `s` + JOIN `vn`.`item` `i` ON ((`i`.`id` = `s`.`itemFk`))) + JOIN `vn`.`ticket` `t` ON ((`t`.`id` = `s`.`ticketFk`))) + JOIN `vn`.`packaging` `cb` ON ((`cb`.`id` = '94'))) + JOIN `bi`.`rotacion` `r` ON (((`r`.`Id_Article` = `s`.`itemFk`) + AND (`r`.`warehouse_id` = `t`.`warehouseFk`)))); diff --git a/db/changes/10141-zoneDoCalc/03-zone_geShippedWarehouse.sql b/db/changes/10141-zoneDoCalc/03-zone_geShippedWarehouse.sql new file mode 100644 index 0000000000..14d5d8cd9a --- /dev/null +++ b/db/changes/10141-zoneDoCalc/03-zone_geShippedWarehouse.sql @@ -0,0 +1,41 @@ +USE `vn`; +DROP procedure IF EXISTS `zone_getShippedWarehouse`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `zone_getShippedWarehouse`(vLanded DATE, vAddressFk INT, vAgencyModeFk INT) +BEGIN +/** + * Devuelve la mínima fecha de envío para cada warehouse + * + * @param vLanded La fecha de recepcion + * @param vAddressFk Id del consignatario + * @param vAgencyModeFk Id de la agencia + * @return tmp.zoneGetShipped + */ + + CALL zone_getFromGeo(address_getGeo(vAddressFk)); + CALL zone_getOptionsForLanding(vLanded,TRUE); + + DROP TEMPORARY TABLE IF EXISTS tmp.zoneGetShipped; + CREATE TEMPORARY TABLE tmp.zoneGetShipped + ENGINE = MEMORY + SELECT * FROM ( + SELECT zo.zoneFk, + TIMESTAMPADD(DAY,-zo.travelingDays, vLanded) shipped, + zo.`hour`, + zw.warehouseFk, + z.agencyModeFk + FROM tmp.zoneOption zo + JOIN zoneWarehouse zw ON zw.zoneFk = zo.zoneFk + JOIN zone z ON z.id = zo.zoneFk + WHERE z.agencyModeFk = vAgencyModeFk + ORDER BY shipped) t + GROUP BY warehouseFk; + + DROP TEMPORARY TABLE + tmp.zone, + tmp.zoneOption; +END$$ + +DELIMITER ; \ No newline at end of file diff --git a/db/changes/10141-zoneDoCalc/03-zone_getAgency.sql b/db/changes/10141-zoneDoCalc/03-zone_getAgency.sql new file mode 100644 index 0000000000..b2837d43cd --- /dev/null +++ b/db/changes/10141-zoneDoCalc/03-zone_getAgency.sql @@ -0,0 +1,42 @@ +USE `vn`; +DROP procedure IF EXISTS `zone_getAgency`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `zone_getAgency`(vAddress INT, vLanded DATE) +BEGIN +/** + * Devuelve el listado de agencias disponibles para la fecha + * y dirección pasadas. + * + * @param vAddress Id de dirección de envío, %NULL si es recogida + * @param vLanded Fecha de recogida + * @select Listado de agencias disponibles + */ + + CALL zone_getFromGeo(address_getGeo(vAddress)); + CALL zone_getOptionsForLanding(vLanded, FALSE); + + DROP TEMPORARY TABLE IF EXISTS tmp.zoneGetAgency; + CREATE TEMPORARY TABLE tmp.zoneGetAgency + (INDEX (agencyModeFk)) ENGINE = MEMORY + SELECT am.name agencyMode, + am.description, + z.agencyModeFk, + am.deliveryMethodFk, + TIMESTAMPADD(DAY,-zo.travelingDays, vLanded) shipped, + TRUE isIncluded, + zo.zoneFk + FROM tmp.zoneOption zo + JOIN zone z ON z.id = zo.zoneFk + JOIN agencyMode am ON am.id = z.agencyModeFk + GROUP BY agencyModeFk; + + DROP TEMPORARY TABLE + tmp.zone, + tmp.zoneOption; + +END$$ + +DELIMITER ; + diff --git a/db/changes/10141-zoneDoCalc/03-zone_getAvailable.sql b/db/changes/10141-zoneDoCalc/03-zone_getAvailable.sql new file mode 100644 index 0000000000..2ef1a1ae96 --- /dev/null +++ b/db/changes/10141-zoneDoCalc/03-zone_getAvailable.sql @@ -0,0 +1,18 @@ +USE `vn`; +DROP procedure IF EXISTS `zone_getAvailable`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `zone_getAvailable`(vAddress INT, vLanded DATE) +BEGIN + CALL zone_getFromGeo(address_getGeo(vAddress)); + CALL zone_getOptionsForLanding(vLanded, FALSE); + + SELECT * FROM tmp.zoneOption; + + DROP TEMPORARY TABLE + tmp.zone, + tmp.zoneOption; +END$$ + +DELIMITER ; \ No newline at end of file diff --git a/db/changes/10141-zoneDoCalc/03-zone_getWarehouse.sql b/db/changes/10141-zoneDoCalc/03-zone_getWarehouse.sql new file mode 100644 index 0000000000..c1cea8b136 --- /dev/null +++ b/db/changes/10141-zoneDoCalc/03-zone_getWarehouse.sql @@ -0,0 +1,41 @@ +USE `vn`; +DROP procedure IF EXISTS `zone_getWarehouse`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `zone_getWarehouse`(vAddress INT, vLanded DATE, vWarehouse INT) +BEGIN +/** + * Devuelve el listado de agencias disponibles para la fecha, + * dirección y almacén pasados. + * + * @param vAddress + * @param vWarehouse warehouse + * @param vLanded Fecha de recogida + * @select Listado de agencias disponibles + */ + + CALL zone_getFromGeo(address_getGeo(vAddress)); + CALL zone_getOptionsForLanding(vLanded, FALSE); + + SELECT am.id agencyModeFk, + am.name agencyMode, + am.description, + am.deliveryMethodFk, + TIMESTAMPADD(DAY, -zo.travelingDays, vLanded) shipped, + zw.warehouseFk, + z.id zoneFk + FROM tmp.zoneOption zo + JOIN zone z ON z.id = zo.zoneFk + JOIN agencyMode am ON am.id = z.agencyModeFk + JOIN zoneWarehouse zw ON zw.zoneFk = zo.zoneFk + WHERE zw.warehouseFk + GROUP BY z.agencyModeFk + ORDER BY agencyMode; + + DROP TEMPORARY TABLE + tmp.zone, + tmp.zoneOption; +END$$ + +DELIMITER ; \ No newline at end of file From 844b27acb9511c5400f094640a47388c78104111 Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Mon, 17 Feb 2020 12:47:03 +0100 Subject: [PATCH 06/14] 2118 - Create new intrastat --- db/changes/10160-postValentineDay/00-ACL.sql | 2 + .../00-taxClassCode.sql | 23 +++++++ db/dump/fixtures.sql | 8 ++- e2e/helpers/selectors.js | 4 ++ e2e/paths/04-item/02_basic_data.spec.js | 24 +++++++- .../item/back/methods/item/createIntrastat.js | 61 +++++++++++++++++++ modules/item/back/methods/item/getCard.js | 3 - .../item/specs/createIntrastat.spec.js | 22 +++++++ modules/item/back/model-config.json | 3 + modules/item/back/models/item.js | 1 + modules/item/back/models/tax-class-code.json | 47 ++++++++++++++ .../__snapshots__/index.spec.js.snap | 3 - modules/item/front/basic-data/index.html | 18 ++---- modules/item/front/basic-data/index.js | 7 ++- 14 files changed, 201 insertions(+), 25 deletions(-) create mode 100644 db/changes/10160-postValentineDay/00-ACL.sql create mode 100644 db/changes/10160-postValentineDay/00-taxClassCode.sql create mode 100644 modules/item/back/methods/item/createIntrastat.js create mode 100644 modules/item/back/methods/item/specs/createIntrastat.spec.js create mode 100644 modules/item/back/models/tax-class-code.json delete mode 100644 modules/item/front/basic-data/__snapshots__/index.spec.js.snap diff --git a/db/changes/10160-postValentineDay/00-ACL.sql b/db/changes/10160-postValentineDay/00-ACL.sql new file mode 100644 index 0000000000..5b6301e3df --- /dev/null +++ b/db/changes/10160-postValentineDay/00-ACL.sql @@ -0,0 +1,2 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES ('Intrastat', '*', '*', 'ALLOW', 'ROLE', 'buyer'); diff --git a/db/changes/10160-postValentineDay/00-taxClassCode.sql b/db/changes/10160-postValentineDay/00-taxClassCode.sql new file mode 100644 index 0000000000..bdc7cb474c --- /dev/null +++ b/db/changes/10160-postValentineDay/00-taxClassCode.sql @@ -0,0 +1,23 @@ +ALTER TABLE `vn`.`taxClassCode` +DROP FOREIGN KEY `taxClassCode_ibfk_2`, +DROP FOREIGN KEY `taxClassCode_ibfk_1`; +ALTER TABLE `vn`.`taxClassCode` +ADD COLUMN `id` INT NOT NULL AUTO_INCREMENT FIRST, +DROP PRIMARY KEY, +ADD PRIMARY KEY (`id`), +DROP INDEX `iva_codigo_id` ; + +ALTER TABLE `vn`.`taxClassCode` +ADD UNIQUE INDEX `taxClassCode_unique` (`taxClassFk` ASC, `effectived` ASC, `taxCodeFk` ASC) VISIBLE; + +ALTER TABLE `vn`.`taxClassCode` +ADD CONSTRAINT `taxClassCode_taxClassFk` + FOREIGN KEY (`taxClassFk`) + REFERENCES `vn`.`taxClass` (`id`) + ON DELETE RESTRICT + ON UPDATE CASCADE, +ADD CONSTRAINT `taxClassCode_taxCodeFk` + FOREIGN KEY (`taxCodeFk`) + REFERENCES `vn`.`taxCode` (`id`) + ON DELETE RESTRICT + ON UPDATE CASCADE; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index f3dd36976b..80bb377090 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -684,8 +684,14 @@ INSERT INTO `vn`.`taxCode`(`id`, `dated`, `code`, `taxTypeFk`, `rate`, `equaliza INSERT INTO `vn`.`taxClass`(`id`, `description`, `code`) VALUES - (1, 'Reduced VAT','R'), + (1, 'Reduced VAT', 'R'), (2, 'General VAT', 'G'); + +INSERT INTO `vn`.`taxClassCode`(`id`, `taxClassFk`, `effectived`, `taxCodeFk`) + VALUES + (1, 1, CURDATE(), 1), + (2, 1, CURDATE(), 21), + (3, 2, CURDATE(), 2); INSERT INTO `vn`.`intrastat`(`id`, `description`, `taxClassFk`, `taxCodeFk`) VALUES diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 63d40f9d5b..1510ff8936 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -262,6 +262,10 @@ export default { longName: 'vn-textfield[ng-model="$ctrl.item.longName"]', isActiveCheckbox: 'vn-check[label="Active"]', priceInKgCheckbox: 'vn-check[label="Price in kg"]', + newIntrastatButton: 'vn-item-basic-data vn-icon-button[vn-tooltip="New intrastat"] > button', + newIntrastatId: '.vn-dialog.shown vn-input-number[ng-model="$ctrl.newIntrastat.intrastatId"]', + newIntrastatDescription: '.vn-dialog.shown vn-textfield[ng-model="$ctrl.newIntrastat.description"]', + acceptIntrastatButton: '.vn-dialog.shown button[response="accept"]', submitBasicDataButton: `button[type=submit]` }, itemTags: { diff --git a/e2e/paths/04-item/02_basic_data.spec.js b/e2e/paths/04-item/02_basic_data.spec.js index 2c8a8a7a10..64827ed9ba 100644 --- a/e2e/paths/04-item/02_basic_data.spec.js +++ b/e2e/paths/04-item/02_basic_data.spec.js @@ -39,6 +39,26 @@ describe('Item Edit basic data path', () => { expect(result).toEqual('Data saved!'); }, 20000); + it(`should create a new intrastat`, async() => { + await page.waitToClick(selectors.itemBasicData.newIntrastatButton); + await page.write(selectors.itemBasicData.newIntrastatId, '588420239'); + await page.write(selectors.itemBasicData.newIntrastatDescription, 'Tropical Flowers'); + await page.waitToClick(selectors.itemBasicData.acceptIntrastatButton); + await page.waitForTextInField(selectors.itemBasicData.intrastat, 'Tropical Flowers'); + let newcode = await page.waitToGetProperty(selectors.itemBasicData.intrastat, 'value'); + + expect(newcode).toEqual('588420239 Tropical Flowers'); + }); + + it(`should save with the new intrastat`, async() => { + await page.waitFor(250); + await page.waitForTextInField(selectors.itemBasicData.intrastat, 'Tropical Flowers'); + await page.waitToClick(selectors.itemBasicData.submitBasicDataButton); + const result = await page.waitForLastSnackbar(); + + expect(result).toEqual('Data saved!'); + }); + it(`should confirm the item name was edited`, async() => { await page.reloadSection('item.card.basicData'); const result = await page.waitToGetProperty(selectors.itemBasicData.name, 'value'); @@ -53,11 +73,11 @@ describe('Item Edit basic data path', () => { expect(result).toEqual('Anthurium'); }); - it(`should confirm the item intrastad was edited`, async() => { + it(`should confirm the item intrastat was edited`, async() => { const result = await page .waitToGetProperty(selectors.itemBasicData.intrastat, 'value'); - expect(result).toEqual('5080000 Coral y materiales similares'); + expect(result).toEqual('588420239 Tropical Flowers'); }); it(`should confirm the item relevancy was edited`, async() => { diff --git a/modules/item/back/methods/item/createIntrastat.js b/modules/item/back/methods/item/createIntrastat.js new file mode 100644 index 0000000000..1a88d16e25 --- /dev/null +++ b/modules/item/back/methods/item/createIntrastat.js @@ -0,0 +1,61 @@ +let UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethod('createIntrastat', { + description: 'Creates a new item intrastat', + accessType: 'WRITE', + accepts: [{ + arg: 'id', + type: 'number', + required: true, + description: 'The item id', + http: {source: 'path'} + }, + { + arg: 'intrastatId', + type: 'number', + required: true + }, + { + arg: 'description', + type: 'string', + required: true + }], + returns: { + type: 'boolean', + root: true + }, + http: { + path: `/:id/createIntrastat`, + verb: 'PATCH' + } + }); + + Self.createIntrastat = async(id, intrastatId, description) => { + const models = Self.app.models; + const country = await models.Country.findOne({ + where: {code: 'ES'} + }); + + const itemTaxCountry = await models.ItemTaxCountry.findOne({ + where: { + itemFk: id, + countryFk: country.id + }, + order: 'effectived DESC' + }); + const taxClassCode = await models.TaxClassCode.findOne({ + where: { + taxClassFk: itemTaxCountry.taxClassFk + }, + order: 'effectived DESC' + }); + + return models.Intrastat.create({ + id: intrastatId, + description: description, + taxClassFk: itemTaxCountry.taxClassFk, + taxCodeFk: taxClassCode.taxCodeFk + }); + }; +}; diff --git a/modules/item/back/methods/item/getCard.js b/modules/item/back/methods/item/getCard.js index 50ff22321d..9780c5601e 100644 --- a/modules/item/back/methods/item/getCard.js +++ b/modules/item/back/methods/item/getCard.js @@ -55,9 +55,6 @@ module.exports = Self => { } }] } - }, - { - relation: 'taxClass' } ] }; diff --git a/modules/item/back/methods/item/specs/createIntrastat.spec.js b/modules/item/back/methods/item/specs/createIntrastat.spec.js new file mode 100644 index 0000000000..fb10de858a --- /dev/null +++ b/modules/item/back/methods/item/specs/createIntrastat.spec.js @@ -0,0 +1,22 @@ +const app = require('vn-loopback/server/server'); + +describe('createIntrastat()', () => { + let newIntrastat; + + afterAll(async done => { + await app.models.Intrastat.destroyById(newIntrastat.id); + + done(); + }); + + it('should create a new intrastat', async() => { + const intrastatId = 588420239; + const description = 'Tropical Flowers'; + const itemId = 9; + newIntrastat = await app.models.Item.createIntrastat(itemId, intrastatId, description); + + expect(newIntrastat.description).toEqual(description); + expect(newIntrastat.taxClassFk).toEqual(1); + expect(newIntrastat.taxCodeFk).toEqual(21); + }); +}); diff --git a/modules/item/back/model-config.json b/modules/item/back/model-config.json index db8eed9d56..d8ec5914a1 100644 --- a/modules/item/back/model-config.json +++ b/modules/item/back/model-config.json @@ -62,6 +62,9 @@ "TaxClass": { "dataSource": "vn" }, + "TaxClassCode": { + "dataSource": "vn" + }, "TaxCode": { "dataSource": "vn" }, diff --git a/modules/item/back/models/item.js b/modules/item/back/models/item.js index 6c221e94df..01061ce999 100644 --- a/modules/item/back/models/item.js +++ b/modules/item/back/models/item.js @@ -12,6 +12,7 @@ module.exports = Self => { require('../methods/item/getVisibleAvailable')(Self); require('../methods/item/new')(Self); require('../methods/item/getWasteDetail')(Self); + require('../methods/item/createIntrastat')(Self); Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'}); diff --git a/modules/item/back/models/tax-class-code.json b/modules/item/back/models/tax-class-code.json new file mode 100644 index 0000000000..efe6a13db8 --- /dev/null +++ b/modules/item/back/models/tax-class-code.json @@ -0,0 +1,47 @@ +{ + "name": "TaxClassCode", + "base": "VnModel", + "options": { + "mysql": { + "table": "taxClassCode" + } + }, + "properties": { + "id": { + "type": "number", + "id": true + }, + "effectived": { + "type": "date", + "required": true + }, + "taxClassFk": { + "type": "number", + "required": true + }, + "taxCodeFk": { + "type": "number", + "required": true + } + }, + "relations": { + "taxClass": { + "type": "belongsTo", + "model": "TaxClass", + "foreignKey": "taxClassFk" + }, + "taxCode": { + "type": "belongsTo", + "model": "TaxCode", + "foreignKey": "taxCodeFk" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } + ] +} \ No newline at end of file diff --git a/modules/item/front/basic-data/__snapshots__/index.spec.js.snap b/modules/item/front/basic-data/__snapshots__/index.spec.js.snap deleted file mode 100644 index 92219bb339..0000000000 --- a/modules/item/front/basic-data/__snapshots__/index.spec.js.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`vnItemBasicData Component vnItemBasicData $onChanges() should pass the data to the watcher 1`] = `"the current value of an item"`; diff --git a/modules/item/front/basic-data/index.html b/modules/item/front/basic-data/index.html index 16d37ff044..3cd879945d 100644 --- a/modules/item/front/basic-data/index.html +++ b/modules/item/front/basic-data/index.html @@ -149,27 +149,19 @@
New intrastat
- - + + + - - - -
diff --git a/modules/item/front/basic-data/index.js b/modules/item/front/basic-data/index.js index 3c3d62c747..33a60b32d4 100644 --- a/modules/item/front/basic-data/index.js +++ b/modules/item/front/basic-data/index.js @@ -11,9 +11,10 @@ class Controller extends Component { this.$.intrastat.show(); } - onCustomAgentAccept() { - return this.$http.post(`CustomsAgents`, this.newCustomsAgent) - .then(res => this.address.customsAgentFk = res.data.id); + onIntrastatAccept() { + const query = `Items/${this.$params.id}/createIntrastat`; + return this.$http.patch(query, this.newIntrastat) + .then(res => this.item.intrastatFk = res.data.id); } } From 7d8e88e884a4f558f06ac1b7134696775db48976 Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Mon, 17 Feb 2020 13:32:12 +0100 Subject: [PATCH 07/14] Updated unit test --- modules/item/front/basic-data/index.spec.js | 25 ++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/modules/item/front/basic-data/index.spec.js b/modules/item/front/basic-data/index.spec.js index e7578b54c0..178fac2784 100644 --- a/modules/item/front/basic-data/index.spec.js +++ b/modules/item/front/basic-data/index.spec.js @@ -2,26 +2,31 @@ import './index.js'; describe('vnItemBasicData', () => { describe('Component vnItemBasicData', () => { + let $httpBackend; let $scope; let controller; - let $timeout; + let $element; beforeEach(ngModule('item')); - beforeEach(angular.mock.inject(($componentController, $rootScope, _$timeout_) => { - $timeout = _$timeout_; + beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => { + $httpBackend = _$httpBackend_; $scope = $rootScope.$new(); - controller = $componentController('vnItemBasicData', {$scope, $timeout}); - controller.$scope.watcher = {}; + $element = angular.element(''); + controller = $componentController('vnItemBasicData', {$element, $scope}); + controller.$.watcher = {}; + controller.$params.id = 1; + controller.item = {id: 1, name: 'Rainbow Coral'}; })); - describe('$onChanges()', () => { + describe('onIntrastatAccept()', () => { it('should pass the data to the watcher', () => { - const data = {item: {currentValue: 'the current value of an item'}}; - controller.$onChanges(data); - $timeout.flush(); + const newIntrastatId = 20; + $httpBackend.expect('PATCH', 'Items/1/createIntrastat').respond({id: 20}); + controller.onIntrastatAccept(); + $httpBackend.flush(); - expect(controller.$scope.watcher.data).toMatchSnapshot(); + expect(controller.item.intrastatFk).toEqual(newIntrastatId); }); }); }); From a148daa36878748204d3275a009ff7ecafdebf60 Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Mon, 17 Feb 2020 14:47:43 +0100 Subject: [PATCH 08/14] 2125 - ticket create invalid type fix --- modules/ticket/front/create/card.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/front/create/card.js b/modules/ticket/front/create/card.js index 2e775c18b0..54cc56c684 100644 --- a/modules/ticket/front/create/card.js +++ b/modules/ticket/front/create/card.js @@ -14,7 +14,7 @@ class Controller { $onInit() { if (this.$stateParams && this.$stateParams.clientFk) - this.clientId = this.$stateParams.clientFk; + this.clientId = parseInt(this.$stateParams.clientFk); this.warehouseId = this.vnConfig.warehouseFk; } From fe8a0b4583e877550310a69764687c87cc775e6e Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Tue, 18 Feb 2020 07:21:35 +0100 Subject: [PATCH 09/14] Added translation. taxClassCode.sql removed --- .../00-taxClassCode.sql | 23 ------------------- db/dump/fixtures.sql | 8 +++---- modules/item/back/models/tax-class-code.json | 19 ++++++++------- modules/item/front/basic-data/locale/es.yml | 4 +++- 4 files changed, 16 insertions(+), 38 deletions(-) delete mode 100644 db/changes/10160-postValentineDay/00-taxClassCode.sql diff --git a/db/changes/10160-postValentineDay/00-taxClassCode.sql b/db/changes/10160-postValentineDay/00-taxClassCode.sql deleted file mode 100644 index bdc7cb474c..0000000000 --- a/db/changes/10160-postValentineDay/00-taxClassCode.sql +++ /dev/null @@ -1,23 +0,0 @@ -ALTER TABLE `vn`.`taxClassCode` -DROP FOREIGN KEY `taxClassCode_ibfk_2`, -DROP FOREIGN KEY `taxClassCode_ibfk_1`; -ALTER TABLE `vn`.`taxClassCode` -ADD COLUMN `id` INT NOT NULL AUTO_INCREMENT FIRST, -DROP PRIMARY KEY, -ADD PRIMARY KEY (`id`), -DROP INDEX `iva_codigo_id` ; - -ALTER TABLE `vn`.`taxClassCode` -ADD UNIQUE INDEX `taxClassCode_unique` (`taxClassFk` ASC, `effectived` ASC, `taxCodeFk` ASC) VISIBLE; - -ALTER TABLE `vn`.`taxClassCode` -ADD CONSTRAINT `taxClassCode_taxClassFk` - FOREIGN KEY (`taxClassFk`) - REFERENCES `vn`.`taxClass` (`id`) - ON DELETE RESTRICT - ON UPDATE CASCADE, -ADD CONSTRAINT `taxClassCode_taxCodeFk` - FOREIGN KEY (`taxCodeFk`) - REFERENCES `vn`.`taxCode` (`id`) - ON DELETE RESTRICT - ON UPDATE CASCADE; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 80bb377090..d561767132 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -687,11 +687,11 @@ INSERT INTO `vn`.`taxClass`(`id`, `description`, `code`) (1, 'Reduced VAT', 'R'), (2, 'General VAT', 'G'); -INSERT INTO `vn`.`taxClassCode`(`id`, `taxClassFk`, `effectived`, `taxCodeFk`) +INSERT INTO `vn`.`taxClassCode`(`taxClassFk`, `effectived`, `taxCodeFk`) VALUES - (1, 1, CURDATE(), 1), - (2, 1, CURDATE(), 21), - (3, 2, CURDATE(), 2); + (1, CURDATE(), 1), + (1, CURDATE(), 21), + (2, CURDATE(), 2); INSERT INTO `vn`.`intrastat`(`id`, `description`, `taxClassFk`, `taxCodeFk`) VALUES diff --git a/modules/item/back/models/tax-class-code.json b/modules/item/back/models/tax-class-code.json index efe6a13db8..ef8c529d96 100644 --- a/modules/item/back/models/tax-class-code.json +++ b/modules/item/back/models/tax-class-code.json @@ -7,21 +7,20 @@ } }, "properties": { - "id": { - "type": "number", - "id": true - }, - "effectived": { - "type": "date", - "required": true - }, "taxClassFk": { "type": "number", - "required": true + "required": true, + "id": 1 }, "taxCodeFk": { "type": "number", - "required": true + "required": true, + "id": 2 + }, + "effectived": { + "type": "date", + "required": true, + "id": 3 } }, "relations": { diff --git a/modules/item/front/basic-data/locale/es.yml b/modules/item/front/basic-data/locale/es.yml index 67780557a3..07e6817709 100644 --- a/modules/item/front/basic-data/locale/es.yml +++ b/modules/item/front/basic-data/locale/es.yml @@ -5,4 +5,6 @@ Full name calculates based on tags 1-3. Is not recommended to change it manually No se recomienda cambiarlo manualmente Is active: Activo Expense: Gasto -Price in kg: Precio en kg \ No newline at end of file +Price in kg: Precio en kg +New intrastat: Nuevo intrastat +Identifier: Identificador \ No newline at end of file From 30e38802992e763badf6aad916b4a9fcaca4dcff Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Tue, 18 Feb 2020 07:50:18 +0100 Subject: [PATCH 10/14] Removed comments --- modules/order/front/catalog/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/order/front/catalog/index.js b/modules/order/front/catalog/index.js index ef33e493f3..ff14c592b5 100644 --- a/modules/order/front/catalog/index.js +++ b/modules/order/front/catalog/index.js @@ -245,7 +245,6 @@ class Controller { this.$state.go(this.$state.current.name, params); } - // Builds the tags filter buildTagsFilter(items) { const tagValues = []; items.forEach(item => { @@ -261,7 +260,6 @@ class Controller { this.tagValues = tagValues; } - // Builds the order filter buildOrderFilter(items) { const tags = []; items.forEach(item => { From 3f978bd32b5544c40d6e700cf0bcab2193ba95ee Mon Sep 17 00:00:00 2001 From: Bernat Exposito Domenech Date: Tue, 18 Feb 2020 10:33:17 +0100 Subject: [PATCH 11/14] entry index refactor --- db/dump/fixtures.sql | 20 ++-- modules/entry/back/methods/entry/filter.js | 1 + .../back/methods/entry/specs/filter.spec.js | 6 +- modules/entry/front/index/index.html | 59 +++++++---- modules/entry/front/index/index.js | 12 ++- modules/entry/front/index/locale/es.yml | 15 +++ modules/entry/front/index/style.scss | 5 + modules/entry/front/locale/es.yml | 14 +-- modules/entry/front/routes.json | 1 + .../item/back/methods/item/getLastEntries.js | 1 + .../back/methods/travel/specs/filter.spec.js | 2 +- .../front/descriptor-popover/index.html | 12 +++ .../travel/front/descriptor-popover/index.js | 88 +++++++++++++++ .../front/descriptor-popover/index.spec.js | 100 ++++++++++++++++++ modules/travel/front/index.js | 2 +- .../worker/front/descriptor-popover/index.js | 1 - .../front/descriptor-popover/style.scss | 11 -- 17 files changed, 292 insertions(+), 58 deletions(-) create mode 100644 modules/entry/front/index/locale/es.yml create mode 100644 modules/entry/front/index/style.scss create mode 100644 modules/travel/front/descriptor-popover/index.html create mode 100644 modules/travel/front/descriptor-popover/index.js create mode 100644 modules/travel/front/descriptor-popover/index.spec.js delete mode 100644 modules/worker/front/descriptor-popover/style.scss diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index d561767132..f7d5d94f1c 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1129,17 +1129,19 @@ INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseO (4, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 50.00, 500, 'fourth travel', 0), (5, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 2, 1, 50.00, 500, 'fifth travel', 1), (6, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 2, 1, 50.00, 500, 'sixth travel', 1), - (7, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 2, 1, 50.00, 500, 'seventh travel', 1); + (7, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 2, 1, 50.00, 500, 'seventh travel', 1), + (8, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 2, 1, 50.00, 500, 'eight travel', 1); -INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `companyFk`, `ref`, `notes`, `evaNotes`) +INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `companyFk`, `ref`,`isInventory`, `isRaid`, `notes`, `evaNotes`) VALUES - (1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 442, 'Movement 1', 'this is the note one', 'observation one'), - (2, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 442, 'Movement 2', 'this is the note two', 'observation two'), - (3, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 442, 'Movement 3', 'this is the note three', 'observation three'), - (4, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 69, 'Movement 4', 'this is the note four', 'observation four'), - (5, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 442, 'Movement 5', 'this is the note five', 'observation five'), - (6, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 6, 442, 'Movement 6', 'this is the note six', 'observation six'), - (7, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 7, 442, 'Movement 7', 'this is the note seven', 'observation seven'); + (1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 442, 'Movement 1', 0, 0, '', ''), + (2, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 442, 'Movement 2', 0, 0, 'this is the note two', 'observation two'), + (3, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 442, 'Movement 3', 0, 0, 'this is the note three', 'observation three'), + (4, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 69, 'Movement 4', 0, 0, 'this is the note four', 'observation four'), + (5, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 442, 'Movement 5', 0, 0, 'this is the note five', 'observation five'), + (6, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 6, 442, 'Movement 6', 0, 0, 'this is the note six', 'observation six'), + (7, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 7, 442, 'Movement 7', 0, 0, 'this is the note seven', 'observation seven'), + (8, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 7, 442, 'Movement 8', 1, 1, '', ''); INSERT INTO `vn`.`claimRatio`(`clientFk`, `yearSale`, `claimAmount`, `claimingRate`, `priceIncreasing`, `packingRate`) VALUES diff --git a/modules/entry/back/methods/entry/filter.js b/modules/entry/back/methods/entry/filter.js index 8cbe5e15e6..93e9558a96 100644 --- a/modules/entry/back/methods/entry/filter.js +++ b/modules/entry/back/methods/entry/filter.js @@ -127,6 +127,7 @@ module.exports = Self => { e.companyFk, e.gestDocFk, e.invoiceInFk, + t.landed, s.name AS supplierName, co.code AS companyCode, cu.code AS currencyCode diff --git a/modules/entry/back/methods/entry/specs/filter.spec.js b/modules/entry/back/methods/entry/specs/filter.spec.js index 9b935d831a..25d2da0b42 100644 --- a/modules/entry/back/methods/entry/specs/filter.spec.js +++ b/modules/entry/back/methods/entry/specs/filter.spec.js @@ -23,7 +23,7 @@ describe('Entry filter()', () => { let result = await app.models.Entry.filter(ctx); - expect(result.length).toEqual(7); + expect(result.length).toEqual(8); }); it('should return the entry matching the supplier', async() => { @@ -35,7 +35,7 @@ describe('Entry filter()', () => { let result = await app.models.Entry.filter(ctx); - expect(result.length).toEqual(5); + expect(result.length).toEqual(6); }); it('should return the entry matching the company', async() => { @@ -47,7 +47,7 @@ describe('Entry filter()', () => { let result = await app.models.Entry.filter(ctx); - expect(result.length).toEqual(6); + expect(result.length).toEqual(7); }); it('should return the entries matching isBooked', async() => { diff --git a/modules/entry/front/index/index.html b/modules/entry/front/index/index.html index 8ddd4d3a39..86d62b1581 100644 --- a/modules/entry/front/index/index.html +++ b/modules/entry/front/index/index.html @@ -16,45 +16,68 @@ + Id - Created - Travel - Notes + Landed Reference - Booked - Is inventory - Confirmed - Ordered - Is raid - Commission Supplier Currency Company + Booked + Confirmed + Ordered + Notes + + + + + + {{::entry.id}} - {{::entry.created | date:'dd/MM/yyyy'}} - {{::entry.travelFk}} - {{::entry.notes}} + + + {{::entry.landed | date:'dd/MM/yyyy'}} + + {{::entry.ref}} - - - - - - {{::entry.commission}} {{::entry.supplierName}} {{::entry.currencyCode}} {{::entry.companyCode}} + + + + + + + + + diff --git a/modules/entry/front/index/index.js b/modules/entry/front/index/index.js index ec78c06dfa..53d2f45e07 100644 --- a/modules/entry/front/index/index.js +++ b/modules/entry/front/index/index.js @@ -1,5 +1,5 @@ import ngModule from '../module'; - +import './style.scss'; export default class Controller { constructor($scope) { this.$ = $scope; @@ -11,6 +11,16 @@ export default class Controller { else this.$.model.clear(); } + + showTravelDescriptor(event, travelFk) { + if (event.defaultPrevented) return; + event.preventDefault(); + event.stopPropagation(); + + this.selectedTravel = travelFk; + this.$.travelDescriptor.parent = event.target; + this.$.travelDescriptor.show(); + } } Controller.$inject = ['$scope']; diff --git a/modules/entry/front/index/locale/es.yml b/modules/entry/front/index/locale/es.yml new file mode 100644 index 0000000000..8ef9b2c7af --- /dev/null +++ b/modules/entry/front/index/locale/es.yml @@ -0,0 +1,15 @@ +Inventory entry: Es inventario +Virtual entry: Es una redada +Supplier: Proveedor +Currency: Moneda +Company: Empresa +Confirmed: Confirmada +Ordered: Pedida +Is raid: Redada +Commission: Comisión +Landed: F. entrega +Reference: Referencia +Created: Creado +Booked: Facturado +Is inventory: Inventario +Notes: Notas \ No newline at end of file diff --git a/modules/entry/front/index/style.scss b/modules/entry/front/index/style.scss new file mode 100644 index 0000000000..ab759d2ccb --- /dev/null +++ b/modules/entry/front/index/style.scss @@ -0,0 +1,5 @@ +@import "variables"; + + vn-icon[icon=insert_drive_file]{ + color: $color-font-secondary; + } diff --git a/modules/entry/front/locale/es.yml b/modules/entry/front/locale/es.yml index 214be93d4d..3de6c59a83 100644 --- a/modules/entry/front/locale/es.yml +++ b/modules/entry/front/locale/es.yml @@ -1,15 +1,3 @@ #Ordenar alfabeticamente -Reference: Referencia -Created: Creado -Booked: Facturado -Is inventory: Inventario -Notes: Notas -Travel: Envío -Supplier: Proveedor -Currency: Moneda -Company: Empresa -Confirmed: Confirmada -Ordered: Pedida -Is raid: Redada -Commission: Comisión + # Sections diff --git a/modules/entry/front/routes.json b/modules/entry/front/routes.json index f23ff02bfb..bd1ace3f25 100644 --- a/modules/entry/front/routes.json +++ b/modules/entry/front/routes.json @@ -2,6 +2,7 @@ "module": "entry", "name": "Entries", "icon": "icon-entry", + "dependencies": ["travel"], "validations": true, "menus": { "main": [ diff --git a/modules/item/back/methods/item/getLastEntries.js b/modules/item/back/methods/item/getLastEntries.js index bab808cef1..a438afcb63 100644 --- a/modules/item/back/methods/item/getLastEntries.js +++ b/modules/item/back/methods/item/getLastEntries.js @@ -22,6 +22,7 @@ module.exports = Self => { let where = filter.where; let query = `CALL vn.itemLastEntries(?, ?)`; let [lastEntries] = await Self.rawSql(query, [where.itemFk, where.date]); + return lastEntries; }; }; diff --git a/modules/travel/back/methods/travel/specs/filter.spec.js b/modules/travel/back/methods/travel/specs/filter.spec.js index f2fe44989d..03849f2b0e 100644 --- a/modules/travel/back/methods/travel/specs/filter.spec.js +++ b/modules/travel/back/methods/travel/specs/filter.spec.js @@ -23,7 +23,7 @@ describe('Travel filter()', () => { let result = await app.models.Travel.filter(ctx); - expect(result.length).toEqual(7); + expect(result.length).toEqual(8); }); it('should return the travel matching "total entries"', async() => { diff --git a/modules/travel/front/descriptor-popover/index.html b/modules/travel/front/descriptor-popover/index.html new file mode 100644 index 0000000000..fc0fb0301d --- /dev/null +++ b/modules/travel/front/descriptor-popover/index.html @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/modules/travel/front/descriptor-popover/index.js b/modules/travel/front/descriptor-popover/index.js new file mode 100644 index 0000000000..bac0d95fdc --- /dev/null +++ b/modules/travel/front/descriptor-popover/index.js @@ -0,0 +1,88 @@ +import ngModule from '../module'; +import Component from 'core/lib/component'; + +class Controller extends Component { + constructor($element, $scope, $http, $timeout, $q) { + super($element, $scope); + this.$timeout = $timeout; + this.$http = $http; + this.$q = $q; + this.travel = null; + this._quicklinks = {}; + } + + set travelFk(travelFk) { + if (travelFk == this._travelFk) return; + + this._travelFk = travelFk; + this.travel = null; + this.loadData(); + } + + get travelFk() { + return this._travelFk; + } + + get quicklinks() { + return this._quicklinks; + } + + set quicklinks(value = {}) { + Object.keys(value).forEach(key => { + this._quicklinks[key] = value[key]; + }); + } + + show() { + this.$.popover.parent = this.parent; + this.$.popover.show(); + } + + loadData() { + let query = `Travels/findOne`; + let filter = { + fields: [ + 'id', + 'ref', + 'shipped', + 'landed', + 'totalEntries', + 'warehouseInFk', + 'warehouseOutFk' + ], + where: { + id: this._travelFk + }, + include: [ + { + relation: 'warehouseIn', + scope: { + fields: ['name'] + } + }, { + relation: 'warehouseOut', + scope: { + fields: ['name'] + } + } + ] + }; + + this.$http.get(query, {params: {filter}}).then(res => { + this.travel = res.data; + this.$.$applyAsync(() => { + this.$.popover.relocate(); + }); + }); + } +} +Controller.$inject = ['$element', '$scope', '$http', '$timeout', '$q']; + +ngModule.component('vnTravelDescriptorPopover', { + template: require('./index.html'), + controller: Controller, + bindings: { + travelFk: '<', + quicklinks: '<' + } +}); diff --git a/modules/travel/front/descriptor-popover/index.spec.js b/modules/travel/front/descriptor-popover/index.spec.js new file mode 100644 index 0000000000..72ba3aeafa --- /dev/null +++ b/modules/travel/front/descriptor-popover/index.spec.js @@ -0,0 +1,100 @@ +import './index.js'; + +describe('travel Component vnTravelDescriptorPopover', () => { + let $httpBackend; + let $httpParamSerializer; + let $scope; + let controller; + let $element; + + beforeEach(ngModule('travel')); + + beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => { + $httpBackend = _$httpBackend_; + $httpParamSerializer = _$httpParamSerializer_; + $element = angular.element(`
`); + $scope = $rootScope.$new(); + $scope.popover = {relocate: () => {}, show: () => {}}; + controller = $componentController('vnTravelDescriptorPopover', {$scope, $element}); + })); + + describe('travelFk()', () => { + it(`should not apply any changes if the received id is the same stored in _travelFk`, () => { + controller.travel = 'I exist!'; + controller._travelFk = 1; + spyOn(controller, 'loadData'); + controller.travelFk = 1; + + expect(controller.travel).toEqual('I exist!'); + expect(controller._travelFk).toEqual(1); + expect(controller.loadData).not.toHaveBeenCalled(); + }); + + it(`should set the received id into _travelFk, set the travel to null and then call loadData()`, () => { + controller.travel = `Please don't`; + controller._travelFk = 1; + spyOn(controller, 'loadData'); + controller.travelFk = 999; + + expect(controller.travel).toBeNull(); + expect(controller._travelFk).toEqual(999); + expect(controller.loadData).toHaveBeenCalledWith(); + }); + }); + + describe('show()', () => { + it(`should call the show()`, () => { + spyOn(controller.$.popover, 'show'); + controller.show(); + + expect(controller.$.popover.show).toHaveBeenCalledWith(); + }); + }); + + describe('loadData()', () => { + it(`should perform a get query to store the worker data into the controller`, () => { + controller.travelFk = 1; + controller.canceler = null; + let response = {}; + + let config = { + filter: { + fields: [ + 'id', + 'ref', + 'shipped', + 'landed', + 'totalEntries', + 'warehouseInFk', + 'warehouseOutFk' + ], + where: { + id: controller.travelFk + }, + include: [ + { + relation: 'warehouseIn', + scope: { + fields: ['name'] + } + }, { + relation: 'warehouseOut', + scope: { + fields: ['name'] + } + } + ] + } + }; + + let json = $httpParamSerializer(config); + + $httpBackend.whenGET(`Travels/findOne?${json}`).respond(response); + $httpBackend.expectGET(`Travels/findOne?${json}`); + controller.loadData(); + $httpBackend.flush(); + + expect(controller.travel).toEqual(response); + }); + }); +}); diff --git a/modules/travel/front/index.js b/modules/travel/front/index.js index 1f5346e987..b72f9fd51c 100644 --- a/modules/travel/front/index.js +++ b/modules/travel/front/index.js @@ -11,4 +11,4 @@ import './log'; import './create'; import './thermograph/index/'; import './thermograph/create/'; - +import './descriptor-popover'; diff --git a/modules/worker/front/descriptor-popover/index.js b/modules/worker/front/descriptor-popover/index.js index b648e8bd20..55843a67da 100644 --- a/modules/worker/front/descriptor-popover/index.js +++ b/modules/worker/front/descriptor-popover/index.js @@ -1,6 +1,5 @@ import ngModule from '../module'; import Component from 'core/lib/component'; -import './style.scss'; class Controller extends Component { constructor($element, $scope, $http, $timeout, $q) { diff --git a/modules/worker/front/descriptor-popover/style.scss b/modules/worker/front/descriptor-popover/style.scss deleted file mode 100644 index 58e65d3206..0000000000 --- a/modules/worker/front/descriptor-popover/style.scss +++ /dev/null @@ -1,11 +0,0 @@ -vn-ticket-descriptor-popover { - vn-ticket-descriptor { - display: block; - width: 16em; - max-height: 28em; - - & > vn-card { - margin: 0!important; - } - } -} \ No newline at end of file From 6540ef9598cfdae1e88ac1bcc62d0d1b8b3079a2 Mon Sep 17 00:00:00 2001 From: Bernat Exposito Domenech Date: Tue, 18 Feb 2020 11:07:55 +0100 Subject: [PATCH 12/14] change Fk to Id --- modules/entry/front/index/index.html | 2 +- .../travel/front/descriptor-popover/index.js | 14 ++++++------ .../front/descriptor-popover/index.spec.js | 22 +++++++++---------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/modules/entry/front/index/index.html b/modules/entry/front/index/index.html index 86d62b1581..f0f5404899 100644 --- a/modules/entry/front/index/index.html +++ b/modules/entry/front/index/index.html @@ -76,7 +76,7 @@ + travel-id="$ctrl.selectedTravel"> { controller = $componentController('vnTravelDescriptorPopover', {$scope, $element}); })); - describe('travelFk()', () => { - it(`should not apply any changes if the received id is the same stored in _travelFk`, () => { + describe('travelId()', () => { + it(`should not apply any changes if the received id is the same stored in _travelId`, () => { controller.travel = 'I exist!'; - controller._travelFk = 1; + controller._travelId = 1; spyOn(controller, 'loadData'); - controller.travelFk = 1; + controller.travelId = 1; expect(controller.travel).toEqual('I exist!'); - expect(controller._travelFk).toEqual(1); + expect(controller._travelId).toEqual(1); expect(controller.loadData).not.toHaveBeenCalled(); }); - it(`should set the received id into _travelFk, set the travel to null and then call loadData()`, () => { + it(`should set the received id into _travelId, set the travel to null and then call loadData()`, () => { controller.travel = `Please don't`; - controller._travelFk = 1; + controller._travelId = 1; spyOn(controller, 'loadData'); - controller.travelFk = 999; + controller.travelId = 999; expect(controller.travel).toBeNull(); - expect(controller._travelFk).toEqual(999); + expect(controller._travelId).toEqual(999); expect(controller.loadData).toHaveBeenCalledWith(); }); }); @@ -53,7 +53,7 @@ describe('travel Component vnTravelDescriptorPopover', () => { describe('loadData()', () => { it(`should perform a get query to store the worker data into the controller`, () => { - controller.travelFk = 1; + controller.travelId = 1; controller.canceler = null; let response = {}; @@ -69,7 +69,7 @@ describe('travel Component vnTravelDescriptorPopover', () => { 'warehouseOutFk' ], where: { - id: controller.travelFk + id: controller.travelId }, include: [ { From 2460725d98a147bb8d39a61feff1d0c11f366df8 Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Tue, 18 Feb 2020 11:14:02 +0100 Subject: [PATCH 13/14] Refactor + updated tests --- modules/client/front/sample/create/index.html | 5 +- modules/client/front/sample/create/index.js | 78 ++++--- .../client/front/sample/create/index.spec.js | 190 +++++++++--------- .../client/front/sample/create/locale/es.yml | 4 +- 4 files changed, 130 insertions(+), 147 deletions(-) diff --git a/modules/client/front/sample/create/index.html b/modules/client/front/sample/create/index.html index 6a87d55b68..cd3412868b 100644 --- a/modules/client/front/sample/create/index.html +++ b/modules/client/front/sample/create/index.html @@ -15,7 +15,8 @@ + ng-model="$ctrl.clientSample.recipient" + info="Its only used when sample is sent"> @@ -30,7 +31,7 @@ { - this.$.showPreview.show(); - let dialog = document.body.querySelector('div.vn-dialog'); - let body = dialog.querySelector('tpl-body'); - let scroll = dialog.querySelector('div:first-child'); - - body.innerHTML = res.data; - scroll.scrollTop = 0; - }); + this.clientSample.companyId = value; } onSubmit() { @@ -73,28 +42,49 @@ class Controller extends Component { ); } + showPreview() { + this.send(true, res => { + this.$.showPreview.show(); + const dialog = document.body.querySelector('div.vn-dialog'); + const body = dialog.querySelector('tpl-body'); + const scroll = dialog.querySelector('div:first-child'); + + body.innerHTML = res.data; + scroll.scrollTop = 0; + }); + } + sendSample() { - let sampleType = this.$.sampleType.selection; - let params = { + this.send(false, () => { + this.vnApp.showSuccess(this.$translate.instant('Notification sent!')); + this.$state.go('client.card.sample.index'); + }); + } + + send(isPreview, cb) { + const sampleType = this.$.sampleType.selection; + const params = { clientId: this.$params.id, recipient: this.clientSample.recipient }; + if (!params.recipient) + return this.vnApp.showError(this.$translate.instant('Email cannot be blank')); + if (!sampleType) return this.vnApp.showError(this.$translate.instant('Choose a sample')); - if (sampleType.hasCompany && !this.clientSample.companyFk) + if (sampleType.hasCompany && !this.clientSample.companyId) return this.vnApp.showError(this.$translate.instant('Choose a company')); if (sampleType.hasCompany) - params.companyId = this.clientSample.companyFk; + params.companyId = this.clientSample.companyId; + + if (isPreview) params.isPreview = true; const serializedParams = this.$httpParamSerializer(params); const query = `email/${sampleType.code}?${serializedParams}`; - this.$http.get(query).then(res => { - this.vnApp.showSuccess(this.$translate.instant('Notification sent!')); - this.$state.go('client.card.sample.index'); - }); + this.$http.get(query).then(cb); } } Controller.$inject = ['$element', '$scope', 'vnApp', '$httpParamSerializer', 'vnConfig']; diff --git a/modules/client/front/sample/create/index.spec.js b/modules/client/front/sample/create/index.spec.js index efcda54012..da9a557f1e 100644 --- a/modules/client/front/sample/create/index.spec.js +++ b/modules/client/front/sample/create/index.spec.js @@ -40,84 +40,16 @@ describe('Client', () => { $httpParamSerializer = _$httpParamSerializer_; $element = angular.element(''); controller = $componentController('vnClientSampleCreate', {$element, $scope}); + const element = document.createElement('div'); + document.body.querySelector = () => { + return { + querySelector: () => { + return element; + } + }; + }; })); - describe('showPreview()', () => { - it(`should perform a query (GET) and open a sample preview`, () => { - spyOn(controller.$.showPreview, 'show'); - const element = document.createElement('div'); - document.body.querySelector = () => { - return { - querySelector: () => { - return element; - } - }; - }; - - controller.$.sampleType.selection = { - hasCompany: false, - code: 'MyReport' - }; - - controller.clientSample = { - clientFk: 101 - }; - - let event = {preventDefault: () => {}}; - - const params = { - clientId: 101, - isPreview: true - }; - const serializedParams = $httpParamSerializer(params); - - $httpBackend.when('GET', `email/MyReport?${serializedParams}`).respond(true); - $httpBackend.expect('GET', `email/MyReport?${serializedParams}`); - controller.showPreview(event); - $httpBackend.flush(); - - expect(controller.$.showPreview.show).toHaveBeenCalledWith(); - }); - - it(`should perform a query (GET) with companyFk param and open a sample preview`, () => { - spyOn(controller.$.showPreview, 'show'); - const element = document.createElement('div'); - document.body.querySelector = () => { - return { - querySelector: () => { - return element; - } - }; - }; - - controller.$.sampleType.selection = { - hasCompany: true, - code: 'MyReport' - }; - - controller.clientSample = { - clientFk: 101, - companyFk: 442 - }; - - let event = {preventDefault: () => {}}; - - const params = { - clientId: 101, - companyId: 442, - isPreview: true - }; - const serializedParams = $httpParamSerializer(params); - - $httpBackend.when('GET', `email/MyReport?${serializedParams}`).respond(true); - $httpBackend.expect('GET', `email/MyReport?${serializedParams}`); - controller.showPreview(event); - $httpBackend.flush(); - - expect(controller.$.showPreview.show).toHaveBeenCalledWith(); - }); - }); - describe('onSubmit()', () => { it(`should call sendSample() method`, () => { spyOn(controller, 'sendSample'); @@ -127,55 +59,113 @@ describe('Client', () => { }); }); - describe('sendSample()', () => { - it(`should perform a query (GET) and call go() method`, () => { - spyOn(controller.$state, 'go'); + describe('send()', () => { + it(`should not perform an HTTP query if no recipient is specified`, () => { + spyOn(controller.$http, 'get'); controller.$.sampleType.selection = { hasCompany: false, code: 'MyReport' }; - controller.clientSample = { - clientFk: 101 - }; - - const params = { clientId: 101 }; - const serializedParams = $httpParamSerializer(params); - $httpBackend.when('GET', `email/MyReport?${serializedParams}`).respond(true); - $httpBackend.expect('GET', `email/MyReport?${serializedParams}`); - controller.sendSample(); - $httpBackend.flush(); + controller.send(false, () => {}); - expect(controller.$state.go).toHaveBeenCalledWith('client.card.sample.index'); + expect(controller.$http.get).not.toHaveBeenCalled(); }); - it(`should perform a query (GET) with companyFk param and call go() method`, () => { - spyOn(controller.$state, 'go'); + it(`should not perform an HTTP query if no sample is specified`, () => { + spyOn(controller.$http, 'get'); + + controller.$.sampleType.selection = null; + controller.clientSample = { + clientId: 101, + recipient: 'client@email.com' + }; + + controller.send(false, () => {}); + + expect(controller.$http.get).not.toHaveBeenCalled(); + }); + + it(`should not perform an HTTP query if company is required and not specified`, () => { + spyOn(controller.$http, 'get'); controller.$.sampleType.selection = { hasCompany: true, code: 'MyReport' }; - controller.clientSample = { - clientFk: 101, - companyFk: 442 + clientId: 101, + recipient: 'client@email.com' }; - const params = { + controller.send(false, () => {}); + + expect(controller.$http.get).not.toHaveBeenCalled(); + }); + + it(`should perform an HTTP query without passing companyId param`, () => { + controller.$.sampleType.selection = { + hasCompany: false, + code: 'MyReport' + }; + controller.clientSample = { clientId: 101, + recipient: 'client@email.com' + }; + + const serializedParams = $httpParamSerializer(controller.clientSample); + $httpBackend.expect('GET', `email/MyReport?${serializedParams}`).respond(true); + controller.send(false, () => {}); + $httpBackend.flush(); + }); + + it(`should perform an HTTP query passing companyId param`, () => { + controller.$.sampleType.selection = { + hasCompany: true, + code: 'MyReport' + }; + controller.clientSample = { + clientId: 101, + recipient: 'client@email.com', companyId: 442 }; - const serializedParams = $httpParamSerializer(params); - $httpBackend.when('GET', `email/MyReport?${serializedParams}`).respond(true); - $httpBackend.expect('GET', `email/MyReport?${serializedParams}`); - controller.sendSample(); + const serializedParams = $httpParamSerializer(controller.clientSample); + $httpBackend.expect('GET', `email/MyReport?${serializedParams}`).respond(true); + controller.send(false, () => {}); $httpBackend.flush(); + }); + }); + + describe('showPreview()', () => { + it(`should open a sample preview`, () => { + spyOn(controller.$.showPreview, 'show'); + + controller.send = (isPreview, cb) => { + cb({ + data: '
' + }); + }; + controller.showPreview(); + + expect(controller.$.showPreview.show).toHaveBeenCalledWith(); + }); + }); + + describe('sendSample()', () => { + it(`should perform a query (GET) and call go() method`, () => { + spyOn(controller.$state, 'go'); + + controller.send = (isPreview, cb) => { + cb({ + data: true + }); + }; + controller.sendSample(); expect(controller.$state.go).toHaveBeenCalledWith('client.card.sample.index'); }); diff --git a/modules/client/front/sample/create/locale/es.yml b/modules/client/front/sample/create/locale/es.yml index d1ef82c0ee..6828e3e489 100644 --- a/modules/client/front/sample/create/locale/es.yml +++ b/modules/client/front/sample/create/locale/es.yml @@ -1,3 +1,5 @@ Choose a sample: Selecciona una plantilla Choose a company: Selecciona una empresa -Recipient: Destinatario \ No newline at end of file +Email cannot be blank: Debes introducir un email +Recipient: Destinatario +Its only used when sample is sent: Se utiliza únicamente cuando se envía la plantilla \ No newline at end of file From bfb8c5e138600242f17f2664092005e159b3b61c Mon Sep 17 00:00:00 2001 From: Bernat Exposito Domenech Date: Tue, 18 Feb 2020 12:51:29 +0100 Subject: [PATCH 14/14] route.basicData validations --- loopback/locale/es.json | 3 ++- modules/route/back/models/route.js | 17 +++++++++++++++++ modules/route/front/basic-data/index.js | 6 ++++-- modules/route/front/basic-data/locale/es.yml | 2 +- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 64fabd5226..7577c5349a 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -126,5 +126,6 @@ "MESSAGE_CHANGED_PAYMETHOD": "He cambiado la forma de pago del cliente [{{clientName}} (#{{clientId}})]({{{url}}})", "Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} (#{{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [#{{ticketId}}]({{{ticketUrl}}})", "Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}", - "ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto" + "ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto", + "Distance must be lesser than 1000": "La distancia debe ser inferior a 1000" } \ No newline at end of file diff --git a/modules/route/back/models/route.js b/modules/route/back/models/route.js index 4dd9f3dc02..6d93cfe405 100644 --- a/modules/route/back/models/route.js +++ b/modules/route/back/models/route.js @@ -5,4 +5,21 @@ module.exports = Self => { require('../methods/route/guessPriority')(Self); require('../methods/route/updateVolume')(Self); require('../methods/route/getDeliveryPoint')(Self); + + Self.validate('kmStart', validateDistance, { + message: 'Distance must be lesser than 1000' + }); + + Self.validate('kmEnd', validateDistance, { + message: 'Distance must be lesser than 1000' + }); + + function validateDistance(err) { + const routeTotalKm = this.kmEnd - this.kmStart; + const routeMaxKm = 1000; + if ( routeTotalKm > routeMaxKm || this.kmStart > this.kmEnd) + err(); + } }; + + diff --git a/modules/route/front/basic-data/index.js b/modules/route/front/basic-data/index.js index 810fd75112..d4a481dc5f 100644 --- a/modules/route/front/basic-data/index.js +++ b/modules/route/front/basic-data/index.js @@ -1,8 +1,10 @@ import ngModule from '../module'; class Controller { - constructor($scope) { + constructor($scope, vnApp, $translate) { this.$ = $scope; + this.vnApp = vnApp; + this.$translate = $translate; } onSubmit() { @@ -11,7 +13,7 @@ class Controller { }); } } -Controller.$inject = ['$scope']; +Controller.$inject = ['$scope', 'vnApp', '$translate']; ngModule.component('vnRouteBasicData', { template: require('./index.html'), diff --git a/modules/route/front/basic-data/locale/es.yml b/modules/route/front/basic-data/locale/es.yml index 442a4fa828..f0414b5b15 100644 --- a/modules/route/front/basic-data/locale/es.yml +++ b/modules/route/front/basic-data/locale/es.yml @@ -2,4 +2,4 @@ Date finished: Fecha fin Date started: Fecha inicio Km start: Km de inicio Km end: Km de fin -Description: Descripción \ No newline at end of file +Description: Descripción