diff --git a/client/claim/routes.json b/client/claim/routes.json index efd4ecec3a..5af69e52fa 100644 --- a/client/claim/routes.json +++ b/client/claim/routes.json @@ -15,7 +15,7 @@ "url": "/index?q", "state": "claim.index", "component": "vn-claim-index", - "description": "Listado", + "description": "List", "acl": ["salesAssistant"] }, { diff --git a/client/claim/src/index/index.html b/client/claim/src/index/index.html index af7a9b2638..88349260ac 100644 --- a/client/claim/src/index/index.html +++ b/client/claim/src/index/index.html @@ -21,7 +21,6 @@ Id - Client Id Client Created Worker @@ -32,8 +31,11 @@ {{::claim.id}} - {{::claim.client.id}} - {{::claim.client.name}} + + + {{::claim.client.name}} + + {{::claim.created | date:'dd/MM/yyyy'}} {{::claim.worker.firstName}} {{::claim.worker.name}} {{::claim.claimState.description}} diff --git a/client/client/src/address/create/index.html b/client/client/src/address/create/index.html index c2d8845b89..d68ca658a0 100644 --- a/client/client/src/address/create/index.html +++ b/client/client/src/address/create/index.html @@ -19,7 +19,8 @@ - - - diff --git a/client/core/src/components/chip/index.js b/client/core/src/components/chip/index.js index b95030d68a..b691bffee9 100644 --- a/client/core/src/components/chip/index.js +++ b/client/core/src/components/chip/index.js @@ -6,12 +6,14 @@ export default class Chip { $transclude($scope.$parent, clone => { angular.element($element[0].querySelector('div')).append(clone); }); - /* this.mdlElement = this.element.querySelector('.mdl-slider'); - componentHandler.upgradeElement(this.mdlElement); */ - /* this.mdlElement.addEventListener('change', () => { - this._value = this.input.value; - this.$.$applyAsync(); - }); */ + } + +/** + * Remove chip event + */ + remove() { + if (this.onRemove) + this.onRemove(); } } @@ -22,6 +24,7 @@ ngModule.component('vnChip', { controller: Chip, transclude: true, bindings: { - disabled: ' { + let $element; + let $scope; + let $httpBackend; + let controller; + + beforeEach(() => { + angular.mock.module('client'); + }); + + beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_, _$timeout_) => { + $scope = $rootScope.$new(); + $element = angular.element(`
${template}
`); + $httpBackend = _$httpBackend_; + $httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({}); + controller = _$componentController_('vnChip', {$element, $scope, $httpBackend, $transclude: () => {}}); + })); + + describe('remove()', () => { + it(`should call onRemove()`, () => { + controller.onRemove = () => {}; + spyOn(controller, 'onRemove'); + controller.remove(); + + expect(controller.onRemove).toHaveBeenCalledWith(); + }); + }); +}); diff --git a/client/core/src/components/chip/style.scss b/client/core/src/components/chip/style.scss index 20dea52ada..aca854efb5 100644 --- a/client/core/src/components/chip/style.scss +++ b/client/core/src/components/chip/style.scss @@ -2,6 +2,10 @@ vn-chip { .mdl-chip { + background-color: rgba($main-01, 0.9); + } + + .mdl-chip:active { background-color: $main-01 } } \ No newline at end of file diff --git a/client/core/src/components/multi-check/multi-check.spec.js b/client/core/src/components/multi-check/multi-check.spec.js index e7855449f3..86bc7e72fd 100644 --- a/client/core/src/components/multi-check/multi-check.spec.js +++ b/client/core/src/components/multi-check/multi-check.spec.js @@ -1,16 +1,18 @@ import './multi-check.js'; -xdescribe('Component vnMultiCheck', () => { +describe('Component vnMultiCheck', () => { let $componentController; let controller; + let $element; beforeEach(() => { - angular.mock.module('client'); + angular.mock.module('ticket'); }); beforeEach(angular.mock.inject(_$componentController_ => { $componentController = _$componentController_; - controller = $componentController('vnMultiCheck', {}); + $element = angular.element(`
`); + controller = $componentController('vnMultiCheck', {$element: $element}); })); describe('checkAll() setter', () => { @@ -25,7 +27,7 @@ xdescribe('Component vnMultiCheck', () => { }); describe('switchChecks()', () => { - it(`should set checked property inside each existing elemenet when id begings with no-`, () => { + it(`should set checked property inside each existing element`, () => { controller.data = [ {name: 'name'}, {name: null} diff --git a/client/item/routes.json b/client/item/routes.json index 21399f9b56..b66d9212ec 100644 --- a/client/item/routes.json +++ b/client/item/routes.json @@ -125,7 +125,7 @@ "item": "$ctrl.item" } }, { - "url" : "/diary?q", + "url" : "/diary?warehouseFk", "state": "item.card.diary", "component": "vn-item-diary", "description": "Diary", diff --git a/client/item/src/diary/index.html b/client/item/src/diary/index.html index 3669026780..63b811b267 100644 --- a/client/item/src/diary/index.html +++ b/client/item/src/diary/index.html @@ -2,8 +2,7 @@ vn-id="model" url="item/api/Items/getDiary" filter="::$ctrl.filter" - data="sales" - auto-load="false"> + data="sales"> @@ -15,9 +14,10 @@ url="/item/api/Warehouses" show-field="name" value-field="id" - initial-data="$ctrl.filter.where.warehouseFk" - field="$ctrl.filter.where.warehouseFk" - label="Select warehouse" on-change="$ctrl.onChange(value)"> + initial-data="$ctrl.warehouseFk" + field="$ctrl.warehouseFk" + label="Select warehouse" + on-change="$ctrl.onChange(value)">
diff --git a/client/item/src/diary/index.js b/client/item/src/diary/index.js index b8fd34aecc..826211c277 100644 --- a/client/item/src/diary/index.js +++ b/client/item/src/diary/index.js @@ -2,61 +2,58 @@ import ngModule from '../module'; import './style.scss'; class Controller { - constructor($scope, $http, $state, $window, $translate) { + constructor($scope, $http, $state, $window, $translate, $stateParams) { this.$scope = $scope; this.$http = $http; this.$state = $state; + this.$stateParams = $stateParams; this.$window = $window; this.$translate = $translate; } - +/* $postLink() { if (this.item) this.filterBuilder(); } - + */ set item(value) { this._item = value; - if (value && this.$scope.model) - this.filterBuilder(); + this.filter = { + where: {itemFk: this.$stateParams.id} + }; + + if (this.$stateParams.warehouseFk) + this.warehouseFk = this.$stateParams.warehouseFk; + else if (value) + this.warehouseFk = value.itemType.warehouseFk; } get item() { return this._item; } - onChange(value) { - if (!value) return; + set warehouseFk(value) { + this._warehouseFk = value; + + this.$state.go(this.$state.current.name, { + warehouseFk: value + }); this.filter.where.warehouseFk = value; - this.$scope.model.refresh(); } -/** - * Builds a filter with default values - * and aplies query params. - */ - filterBuilder() { - this.filter = { - where: { - itemFk: this.item.id, - warehouseFk: this.item.itemType.warehouseFk - } - - }; - let where = this.filter.where; - - if (this.$state.params.q) { - let queryFilter = JSON.parse(this.$state.params.q); - where.warehouseFk = queryFilter.warehouseFk; - } + get warehouseFk() { + return this._warehouseFk; } get freeLineIndex() { let lines = this.$scope.model.data; + let currentDate = new Date(); + currentDate.setHours(0, 0, 0); + for (let i = 0; i < lines.length; i++) { - let isFutureDate = new Date(lines[i].date) > new Date(); + let isFutureDate = new Date(lines[i].date) >= currentDate; if (isFutureDate) return i; @@ -140,7 +137,7 @@ class Controller { } } -Controller.$inject = ['$scope', '$http', '$state', '$window', '$translate']; +Controller.$inject = ['$scope', '$http', '$state', '$window', '$translate', '$stateParams']; ngModule.component('vnItemDiary', { template: require('./index.html'), diff --git a/client/item/src/diary/index.spec.js b/client/item/src/diary/index.spec.js index c5c909ed50..4e17653ad3 100644 --- a/client/item/src/diary/index.spec.js +++ b/client/item/src/diary/index.spec.js @@ -3,6 +3,7 @@ import './index.js'; describe('Item', () => { describe('Component vnItemDiary', () => { let $componentController; + let $stateParams; let $scope; let controller; let $httpBackend; @@ -11,12 +12,14 @@ describe('Item', () => { angular.mock.module('item'); }); - beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_) => { + beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$stateParams_, _$httpBackend_) => { $componentController = _$componentController_; + $stateParams = _$stateParams_; + $stateParams.id = 1; $httpBackend = _$httpBackend_; $httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({}); $scope = $rootScope.$new(); - controller = $componentController('vnItemDiary', {$scope: $scope}); + controller = $componentController('vnItemDiary', {$scope: $scope, $stateParams}); controller.$scope.model = {}; })); @@ -71,12 +74,19 @@ describe('Item', () => { }); describe('set item()', () => { - it(`should call filterBuilder()`, () => { - spyOn(controller, 'filterBuilder'); - controller.item = {id: 1}; + it(`should set warehouseFk property based on itemType warehouseFk`, () => { + controller.item = {id: 1, itemType: {warehouseFk: 1}}; - expect(controller.filterBuilder).toHaveBeenCalledWith(); - expect(controller.item).toEqual({id: 1}); + expect(controller.warehouseFk).toEqual(1); + expect(controller.item.id).toEqual(1); + }); + + it(`should set warehouseFk property based on url query warehouseFk`, () => { + controller.$stateParams.warehouseFk = 4; + controller.item = {id: 1, itemType: {warehouseFk: 1}}; + + expect(controller.warehouseFk).toEqual(4); + expect(controller.item.id).toEqual(1); }); }); }); diff --git a/client/order/src/index/index.html b/client/order/src/index/index.html index a74f83da15..24bc5eaedd 100644 --- a/client/order/src/index/index.html +++ b/client/order/src/index/index.html @@ -1,7 +1,7 @@ @@ -10,18 +10,22 @@ - Id + Id Client Company - Created + Created {{::order.id}} - {{::order.clientFk}} - {{::order.companyFk}} + + + {{::order.client.name}} + + + {{::order.company.code}} {{::order.created | date:'dd/MM/yyyy'}} @@ -38,10 +42,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/client/order/src/index/index.js b/client/order/src/index/index.js index aa0c59183c..384cfb13ef 100644 --- a/client/order/src/index/index.js +++ b/client/order/src/index/index.js @@ -2,8 +2,20 @@ import ngModule from '../module'; export default class Controller { constructor($scope) { - this.$ = $scope; + this.$scope = $scope; this.ticketSelected = null; + this.filter = { + include: [ + { + relation: 'client', + fields: ['name'] + }, + { + relation: 'company', + fields: ['code'] + } + ] + }; } /* exprBuilder(param, value) { @@ -26,10 +38,22 @@ export default class Controller { } } */ + showDescriptor(event, clientFk) { + this.$scope.descriptor.clientFk = clientFk; + this.$scope.descriptor.parent = event.target; + this.$scope.descriptor.show(); + event.preventDefault(); + event.stopImmediatePropagation(); + } + + onDescriptorLoad() { + this.$scope.popover.relocate(); + } + preview(event, ticket) { event.preventDefault(); event.stopImmediatePropagation(); - this.$.dialogSummaryTicket.show(); + this.$scope.dialogSummaryTicket.show(); this.ticketSelected = ticket; } } diff --git a/client/route/index.js b/client/route/index.js index eadbde870f..8420b1093f 100644 --- a/client/route/index.js +++ b/client/route/index.js @@ -1 +1 @@ -export * from './src/route'; +export * from './src'; diff --git a/client/route/routes.json b/client/route/routes.json index 907a65b75d..f9d358bbdf 100644 --- a/client/route/routes.json +++ b/client/route/routes.json @@ -1,4 +1,4 @@ -/* { +{ "module": "route", "name": "Routes", "icon" : "local_shipping", @@ -8,61 +8,15 @@ "url": "/routes", "state": "routes", "abstract": true, - "component": "ui-view" + "component": "ui-view", + "description": "Routes" }, { - "url": "/list", + "url": "/index?q", "state": "routes.index", "component": "vn-route-index", + "description": "List", "acl": ["developer"] - }, - { - "url": "/create", - "state": "routes.create", - "component": "vn-route-create" - }, - { - "url": "/:id", - "state": "routes.card", - "abstract": true, - "component": "vn-route-card" - }, - { - "url": "/basicData", - "state": "routes.card.basicData", - "component": "vn-route-basic-data", - "params": { - "route": "$ctrl.route" - }, - "menu": { - "description": "Basic data", - "icon": "person" - } - }, - { - "url": "/logisticData", - "state": "routes.card.logisticData", - "component": "vn-route-logistic-data", - "acl": ["employee"], - "params": { - "route": "$ctrl.route" - }, - "menu": { - "description": "Logistic data", - "icon": "local_shipping" - } - }, - { - "url": "/tickets", - "state": "routes.card.tickets", - "component": "vn-route-tickets", - "params": { - "route": "$ctrl.route" - }, - "menu": { - "description": "Assigned tickets", - "icon": "assignment" - } } ] -} */ \ No newline at end of file +} \ No newline at end of file diff --git a/client/route/src/basic-data/basic-data.html b/client/route/src/basic-data/basic-data.html deleted file mode 100644 index 91a4bd70fe..0000000000 --- a/client/route/src/basic-data/basic-data.html +++ /dev/null @@ -1,35 +0,0 @@ - - -
- - - Basic data - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/client/route/src/basic-data/basic-data.js b/client/route/src/basic-data/basic-data.js deleted file mode 100644 index 9f2278dbb5..0000000000 --- a/client/route/src/basic-data/basic-data.js +++ /dev/null @@ -1,8 +0,0 @@ -import ngModule from '../module'; - -ngModule.component('vnRouteBasicData', { - template: require('./basic-data.html'), - bindings: { - route: '<' - } -}); diff --git a/client/route/src/card/card.html b/client/route/src/card/card.html deleted file mode 100644 index b787b738f9..0000000000 --- a/client/route/src/card/card.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - local_shipping - - -
Route {{::$ctrl.route.id}}
-
{{$ctrl.route.date | date:'dd/MM/yyyy'}}
-
-
-
-
- -
- - - -
- \ No newline at end of file diff --git a/client/route/src/card/card.js b/client/route/src/card/card.js deleted file mode 100644 index e0655c0691..0000000000 --- a/client/route/src/card/card.js +++ /dev/null @@ -1,12 +0,0 @@ -import ngModule from '../module'; - -class RouteCard { - constructor() { - this.route = null; - } -} - -ngModule.component('vnRouteCard', { - template: require('./card.html'), - controller: RouteCard -}); diff --git a/client/route/src/card/style.css b/client/route/src/card/style.css deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/client/route/src/create/create.html b/client/route/src/create/create.html deleted file mode 100644 index 8b7b7c6ba2..0000000000 --- a/client/route/src/create/create.html +++ /dev/null @@ -1,43 +0,0 @@ - - - -
-
- - - Create Route - - - - - - - - - - - - - - - - - -
-
diff --git a/client/route/src/create/create.js b/client/route/src/create/create.js deleted file mode 100644 index a51a32da7f..0000000000 --- a/client/route/src/create/create.js +++ /dev/null @@ -1,20 +0,0 @@ -import ngModule from '../module'; - -class RouteCreate { - constructor($scope, $state) { - this.$ = $scope; - this.$state = $state; - this.delivery = {}; - } - onSubmit() { - this.$.watcher.submit().then( - json => this.$state.go('routes.card.basicData', {id: json.data.id}) - ); - } -} -RouteCreate.$inject = ['$scope', '$state']; - -ngModule.component('vnRouteCreate', { - template: require('./create.html'), - controller: RouteCreate -}); diff --git a/client/route/src/index.js b/client/route/src/index.js new file mode 100644 index 0000000000..cfb4664b47 --- /dev/null +++ b/client/route/src/index.js @@ -0,0 +1,3 @@ +export * from './module'; + +// import components diff --git a/client/route/src/index/googleMaps.svg b/client/route/src/index/googleMaps.svg deleted file mode 100644 index 9a7fc59d7f..0000000000 --- a/client/route/src/index/googleMaps.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/client/route/src/index/index.html b/client/route/src/index/index.html deleted file mode 100644 index e9debbac41..0000000000 --- a/client/route/src/index/index.html +++ /dev/null @@ -1,23 +0,0 @@ - -
-
- - - - - - - - - - -
- - - -
diff --git a/client/route/src/index/index.js b/client/route/src/index/index.js deleted file mode 100644 index c8dc8ffd6f..0000000000 --- a/client/route/src/index/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import ngModule from '../module'; -import './style.css'; -import './item-route'; - -export default class Controller { - constructor() { - this.model = {}; - } - search(index) { - index.filter.search = this.model.search; - index.accept(); - } -} - -ngModule.component('vnRouteIndex', { - template: require('./index.html'), - controller: Controller -}); diff --git a/client/route/src/index/item-route.html b/client/route/src/index/item-route.html deleted file mode 100644 index 226d75810c..0000000000 --- a/client/route/src/index/item-route.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - ID_RUTA: - {{$ctrl.route.id}} - - - Fecha: - {{$ctrl.route.date | date:'dd/MM/yyyy'}} - - - m3: - {{$ctrl.route.m3}} - - - - - - - \ No newline at end of file diff --git a/client/route/src/index/item-route.js b/client/route/src/index/item-route.js deleted file mode 100644 index 0eeb9fcd5f..0000000000 --- a/client/route/src/index/item-route.js +++ /dev/null @@ -1,8 +0,0 @@ -import ngModule from '../module'; - -ngModule.component('vnItemRoute', { - template: require('./item-route.html'), - bindings: { - route: '<' - } -}); diff --git a/client/route/src/index/routeIn.svg b/client/route/src/index/routeIn.svg deleted file mode 100644 index dec26dfbfa..0000000000 --- a/client/route/src/index/routeIn.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - diff --git a/client/route/src/index/routeOut.svg b/client/route/src/index/routeOut.svg deleted file mode 100644 index 7a69b77864..0000000000 --- a/client/route/src/index/routeOut.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - diff --git a/client/route/src/index/style.css b/client/route/src/index/style.css deleted file mode 100644 index 0a369664ed..0000000000 --- a/client/route/src/index/style.css +++ /dev/null @@ -1,12 +0,0 @@ -vn-item-route { - display: block; -} -vn-item-route a { - display: block; - text-decoration: none; - color: inherit; -} -vn-item-route a:hover { - color: white; - background-color: #424242; -} \ No newline at end of file diff --git a/client/route/src/logistic-data/logistic-data.html b/client/route/src/logistic-data/logistic-data.html deleted file mode 100644 index 9ea4c802b2..0000000000 --- a/client/route/src/logistic-data/logistic-data.html +++ /dev/null @@ -1,26 +0,0 @@ - - -
- - - Logistic data - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/client/route/src/logistic-data/logistic-data.js b/client/route/src/logistic-data/logistic-data.js deleted file mode 100644 index 4230a82826..0000000000 --- a/client/route/src/logistic-data/logistic-data.js +++ /dev/null @@ -1,8 +0,0 @@ -import ngModule from '../module'; - -ngModule.component('vnRouteLogisticData', { - template: require('./logistic-data.html'), - bindings: { - route: '<' - } -}); diff --git a/client/route/src/route.js b/client/route/src/route.js deleted file mode 100644 index a9db6db33c..0000000000 --- a/client/route/src/route.js +++ /dev/null @@ -1,10 +0,0 @@ -export * from './module'; - -// import components -import './index/index'; -import './search-panel/search-panel'; -import './create/create'; -import './card/card'; -import './basic-data/basic-data'; -import './logistic-data/logistic-data'; -import './tickets/tickets'; diff --git a/client/route/src/search-panel/locale/es.yml b/client/route/src/search-panel/locale/es.yml deleted file mode 100644 index 590d0e6d8c..0000000000 --- a/client/route/src/search-panel/locale/es.yml +++ /dev/null @@ -1,8 +0,0 @@ -Client id: Id cliente -Tax number: NIF/CIF -Name: Nombre -Social name: Razon social -Town/City: Ciudad -Postcode: Código postal -Email: Correo electrónico -Phone: Teléfono \ No newline at end of file diff --git a/client/route/src/search-panel/search-panel.html b/client/route/src/search-panel/search-panel.html deleted file mode 100644 index 3661a2c5f3..0000000000 --- a/client/route/src/search-panel/search-panel.html +++ /dev/null @@ -1,21 +0,0 @@ -
-
- - - - - - - - - - - - -
-
diff --git a/client/route/src/search-panel/search-panel.js b/client/route/src/search-panel/search-panel.js deleted file mode 100644 index c1b79d5de0..0000000000 --- a/client/route/src/search-panel/search-panel.js +++ /dev/null @@ -1,27 +0,0 @@ -import ngModule from '../module'; - -export default class Controller { - constructor($window) { - this.$window = $window; - // onSubmit() is defined by @vnSearchbar - this.onSubmit = () => {}; - } - onSearch() { - this.setStorageValue(); - this.onSubmit(this.filter); - } - $onChanges() { - var value = JSON.parse(this.$window.sessionStorage.getItem('filter')); - if (value !== undefined) - this.filter = value; - } - setStorageValue() { - this.$window.sessionStorage.setItem('filter', JSON.stringify(this.filter)); - } -} -Controller.$inject = ['$window']; - -ngModule.component('vnRouteSearchPanel', { - template: require('./search-panel.html'), - controller: Controller -}); diff --git a/client/route/src/tickets/tickets.html b/client/route/src/tickets/tickets.html deleted file mode 100644 index e78e9ab70f..0000000000 --- a/client/route/src/tickets/tickets.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - Assigned tickets - - - \ No newline at end of file diff --git a/client/route/src/tickets/tickets.js b/client/route/src/tickets/tickets.js deleted file mode 100644 index 2405d5d9e4..0000000000 --- a/client/route/src/tickets/tickets.js +++ /dev/null @@ -1,8 +0,0 @@ -import ngModule from '../module'; - -ngModule.component('vnRouteTickets', { - template: require('./tickets.html'), - bindings: { - route: '<' - } -}); diff --git a/client/ticket/routes.json b/client/ticket/routes.json index 312e28c4d1..02a8703a45 100644 --- a/client/ticket/routes.json +++ b/client/ticket/routes.json @@ -15,7 +15,7 @@ "url": "/index?q", "state": "ticket.index", "component": "vn-ticket-index", - "description": "Listado" + "description": "List" }, { "url": "/:id", diff --git a/client/ticket/src/sale/index.html b/client/ticket/src/sale/index.html index 62e753ae1f..34ec343bad 100644 --- a/client/ticket/src/sale/index.html +++ b/client/ticket/src/sale/index.html @@ -12,7 +12,8 @@ + ng-click="$ctrl.onStateOkClick()" + vn-tooltip="Change ticket state to 'Ok'"> + vn-tooltip="Visible: {{::sale.visible || 0}}
{{::$ctrl.$translate.instant('Available')}}: {{::sale.available || 0}}"> diff --git a/client/ticket/src/sale/locale/es.yml b/client/ticket/src/sale/locale/es.yml index f52716b8c8..bfc7ea7057 100644 --- a/client/ticket/src/sale/locale/es.yml +++ b/client/ticket/src/sale/locale/es.yml @@ -23,4 +23,6 @@ Thursday: Jueves Friday: Viernes Saturday: Sábado Sunday: Domingo -Add claim: Crear reclamación \ No newline at end of file +Add claim: Crear reclamación +Transfer lines: Transferir líneas +Change ticket state to 'Ok': Cambiar estado del ticket a 'Ok' diff --git a/e2e/helpers/extensions.js b/e2e/helpers/extensions.js index d40007f6ea..f4d31856bc 100644 --- a/e2e/helpers/extensions.js +++ b/e2e/helpers/extensions.js @@ -147,6 +147,26 @@ Nightmare.action('waitForNumberOfElements', function(selector, count, done) { .then(done); }); +Nightmare.action('waitForClassNotPresent', function(selector, className, done) { + this.wait(selector) + .wait((resultSelector, targetClass) => { + if (!document.querySelector(resultSelector).classList.contains(targetClass)) { + return true; + } + }, selector, className) + .then(done); +}); + +Nightmare.action('waitForClassPresent', function(selector, className, done) { + this.wait(selector) + .wait((resultSelector, targetClass) => { + if (document.querySelector(resultSelector).classList.contains(targetClass)) { + return true; + } + }, selector, className) + .then(done); +}); + Nightmare.action('waitForTextInElement', function(selector, name, done) { this.wait(selector) .wait((resultSelector, expectedText) => { @@ -181,19 +201,6 @@ Nightmare.action('waitForEmptyInnerText', function(selector, done) { .then(done); }); -Nightmare.action('waitForSnackbarReset', function(done) { - this.click('vn-snackbar button') - .waitForEmptyInnerText('vn-snackbar .text') - .then(done); -}); - -Nightmare.action('waitForSnackbar', function(done) { - this.wait(500).waitForShapes('vn-snackbar .shape .text') - .then(shapes => { - done(null, shapes); - }); -}); - Nightmare.action('waitForURL', function(hashURL, done) { this.wait(hash => { return document.location.hash.includes(hash); @@ -214,3 +221,26 @@ Nightmare.action('waitForShapes', function(selector, done) { return shapesList; }, done, selector); }); + +Nightmare.action('waitForSnackbar', function(done) { + this.wait(500).waitForShapes('vn-snackbar .shape .text') + .then(shapes => { + done(null, shapes); + }); +}); + +Nightmare.action('waitForLastShape', function(selector, done) { + this.wait(selector) + .evaluate_now(selector => { + let shape = document.querySelector(selector); + + return shape.innerText; + }, done, selector); +}); + +Nightmare.action('waitForLastSnackbar', function(done) { + this.wait(500).waitForLastShape('vn-snackbar .shape .text') + .then(shapes => { + done(null, shapes); + }); +}); diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 2a8e622331..0d88574aa9 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -154,6 +154,7 @@ export default { firstInvoiceText: 'vn-client-invoice vn-card > div vn-table vn-tbody > vn-tr' }, itemsIndex: { + goBackToModuleIndexButton: `vn-ticket-descriptor a[href="#!/ticket/index"]`, createItemButton: `${components.vnFloatButton}`, searchResult: `vn-item-product a`, searchResultPreviewButton: `vn-item-product .buttons > [icon="desktop_windows"]`, @@ -302,22 +303,58 @@ export default { savePackagesButton: `${components.vnSubmit}` }, ticketSales: { + saleLine: `vn-table div > vn-tbody > vn-tr`, + saleDescriptorPopover: `vn-item-descriptor-popover vn-item-descriptor`, + saleDescriptorPopoverSummaryButton: 'vn-item-descriptor-popover a[href="#!/item/1/summary"]', saleButton: `vn-menu-item a[ui-sref="ticket.card.sale"]`, + descriptorItemDiaryButton: `vn-item-descriptor > vn-card > div > vn-horizontal.quicklinks.ng-scope > vn-horizontal > a > vn-icon > i`, firstSaleText: `vn-table div > vn-tbody > vn-tr:nth-child(1)`, firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(3) > img', firstSaleZoomedImage: 'body > div > div > img', firstSaleQuantity: `vn-textfield[model="sale.quantity"]:nth-child(1) input`, - firstSaleID: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(4)', + firstSaleQuantityClearInput: `vn-textfield[model="sale.quantity"] div.suffix > i`, + firstSaleID: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(4) span', firstSalePrice: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(7)', + firstSalePriceInput: 'vn-ticket-sale:nth-child(1) > vn-vertical > vn-popover.edit.dialog-summary.ng-isolate-scope.vn-popover.shown > div > div.content > div > vn-textfield', firstSaleDiscount: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(8)', + firstSaleDiscountInput: 'vn-ticket-sale:nth-child(1) vn-ticket-sale-edit-discount > div > vn-textfield > div > div > div.infix > input.ng-not-empty', firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(9)', - secondSaleText: `vn-table div > vn-tbody > vn-tr:nth-child(2)` + firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td:nth-child(2) > vn-icon:nth-child(2)', + firstSaleColour: `vn-ticket-sale vn-tr:nth-child(1) vn-td:nth-child(5) section:nth-child(5)`, + firstSaleLength: `vn-ticket-sale vn-tr:nth-child(1) vn-td:nth-child(5) section:nth-child(3)`, + firstSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(1) vn-check[field="sale.checked"] label`, + secondSaleColour: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(5) section:nth-child(5)`, + secondSalePrice: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(7)`, + secondSaleDiscount: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(8)`, + secondSaleImport: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(9)`, + secondSaleText: `vn-table div > vn-tbody > vn-tr:nth-child(2)`, + totalImport: 'vn-ticket-sale vn-tfoot > vn-tr > vn-td:nth-child(9) > section > p:nth-child(3) > strong', + selectAllSalesCheckbox: `vn-ticket-sale vn-thead vn-check label`, + secondSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(2) vn-check[field="sale.checked"] label`, + thirdSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(3) vn-check[field="sale.checked"] label`, + deleteSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="delete"]', + transferSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="call_split"]', + moveToTicketInput: 'vn-ticket-sale vn-popover.transfer vn-textfield[model="$ctrl.moveToTicketFk"] input', + moveToTicketInputClearButton: 'vn-popover.shown i[title="Clear"]', + moveToTicketButton: 'vn-ticket-sale vn-popover.transfer vn-icon[icon="arrow_forward_ios"]', + moveToNewTicketButton: 'vn-ticket-sale vn-popover.transfer vn-button[label="New ticket"]', + acceptDeleteButton: `vn-ticket-sale > vn-confirm[vn-id="delete-lines"] button[response=ACCEPT]`, + stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-icon-menu[label="State"] button', + stateMenuOptions: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(1)', + moreMenuButton: 'vn-ticket-sale vn-tool-bar > vn-icon-menu[label="More"] button', + moreMenuDeleteOption: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(2)', + moreMenuReseveOption: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(3)', + moreMenuUnmarkResevedOption: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(4)', + moreMenuUpdateDiscount: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(5)', + moreMenuUpdateDiscountInput: 'vn-ticket-sale vn-dialog.shown vn-ticket-sale-edit-discount input' }, ticketTracking: { - trackingButton: `vn-menu-item a[ui-sref="ticket.card.tracking.index"]`, + trackingButton: `vn-left-menu a[ui-sref="ticket.card.tracking.index"]`, createStateButton: `${components.vnFloatButton}`, - firstSaleText: `vn-table div > vn-tbody > vn-tr:nth-child(1)`, - secondSaleText: `vn-table div > vn-tbody > vn-tr:nth-child(2)` + stateSelect: 'vn-ticket-tracking-edit vn-autocomplete[field="$ctrl.ticket.stateFk"] input', + stateSelectInput: 'vn-ticket-tracking-edit vn-autocomplete > vn-drop-down > vn-popover vn-textfield input', + stateSelectFirstResult: 'vn-ticket-tracking-edit vn-autocomplete > vn-drop-down > vn-popover ul > li:nth-child(1)', + saveButton: `${components.vnSubmit}` }, ticketBasicData: { basicDataButton: `vn-menu-item a[ui-sref="ticket.card.data.stepOne"]`, diff --git a/e2e/paths/ticket-module/04_create_ticket_packages.spec.js b/e2e/paths/ticket-module/04_create_ticket_packages.spec.js index 6bea2eedc8..c65bf7d4fa 100644 --- a/e2e/paths/ticket-module/04_create_ticket_packages.spec.js +++ b/e2e/paths/ticket-module/04_create_ticket_packages.spec.js @@ -1,128 +1,127 @@ -// import selectors from '../../helpers/selectors.js'; -// import createNightmare from '../../helpers/helpers'; +import selectors from '../../helpers/selectors.js'; +import createNightmare from '../../helpers/helpers'; -// describe('Ticket', () => { -// describe('Create packages path', () => { -// const nightmare = createNightmare(); +// #640 Ticket Create packages path is excluded +xdescribe('Ticket Create packages path', () => { + const nightmare = createNightmare(); -// beforeAll(() => { -// return nightmare -// .waitForLogin('developer'); -// }); + beforeAll(() => { + return nightmare + .waitForLogin('developer'); + }); -// it('should click on the Tickets button of the top bar menu', () => { -// return nightmare -// .waitToClick(selectors.globalItems.applicationsMenuButton) -// .wait(selectors.globalItems.applicationsMenuVisible) -// .waitToClick(selectors.globalItems.ticketsButton) -// .wait(selectors.ticketsIndex.createTicketButton) -// .parsedUrl() -// .then(url => { -// expect(url.hash).toEqual('#!/ticket/index'); -// }); -// }); + it('should click on the Tickets button of the top bar menu', () => { + return nightmare + .waitToClick(selectors.globalItems.applicationsMenuButton) + .wait(selectors.globalItems.applicationsMenuVisible) + .waitToClick(selectors.globalItems.ticketsButton) + .wait(selectors.ticketsIndex.createTicketButton) + .parsedUrl() + .then(url => { + expect(url.hash).toEqual('#!/ticket/index'); + }); + }); -// it('should search for the ticket 1', () => { -// return nightmare -// .wait(selectors.ticketsIndex.searchResult) -// .type(selectors.ticketsIndex.searchTicketInput, 'id:1') -// .click(selectors.ticketsIndex.searchButton) -// .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) -// .countElement(selectors.ticketsIndex.searchResult) -// .then(result => { -// expect(result).toEqual(1); -// }); -// }); + it('should search for the ticket 1', () => { + return nightmare + .wait(selectors.ticketsIndex.searchResult) + .type(selectors.ticketsIndex.searchTicketInput, 'id:1') + .click(selectors.ticketsIndex.searchButton) + .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) + .countElement(selectors.ticketsIndex.searchResult) + .then(result => { + expect(result).toEqual(1); + }); + }); -// it(`should click on the search result to access to the ticket packages`, () => { -// return nightmare -// .waitForTextInElement(selectors.ticketsIndex.searchResult, 'Batman') -// .waitToClick(selectors.ticketsIndex.searchResult) -// .waitToClick(selectors.ticketPackages.packagesButton) -// .waitForURL('package/index') -// .url() -// .then(url => { -// expect(url).toContain('package/index'); -// }); -// }); + it(`should click on the search result to access to the ticket packages`, () => { + return nightmare + .waitForTextInElement(selectors.ticketsIndex.searchResult, 'Batman') + .waitToClick(selectors.ticketsIndex.searchResult) + .waitToClick(selectors.ticketPackages.packagesButton) + .waitForURL('package/index') + .url() + .then(url => { + expect(url).toContain('package/index'); + }); + }); -// it(`should delete the first package and receive and error to save a new one with blank quantity`, () => { -// return nightmare -// .waitToClick(selectors.ticketPackages.firstRemovePackageButton) -// .waitToClick(selectors.ticketPackages.addPackageButton) -// .waitToClick(selectors.ticketPackages.firstPackageSelect) -// .waitToClick(selectors.ticketPackages.firstPackageSelectOptionThree) -// .click(selectors.ticketPackages.savePackagesButton) -// .waitForSnackbar() -// .then(result => { -// expect(result).toEqual(jasmine.arrayContaining(['Some fields are invalid'])); -// }); -// }); + it(`should delete the first package and receive and error to save a new one with blank quantity`, () => { + return nightmare + .waitToClick(selectors.ticketPackages.firstRemovePackageButton) + .waitToClick(selectors.ticketPackages.addPackageButton) + .waitToClick(selectors.ticketPackages.firstPackageSelect) + .waitToClick(selectors.ticketPackages.firstPackageSelectOptionThree) + .click(selectors.ticketPackages.savePackagesButton) + .waitForSnackbar() + .then(result => { + expect(result).toEqual(jasmine.arrayContaining(['Some fields are invalid'])); + }); + }); -// it(`should attempt create a new package but receive an error if quantity is a string`, () => { -// return nightmare -// .type(selectors.ticketPackages.firstQuantityInput, 'ninety 9') -// .click(selectors.ticketPackages.savePackagesButton) -// .waitForSnackbar() -// .then(result => { -// expect(result).toEqual(jasmine.arrayContaining(['Some fields are invalid'])); -// }); -// }); + it(`should attempt create a new package but receive an error if quantity is a string`, () => { + return nightmare + .type(selectors.ticketPackages.firstQuantityInput, 'ninety 9') + .click(selectors.ticketPackages.savePackagesButton) + .waitForSnackbar() + .then(result => { + expect(result).toEqual(jasmine.arrayContaining(['Some fields are invalid'])); + }); + }); -// it(`should attempt create a new package but receive an error if quantity is 0`, () => { -// return nightmare -// .clearInput(selectors.ticketPackages.firstQuantityInput) -// .type(selectors.ticketPackages.firstQuantityInput, '0') -// .click(selectors.ticketPackages.savePackagesButton) -// .waitForSnackbar() -// .then(result => { -// expect(result).toEqual(jasmine.arrayContaining(['Some fields are invalid'])); -// }); -// }); + it(`should attempt create a new package but receive an error if quantity is 0`, () => { + return nightmare + .clearInput(selectors.ticketPackages.firstQuantityInput) + .type(selectors.ticketPackages.firstQuantityInput, '0') + .click(selectors.ticketPackages.savePackagesButton) + .waitForSnackbar() + .then(result => { + expect(result).toEqual(jasmine.arrayContaining(['Some fields are invalid'])); + }); + }); -// it(`should attempt create a new package but receive an error if package is blank`, () => { -// return nightmare -// .clearInput(selectors.ticketPackages.firstQuantityInput) -// .type(selectors.ticketPackages.firstQuantityInput, '99') -// .click(selectors.ticketPackages.clearPackageSelectButton) -// .click(selectors.ticketPackages.savePackagesButton) -// .waitForSnackbar() -// .then(result => { -// expect(result).toEqual(jasmine.arrayContaining(['Package cannot be blank'])); -// }); -// }); + it(`should attempt create a new package but receive an error if package is blank`, () => { + return nightmare + .clearInput(selectors.ticketPackages.firstQuantityInput) + .type(selectors.ticketPackages.firstQuantityInput, '99') + .click(selectors.ticketPackages.clearPackageSelectButton) + .click(selectors.ticketPackages.savePackagesButton) + .waitForSnackbar() + .then(result => { + expect(result).toEqual(jasmine.arrayContaining(['Package cannot be blank'])); + }); + }); -// it(`should create a new package with correct data`, () => { -// return nightmare -// .waitToClick(selectors.ticketPackages.firstPackageSelect) -// .waitToClick(selectors.ticketPackages.firstPackageSelectOptionThree) -// .waitForTextInInput(selectors.ticketPackages.firstPackageSelect, 'Iron Patriot') -// .click(selectors.ticketPackages.savePackagesButton) -// .waitForSnackbar() -// .then(result => { -// expect(result).toEqual(jasmine.arrayContaining(['Data saved!'])); -// }); -// }); + it(`should create a new package with correct data`, () => { + return nightmare + .waitToClick(selectors.ticketPackages.firstPackageSelect) + .waitToClick(selectors.ticketPackages.firstPackageSelectOptionThree) + .waitForTextInInput(selectors.ticketPackages.firstPackageSelect, 'Iron Patriot') + .click(selectors.ticketPackages.savePackagesButton) + .waitForSnackbar() + .then(result => { + expect(result).toEqual(jasmine.arrayContaining(['Data saved!'])); + }); + }); -// it(`should confirm the first select is the expected one`, () => { -// return nightmare -// .click(selectors.ticketSales.saleButton) -// .wait(selectors.ticketSales.firstPackageSelect) -// .click(selectors.ticketPackages.packagesButton) -// .waitForTextInInput(selectors.ticketPackages.firstPackageSelect, 'Iron Patriot') -// .getInputValue(selectors.ticketPackages.firstPackageSelect) -// .then(result => { -// expect(result).toEqual('Iron Patriot'); -// }); -// }); + it(`should confirm the first select is the expected one`, () => { + return nightmare + .click(selectors.ticketSales.saleButton) + .wait(selectors.ticketSales.firstPackageSelect) + .click(selectors.ticketPackages.packagesButton) + .waitForTextInInput(selectors.ticketPackages.firstPackageSelect, 'Iron Patriot') + .getInputValue(selectors.ticketPackages.firstPackageSelect) + .then(result => { + expect(result).toEqual('Iron Patriot'); + }); + }); -// it(`should confirm the first quantity is the expected one`, () => { -// return nightmare -// .waitForTextInInput(selectors.ticketPackages.firstQuantityInput, '99') -// .getInputValue(selectors.ticketPackages.firstQuantityInput) -// .then(result => { -// expect(result).toEqual('99'); -// }); -// }); -// }); -// }); + it(`should confirm the first quantity is the expected one`, () => { + return nightmare + .waitForTextInInput(selectors.ticketPackages.firstQuantityInput, '99') + .getInputValue(selectors.ticketPackages.firstQuantityInput) + .then(result => { + expect(result).toEqual('99'); + }); + }); +}); diff --git a/e2e/paths/ticket-module/07_edit_sale.spec.js b/e2e/paths/ticket-module/07_edit_sale.spec.js new file mode 100644 index 0000000000..a800690450 --- /dev/null +++ b/e2e/paths/ticket-module/07_edit_sale.spec.js @@ -0,0 +1,657 @@ +import selectors from '../../helpers/selectors.js'; +import createNightmare from '../../helpers/helpers'; + +// #603 in progress +xdescribe('Ticket Edit sale path', () => { + const nightmare = createNightmare(); + + beforeAll(() => { + return nightmare + .waitForLogin('salesPerson'); + }); + + it('should click on the Tickets button of the top bar menu', () => { + return nightmare + .waitToClick(selectors.globalItems.applicationsMenuButton) + .wait(selectors.globalItems.applicationsMenuVisible) + .waitToClick(selectors.globalItems.ticketsButton) + .wait(selectors.ticketsIndex.createTicketButton) + .parsedUrl() + .then(url => { + expect(url.hash).toEqual('#!/ticket/index'); + }); + }); + + it('should search for a specific ticket', () => { + return nightmare + .wait(selectors.ticketsIndex.searchResult) + .type(selectors.ticketsIndex.searchTicketInput, 'id:16') + .click(selectors.ticketsIndex.searchButton) + .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) + .countElement(selectors.ticketsIndex.searchResult) + .then(result => { + expect(result).toEqual(1); + }); + }); + + it(`should click on the search result to access to the ticket Sale`, () => { + return nightmare + .waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21') + .waitToClick(selectors.ticketsIndex.searchResult) + .waitToClick(selectors.ticketSales.saleButton) + .waitForURL('/sale') + .url() + .then(url => { + expect(url).toContain('/sale'); + }); + }); + + describe('Before tests begings', () => { + it(`should check the quantity in the 1st line which we will be using in the further tests`, () => { + return nightmare + .wait(selectors.ticketSales.firstSaleText) + .getInputValue(selectors.ticketSales.firstSaleQuantity) + .then(value => { + expect(value).toEqual('5'); + }); + }); + + it(`should check the Price in the 1st line which we will be using in the further tests`, () => { + return nightmare + .wait(selectors.ticketSales.firstSaleText) + .getInnerText(selectors.ticketSales.firstSalePrice) + .then(value => { + expect(value).toEqual('€9.60'); + }); + }); + + it(`should check the Discount in the 1st line which we will be using in the further tests`, () => { + return nightmare + .wait(selectors.ticketSales.firstSaleText) + .getInnerText(selectors.ticketSales.firstSaleDiscount) + .then(value => { + expect(value).toEqual('0 %'); + }); + }); + + it(`should check the Import in the 1st line which we will be using in the further tests`, () => { + return nightmare + .wait(selectors.ticketSales.firstSaleText) + .getInnerText(selectors.ticketSales.firstSaleImport) + .then(value => { + expect(value).toEqual('€48.00'); + }); + }); + + it(`should count the ticket lines to verify there are 4 for further testing`, () => { + return nightmare + .countElement(selectors.ticketSales.saleLine) + .then(result => { + expect(result).toEqual(4); + }); + }); + }); + + it(`should check the zoomed image isnt present`, () => { + return nightmare + .countElement(selectors.ticketSales.firstSaleZoomedImage) + .then(result => { + expect(result).toEqual(0); + }); + }); + + it(`should click on the thumbnail image of the 1st sale and see the zoomed image`, () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSaleThumbnailImage) + .countElement(selectors.ticketSales.firstSaleZoomedImage) + .then(result => { + expect(result).toEqual(1); + }); + }); + + it(`should click on the zoomed image to close it`, () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSaleZoomedImage) + .countElement(selectors.ticketSales.firstSaleZoomedImage) + .then(result => { + expect(result).toEqual(0); + }); + }); + + it(`should confirm the item descriptor insnt visible yet`, () => { + return nightmare + .isVisible(selectors.ticketSales.saleDescriptorPopover) + .then(result => { + expect(result).toBeFalsy(); + }); + }); + + it(`should click on the first sale ID making the item descriptor visible`, () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSaleID) + .isVisible(selectors.ticketSales.saleDescriptorPopover) + .then(result => { + expect(result).toBeTruthy(); + }); + }); + + it(`should click on the descriptor image of the 1st sale and see the zoomed image`, () => { + return nightmare + .waitToClick('vn-item-descriptor img') + .countElement(selectors.ticketSales.firstSaleZoomedImage) + .then(result => { + expect(result).toEqual(1); + }); + }); + + it(`should click on the zoomed image to close it`, () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSaleZoomedImage) + .countElement(selectors.ticketSales.firstSaleZoomedImage) + .then(result => { + expect(result).toEqual(0); + }); + }); + + it(`should click on the summary icon of the item-descriptor to access to the item summary`, () => { + return nightmare + .waitToClick(selectors.ticketSales.saleDescriptorPopoverSummaryButton) + .waitForURL('/summary') + .url() + .then(url => { + expect(url).toContain('/summary'); + }); + }); + + it('should return to ticket sales section', () => { + return nightmare + .waitToClick(selectors.globalItems.applicationsMenuButton) + .wait(selectors.globalItems.applicationsMenuVisible) + .waitToClick(selectors.globalItems.ticketsButton) + .wait(selectors.ticketsIndex.createTicketButton) + .wait(selectors.ticketsIndex.searchResult) + .type(selectors.ticketsIndex.searchTicketInput, 'id:16') + .click(selectors.ticketsIndex.searchButton) + .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) + .waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21') + .waitToClick(selectors.ticketsIndex.searchResult) + .waitToClick(selectors.ticketSales.saleButton) + .waitForURL('/sale') + .url() + .then(url => { + expect(url).toContain('/sale'); + }); + }); + + it('should try to add a higher quantity value and then receive an error', () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSaleQuantityClearInput) + .type(selectors.ticketSales.firstSaleQuantity, '9\u000d') + .waitForLastSnackbar() + .then(result => { + expect(result).toEqual('The new quantity should be smaller than the old one'); + }); + }); + + it('should remove 1 from quantity', () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSaleQuantityClearInput) + .type(selectors.ticketSales.firstSaleQuantity, '4\u000d') + .waitForLastSnackbar() + .then(result => { + expect(result).toEqual('Data saved!'); + }); + }); + + it('should update the price', () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSalePrice) + .wait(selectors.ticketSales.firstSalePriceInput) + .type(selectors.ticketSales.firstSalePriceInput, 5) + .type('body', '\u000d') // simulates enter + .waitForLastSnackbar() + .then(result => { + expect(result).toEqual('Data saved!'); + }); + }); + + it('should confirm the price have been updated', () => { + return nightmare + .getInnerText(selectors.ticketSales.firstSalePrice) + .then(result => { + expect(result).toContain('€5.00'); + }); + }); + + it('should confirm the total price for that item have been updated', () => { + return nightmare + .getInnerText(selectors.ticketSales.firstSaleImport) + .then(result => { + expect(result).toContain('€20.00'); + }); + }); + + it('should update the discount', () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSaleDiscount) + .wait('vn-textfield[label="Discount"] > div[class="container selected"]') // a function selects the text after it's loaded + .type(selectors.ticketSales.firstSaleDiscountInput, 50) + .type('body', '\u000d') // simulates enter + .waitForLastSnackbar() + .then(result => { + expect(result).toEqual('Data saved!'); + }); + }); + + it('should confirm the discount have been updated', () => { + return nightmare + .waitForTextInElement(selectors.ticketSales.firstSaleDiscount, '50 %') + .getInnerText(selectors.ticketSales.firstSaleDiscount) + .then(result => { + expect(result).toContain('50 %'); + }); + }); + + it('should confirm the total import for that item have been updated', () => { + return nightmare + .waitForTextInElement(selectors.ticketSales.firstSaleImport, '€10.00') + .getInnerText(selectors.ticketSales.firstSaleImport) + .then(result => { + expect(result).toContain('€10.00'); + }); + }); + + it('should select the third sale and delete it', () => { + return nightmare + .waitToClick(selectors.ticketSales.thirdSaleCheckbox) + .waitToClick(selectors.ticketSales.deleteSaleButton) + .waitToClick(selectors.ticketSales.acceptDeleteButton) + .waitForLastSnackbar() + .then(result => { + expect(result).toEqual('Data saved!'); + }); + }); + + it(`should confirm the third sale was deleted`, () => { + return nightmare + .countElement(selectors.ticketSales.saleLine) + .then(result => { + expect(result).toEqual(3); + }); + }); + + it('should select the third sale and attempt to send it to a frozen client ticket', () => { + return nightmare + .waitToClick(selectors.ticketSales.thirdSaleCheckbox) + .waitToClick(selectors.ticketSales.transferSaleButton) + .wait(selectors.ticketSales.moveToTicketInput) + .type(selectors.ticketSales.moveToTicketInput, 2) + .waitToClick(selectors.ticketSales.moveToTicketButton) + .waitForLastSnackbar() + .then(result => { + expect(result).toEqual(`The sales of that ticket can't be modified`); + }); + }); + + it('should transfer the sale to a valid ticket', () => { + return nightmare + .waitToClick(selectors.ticketSales.moveToTicketInputClearButton) + .type(selectors.ticketSales.moveToTicketInput, 12) + .waitToClick(selectors.ticketSales.moveToTicketButton) + .waitForURL('ticket/12/sale') + .url() + .then(result => { + expect(result).toContain(`ticket/12/sale`); + }); + }); + + it('should confirm the transfered line is the correct one', () => { + return nightmare + .wait(selectors.ticketSales.firstSaleText) + .getInnerText(selectors.ticketSales.firstSaleText) + .then(result => { + expect(result).toContain(`Mark I`); + }); + }); + + it('should go back to the original ticket sales section', () => { + return nightmare + .waitToClick(selectors.itemsIndex.goBackToModuleIndexButton) + .wait(selectors.ticketsIndex.searchResult) + .type(selectors.ticketsIndex.searchTicketInput, 'id:16') + .click(selectors.ticketsIndex.searchButton) + .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) + .waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21') + .waitToClick(selectors.ticketsIndex.searchResult) + .waitToClick(selectors.ticketSales.saleButton) + .waitForURL('/sale') + .url() + .then(url => { + expect(url).toContain('/sale'); + }); + }); + + it(`should confirm the original ticket has only two lines now`, () => { + return nightmare + .wait(selectors.ticketSales.saleLine) + .countElement(selectors.ticketSales.saleLine) + .then(result => { + expect(result).toEqual(2); + }); + }); + + it('should go back to the receiver ticket sales section', () => { + return nightmare + .waitToClick(selectors.itemsIndex.goBackToModuleIndexButton) + .wait(selectors.ticketsIndex.searchResult) + .type(selectors.ticketsIndex.searchTicketInput, 'id:12') + .click(selectors.ticketsIndex.searchButton) + .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) + .waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21') + .waitToClick(selectors.ticketsIndex.searchResult) + .waitToClick(selectors.ticketSales.saleButton) + .waitForURL('/sale') + .url() + .then(url => { + expect(url).toContain('/sale'); + }); + }); + + it('should transfer the sale back to the original ticket', () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSaleCheckbox) + .waitToClick(selectors.ticketSales.transferSaleButton) + .wait(selectors.ticketSales.moveToTicketInput) + .type(selectors.ticketSales.moveToTicketInput, 16) + .waitToClick(selectors.ticketSales.moveToTicketButton) + .waitForURL('ticket/16/sale') + .url() + .then(result => { + expect(result).toContain(`ticket/16/sale`); + }); + }); + + it('should confirm the original ticket received the line', () => { + return nightmare + .wait(selectors.ticketSales.saleLine) + .countElement(selectors.ticketSales.saleLine) + .then(result => { + expect(result).toEqual(3); + }); + }); + + it('should select the second and third sale and tranfer them to a new ticket then get to the ticket index', () => { + return nightmare + .waitToClick(selectors.ticketSales.secondSaleCheckbox) + .waitToClick(selectors.ticketSales.thirdSaleCheckbox) + .waitToClick(selectors.ticketSales.transferSaleButton) + .waitToClick(selectors.ticketSales.moveToNewTicketButton) + .waitForLogin('salesPerson') + .waitToClick(selectors.globalItems.applicationsMenuButton) + .wait(selectors.globalItems.applicationsMenuVisible) + .waitToClick(selectors.globalItems.ticketsButton) + .wait(selectors.ticketsIndex.createTicketButton) + .parsedUrl() + .then(url => { + expect(url.hash).toEqual('#!/ticket/index'); + }); + }); + + it('should search for a specific created ticket', () => { + return nightmare + .wait(selectors.ticketsIndex.searchResult) + .type(selectors.ticketsIndex.searchTicketInput, 'id:22') + .click(selectors.ticketsIndex.searchButton) + .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) + .countElement(selectors.ticketsIndex.searchResult) + .then(result => { + expect(result).toEqual(1); + }); + }); + + it(`should click on the search result to access to the ticket Sale`, () => { + return nightmare + .waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21') + .waitToClick(selectors.ticketsIndex.searchResult) + .waitToClick(selectors.ticketSales.saleButton) + .waitForURL('/sale') + .url() + .then(url => { + expect(url).toContain('/sale'); + }); + }); + + it('should confirm the new ticket received both lines', () => { + return nightmare + .countElement(selectors.ticketSales.saleLine) + .then(result => { + expect(result).toEqual(2); + }); + }); + + it('should check the first sale reserved icon isnt visible', () => { + return nightmare + .isVisible(selectors.ticketSales.firstSaleReservedIcon) + .then(result => { + expect(result).toBeFalsy(); + }); + }); + + it('should mark the first sale as reserved', () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSaleCheckbox) + .waitToClick(selectors.ticketSales.moreMenuButton) + .waitToClick(selectors.ticketSales.moreMenuReseveOption) + .waitForClassNotPresent(selectors.ticketSales.firstSaleReservedIcon, 'ng-hide') + .isVisible(selectors.ticketSales.firstSaleReservedIcon) + .then(result => { + expect(result).toBeTruthy(); + }); + }); + + it('should unmark the first sale as reserved', () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSaleCheckbox) + .waitToClick(selectors.ticketSales.moreMenuButton) + .waitToClick(selectors.ticketSales.moreMenuUnmarkResevedOption) + .waitForClassPresent(selectors.ticketSales.firstSaleReservedIcon, 'ng-hide') + .isVisible(selectors.ticketSales.firstSaleReservedIcon) + .then(result => { + expect(result).toBeFalsy(); + }); + }); + + it('should update all sales discount', () => { + return nightmare + .waitToClick(selectors.ticketSales.selectAllSalesCheckbox) + .waitToClick(selectors.ticketSales.moreMenuButton) + .waitToClick(selectors.ticketSales.moreMenuUpdateDiscount) + .wait(selectors.ticketSales.moreMenuUpdateDiscountInput) + .type(selectors.ticketSales.moreMenuUpdateDiscountInput, 100) + .type('body', '\u000d') // simulates enter + .waitForTextInElement(selectors.ticketSales.totalImport, '€0.00') + .getInnerText(selectors.ticketSales.totalImport) + .then(result => { + expect(result).toEqual('€0.00'); + }); + }); + + it('should log in as Production role and go to the ticket index', () => { + return nightmare + .waitToClick(selectors.globalItems.logOutButton) + .waitForLogin('production') + .waitToClick(selectors.globalItems.applicationsMenuButton) + .wait(selectors.globalItems.applicationsMenuVisible) + .waitToClick(selectors.globalItems.ticketsButton) + .wait(selectors.ticketsIndex.createTicketButton) + .parsedUrl() + .then(url => { + expect(url.hash).toEqual('#!/ticket/index'); + }); + }); + + it('should now search for a specific ticket', () => { + return nightmare + .wait(selectors.ticketsIndex.searchResult) + .type(selectors.ticketsIndex.searchTicketInput, 'id:16') + .click(selectors.ticketsIndex.searchButton) + .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) + .countElement(selectors.ticketsIndex.searchResult) + .then(result => { + expect(result).toEqual(1); + }); + }); + + it(`should now click on the search result to access to the ticket Tracking`, () => { + return nightmare + .waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21') + .waitToClick(selectors.ticketsIndex.searchResult) + .waitToClick(selectors.ticketTracking.trackingButton) + .waitForURL('/tracking/index') + .url() + .then(url => { + expect(url).toContain('/tracking/index'); + }); + }); + + it(`should click on the edit ticket tracking state button`, () => { + return nightmare + .waitToClick(selectors.ticketTracking.createStateButton) + .waitForURL('/tracking/edit') + .url() + .then(url => { + expect(url).toContain('/tracking/edit'); + }); + }); + + it(`should set the state of the ticket to preparation`, () => { + return nightmare + .waitToClick(selectors.ticketTracking.stateSelect) + .wait(selectors.ticketTracking.stateSelectInput) + .type(selectors.ticketTracking.stateSelectInput, 'Preparación') + .waitToClick(selectors.ticketTracking.stateSelectFirstResult) + .waitForTextInInput(selectors.ticketTracking.stateSelectInput, 'Preparación') + .click(selectors.ticketTracking.saveButton) + .waitForURL('/tracking/index') + .url() + .then(url => { + expect(url).toContain('/tracking/index'); + }); + }); + + it(`should click on the ticket Sale menu button`, () => { + return nightmare + .waitToClick(selectors.ticketSales.saleButton) + .waitForURL('/sale') + .url() + .then(url => { + expect(url).toContain('/sale'); + }); + }); + + describe('when state is preparation and loged as Production', () => { + it(`should not be able to edit the sale price`, () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSalePrice) + .exists(selectors.ticketSales.firstSalePriceInput) + .then(result => { + expect(result).toBeFalsy(); + }); + }); + + it(`should not be able to edit the sale discount`, () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSaleDiscount) + .exists(selectors.ticketSales.firstSaleDiscountInput) + .then(result => { + expect(result).toBeFalsy(); + }); + }); + + it(`should not be able to edit the sale state`, () => { + return nightmare + .waitToClick(selectors.ticketSales.stateMenuButton) + .exists(selectors.ticketSales.stateMenuOptions) + .then(result => { + expect(result).toBeFalsy(); + }); + }); + + it('should log in as salesPerson role and go to the ticket index', () => { + return nightmare + .waitToClick(selectors.globalItems.logOutButton) + .waitForLogin('salesPerson') + .waitToClick(selectors.globalItems.applicationsMenuButton) + .wait(selectors.globalItems.applicationsMenuVisible) + .waitToClick(selectors.globalItems.ticketsButton) + .wait(selectors.ticketsIndex.createTicketButton) + .parsedUrl() + .then(url => { + expect(url.hash).toEqual('#!/ticket/index'); + }); + }); + + it('should again search for a specific ticket', () => { + return nightmare + .wait(selectors.ticketsIndex.searchResult) + .type(selectors.ticketsIndex.searchTicketInput, 'id:16') + .click(selectors.ticketsIndex.searchButton) + .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) + .countElement(selectors.ticketsIndex.searchResult) + .then(result => { + expect(result).toEqual(1); + }); + }); + + it(`should again click on the search result to access to the ticket Sales`, () => { + return nightmare + .waitForTextInElement(selectors.ticketsIndex.searchResult, 'address 21') + .waitToClick(selectors.ticketsIndex.searchResult) + .waitToClick(selectors.ticketSales.saleButton) + .waitForURL('/sale') + .url() + .then(url => { + expect(url).toContain('/sale'); + }); + }); + }); + + describe('when state is preparation and loged as salesPerson', () => { + it(`shouldnt be able to edit the sale price`, () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSalePrice) + .exists(selectors.ticketSales.firstSalePriceInput) + .then(result => { + expect(result).toBeFalsy(); + }); + }); + + it(`shouldnt be able to edit the sale discount`, () => { + return nightmare + .waitToClick(selectors.ticketSales.firstSaleDiscount) + .exists(selectors.ticketSales.firstSaleDiscountInput) + .then(result => { + expect(result).toBeFalsy(); + }); + }); + + it(`shouldnt be able to edit the sale state`, () => { + return nightmare + .waitToClick(selectors.ticketSales.stateMenuButton) + .exists(selectors.ticketSales.stateMenuOptions) + .then(result => { + expect(result).toBeFalsy(); + }); + }); + + it(`should be able to delete the ticket`, () => { + // return nightmare + // .waitToClick(selectors.ticketSales.moreMenuButton) + // .waitToClick(selectors.ticketSales.moreMenuDeleteOption) + // .exists(selectors.ticketSales.stateMenuOptions) + // .then(result => { + // expect(result).toBeFalsy(); + // }); + }); + }); +}); diff --git a/services/client/common/models/greuge.json b/services/client/common/models/greuge.json index 8524d3e194..36aa19ff81 100644 --- a/services/client/common/models/greuge.json +++ b/services/client/common/models/greuge.json @@ -2,42 +2,46 @@ "name": "Greuge", "base": "VnModel", "options": { - "mysql": { - "table": "greuge" - } + "mysql": { + "table": "greuge" + } }, "properties": { - "id": { - "id": true, - "type": "Number", - "description": "Identifier" - }, - "description": { - "type": "String", - "required": true - }, - "amount": { - "type": "Number", - "required": true - }, - "shipped": { - "type": "date" - }, - "created": { - "type": "date" - } + "id": { + "id": true, + "type": "Number", + "description": "Identifier" + }, + "description": { + "type": "String", + "required": true + }, + "amount": { + "type": "Number", + "required": true + }, + "shipped": { + "type": "date" + }, + "created": { + "type": "date" + }, + "greugeTypeFk": { + "type": "Number", + "required": true + } + }, "relations": { - "client": { - "type": "belongsTo", - "model": "Client", - "foreignKey": "clientFk" - }, - "greugeType": { - "type": "belongsTo", - "model": "GreugeType", - "foreignKey": "greugeTypeFk", - "required": true - } + "client": { + "type": "belongsTo", + "model": "Client", + "foreignKey": "clientFk" + }, + "greugeType": { + "type": "belongsTo", + "model": "GreugeType", + "foreignKey": "greugeTypeFk" + } } - } \ No newline at end of file +} \ No newline at end of file diff --git a/services/db/export-data.cmd b/services/db/export-data.cmd index e6e35c9095..e9a89854db 100755 --- a/services/db/export-data.cmd +++ b/services/db/export-data.cmd @@ -4,7 +4,7 @@ mysqldump --defaults-file=connect.ini --no-create-info account role roleRole rol echo USE `salix`; >> install/dump/03-dumpedFixtures.sql mysqldump --defaults-file=connect.ini --no-create-info salix ACL >> install/dump/03-dumpedFixtures.sql echo USE `vn`; >> install/dump/03-dumpedFixtures.sql -mysqldump --defaults-file=connect.ini --no-create-info vn cplusInvoiceType477 cplusSubjectOp cplusTaxBreak bookingPlanner pgc tag >> install/dump/03-dumpedFixtures.sql +mysqldump --defaults-file=connect.ini --no-create-info vn cplusInvoiceType477 cplusSubjectOp cplusTaxBreak bookingPlanner pgc tag alertLevel>> install/dump/03-dumpedFixtures.sql echo USE `vn2008`; >> install/dump/03-dumpedFixtures.sql mysqldump --defaults-file=connect.ini --no-create-info vn2008 accion_dits Gastos Tintas tarifa_componentes tarifa_componentes_series state bionic_updating_options Grupos Monedas container iva_group_codigo escritos cl_est cl_con cl_res cl_dev cl_mot cl_sol>> install/dump/03-dumpedFixtures.sql echo USE `bi`; >> install/dump/03-dumpedFixtures.sql diff --git a/services/db/export-data.sh b/services/db/export-data.sh index a1d42f501f..3fb0fd3c40 100755 --- a/services/db/export-data.sh +++ b/services/db/export-data.sh @@ -5,13 +5,10 @@ mysqldump --defaults-file=connect.ini --no-create-info account role roleRole rol echo "USE \`salix\`;" >> install/dump/03-dumpedFixtures.sql mysqldump --defaults-file=connect.ini --no-create-info salix ACL >> install/dump/03-dumpedFixtures.sql echo "USE \`vn\`;" >> install/dump/03-dumpedFixtures.sql -mysqldump --defaults-file=connect.ini --no-create-info vn cplusInvoiceType477 cplusSubjectOp cplusTaxBreak bookingPlanner pgc tag >> install/dump/03-dumpedFixtures.sql +mysqldump --defaults-file=connect.ini --no-create-info vn cplusInvoiceType477 cplusSubjectOp cplusTaxBreak bookingPlanner pgc tag alertLevel >> install/dump/03-dumpedFixtures.sql echo "USE \`vn2008\`;" >> install/dump/03-dumpedFixtures.sql mysqldump --defaults-file=connect.ini --no-create-info vn2008 accion_dits Gastos Tintas tarifa_componentes tarifa_componentes_series state bionic_updating_options Grupos Monedas container iva_group_codigo escritos cl_est cl_con cl_res cl_dev cl_mot cl_sol>> install/dump/03-dumpedFixtures.sql echo "USE \`bi\`;" >> install/dump/03-dumpedFixtures.sql mysqldump --defaults-file=connect.ini --no-create-info bi tarifa_componentes tarifa_componentes_series >> install/dump/03-dumpedFixtures.sql echo "USE \`cache\`;" >> install/dump/03-dumpedFixtures.sql mysqldump --defaults-file=connect.ini --no-create-info cache cache >> install/dump/03-dumpedFixtures.sql - - - diff --git a/services/db/install/changes/1.0.9/01-acl.sql b/services/db/install/changes/1.0.9/01-acl.sql deleted file mode 100644 index 0124a6ad3c..0000000000 --- a/services/db/install/changes/1.0.9/01-acl.sql +++ /dev/null @@ -1,6 +0,0 @@ -INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (95, 'ClientNotification', '*', '*', 'ALLOW', 'ROLE', 'employee'); -INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (96, 'ClaimAction', '*', 'READ', 'ALLOW', 'ROLE', 'employee'); -INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (97, 'ClaimAction', '*', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'); -INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (98, 'ClaimDetail', '*', 'WRITE', 'ALLOW', 'ROLE', 'employee'); -INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (99, 'claimDevelopment', '*', 'READ', 'ALLOW', 'ROLE', 'employee'); -INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (100, 'claimDevelopment', '*', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'); \ No newline at end of file diff --git a/services/db/install/changes/1.0.9/02-logAddWithUser.sql b/services/db/install/changes/1.0.9/02-logAddWithUser.sql deleted file mode 100644 index 68dee9352c..0000000000 --- a/services/db/install/changes/1.0.9/02-logAddWithUser.sql +++ /dev/null @@ -1,32 +0,0 @@ -USE `vn`; -DROP procedure IF EXISTS `logAddWithUser`; - -DELIMITER $$ -USE `vn`$$ -CREATE DEFINER=`root`@`%` PROCEDURE `logAddWithUser`(vOriginFk INT, vUserId INT, vActionCode VARCHAR(45), vEntity VARCHAR(45), vDescription TEXT) -BEGIN -/** - * Guarda las acciones realizadas por el usuario - * - * @param vOriginFk Id del registro de origen. - * @param vUserId Id del usuario. - * @param vActionCode Código de la acción {insert | delete | update}. - * @param vEntity Nombre que hace referencia a la tabla. - * @param descripcion Descripción de la acción realizada por el usuario. - */ - DECLARE vTableName VARCHAR(45); - - SET vTableName = CONCAT(vEntity, 'Log'); - - SET @qryLog := CONCAT( - 'INSERT INTO ', vTableName, ' (originFk, userFk, action, description)', - ' VALUES (', vOriginFk, ', ', vUserId, ', "', vActionCode, '", "', vDescription, '")' - ); - - PREPARE stmt FROM @qryLog; - EXECUTE stmt; - DEALLOCATE PREPARE stmt; -END$$ - -DELIMITER ; - diff --git a/services/db/install/changes/1.0.9/03-ticketCreateWithUser.sql b/services/db/install/changes/1.0.9/03-ticketCreateWithUser.sql deleted file mode 100644 index 6fc1abb2f0..0000000000 --- a/services/db/install/changes/1.0.9/03-ticketCreateWithUser.sql +++ /dev/null @@ -1,82 +0,0 @@ -USE `vn`; -DROP procedure IF EXISTS `ticketCreateWithUser`; - -DELIMITER $$ -USE `vn`$$ -CREATE DEFINER=`root`@`%` PROCEDURE `ticketCreateWithUser`( - vClientId INT - ,vShipped DATE - ,vWarehouseId INT - ,vCompanyFk INT - ,vAddressFk INT - ,vAgencyType INT - ,vRouteFk INT - ,vlanded DATE - ,vUserId INT - ,OUT vNewTicket INT) -BEGIN - - DECLARE vClientOrnamentales INT DEFAULT 5270; - DECLARE vCompanyOrn INT DEFAULT 1381; - DECLARE vProvinceName VARCHAR(255); - - SELECT p.name INTO vProvinceName - FROM vn.client c - JOIN province p ON p.id = c.provinceFk - WHERE c.id = vClientId; - - IF vProvinceName IN ('SANTA CRUZ DE TENERIFE', 'LAS PALMAS DE GRAN CANARIA') AND vClientId <> vClientOrnamentales THEN - SET vCompanyFk = vCompanyOrn; - END IF; - - IF NOT vAddressFk THEN - SELECT id INTO vAddressFk - FROM address - WHERE clientFk = vClientId AND isDefaultAddress; - END IF; - - INSERT INTO vn2008.Tickets ( - Id_Cliente, - Fecha, - Id_Consigna, - Id_Agencia, - Alias, - warehouse_id, - Id_Ruta, - empresa_id, - landing - ) - SELECT - vClientId, - vShipped, - a.id, - IF(vAgencyType, vAgencyType, a.agencyModeFk), - a.nickname, - vWarehouseId, - IF(vRouteFk,vRouteFk,NULL), - vCompanyFk, - vlanded - FROM address a - JOIN agencyMode am ON am.id = a.agencyModeFk - WHERE a.id = vAddressFk; - - SET vNewTicket = LAST_INSERT_ID(); - - INSERT INTO ticketObservation(ticketFk, observationTypeFk, description) - SELECT vNewTicket, ao.observationTypeFk, ao.description - FROM addressObservation ao - JOIN address a ON a.id = ao.addressFk - WHERE a.id = vAddressFk; - - CALL logAddWithUser(vNewTicket, vUserId, 'insert', 'ticket', CONCAT('Ha creado el ticket', ' ', vNewTicket)); - - IF (SELECT isCreatedAsServed FROM vn.client WHERE id = vClientId ) <> FALSE THEN - INSERT INTO vncontrol.inter(state_id, Id_Ticket, Id_Trabajador) - SELECT id, vNewTicket, getWorker() - FROM state - WHERE `code` = 'DELIVERED'; - END IF; -END$$ - -DELIMITER ; - diff --git a/services/db/install/changes/1.0.9/05-clientSample.sql b/services/db/install/changes/1.0.9/05-clientSample.sql deleted file mode 100644 index 92b2f3d4aa..0000000000 --- a/services/db/install/changes/1.0.9/05-clientSample.sql +++ /dev/null @@ -1,16 +0,0 @@ -USE `vn`; -CREATE - OR REPLACE ALGORITHM = UNDEFINED - DEFINER = `root`@`%` - SQL SECURITY DEFINER -VIEW `clientSample` AS - SELECT - `e`.`id` AS `id`, - `e`.`Id_Cliente` AS `clientFk`, - `e`.`escritos_id` AS `typeFk`, - `e`.`fecha` AS `created`, - `e`.`Id_Trabajador` AS `workerFk`, - `e`.`userFk` AS `userFk`, - `e`.`empresa_id` AS `companyFk` - FROM - `vn2008`.`escritos_det` `e`; \ No newline at end of file diff --git a/services/db/install/changes/1.1.0/01-claimBeginning.sql b/services/db/install/changes/1.1.0/01-claimBeginning.sql deleted file mode 100644 index e675c0fbeb..0000000000 --- a/services/db/install/changes/1.1.0/01-claimBeginning.sql +++ /dev/null @@ -1,13 +0,0 @@ -USE `vn`; -CREATE - OR REPLACE ALGORITHM = UNDEFINED - DEFINER = `root`@`%` - SQL SECURITY DEFINER -VIEW `claimBeginning` AS - SELECT - `c`.`id` AS `id`, - `c`.`cl_main_id` AS `claimFk`, - `c`.`Id_Movimiento` AS `saleFk`, - `c`.`numero` AS `quantity` - FROM - `vn2008`.`cl_det` `c`; diff --git a/services/db/install/changes/1.1.0/03-clientGetDebtDiary.sql b/services/db/install/changes/1.1.0/03-clientGetDebtDiary.sql deleted file mode 100644 index 0ee4c653c8..0000000000 --- a/services/db/install/changes/1.1.0/03-clientGetDebtDiary.sql +++ /dev/null @@ -1,98 +0,0 @@ -USE `vn`; -DROP procedure IF EXISTS `clientGetDebtDiary`; - -DELIMITER $$ -USE `vn`$$ -CREATE DEFINER=`root`@`%` PROCEDURE `clientGetDebtDiary`(vClientFK INT, vCompanyFk INT) -BEGIN -/** - * Devuelve el registro de deuda - * - * @param vClientFK Id del cliente - * @param vCompanyFk Id de la empresa - */ - DECLARE vDate DATETIME DEFAULT CURDATE(); - - SET @balance:= 0; - - SELECT MAX(issued) INTO vDate FROM - (SELECT - created, - issued, - @balance:= ROUND(amount, 2) + @balance AS balance - FROM invoiceOut - WHERE clientFk = vClientFk AND companyFk = vCompanyFk - - UNION ALL - - SELECT - created, - payed, - @balance:= ROUND(-1 * amountPaid, 2) + @balance AS balance - FROM receipt - WHERE clientFk = vClientFk AND companyFk = vCompanyFk - ORDER BY issued, created) balance - WHERE balance = 0; - - SELECT - issued, - CAST(debtOut AS DECIMAL(10,2)) debtOut, - CAST(debtIn AS DECIMAL(10,2)) debtIn, - ref, - companyFk, - priority - FROM - (SELECT - NULL AS issued, - SUM(amountUnpaid) AS debtOut, - NULL AS debtIn, - 'Saldo Anterior' AS ref, - companyFk, - 0 as priority - FROM - (SELECT SUM(amount) AS amountUnpaid, companyFk, 0 - FROM invoiceOut - WHERE clientFk = vClientFK - AND issued < vDate - GROUP BY companyFk - - UNION ALL - - SELECT SUM(-1 * amountPaid), companyFk, 0 - FROM receipt - WHERE clientFk = vClientFK - AND payed < vDate - GROUP BY companyFk) AS transactions - GROUP BY companyFk - - UNION ALL - - SELECT - issued, - amount as debtOut, - NULL AS debtIn, - id AS ref, - companyFk, - 1 - FROM invoiceOut - WHERE clientFk = vClientFK - AND issued >= vDate - UNION ALL - - SELECT - r.payed, - NULL as debtOut, - r.amountPaid, - r.id, - r.companyFk, - 0 - FROM receipt r - WHERE r.clientFk = vClientFK - AND r.payed >= vDate) t - INNER JOIN `client` c ON c.id = vClientFK - HAVING debtOut <> 0 OR debtIn <> 0 - ORDER BY issued, priority DESC, debtIn; -END$$ - -DELIMITER ; - diff --git a/services/db/install/changes/1.1.0/04-orderListTax.sql b/services/db/install/changes/1.1.0/04-orderListTax.sql deleted file mode 100644 index cd1cc92968..0000000000 --- a/services/db/install/changes/1.1.0/04-orderListTax.sql +++ /dev/null @@ -1,16 +0,0 @@ -USE `hedera`; -DROP procedure IF EXISTS `orderListTax`; - -DELIMITER $$ -USE `hedera`$$ -CREATE DEFINER=`root`@`%` PROCEDURE `orderListTax`(IN vOrderId INT) -BEGIN - - CALL hedera.orderGetTax(vOrderId); - - SELECT * FROM tmp.orderTax; - -END$$ - -DELIMITER ; - diff --git a/services/db/install/changes/1.1.0/05-ticketGetProblems.sql b/services/db/install/changes/1.1.0/05-ticketGetProblems.sql deleted file mode 100644 index 169ee6ff2e..0000000000 --- a/services/db/install/changes/1.1.0/05-ticketGetProblems.sql +++ /dev/null @@ -1,151 +0,0 @@ -USE `vn`; -DROP procedure IF EXISTS `ticketGetProblems`; - -DELIMITER $$ -USE `vn`$$ -CREATE DEFINER=`root`@`%` PROCEDURE `ticketGetProblems`() -BEGIN -/* - * Obtiene los problemas de uno o varios tickets - * - * @table tmp.ticketGetProblems(ticketFk, clientFk, warehouseFk, shipped) - * @return tmp.ticketProblems - */ - DECLARE vWarehouse INT; - DECLARE vDate DATE; - DECLARE vAvailableCache INT; - DECLARE vVisibleCache INT; - DECLARE vDone INT DEFAULT 0; - - DECLARE vCursor CURSOR FOR - SELECT DISTINCT tt.warehouseFk, date(tt.shipped) - FROM tmp.ticketGetProblems tt - WHERE DATE(tt.shipped) BETWEEN CURDATE() - AND TIMESTAMPADD(DAY, 1.9, CURDATE()); - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1; - - DROP TEMPORARY TABLE IF EXISTS tmp.ticketProblems; - CREATE TEMPORARY TABLE tmp.ticketProblems ( - ticketFk INT(11), - problem VARCHAR(50), - INDEX (ticketFk) - ) - ENGINE = MEMORY; - - -- CONGELADO - INSERT INTO tmp.ticketProblems(ticketFk, problem) - SELECT DISTINCT tt.ticketFk, 'Freezed' - FROM tmp.ticketGetProblems tt - JOIN vn.client c ON c.id = tt.clientFk - WHERE c.isFreezed; - - -- eliminamos tickets con problemas para no volverlos a mirar - DROP TEMPORARY TABLE IF EXISTS tmp.ticketListFiltered; - - CREATE TEMPORARY TABLE tmp.ticketListFiltered - (PRIMARY KEY (ticketFk)) - ENGINE = MEMORY - SELECT tt.ticketFk, c.id - FROM tmp.ticketGetProblems tt - JOIN vn.client c ON c.id = tt.clientFk - WHERE c.isFreezed = 0; - - DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt; - CREATE TEMPORARY TABLE tmp.clientGetDebt - (PRIMARY KEY (clientFk)) - ENGINE = MEMORY - SELECT DISTINCT tt.clientFk - FROM tmp.ticketGetProblems tt; - - -- RIESGO - CALL clientGetDebt(CURDATE()); - - INSERT INTO tmp.ticketProblems(ticketFk, problem) - SELECT DISTINCT tt.ticketFk, 'Risk' - FROM tmp.ticketListFiltered tt - JOIN vn.ticket t ON t.id = tt.ticketFk - JOIN vn.agencyMode a ON t.agencyModeFk = a.id - JOIN tmp.risk r ON r.clientFk = t.clientFk - JOIN vn.client c ON c.id = t.clientFk - WHERE r.risk > c.credit + 10 - AND a.deliveryMethodFk != 3; -- para que las recogidas se preparen - - -- eliminamos tickets con problemas para no volverlos a mirar - DELETE tlf FROM tmp.ticketListFiltered tlf - JOIN tmp.ticketProblems tp ON tlf.ticketFk = tp.ticketFk; - - -- CODIGO 100 - INSERT INTO tmp.ticketProblems(ticketFk, problem) - SELECT DISTINCT tt.ticketFk, 'Code 100' - FROM tmp.ticketGetProblems tt - JOIN sale s ON s.ticketFk = tt.ticketFk - WHERE s.itemFk = 100; - - -- eliminamos tickets con problemas para no volverlos a mirar - DELETE tlf FROM tmp.ticketListFiltered tlf - JOIN tmp.ticketProblems tp ON tlf.ticketFk = tp.ticketFk; - - OPEN vCursor; - - WHILE NOT vDone - DO - FETCH vCursor INTO vWarehouse, vDate; - - CALL cache.visible_refresh(vVisibleCache, FALSE, vWarehouse); - CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouse, vDate); - - -- El disponible es menor que 0 - INSERT INTO tmp.ticketProblems(ticketFk, problem) - SELECT tt.ticketFk, i.name - FROM tmp.ticketListFiltered tt - JOIN vn.ticket t ON t.id = tt.ticketFk - LEFT JOIN vn.sale s ON s.ticketFk = t.id - JOIN vn.item i ON i.id = s.itemFk - JOIN vn.itemType it on it.id = i.typeFk - LEFT JOIN cache.visible v ON i.id = v.item_id - AND v.calc_id = vVisibleCache - LEFT JOIN cache.available av ON av.item_id = i.id - AND av.calc_id = vAvailableCache - WHERE date(t.shipped) = vDate - AND categoryFk != 6 - AND s.quantity > IFNULL(v.visible, 0) - AND IFNULL(av.available, 0) < 0 - AND s.isPicked = FALSE - AND NOT i.generic - AND vWarehouse = t.warehouseFk; - - -- eliminamos tickets con problemas para no volverlos a mirar - DELETE tlf FROM tmp.ticketListFiltered tlf - JOIN tmp.ticketProblems tp ON tlf.ticketFk = tp.ticketFk; - - -- Amarillo: El disponible es mayor que cero y la cantidad supera el visible, estando aun sin preparar - INSERT INTO tmp.ticketProblems(ticketFk, problem) - SELECT tt.ticketFk, CONCAT('Delay', i.name) - FROM tmp.ticketListFiltered tt - JOIN vn.ticket t ON t.id = tt.ticketFk - LEFT JOIN vn.sale s ON s.ticketFk = t.id - JOIN vn.item i ON i.id = s.itemFk - JOIN vn.itemType it on it.id = i.typeFk - LEFT JOIN cache.visible v ON i.id = v.item_id AND v.calc_id = vVisibleCache - LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache - WHERE IFNULL(av.available, 0) >= 0 - AND s.quantity > IFNULL(v.visible, 0) - AND s.isPicked = FALSE - AND s.reserved = FALSE - AND it.categoryFk != 6 - AND date(t.shipped) = vDate - AND NOT i.generic - AND CURDATE() = vDate - AND t.warehouseFk = vWarehouse; - END WHILE; - - CLOSE vCursor; - - DROP TEMPORARY TABLE - tmp.clientGetDebt, - tmp.ticketListFiltered; -END$$ - -DELIMITER ; - diff --git a/services/db/install/changes/1.1.0/07-agencyHourGetLanded.sql b/services/db/install/changes/1.1.0/07-agencyHourGetLanded.sql deleted file mode 100644 index 091720df52..0000000000 --- a/services/db/install/changes/1.1.0/07-agencyHourGetLanded.sql +++ /dev/null @@ -1,42 +0,0 @@ -USE `vn`; -DROP procedure IF EXISTS `agencyHourGetLanded`; - -DELIMITER $$ -USE `vn`$$ -CREATE DEFINER=`root`@`%` PROCEDURE `agencyHourGetLanded`(vDated DATE, vAddress INT, vAgency INT, vWarehouse INT) -BEGIN -/** - * Devuelve una tabla temporal con el dia de recepcion para vDated. - * - * @param vDated Fecha de preparacion de mercancia - * @param vAddress Id de consignatario, %NULL para recogida - * @param vAgency Id agencia - * @table tmp.agencyHourGetLanded Datos de recepción - */ - DROP TEMPORARY TABLE IF EXISTS tmp.agencyHourGetLanded; - CREATE TEMPORARY TABLE tmp.agencyHourGetLanded - ENGINE = MEMORY - SELECT vWarehouse warehouseFk, landed FROM ( - SELECT * FROM ( - SELECT vWarehouse, TIMESTAMPADD(DAY, ah.substractDay, vDated) landed, ah.substractDay, ah.maxHour - FROM agencyHour ah - LEFT JOIN address a ON a.id = vAddress - WHERE (ah.weekDay = WEEKDAY(TIMESTAMPADD(DAY, ah.substractDay, vDated)) OR ah.weekDay IS NULL) - AND (ah.agencyFk = vAgency OR ah.agencyFk IS NULL) - AND ah.warehouseFk = vWarehouse - AND (ah.provinceFk = a.provinceFk OR ah.provinceFk IS NULL OR vAddress IS NULL) - ORDER BY ( - (ah.weekDay IS NOT NULL) + - (ah.agencyFk IS NOT NULL) + - (- ah.substractDay) + - ((ah.provinceFk IS NOT NULL)*3) - ) DESC - ) t - LIMIT 1 - ) t - WHERE IF(vDated = CURDATE(), t.maxHour > HOUR(NOW()), TRUE) AND t.substractDay < 225; - -END$$ - -DELIMITER ; - diff --git a/services/db/install/changes/1.1.0/09-itemCategory.sql b/services/db/install/changes/1.1.0/09-itemCategory.sql deleted file mode 100644 index cfb9781c0a..0000000000 --- a/services/db/install/changes/1.1.0/09-itemCategory.sql +++ /dev/null @@ -1,14 +0,0 @@ -USE `vn`; -CREATE - OR REPLACE ALGORITHM = UNDEFINED - DEFINER = `root`@`%` - SQL SECURITY DEFINER -VIEW `itemCategory` AS - SELECT - `r`.`id` AS `id`, - `r`.`reino` AS `name`, - `r`.`display` AS `display`, - `r`.`color` AS `color`, - r.icon - FROM - `vn2008`.`reinos` `r`; diff --git a/services/db/install/changes/1.1.0/10-ticketCalculate.sql b/services/db/install/changes/1.1.0/10-ticketCalculate.sql deleted file mode 100644 index ae5f918042..0000000000 --- a/services/db/install/changes/1.1.0/10-ticketCalculate.sql +++ /dev/null @@ -1,117 +0,0 @@ -USE `vn`; -DROP procedure IF EXISTS `ticketCalculate`; - -DELIMITER $$ -USE `vn`$$ -CREATE DEFINER=`root`@`%` PROCEDURE `ticketCalculate`( - vDate DATE, - vAddress INT, - vAgencyMode INT) -proc: BEGIN -/** - * Calcula los articulos disponibles y sus precios - * - * @param vDate Fecha de recepcion de mercancia - * @param vAddress Id del consignatario - * @param vAgencyMode Id de la agencia - * @return tmp.ticketCalculateItem, tmp.ticketComponentPrice - **/ - - DECLARE vAvailableCalc INT; - DECLARE vShipment DATE; - DECLARE vAgencyId INT; - DECLARE vClient INT; - DECLARE vWarehouseFk SMALLINT; - DECLARE vDone BOOL; - DECLARE cTravelTree CURSOR FOR - SELECT warehouseFk, shipped FROM tmp.agencyHourGetShipped; - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; - - -- Establece los almacenes y las fechas que van a entrar al disponible - - SELECT agencyFk INTO vAgencyId - FROM agencyMode WHERE id = vAgencyMode; - - SELECT clientFk INTO vClient - FROM address WHERE id = vAddress; - - CALL vn.agencyHourGetShipped(vDate, vAddress, vAgencyId); - - DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot; - CREATE TEMPORARY TABLE tmp.ticketLot( - `warehouseFk` smallint(5) unsigned NOT NULL, - `itemFk` int(11) NOT NULL, - `available` double DEFAULT NULL, - `buyFk` int(11) DEFAULT NULL, - `fix` tinyint(3) unsigned DEFAULT '0', - KEY `itemFk` (`itemFk`), - KEY `item_warehouse` (`itemFk`,`warehouseFk`) USING HASH - ) ENGINE=MEMORY DEFAULT CHARSET=utf8; - - OPEN cTravelTree; - - l: LOOP - SET vDone = FALSE; - FETCH cTravelTree INTO vWarehouseFk, vShipment; - - IF vDone THEN - LEAVE l; - END IF; - - CALL `cache`.available_refresh (vAvailableCalc, FALSE, vWarehouseFk, vShipment); - CALL buyUltimate (vWarehouseFk, vShipment); - - INSERT INTO tmp.ticketLot (warehouseFk, itemFk, available, buyFk) - SELECT - vWarehouseFk, - i.item_id, - IFNULL(i.available, 0), - bu.buyFk - FROM `cache`.available i - JOIN tmp.item br ON br.itemFk = i.item_id - LEFT JOIN item it ON it.id = i.item_id - LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = i.item_id - WHERE i.calc_id = vAvailableCalc - AND it.id != 100 - AND i.available > 0; - - DROP TEMPORARY TABLE tmp.buyUltimate; - END LOOP; - - CLOSE cTravelTree; - - CALL vn.ticketComponentCalculate(vAddress, vAgencyMode); - - DROP TEMPORARY TABLE IF EXISTS tmp.ticketCalculateItem; - CREATE TEMPORARY TABLE tmp.ticketCalculateItem - ENGINE = MEMORY - SELECT - b.itemFk, - SUM(b.available) available, - p.name producer, - i.name item, - i.size size, - i.stems, - i.category, - i.inkFk, - i.image, - o.code origin, bl.price - FROM tmp.ticketLot b - JOIN item i ON b.itemFk = i.id - LEFT JOIN producer p ON p.id = i.producerFk AND p.isVisible - JOIN origin o ON o.id = i.originFk - JOIN ( - SELECT MIN(price) price, itemFk - FROM tmp.ticketComponentPrice - GROUP BY itemFk - ) bl ON bl.itemFk = b.itemFk - GROUP BY b.itemFk; - - DROP TEMPORARY TABLE - tmp.ticketComponent, - tmp.ticketLot; -END$$ - -DELIMITER ; - diff --git a/services/db/install/changes/1.1.0/11-clientGetDebt.sql b/services/db/install/changes/1.1.0/11-clientGetDebt.sql deleted file mode 100644 index 62ded4d694..0000000000 --- a/services/db/install/changes/1.1.0/11-clientGetDebt.sql +++ /dev/null @@ -1,70 +0,0 @@ -DROP procedure IF EXISTS vn.`clientGetDebt`; - -DELIMITER $$ -CREATE DEFINER=`root`@`%` PROCEDURE vn.`clientGetDebt`(vDate DATE) -BEGIN -/** - * Calcula el riesgo para los clientes activos - * - * @table tmp.clientGetDebt(clientFk) - * @param vDate Fecha maxima de los registros - * @return tmp.risk - */ - DECLARE vStarted DATETIME DEFAULT TIMESTAMPADD(DAY, - DAYOFMONTH(CURDATE()) - 5, CURDATE()); - DECLARE vEnded DATETIME; - - SET vEnded = TIMESTAMP(IFNULL(vDate, CURDATE()), '23:59:59'); - - DROP TEMPORARY TABLE IF EXISTS tmp.ticket; - CREATE TEMPORARY TABLE tmp.ticket - (INDEX (ticketFk)) - ENGINE = MEMORY - SELECT id ticketFk, c.clientFk - FROM ticket t - JOIN tmp.clientGetDebt c ON c.clientFk = t.clientFk - WHERE refFk IS NULL - AND shipped BETWEEN vStarted AND vEnded; - - CALL ticketGetTotal(); - - DROP TEMPORARY TABLE IF EXISTS tClientRisk; - CREATE TEMPORARY TABLE tClientRisk - ENGINE = MEMORY - SELECT cr.customer_id clientFk, SUM(cr.amount) amount - FROM bi.customer_risk cr - JOIN tmp.clientGetDebt c ON c.clientFk = cr.customer_id - GROUP BY cr.customer_id; - - INSERT INTO tClientRisk - SELECT c.clientFk, SUM(r.amountPaid) - FROM receipt r - JOIN tmp.clientGetDebt c ON c.clientFk = r.clientFk - WHERE r.payed > vStarted - GROUP BY c.clientFk; - - INSERT INTO tClientRisk - SELECT t.clientFk, CAST(-SUM(t.amount) / 100 AS DECIMAL(10,2)) - FROM hedera.tpvTransaction t - JOIN tmp.clientGetDebt c ON c.clientFk = t.clientFk - WHERE t.receiptFk IS NULL - AND t.status = 'ok' - GROUP BY t.clientFk; - - INSERT INTO tClientRisk - SELECT t.clientFk, total - FROM tmp.ticketTotal tt - JOIN tmp.ticket t ON t.ticketFk = tt.ticketFk; - - DROP TEMPORARY TABLE IF EXISTS tmp.risk; - CREATE TEMPORARY TABLE tmp.risk - (PRIMARY KEY (clientFk)) - ENGINE = MEMORY - SELECT clientFk, SUM(amount) risk - FROM client c - JOIN tClientRisk cr ON cr.clientFk = c.id - WHERE c.isActive - GROUP BY c.id; -END$$ - -DELIMITER ; - diff --git a/services/db/install/changes/1.1.0/12-itemDiary.sql b/services/db/install/changes/1.1.0/12-itemDiary.sql deleted file mode 100644 index 4f7ba662ed..0000000000 --- a/services/db/install/changes/1.1.0/12-itemDiary.sql +++ /dev/null @@ -1,115 +0,0 @@ -USE `vn`; -DROP procedure IF EXISTS `itemDiary`; - -DELIMITER $$ -USE `vn`$$ -CREATE DEFINER=`root`@`%` PROCEDURE `itemDiary`(IN vItemId INT, IN vWarehouse INT) -BEGIN - DECLARE vDateInventory DATETIME; - DECLARE vCurdate DATE DEFAULT CURDATE(); - DECLARE vDayEnd DATETIME DEFAULT util.dayEnd(vCurdate); - -- traduccion: date, alertLevel, origin, reference, name, In, Out, Balance - SELECT Fechainventario INTO vDateInventory FROM vn2008.tblContadores; - SET @a = 0; - SELECT sql_no_cache DATE(date) AS date, - alertLevel, - stateName, - origin, - reference, - name, - `in`, - `out`, - @a := @a + IFNULL(`in`,0) - IFNULL(`out`,0) as balance, - isPicked, - isTicket - FROM - ( SELECT tr.landed as date, - b.quantity as `in`, - NULL as `out`, - IF(tr.isReceived != FALSE,3, IF(tr.isDelivered,1,0)) as alertLevel, - st.name AS stateName, - s.name as name, - e.ref as reference, - e.id as origin, - TRUE isPicked, - FALSE AS isTicket - FROM vn.buy b - JOIN vn.entry e ON e.id = b.entryFk - JOIN vn.travel tr ON tr.id = e.travelFk - JOIN vn.supplier s ON s.id = e.supplierFk - JOIN vn.alertLevel al ON al.alertLevel = - CASE - WHEN tr.isReceived != FALSE THEN 3 - WHEN tr.isDelivered THEN 1 - ELSE 0 - END - JOIN vn.state st ON st.code = al.code - WHERE tr.landed >= vDateInventory - AND vWarehouse = tr.warehouseInFk - AND b.itemFk = vItemId - AND e.isInventory = 0 - - UNION ALL - - SELECT tr.shipped as date, - NULL as `in`, - b.quantity as `out`, - IF(tr.isReceived != FALSE,3, IF(tr.isDelivered,1,0)) as alertLevel, - st.name AS stateName, - s.name as name, - e.ref as reference, - e.id as origin, - TRUE isPicked, - FALSE AS isTicket - FROM vn.buy b - JOIN vn.entry e ON e.id = b.entryFk - JOIN vn.travel tr ON tr.id = e.travelFk - JOIN vn.warehouse w ON w.id = tr.warehouseOutFk - JOIN vn.supplier s ON s.id = e.supplierFk - JOIN vn.alertLevel al ON al.alertLevel = - CASE - WHEN tr.isReceived != FALSE THEN 3 - WHEN tr.isDelivered THEN 1 - ELSE 0 - END - JOIN vn.state st ON st.code = al.code - WHERE tr.shipped >= vDateInventory - AND vWarehouse =tr.warehouseOutFk - AND s.id <> 4 - AND b.itemFk = vItemId - AND e.isInventory = 0 - AND w.isFeedStock = 0 - - UNION ALL - - SELECT t.shipped as date, - NULL as `in`, - s.quantity as `out`, - al.alertLevel as alertLevel, - st.name AS stateName, - t.nickname as name, - t.refFk as reference, - t.id as origin, - TRUE as isPicked, -- stk.id as isPicked - TRUE as isTicket - FROM vn.sale s - JOIN vn.ticket t ON t.id = s.ticketFk - LEFT JOIN vn.ticketState ts ON ts.ticket = t.id - JOIN vn.client c ON c.id = t.clientFk - JOIN vn.alertLevel al ON al.alertLevel = - CASE - WHEN t.shipped < vCurdate THEN 3 - WHEN t.shipped > vDayEnd THEN 0 - ELSE IFNULL(ts.alertLevel, 0) - END - JOIN vn.state st ON st.code = al.code - -- LEFT JOIN vn.saleTracking stk ON stk.saleFk = s.id AND stk.stateFk = 14 - WHERE t.shipped >= vDateInventory - AND s.itemFk = vItemId - AND vWarehouse =t.warehouseFk - ) AS itemDiary - ORDER BY date, alertLevel DESC, isPicked DESC, `in` DESC, `out` DESC; -END$$ - -DELIMITER ; - diff --git a/services/db/install/dump/03-dumpedFixtures.sql b/services/db/install/dump/03-dumpedFixtures.sql index 9513353a08..69c0854bd3 100644 --- a/services/db/install/dump/03-dumpedFixtures.sql +++ b/services/db/install/dump/03-dumpedFixtures.sql @@ -55,7 +55,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2018-09-05 11:59:54 +-- Dump completed on 2018-09-06 14:58:36 USE `salix`; -- MySQL dump 10.13 Distrib 5.7.21, for osx10.13 (x86_64) -- @@ -93,7 +93,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2018-09-05 11:59:54 +-- Dump completed on 2018-09-06 14:58:36 USE `vn`; -- MySQL dump 10.13 Distrib 5.7.21, for osx10.13 (x86_64) -- @@ -171,6 +171,16 @@ LOCK TABLES `tag` WRITE; INSERT INTO `tag` VALUES (1,'Color',0,1,'ink',NULL),(2,'Forma',1,1,NULL,NULL),(3,'Material',1,1,NULL,NULL),(4,'Longitud',1,0,NULL,NULL),(5,'Diámetro',1,0,NULL,'mm'),(6,'Perímetro',1,0,NULL,'mm'),(7,'Ancho de la base',1,0,NULL,'mm'),(8,'Altura',1,0,NULL,'mm'),(9,'Volumen',1,0,NULL,'ml'),(10,'Densidad',1,0,NULL,NULL),(11,'Calidad',1,1,NULL,NULL),(12,'Textura',1,1,NULL,NULL),(13,'Material del mango',1,1,NULL,NULL),(14,'Compra mínima',1,1,NULL,NULL),(15,'Nº pétalos',1,0,NULL,NULL),(16,'Ancho',1,0,NULL,'mm'),(17,'Alto',1,0,NULL,'mm'),(18,'Profundidad',1,0,NULL,'mm'),(19,'Largo',1,0,NULL,'mm'),(20,'Ancho superior',1,0,NULL,'mm'),(21,'Ancho inferior',1,0,NULL,'mm'),(22,'Gramaje',1,0,NULL,'g'),(23,'Tallos',1,0,NULL,NULL),(24,'Estado',0,1,NULL,NULL),(25,'Color principal',0,1,NULL,NULL),(26,'Color secundario',0,1,NULL,NULL),(27,'Longitud(cm)',1,0,NULL,'cm'),(28,'Diámetro base',1,0,NULL,NULL),(29,'Colección',1,1,NULL,NULL),(30,'Uds / caja',1,0,NULL,NULL),(31,'Contenido',1,1,NULL,NULL),(32,'Peso',1,0,NULL,'g'),(33,'Grosor',1,0,NULL,'mm'),(34,'Marca',1,1,NULL,NULL),(35,'Origen',0,1,'origin',NULL),(36,'Proveedor',1,1,NULL,NULL),(37,'Productor',1,1,'producer',NULL),(38,'Duración',1,0,NULL,'s'),(39,'Flor',1,1,NULL,NULL),(40,'Soporte',1,1,NULL,NULL),(41,'Tamaño flor',1,1,NULL,NULL),(42,'Apertura',1,1,NULL,NULL),(43,'Tallo',0,1,NULL,NULL),(44,'Numero hojas',1,1,NULL,NULL),(45,'Dimensiones',1,1,NULL,NULL),(46,'Diámetro boca',1,1,NULL,NULL),(47,'Nº flores',1,0,NULL,NULL),(48,'Uds / paquete',1,0,NULL,NULL),(49,'Maceta',1,1,NULL,NULL),(50,'Textura flor',1,1,NULL,NULL),(51,'Textura hoja',1,1,NULL,NULL),(52,'Tipo de iva',1,1,NULL,NULL),(53,'Tronco',1,1,NULL,NULL),(54,'Hoja',1,1,NULL,NULL),(55,'Formato',1,1,NULL,NULL),(56,'Genero',1,1,NULL,NULL),(57,'Especie',1,1,NULL,NULL),(58,'Variedad',1,1,NULL,NULL),(59,'Medida grande',1,0,NULL,NULL),(60,'Medida mediano',1,0,NULL,NULL),(61,'Medida pequeño',1,0,NULL,NULL),(62,'Medida pequeño',1,0,NULL,NULL),(63,'Recipiente interior',1,1,NULL,NULL),(64,'Material secundario',1,1,NULL,NULL),(65,'Colores',1,1,NULL,NULL),(66,'Referencia',1,1,NULL,NULL),(67,'Categoria',1,0,NULL,NULL),(68,'Amb',0,1,NULL,NULL),(69,'Anchura',1,1,NULL,'cm'),(70,'Hueco interior',-1,1,NULL,NULL),(71,'Tamaño',1,1,NULL,NULL),(72,'Color botón',1,1,NULL,NULL),(73,'Tamaño minimo del botón',1,1,NULL,NULL),(74,'Obtentor',1,1,NULL,NULL),(75,'Logitud del brote',1,1,NULL,NULL),(76,'Tallos / u.v.',1,1,NULL,NULL),(77,'Madera de',1,1,NULL,NULL),(78,'Unidad de venta',1,1,NULL,NULL),(79,'Temporal',1,1,NULL,NULL),(80,'Gramaje/tallo',1,1,NULL,NULL),(81,'Gramaje/paquete',1,1,NULL,NULL),(82,'Flexibilidad del tallo',1,1,NULL,NULL),(83,'Nº planchas',1,1,NULL,NULL); /*!40000 ALTER TABLE `tag` ENABLE KEYS */; UNLOCK TABLES; + +-- +-- Dumping data for table `alertLevel` +-- + +LOCK TABLES `alertLevel` WRITE; +/*!40000 ALTER TABLE `alertLevel` DISABLE KEYS */; +INSERT INTO `alertLevel` VALUES ('DELIVERED',3),('FREE',0),('ON_PREPARATION',1),('PACKED',2); +/*!40000 ALTER TABLE `alertLevel` ENABLE KEYS */; +UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -181,7 +191,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2018-09-05 11:59:54 +-- Dump completed on 2018-09-06 14:58:37 USE `vn2008`; -- MySQL dump 10.13 Distrib 5.7.21, for osx10.13 (x86_64) -- @@ -296,7 +306,7 @@ UNLOCK TABLES; LOCK TABLES `escritos` WRITE; /*!40000 ALTER TABLE `escritos` DISABLE KEYS */; -INSERT INTO `escritos` VALUES (1,'Carta_1','Aviso inicial por saldo deudor',0,'0'),(2,'Carta_2','Reiteracion de aviso por saldo deudor',0,'0'),(3,'Cred_Up','Notificación de aumento de crédito',0,'0'),(4,'Cred_down','Notificación de reducción de crédito',0,'0'),(5,'Pet_CC','Petición de datos bancarios B2B',0,'0'),(6,'SolCredito','Solicitud de crédito',0,'0'),(7,'LeyPago','Ley de pagos',0,'0'),(8,'Pet_CC_Core','Petición de datos bancarios CORE',0,'0'),(9,'nueva_alta','Documento de nueva alta de cliente',0,'0'),(10,'client_welcome','Email de bienvenida para nuevo cliente',0,'0'),(11,'setup_printer','Email de instalación de impresora',0,'0'),(12,'client-welcome','Email de bienvenida como nuevo cliente.',1,'0'),(13,'printer-setup','Email de instalación y configuración de impresora de coronas.',1,'0'),(14,'sepa-core','Email de solicitud de datos bancarios core.',1,'1'),(15,'letter-debtor-st','Email de aviso inicial por saldo deudor',1,'1'),(16,'letter-debtor-nd','Email de aviso reiterado por saldo deudor',1,'1'); +INSERT INTO `escritos` VALUES (1,'Carta_1','Aviso inicial por saldo deudor',1,'0'),(2,'Carta_2','Reiteracion de aviso por saldo deudor',1,'0'),(3,'Cred_Up','Notificación de aumento de crédito',0,'0'),(4,'Cred_down','Notificación de reducción de crédito',0,'0'),(5,'Pet_CC','Petición de datos bancarios B2B',0,'0'),(6,'SolCredito','Solicitud de crédito',0,'0'),(7,'LeyPago','Ley de pagos',0,'0'),(8,'Pet_CC_Core','Petición de datos bancarios CORE',1,'0'),(9,'nueva_alta','Documento de nueva alta de cliente',0,'0'),(10,'client_welcome','Email de bienvenida para nuevo cliente',1,'0'),(11,'setup_printer','Email de instalación de impresora',1,'0'),(12,'client-welcome','Email de bienvenida como nuevo cliente.',0,'0'),(13,'printer-setup','Email de instalación y configuración de impresora de coronas.',0,'0'),(14,'sepa-core','Email de solicitud de datos bancarios core.',0,'1'),(15,'letter-debtor-st','Email de aviso inicial por saldo deudor',0,'1'),(16,'letter-debtor-nd','Email de aviso reiterado por saldo deudor',0,'1'); /*!40000 ALTER TABLE `escritos` ENABLE KEYS */; UNLOCK TABLES; @@ -369,7 +379,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2018-09-05 11:59:55 +-- Dump completed on 2018-09-06 14:58:37 USE `bi`; -- MySQL dump 10.13 Distrib 5.7.21, for osx10.13 (x86_64) -- @@ -417,7 +427,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2018-09-05 11:59:55 +-- Dump completed on 2018-09-06 14:58:37 USE `cache`; -- MySQL dump 10.13 Distrib 5.7.21, for osx10.13 (x86_64) -- @@ -455,4 +465,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2018-09-05 11:59:55 +-- Dump completed on 2018-09-06 14:58:37 diff --git a/services/loopback/common/methods/item/specs/getDiary.spec.js b/services/loopback/common/methods/item/specs/getDiary.spec.js new file mode 100644 index 0000000000..6ebbbe004d --- /dev/null +++ b/services/loopback/common/methods/item/specs/getDiary.spec.js @@ -0,0 +1,11 @@ +const app = require(`${servicesDir}/item/server/server`); + +describe('item getShipped()', () => { + it('should return 3 entries, the first one with the property balance -100', async() => { + let params = {where: {itemFk: 1, warehouseFk: 2}}; + let result = await app.models.Item.getDiary(params); + + expect(result.length).toBe(3); + expect(result[0].balance).toBe(-100); + }); +}); diff --git a/services/loopback/common/methods/sale/specs/getClaimableFromTicket.spec.js b/services/loopback/common/methods/sale/specs/getClaimableFromTicket.spec.js new file mode 100644 index 0000000000..fbcb0a4b3b --- /dev/null +++ b/services/loopback/common/methods/sale/specs/getClaimableFromTicket.spec.js @@ -0,0 +1,10 @@ +const app = require(`${servicesDir}/ticket/server/server`); + +describe('sale getClaimableFromTicket()', () => { + it('should throw an error if the ticket is not editable', async() => { + let claimableFromTicket = await app.models.Sale.getClaimableFromTicket(16); + + expect(claimableFromTicket[0].concept).toBe('Gem of Time'); + expect(claimableFromTicket.length).toBe(4); + }); +}); diff --git a/services/order/common/methods/order/catalogFilter.js b/services/order/common/methods/order/catalogFilter.js index 1666f8ef28..5065f85c41 100644 --- a/services/order/common/methods/order/catalogFilter.js +++ b/services/order/common/methods/order/catalogFilter.js @@ -86,6 +86,8 @@ module.exports = Self => { tcp.itemFk, tcp.grouping, tcp.price, + tcp.rate, + tcp.warehouseFk, w.name AS warehouse FROM tmp.ticketComponentPrice tcp JOIN vn.warehouse w ON w.id = tcp.warehouseFk` diff --git a/services/order/common/models/order.json b/services/order/common/models/order.json index d51d6a843b..0c58396d9c 100644 --- a/services/order/common/models/order.json +++ b/services/order/common/models/order.json @@ -90,6 +90,11 @@ "type": "hasMany", "model": "OrderRow", "foreignKey": "orderFk" + }, + "company": { + "type": "belongsTo", + "model": "Company", + "foreignKey": "company_id" } } } diff --git a/services/route/common/methods/comboVehicles.js b/services/route/common/methods/comboVehicles.js deleted file mode 100644 index df3978d9f5..0000000000 --- a/services/route/common/methods/comboVehicles.js +++ /dev/null @@ -1,42 +0,0 @@ -module.exports = Self => { - Self.remoteMethod('comboVehicles', { - description: 'returns list of vehicles', - accessType: 'READ', - accepts: [{ - arg: 'filter', - type: 'Object', - required: false, - description: 'Filter defining where and paginated data', - http: {source: 'query'} - }], - returns: { - arg: 'data', - type: 'Vehicle', - root: true - }, - http: { - path: `/comboVehicles`, - verb: 'get' - } - }); - - Self.comboVehicles = (filter, callback) => { - Self.find(filter, (_, instances) => { - callback(null, formatOutput(instances)); - }); - }; - - function formatOutput(instances) { - let results = []; - - for (let instance of instances) { - let numberPlate = ` ${instance.numberPlate}` || ''; - results.push({ - id: instance.id, - name: `${instance.tradeMark} ${instance.model}${numberPlate}` - }); - } - - return results; - } -}; diff --git a/services/route/common/methods/drivers.js b/services/route/common/methods/drivers.js deleted file mode 100644 index d074391faa..0000000000 --- a/services/route/common/methods/drivers.js +++ /dev/null @@ -1,79 +0,0 @@ -module.exports = Self => { - Self.remoteMethod('activeDrivers', { - description: 'returns actives workers with driver role', - accessType: 'READ', - accepts: [{ - arg: 'filter', - type: 'Object', - required: false, - description: 'Filter defining where and paginated data', - http: {source: 'query'} - }], - returns: { - arg: 'data', - type: 'Worker', - root: true - }, - http: { - path: `/activeDrivers`, - verb: 'get' - } - }); - - Self.activeDrivers = (filter, callback) => { - let skip = filter.skip || 0; - let limit = filter.limit || 10; - let where = getCondition(filter.where); - // TODO: change salesPerson role to Driver role when it will be created - let query = `SELECT em.id, em.firstName, em.name - FROM worker em - JOIN account.user ac ON em.userFk = ac.id - JOIN account.role r ON r.id = ac.roleFK - WHERE ac.active AND r.\`name\` = 'salesPerson' ${where} - ORDER BY em.name ASC - LIMIT ${limit} OFFSET ${skip}`; - - Self.rawSql(query, [], callback) - .then(response => { - callback(null, formatDriver(response)); - }) - .catch(reject => { - callback(reject, null); - }); - }; - - function getCondition(where) { - let out = []; - if (typeof where === 'object') { - Object.keys(where).forEach(k => { - let value = where[k]; - if (typeof value === 'number') { - out.push(`em.${k}=${value}`); - } else if (typeof value === 'string') { - out.push(`em.${k}='${value}'`); - } else if (typeof value === 'boolean' || value === null) { - out.push(`em.${k} IS ${String(value).toUpperCase()}`); - } else if (Object.keys(value).length) { - let firstProperty = Object.keys(value)[0]; - out.push(`em.${k} ${firstProperty} '${value[firstProperty]}'`); - } else { - throw new Error('Error: unexpected type'); - } - }); - } - return out.length ? `AND (${out.join(' AND ')})` : ''; - } - - function formatDriver(response) { - let results = []; - - response.forEach(person => { - results.push({ - id: person.id, - name: `${person.firstName} ${person.name}` - }); - }); - - return results; - } -}; diff --git a/services/route/common/methods/filterRoutes.js b/services/route/common/methods/filterRoutes.js deleted file mode 100644 index 8d15050ddb..0000000000 --- a/services/route/common/methods/filterRoutes.js +++ /dev/null @@ -1,48 +0,0 @@ -module.exports = function(Self) { - Self.installMethod('filter', filterRoutes); - - function filterRoutes(params) { - if (params.search) - return searchWhere(params); - return andWhere(params); - } - - function searchWhere(params) { - return { - where: { - or: [ - {id: params.search}, - {name: {regexp: params.search}} - ] - - }, - skip: (parseInt(params.page, 10) - 1) * parseInt(params.size, 10), - limit: parseInt(params.size, 10) - }; - } - - function andWhere(params) { - let filters = { - where: {}, - skip: (parseInt(params.page, 10) - 1) * parseInt(params.size, 10), - limit: parseInt(params.size, 10) - }; - - delete params.page; - delete params.size; - - if (params.phone) { - filters.where.or = [ - {phone: params.phone}, - {mobile: params.phone} - ]; - delete params.phone; - } - Object.keys(params).forEach( - key => { - filters.where[key] = {regexp: params[key]}; - } - ); - return filters; - } -}; diff --git a/services/route/common/models/delivery.js b/services/route/common/models/delivery.js deleted file mode 100644 index 5bb764ee3e..0000000000 --- a/services/route/common/models/delivery.js +++ /dev/null @@ -1,4 +0,0 @@ - -module.exports = function(Self) { - require('../methods/filterRoutes.js')(Self); -}; diff --git a/services/route/common/models/vehicle.js b/services/route/common/models/vehicle.js deleted file mode 100644 index 6d6c3a1135..0000000000 --- a/services/route/common/models/vehicle.js +++ /dev/null @@ -1,5 +0,0 @@ - -module.exports = function(Self) { - require('../methods/comboVehicles.js')(Self); - require('../methods/drivers.js')(Self); -}; diff --git a/services/route/server/server.js.bak b/services/route/server/server.js similarity index 100% rename from services/route/server/server.js.bak rename to services/route/server/server.js