diff --git a/client/client/src/address-edit/address-edit.html b/client/client/src/address-edit/address-edit.html index ba83368eb9..cc50c10609 100644 --- a/client/client/src/address-edit/address-edit.html +++ b/client/client/src/address-edit/address-edit.html @@ -54,6 +54,7 @@ + + 0 || observationsObj.create.length > 0 || observationsObj.delete.length > 0; + canSubmitObservations = observationsObj.update.length > 0 || observationsObj.create.length > 0 || observationsObj.delete.length > 0; if (repeatedTypes) { this.vnApp.showMessage( this.$translate.instant('The observation type must be unique') ); - } else if (canWatcherSubmit && !canObservationsSubmit) { + } else if (canSubmitWatcher && !canSubmitObservations) { this.$scope.watcher.submit().then(() => { this.$state.go('clientCard.addresses.list', {id: this.$state.params.id}); }); - } else if (!canWatcherSubmit && canObservationsSubmit) { + } else if (!canSubmitWatcher && canSubmitObservations) { this._submitObservations(observationsObj).then(() => { this.$state.go('clientCard.addresses.list', {id: this.$state.params.id}); }); - } else if (canWatcherSubmit && canObservationsSubmit) { + } else if (canSubmitWatcher && canSubmitObservations) { this.$q.all([this.$scope.watcher.submit(), this._submitObservations(observationsObj)]).then(() => { this.$state.go('clientCard.addresses.list', {id: this.$state.params.id}); }); @@ -113,7 +115,7 @@ export default class Controller { this._unsetDirtyForm(); } - $onInit() { + _getAddressNotes() { let filter = { where: {addressFk: this.address.id}, include: {relation: 'observationType'} @@ -121,10 +123,14 @@ export default class Controller { this.$http.get(`/client/api/AddressObservations?filter=${JSON.stringify(filter)}`).then(res => { this.observations = res.data; res.data.forEach(item => { - this.observationsOld[item.id] = Object.assign({}, item); + this.oldObservations[item.id] = Object.assign({}, item); }); }); } + + $onInit() { + this._getAddressNotes(); + } } Controller.$inject = ['$state', '$scope', '$http', '$q', '$translate', 'vnApp']; diff --git a/client/client/src/fiscal-data/fiscal-data.html b/client/client/src/fiscal-data/fiscal-data.html index b70dd319f8..b0493cd25f 100644 --- a/client/client/src/fiscal-data/fiscal-data.html +++ b/client/client/src/fiscal-data/fiscal-data.html @@ -89,13 +89,20 @@ + + diff --git a/client/core/src/components/autocomplete/autocomplete.html b/client/core/src/components/autocomplete/autocomplete.html index 0ee10c5ae8..4d04f884fd 100755 --- a/client/core/src/components/autocomplete/autocomplete.html +++ b/client/core/src/components/autocomplete/autocomplete.html @@ -16,8 +16,8 @@ - - - \ No newline at end of file + + + \ No newline at end of file diff --git a/client/core/src/components/drop-down/drop-down.js b/client/core/src/components/drop-down/drop-down.js index 482297618b..07a8562731 100755 --- a/client/core/src/components/drop-down/drop-down.js +++ b/client/core/src/components/drop-down/drop-down.js @@ -45,6 +45,9 @@ export default class DropDown extends Component { this._search = value; this.$.model.clear(); + if (value != null) + this._activeOption = 0; + this.$timeout.cancel(this.searchTimeout); this.searchTimeout = this.$timeout(() => { this.refreshModel(); @@ -86,8 +89,8 @@ export default class DropDown extends Component { * @param {String} search The initial search term or %null */ show(search) { - this.search = search; this._activeOption = -1; + this.search = search; this.buildList(); this.$.popover.parent = this.parent; this.$.popover.show(); @@ -101,7 +104,7 @@ export default class DropDown extends Component { } /** - * Activates a option and scrolls the drop-down to that option. + * Activates an option and scrolls the drop-down to that option. * * @param {Number} option The option index */ @@ -122,7 +125,7 @@ export default class DropDown extends Component { } /** - * Activates a option. + * Activates an option. * * @param {Number} option The option index */ @@ -146,10 +149,11 @@ export default class DropDown extends Component { * @param {Number} option The option index */ selectOption(option) { - if (option != -1) { - let data = this.$.model.data; - let item = data ? data[option] : null; - let value = item ? item[this.valueField] : null; + let data = this.$.model.data; + let item = option != -1 && data ? data[option] : null; + + if (item) { + let value = item[this.valueField]; if (this.multiple) { if (!Array.isArray(this.selection)) { @@ -252,6 +256,9 @@ export default class DropDown extends Component { let nOpts = data ? data.length - 1 : 0; switch (event.keyCode) { + case 9: // Tab + this.selectOption(option); + return; case 13: // Enter this.selectOption(option); break; diff --git a/client/core/src/components/popover/popover.js b/client/core/src/components/popover/popover.js index 4e2326c77f..afc1f7c4e3 100644 --- a/client/core/src/components/popover/popover.js +++ b/client/core/src/components/popover/popover.js @@ -32,14 +32,21 @@ export default class Popover extends Component { this.content = this.element.querySelector('.content'); } - set child(value) { - this.content.appendChild(value); - } - + /** + * @type {HTMLElement} The popover child. + */ get child() { return this.content.firstChild; } + set child(value) { + this.content.innerHTML = ''; + this.content.appendChild(value); + } + + /** + * @type {Boolean} Wether to show or hide the popover. + */ get shown() { return this._shown; } @@ -88,6 +95,9 @@ export default class Popover extends Component { this.showTimeout = this.$timeout(() => { this.element.style.display = 'none'; this.showTimeout = null; + + if (this.onClose) + this.onClose(); }, 250); this.document.removeEventListener('keydown', this.docKeyDownHandler); @@ -95,12 +105,6 @@ export default class Popover extends Component { if (this.deregisterCallback) this.deregisterCallback(); - - if (this.parent) - this.parent.focus(); - - if (this.onClose) - this.onClose(); } /** @@ -189,35 +193,3 @@ ngModule.component('vnPopover', { onClose: '&?' } }); - -class PopoverService { - constructor($document, $compile, $transitions, $rootScope) { - this.$compile = $compile; - this.$rootScope = $rootScope; - this.$document = $document; - this.stack = []; - } - show(child, parent, $scope) { - let element = this.$compile('')($scope || this.$rootScope)[0]; - let popover = element.$ctrl; - popover.parent = parent; - popover.child = child; - popover.show(); - popover.onClose = () => { - this.$document[0].body.removeChild(element); - if ($scope) $scope.$destroy(); - }; - this.$document[0].body.appendChild(element); - return popover; - } - - showComponent(componentTag, $scope, parent) { - let $newScope = $scope.$new(); - let childElement = this.$compile(`<${componentTag}/>`)($newScope)[0]; - this.show(childElement, parent, $newScope); - return childElement; - } -} -PopoverService.$inject = ['$document', '$compile', '$transitions', '$rootScope']; - -ngModule.service('vnPopover', PopoverService); diff --git a/client/core/src/components/textfield/textfield.html b/client/core/src/components/textfield/textfield.html index 43599186b8..7f39ccf643 100644 --- a/client/core/src/components/textfield/textfield.html +++ b/client/core/src/components/textfield/textfield.html @@ -1,8 +1,8 @@ -
- + ng-blur="$ctrl.hasFocus = false"/>
{ @@ -30,11 +31,13 @@ export default class Controller { this.$scope.form.$setDirty(); } } + _unsetDirtyForm() { if (this.$scope.form) { this.$scope.form.$setPristine(); } } + _equalBarcodes(oldBarcode, newBarcode) { return oldBarcode.id === newBarcode.id && oldBarcode.code === newBarcode.code; } diff --git a/client/item/src/niche/item-niche.html b/client/item/src/niche/item-niche.html index ae30034db7..068eedb41d 100644 --- a/client/item/src/niche/item-niche.html +++ b/client/item/src/niche/item-niche.html @@ -8,7 +8,8 @@ Item Niches + + { this.niches = response.data; this.setOldNiches(response); @@ -95,6 +97,7 @@ export default class Controller { create: [], update: [] }; + this.niches.forEach(niche => { let isNewNiche = !niche.id; diff --git a/client/item/src/niche/item-niche.spec.js b/client/item/src/niche/item-niche.spec.js index 3218f262e4..e223133d93 100644 --- a/client/item/src/niche/item-niche.spec.js +++ b/client/item/src/niche/item-niche.spec.js @@ -92,7 +92,7 @@ describe('Item', () => { }); describe('submit()', () => { - it("should return an error message 'The niche must be unique' when the niche code isnt unique", () => { + it("should return an error message 'The niche must be unique' when the niche warehouse isnt unique", () => { controller.$scope.form = {}; spyOn(controller.vnApp, 'showMessage').and.callThrough(); controller.niches = [ diff --git a/client/item/src/tags/item-tags.html b/client/item/src/tags/item-tags.html index 318a5dec7b..c92a13292f 100644 --- a/client/item/src/tags/item-tags.html +++ b/client/item/src/tags/item-tags.html @@ -8,6 +8,7 @@ Item tags + + - - - - - - - - \ No newline at end of file + + + + + + + + + + diff --git a/client/salix/src/components/searchbar/searchbar.js b/client/salix/src/components/searchbar/searchbar.js index 324ddf5a47..81e71198cf 100644 --- a/client/salix/src/components/searchbar/searchbar.js +++ b/client/salix/src/components/searchbar/searchbar.js @@ -1,12 +1,10 @@ import ngModule from '../../module'; export default class Controller { - constructor($element, $scope, $document, $compile, vnPopover, $timeout, $state, $transitions) { + constructor($element, $scope, $compile, $timeout, $state, $transitions) { this.element = $element[0]; - this.$scope = $scope; - this.$document = $document; + this.$ = $scope; this.$compile = $compile; - this.vnPopover = vnPopover; this.$timeout = $timeout; this.stringSearch = ''; this.$state = $state; @@ -91,23 +89,32 @@ export default class Controller { filter = this.getFiltersFromString(this.stringSearch); } - this.child = this.vnPopover.showComponent(this.popover, this.$scope, this.element); + this.$child = this.$compile(`<${this.popover}/>`)(this.$.$new()); - // XXX: ¿Existe una forma más adecuada de acceder al controlador de un componente? - var childCtrl = angular.element(this.child).isolateScope().$ctrl; + var childCtrl = this.$child.isolateScope().$ctrl; childCtrl.filter = Object.assign({}, filter); childCtrl.onSubmit = filter => this.onChildSubmit(filter); if (this.data) childCtrl.data = Object.assign({}, this.data); + event.preventDefault(); + + this.$.popover.parent = this.element; + this.$.popover.child = this.$child[0]; + this.$.popover.show(); + } + + onPopoverClose() { + this.$child.scope().$destroy(); + this.$child.remove(); + this.$child = null; } onChildSubmit(filter) { + this.$.popover.hide(); this.stringSearch = this.createStringFromObject(filter); this.clearFilter(); - this.$timeout(() => { - this.onSubmit(); - }); + this.$timeout(() => this.onSubmit()); } onSubmit() { @@ -120,12 +127,6 @@ export default class Controller { if (this.onSearch) this.onSearch(); - if (angular.element(this.child)) { - if (angular.element(this.child).scope()) - angular.element(this.child).scope().$destroy(); - angular.element(this.child).remove(); - } - delete this.child; this.pushFiltersToState(filter); } @@ -139,12 +140,10 @@ export default class Controller { let filter = JSON.parse(decodeURIComponent(this.$state.params.q)); this.stringSearch = this.createStringFromObject(filter); } - this.$timeout(() => { - this.onSubmit(); - }); + this.$timeout(() => this.onSubmit()); } } -Controller.$inject = ['$element', '$scope', '$document', '$compile', 'vnPopover', '$timeout', '$state', '$transitions']; +Controller.$inject = ['$element', '$scope', '$compile', '$timeout', '$state', '$transitions']; ngModule.component('vnSearchbar', { template: require('./searchbar.html'), diff --git a/client/ticket/routes.json b/client/ticket/routes.json index c35adf301d..8f88f96849 100644 --- a/client/ticket/routes.json +++ b/client/ticket/routes.json @@ -46,6 +46,18 @@ "icon": "settings" } }, + { + "url": "/observations", + "state": "ticket.card.observations", + "component": "vn-ticket-observations", + "params": { + "ticket": "$ctrl.ticket" + }, + "menu": { + "description": "Notes", + "icon": "insert_drive_file" + } + }, { "url" : "/package", "abstract": true, @@ -64,6 +76,18 @@ "icon": "icon-bucket" } }, + { + "url" : "/review", + "state": "ticket.card.review", + "component": "vn-ticket-review", + "params": { + "ticket": "$ctrl.ticket" + }, + "menu": { + "description": "Review", + "icon": "remove_red_eye" + } + }, { "url" : "/sale", "state": "ticket.card.sale", diff --git a/client/ticket/src/locale/es.yml b/client/ticket/src/locale/es.yml index 1f272d4201..e65b6ab54c 100644 --- a/client/ticket/src/locale/es.yml +++ b/client/ticket/src/locale/es.yml @@ -1 +1,6 @@ -Tickets: Tickets \ No newline at end of file +Tickets: Tickets +Notes: Notas +Observation type: Tipo de observación +Description: Descripción +The observation type must be unique: El tipo de observación debe ser único +Some fields are invalid: Algunos campos no son válidos \ No newline at end of file diff --git a/client/ticket/src/notes/ticket-observations.html b/client/ticket/src/notes/ticket-observations.html new file mode 100644 index 0000000000..b48ec5a727 --- /dev/null +++ b/client/ticket/src/notes/ticket-observations.html @@ -0,0 +1,60 @@ + + +
+ + + Notes + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/client/ticket/src/notes/ticket-observations.js b/client/ticket/src/notes/ticket-observations.js new file mode 100644 index 0000000000..793865fde6 --- /dev/null +++ b/client/ticket/src/notes/ticket-observations.js @@ -0,0 +1,140 @@ +import ngModule from '../module'; + +class TicketObservations { + constructor($stateParams, $scope, $http, $translate, vnApp) { + this.params = $stateParams; + this.$scope = $scope; + this.$http = $http; + this.$translate = $translate; + this.vnApp = vnApp; + + this.ticketObservations = []; + this.oldObservations = {}; + this.removedObservations = []; + } + + _setIconAdd() { + if (this.ticketObservations.length) { + this.ticketObservations.map(element => { + element.showAddIcon = false; + return true; + }); + this.ticketObservations[this.ticketObservations.length - 1].showAddIcon = true; + } + } + + _setDirtyForm() { + if (this.$scope.form) { + this.$scope.form.$setDirty(); + } + } + + _unsetDirtyForm() { + if (this.$scope.form) { + this.$scope.form.$setPristine(); + } + } + + addObservation() { + this.ticketObservations.push({description: null, ticketFk: this.params.id, showAddIcon: true}); + this._setIconAdd(); + } + + removeObservation(index) { + let item = this.ticketObservations[index]; + if (item) { + this.ticketObservations.splice(index, 1); + this._setIconAdd(); + if (item.id) { + this.removedObservations.push(item.id); + this._setDirtyForm(); + } + } + } + + _equalObservations(oldObservation, newObservation) { + return oldObservation.id === newObservation.id && oldObservation.observationTypeFk === newObservation.observationTypeFk && oldObservation.description === newObservation.description; + } + + setOldObservations(response) { + this._setIconAdd(); + response.data.forEach(observation => { + this.oldObservations[observation.id] = Object.assign({}, observation); + }); + } + + getObservations() { + let filter = { + where: {ticketFk: this.params.id}, + include: ['observationType'] + }; + + this.$http.get(`/ticket/api/TicketObservations?filter=${JSON.stringify(filter)}`).then(response => { + this.ticketObservations = response.data; + this.setOldObservations(response); + }); + } + + submit() { + let typesDefined = []; + let repeatedType = false; + let canSubmit; + let observationsObj = { + delete: this.removedObservations, + create: [], + update: [] + }; + + this.ticketObservations.forEach(observation => { + let isNewObservation = !observation.id; + + delete observation.showAddIcon; + + if (typesDefined.indexOf(observation.observationTypeFk) !== -1) { + repeatedType = true; + return; + } + typesDefined.push(observation.observationTypeFk); + + if (isNewObservation && observation.description && observation.observationTypeFk) { + observationsObj.create.push(observation); + } + + if (!isNewObservation && !this._equalObservations(this.oldObservations[observation.id], observation)) { + observationsObj.update.push(observation); + } + }); + + if (this.$scope.form.$invalid) { + return this.vnApp.showMessage(this.$translate.instant('Some fields are invalid')); + } + + if (repeatedType) { + return this.vnApp.showMessage(this.$translate.instant('The observation type must be unique')); + } + + canSubmit = observationsObj.update.length > 0 || observationsObj.create.length > 0 || observationsObj.delete.length > 0; + + if (canSubmit) { + return this.$http.post(`/ticket/api/TicketObservations/crudTicketObservations`, observationsObj).then(() => { + this.getObservations(); + this._unsetDirtyForm(); + }); + } + this.vnApp.showMessage(this.$translate.instant('No changes to save')); + } + + $onInit() { + this.getObservations(); + } +} + +TicketObservations.$inject = ['$stateParams', '$scope', '$http', '$translate', 'vnApp']; + +ngModule.component('vnTicketObservations', { + template: require('./ticket-observations.html'), + controller: TicketObservations, + bindings: { + ticket: '<' + } +}); diff --git a/client/ticket/src/notes/ticket-observations.spec.js b/client/ticket/src/notes/ticket-observations.spec.js new file mode 100644 index 0000000000..982cfb61b1 --- /dev/null +++ b/client/ticket/src/notes/ticket-observations.spec.js @@ -0,0 +1,143 @@ +import './ticket-observations.js'; + +describe('ticket', () => { + describe('Component vnTicketObservations', () => { + let $componentController; + let $state; + let controller; + let $httpBackend; + + beforeEach(() => { + angular.mock.module('ticket'); + }); + + beforeEach(angular.mock.inject((_$componentController_, _$state_, _$httpBackend_) => { + $componentController = _$componentController_; + $state = _$state_; + $httpBackend = _$httpBackend_; + controller = $componentController('vnTicketObservations', {$state: $state}); + })); + + describe('add / remove observation', () => { + it('should add one empty observation into controller observations collection and call _setIconAdd()', () => { + controller.ticketObservations = []; + spyOn(controller, '_setIconAdd').and.callThrough(); + controller.addObservation(); + + expect(controller._setIconAdd).toHaveBeenCalledWith(); + expect(controller.ticketObservations.length).toEqual(1); + expect(controller.ticketObservations[0].id).toBe(undefined); + expect(controller.ticketObservations[0].showAddIcon).toBeTruthy(); + }); + + it('should remove an observation that occupies the position in the index given and call _setIconAdd()', () => { + let index = 2; + controller.ticketObservations = [ + {id: 1, observationTypeFk: 1, description: 'one', showAddIcon: false}, + {id: 2, observationTypeFk: 2, description: 'two', showAddIcon: false}, + {id: 3, observationTypeFk: 3, description: 'three', showAddIcon: true} + ]; + + spyOn(controller, '_setIconAdd').and.callThrough(); + + controller.removeObservation(index); + + expect(controller._setIconAdd).toHaveBeenCalledWith(); + expect(controller.ticketObservations.length).toEqual(2); + expect(controller.ticketObservations[0].showAddIcon).toBeFalsy(); + expect(controller.ticketObservations[1].showAddIcon).toBeTruthy(); + expect(controller.ticketObservations[index]).toBe(undefined); + }); + }); + + describe('_equalObservations()', () => { + it('should return true if two observations are equals independent of control attributes', () => { + let observationOne = {id: 1, observationTypeFk: 1, description: 'one', showAddIcon: true}; + let observationTwo = {id: 1, observationTypeFk: 1, description: 'one', showAddIcon: false}; + let equals = controller._equalObservations(observationOne, observationTwo); + + expect(equals).toBeTruthy(); + }); + + it('should return false if two observations aint equals independent of control attributes', () => { + let observationOne = {id: 1, observationTypeFk: 1, description: 'one', showAddIcon: true}; + let observationTwo = {id: 1, observationTypeFk: 1, description: 'two', showAddIcon: true}; + let equals = controller._equalObservations(observationOne, observationTwo); + + expect(equals).toBeFalsy(); + }); + }); + + describe('get Observations()', () => { + it('should perform a GET query to receive the ticket observations', () => { + let res = [{id: 1, observationTypeFk: 1, description: 'one'}]; + + $httpBackend.whenGET(`/ticket/api/TicketObservations?filter={"where":{},"include":["observationType"]}`).respond(res); + $httpBackend.expectGET(`/ticket/api/TicketObservations?filter={"where":{},"include":["observationType"]}`); + controller.getObservations(); + $httpBackend.flush(); + }); + }); + + describe('submit()', () => { + it("should return an error message 'The observation type must be unique'", () => { + controller.$scope.form = {}; + spyOn(controller.vnApp, 'showMessage').and.callThrough(); + controller.ticketObservations = [ + {id: 1, observationTypeFk: 1, description: 'one', itemFk: 1}, + {observationTypeFk: 1, description: 'one', itemFk: 1} + ]; + controller.oldObservations = {1: {id: 1, observationTypeFk: 1, description: 'one', itemFk: 1}}; + controller.submit(); + + expect(controller.vnApp.showMessage).toHaveBeenCalledWith('The observation type must be unique'); + }); + + it("should perfom a query to delete observations", () => { + controller.$scope.form = {$setPristine: () => {}}; + controller.oldObservations = {1: {id: 1, observationTypeFk: 1, description: 'one'}}; + controller.ticketObservations = []; + controller.removedObservations = [1]; + + $httpBackend.whenGET(`/ticket/api/TicketObservations?filter={"where":{},"include":["observationType"]}`).respond([]); + $httpBackend.expectPOST(`/ticket/api/TicketObservations/crudTicketObservations`).respond('ok!'); + controller.submit(); + $httpBackend.flush(); + }); + + it("should perfom a query to update observations", () => { + controller.$scope.form = {$setPristine: () => {}}; + controller.ticketObservations = [{id: 1, observationTypeFk: 1, description: 'number one!'}]; + controller.oldObservations = {1: {id: 1, observationTypeFk: 1, description: 'one'}}; + + $httpBackend.whenGET(`/ticket/api/TicketObservations?filter={"where":{},"include":["observationType"]}`).respond([]); + $httpBackend.expectPOST(`/ticket/api/TicketObservations/crudTicketObservations`).respond('ok!'); + controller.submit(); + $httpBackend.flush(); + }); + + it("should perfom a query to create new observation", () => { + controller.$scope.form = {$setPristine: () => {}}; + controller.ticketObservations = [{observationTypeFk: 2, description: 'two'}]; + + $httpBackend.whenGET(`/ticket/api/TicketObservations?filter={"where":{},"include":["observationType"]}`).respond([]); + $httpBackend.expectPOST(`/ticket/api/TicketObservations/crudTicketObservations`).respond('ok!'); + controller.submit(); + $httpBackend.flush(); + }); + + it("should return a message 'No changes to save' when there are no changes to apply", () => { + controller.$scope.form = {$setPristine: () => {}}; + spyOn(controller.vnApp, 'showMessage').and.callThrough(); + controller.oldObservations = [ + {id: 1, observationTypeFk: 1, description: 'one', showAddIcon: false}, + {id: 2, observationTypeFk: 2, description: 'two', showAddIcon: true} + ]; + controller.ticketObservations = []; + controller.submit(); + + expect(controller.vnApp.showMessage).toHaveBeenCalledWith('No changes to save'); + }); + }); + }); +}); diff --git a/client/ticket/src/review/locale/es.yml b/client/ticket/src/review/locale/es.yml new file mode 100644 index 0000000000..ae3a7e678e --- /dev/null +++ b/client/ticket/src/review/locale/es.yml @@ -0,0 +1,4 @@ +date : Fecha +Employee : Empleado +State: Estado +Review: Revision \ No newline at end of file diff --git a/client/ticket/src/review/review.html b/client/ticket/src/review/review.html new file mode 100644 index 0000000000..d38b231e5c --- /dev/null +++ b/client/ticket/src/review/review.html @@ -0,0 +1,23 @@ + + + + + Review + + + + + + + +
+ + No results + + + + + + + + \ No newline at end of file diff --git a/client/ticket/src/review/review.js b/client/ticket/src/review/review.js new file mode 100644 index 0000000000..7b4cc5678a --- /dev/null +++ b/client/ticket/src/review/review.js @@ -0,0 +1,18 @@ +import ngModule from '../module'; + +class ticketReview { + construct($http, $scope) { + this.$http = $http; + this.$ = $scope; + } +} + +ticketReview.$inject = ['$http', '$scope']; + +ngModule.component('vnTicketReview', { + template: require('./review.html'), + controller: ticketReview, + bindings: { + ticket: '<' + } +}); diff --git a/client/ticket/src/ticket.js b/client/ticket/src/ticket.js index 17973330e9..d02656ba2f 100644 --- a/client/ticket/src/ticket.js +++ b/client/ticket/src/ticket.js @@ -5,5 +5,7 @@ import './create/ticket-create'; import './card/ticket-card'; import './summary/ticket-summary'; import './data/ticket-data'; +import './notes/ticket-observations'; import './package/list/package-list'; import './sale/sale'; +import './review/review'; diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index ab30e2db70..9acf8b1fe2 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -11,7 +11,8 @@ export default { }, moduleAccessView: { clientsSectionButton: `${components.vnModuleContainer}[ui-sref="clients"]`, - itemsSectionButton: `${components.vnModuleContainer}[ui-sref="item.index"]` + itemsSectionButton: `${components.vnModuleContainer}[ui-sref="item.index"]`, + ticketsSectionButton: `${components.vnModuleContainer}[ui-sref="ticket.list"]` }, clientsIndex: { searchClientInput: `${components.vnTextfield}`, @@ -56,9 +57,10 @@ export default { provinceFifthOption: `${components.vnAutocomplete}[field="$ctrl.client.provinceFk"] vn-drop-down ul > li:nth-child(5)`, countryInput: `${components.vnAutocomplete}[field="$ctrl.client.countryFk"] input`, countryThirdOption: `${components.vnAutocomplete}[field="$ctrl.client.countryFk"] vn-drop-down ul > li:nth-child(3)`, - activeCheckboxLabel: `${components.vnCheck}[label='Active'] > label`, + activeCheckboxLabel: `${components.vnCheck}[label="Active"] > label`, + frozenCheckboxLabel: `${components.vnCheck}[label="Frozen"] > label`, invoiceByAddressCheckboxInput: `${components.vnCheck}[label='Invoice by address'] > label > input`, - verifiedDataCheckboxInput: `${components.vnCheck}[label='Verified data'] > label > input`, + verifiedDataCheckboxInput: `${components.vnCheck}[label="Verified data"] > label > input`, hasToInvoiceCheckboxLabel: `${components.vnCheck}[label='Has to invoice'] > label`, invoiceByMailCheckboxLabel: `${components.vnCheck}[label='Invoice by mail'] > label`, viesCheckboxInput: `${components.vnCheck}[label='Vies'] > label > input`, @@ -188,24 +190,29 @@ export default { itemTags: { goToItemIndexButton: 'vn-item-descriptor [ui-sref="item.index"]', tagsButton: `${components.vnMenuItem}[ui-sref="item.card.tags"]`, + firstRemoveTagButton: `vn-item-tags vn-horizontal:nth-child(2) > ${components.vnIcon}[icon="remove_circle_outline"]`, firstTagSelect: `vn-item-tags vn-horizontal:nth-child(2) > ${components.vnAutocomplete}[field="itemTag.tagFk"] input`, + firstTagDisabled: `vn-item-tags vn-horizontal:nth-child(2) > vn-textfield[label="Tag"] > div > input`, firstTagSelectOptionOne: `vn-item-tags vn-horizontal:nth-child(2) > ${components.vnAutocomplete}[field="itemTag.tagFk"] vn-drop-down ul > li:nth-child(1)`, firstValueInput: `vn-item-tags vn-horizontal:nth-child(2) > vn-textfield[label="Value"] > div > input`, firstRelevancyInput: `vn-horizontal:nth-child(2) > vn-textfield[label="Relevancy"] > div > input`, secondTagSelect: `vn-item-tags vn-horizontal:nth-child(3) > ${components.vnAutocomplete}[field="itemTag.tagFk"] input`, + secondTagDisabled: `vn-item-tags vn-horizontal:nth-child(3) > vn-textfield[label="Tag"] > div > input`, secondTagSelectOptionOne: `vn-item-tags vn-horizontal:nth-child(3) > ${components.vnAutocomplete}[field="itemTag.tagFk"] vn-drop-down ul > li:nth-child(1)`, secondValueInput: `vn-item-tags vn-horizontal:nth-child(3) > vn-textfield[label="Value"] > div > input`, secondRelevancyInput: `vn-horizontal:nth-child(3) > vn-textfield[label="Relevancy"] > div > input`, thirdTagSelect: `vn-item-tags vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemTag.tagFk"] input`, + thirdTagDisabled: `vn-item-tags vn-horizontal:nth-child(4) > vn-textfield[label="Tag"] > div > input`, thirdTagSelectOptionOne: `vn-item-tags vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemTag.tagFk"] vn-drop-down ul > li:nth-child(1)`, thirdValueInput: `vn-item-tags vn-horizontal:nth-child(4) > vn-textfield[label="Value"] > div > input`, thirdRelevancyInput: `vn-horizontal:nth-child(4) > vn-textfield[label="Relevancy"] > div > input`, fourthTagSelect: `vn-item-tags vn-horizontal:nth-child(5) > ${components.vnAutocomplete}[field="itemTag.tagFk"] input`, + fourthTagDisabled: `vn-item-tags vn-horizontal:nth-child(5) > vn-textfield[label="Tag"] > div > input`, fourthTagSelectOptionOne: `vn-item-tags vn-horizontal:nth-child(5) > ${components.vnAutocomplete}[field="itemTag.tagFk"] vn-drop-down ul > li:nth-child(1)`, fourthValueInput: `vn-item-tags vn-horizontal:nth-child(5) > vn-textfield[label="Value"] > div > input`, fourthRelevancyInput: `vn-horizontal:nth-child(5) > vn-textfield[label="Relevancy"] > div > input`, - fifthRemoveTagButton: `vn-item-tags vn-horizontal:nth-child(6) > ${components.vnIcon}[icon="remove_circle_outline"]`, fifthTagSelect: `vn-item-tags vn-horizontal:nth-child(6) > ${components.vnAutocomplete}[field="itemTag.tagFk"] input`, + fifthTagDisabled: `vn-item-tags vn-horizontal:nth-child(6) > vn-textfield[label="Tag"] > div > input`, fifthTagSelectOptionFive: `vn-item-tags vn-horizontal:nth-child(6) > ${components.vnAutocomplete}[field="itemTag.tagFk"] vn-drop-down ul > li:nth-child(5)`, fifthValueInput: `vn-item-tags vn-horizontal:nth-child(6) > vn-textfield[label="Value"] > div > input`, fifthRelevancyInput: `vn-horizontal:nth-child(6) > vn-textfield[label="Relevancy"] > div > input`, @@ -233,14 +240,17 @@ export default { nicheButton: `${components.vnMenuItem}[ui-sref="item.card.niche"]`, addNicheButton: `${components.vnIcon}[icon="add_circle"]`, firstWarehouseSelect: `${components.vnAutocomplete}[field="itemNiche.warehouseFk"] input`, + firstWarehouseDisabled: `vn-horizontal:nth-child(2) > vn-textfield[label="Warehouse"] > div > input`, firstWarehouseSelectSecondOption: `${components.vnAutocomplete}[field="itemNiche.warehouseFk"] vn-drop-down ul > li:nth-child(2)`, + firstCodeInput: `vn-horizontal:nth-child(2) > vn-textfield[label="code"] > div > input`, secondWarehouseSelect: `vn-horizontal:nth-child(3) > ${components.vnAutocomplete}[field="itemNiche.warehouseFk"] input`, - thirdWarehouseSelect: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemNiche.warehouseFk"] input`, - thirdWarehouseSelectFourthOption: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemNiche.warehouseFk"] vn-drop-down ul > li:nth-child(4)`, + secondWarehouseDisabled: `vn-horizontal:nth-child(3) > vn-textfield[label="Warehouse"] > div > input`, + secondCodeInput: `vn-horizontal:nth-child(3) > vn-textfield[label="code"] > div > input`, secondNicheRemoveButton: `vn-horizontal:nth-child(3) > vn-one > ${components.vnIcon}[icon="remove_circle_outline"]`, - firstCodeInput: `vn-horizontal:nth-child(2) > ${components.vnTextfield}`, - secondCodeInput: `vn-horizontal:nth-child(3) > ${components.vnTextfield}`, - thirdCodeInput: `vn-horizontal:nth-child(4) > ${components.vnTextfield}`, + thirdWarehouseSelect: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemNiche.warehouseFk"] input`, + thirdWarehouseDisabled: `vn-horizontal:nth-child(4) > vn-textfield[label="Warehouse"] > div > input`, + thirdWarehouseSelectFourthOption: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemNiche.warehouseFk"] vn-drop-down ul > li:nth-child(4)`, + thirdCodeInput: `vn-horizontal:nth-child(4) > vn-textfield[label="code"] > div > input`, submitNichesButton: `${components.vnSubmit}` }, itemBotanical: { @@ -261,5 +271,25 @@ export default { niche: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(2) > vn-vertical > p:nth-child(2)`, botanical: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(3) > vn-vertical > p`, barcode: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(4) > vn-vertical > p` + }, + ticketsIndex: { + createTicketButton: `${components.vnFloatButton}`, + searchResult: `vn-ticket-item a`, + searchTicketInput: `${components.vnTextfield}`, + searchButton: `${components.vnSearchBar} > vn-icon-button > button` + }, + ticketNotes: { + notesButton: `${components.vnMenuItem}[ui-sref="ticket.card.observations"]`, + firstNoteRemoveButton: `${components.vnIcon}[icon="remove_circle_outline"]`, + addNoteButton: `${components.vnIcon}[icon="add_circle"]`, + firstNoteSelect: `${components.vnAutocomplete}[field="ticketObservation.observationTypeFk"] input`, + firstNoteSelectSecondOption: `${components.vnAutocomplete}[field="ticketObservation.observationTypeFk"] vn-drop-down ul > li:nth-child(2)`, + firstNoteDisabled: `vn-textfield[label="Observation type"] > div > input`, + firstDescriptionInput: `vn-textfield[label="Description"] > div > input`, + submitNotesButton: `${components.vnSubmit}` + }, + ticketPackages: { + packagesButton: `${components.vnMenuItem}[ui-sref="ticket.card.package.list"]`, + firstPackageSelect: `${components.vnAutocomplete}[label="Package"] input` } }; diff --git a/e2e/paths/client-module/03_edit_fiscal_data.spec.js b/e2e/paths/client-module/03_edit_fiscal_data.spec.js index 099c422ab9..5564bc51d4 100644 --- a/e2e/paths/client-module/03_edit_fiscal_data.spec.js +++ b/e2e/paths/client-module/03_edit_fiscal_data.spec.js @@ -99,6 +99,7 @@ describe('Edit fiscalData path', () => { .waitToClick(selectors.clientFiscalData.provinceInput) .waitToClick(selectors.clientFiscalData.provinceFifthOption) .waitToClick(selectors.clientFiscalData.activeCheckboxLabel) + .waitToClick(selectors.clientFiscalData.frozenCheckboxLabel) .waitToClick(selectors.clientFiscalData.invoiceByAddressCheckboxInput) .waitToClick(selectors.clientFiscalData.verifiedDataCheckboxInput) .waitToClick(selectors.clientFiscalData.hasToInvoiceCheckboxLabel) @@ -227,6 +228,16 @@ describe('Edit fiscalData path', () => { }); }); + it('should confirm frozen checkbox is unchecked', () => { + return nightmare + .evaluate(selector => { + return document.querySelector(selector).checked; + }, selectors.clientFiscalData.frozenCheckboxLabel) + .then(value => { + expect(value).toBeFalsy(); + }); + }); + it('should confirm invoice by address checkbox is unchecked', () => { return nightmare .evaluate(selector => { diff --git a/e2e/paths/client-module/12_lock_of_verified_data.spec.js b/e2e/paths/client-module/12_lock_of_verified_data.spec.js index 764476e62a..775e588b13 100644 --- a/e2e/paths/client-module/12_lock_of_verified_data.spec.js +++ b/e2e/paths/client-module/12_lock_of_verified_data.spec.js @@ -61,7 +61,7 @@ describe('lock verified data path', () => { .wait(selectors.clientFiscalData.verifiedDataCheckboxInput) .evaluate(selector => { return document.querySelector(selector).className; - }, 'body > vn-app > vn-vertical > vn-vertical > vn-client-card > vn-main-block > vn-horizontal > vn-one > vn-vertical > vn-client-fiscal-data > form > vn-card > div > vn-horizontal:nth-child(5) > vn-check:nth-child(3) > label') + }, 'body > vn-app > vn-vertical > vn-vertical > vn-client-card > vn-main-block > vn-horizontal > vn-one > vn-vertical > vn-client-fiscal-data > form > vn-card > div > vn-horizontal:nth-child(5) > vn-check:nth-child(4) > label') .then(result => { expect(result).toContain('is-disabled'); }); @@ -452,7 +452,7 @@ describe('lock verified data path', () => { .wait(selectors.clientFiscalData.verifiedDataCheckboxInput) .evaluate(selector => { return document.querySelector(selector).className; - }, 'body > vn-app > vn-vertical > vn-vertical > vn-client-card > vn-main-block > vn-horizontal > vn-one > vn-vertical > vn-client-fiscal-data > form > vn-card > div > vn-horizontal:nth-child(5) > vn-check:nth-child(3) > label') + }, 'body > vn-app > vn-vertical > vn-vertical > vn-client-card > vn-main-block > vn-horizontal > vn-one > vn-vertical > vn-client-fiscal-data > form > vn-card > div > vn-horizontal:nth-child(5) > vn-check:nth-child(4) > label') .then(result => { expect(result).toContain('is-disabled'); }); diff --git a/e2e/paths/item-module/02_edit_item_basic_data.spec.js b/e2e/paths/item-module/02_edit_item_basic_data.spec.js index c2de03c068..36b7fb81e8 100644 --- a/e2e/paths/item-module/02_edit_item_basic_data.spec.js +++ b/e2e/paths/item-module/02_edit_item_basic_data.spec.js @@ -66,9 +66,10 @@ describe('edit item basic data path', () => { it(`should confirm the item name was edited`, () => { return nightmare - .click(selectors.itemNiches.firstCodeInput) - .wait(selectors.itemNiches.firstCodeInput) + .click(selectors.itemNiches.nicheButton) + .wait(selectors.itemNiches.firstWarehouseDisabled) .waitToClick(selectors.itemBasicData.basicDataButton) + .waitForTextInInput(selectors.itemBasicData.nameInput, 'Rose of Purity') .getInputValue(selectors.itemBasicData.nameInput) .then(result => { expect(result).toEqual('Rose of Purity'); diff --git a/e2e/paths/item-module/03_edit_item_tax.spec.js b/e2e/paths/item-module/03_edit_item_tax.spec.js index 07bb754141..4347d17521 100644 --- a/e2e/paths/item-module/03_edit_item_tax.spec.js +++ b/e2e/paths/item-module/03_edit_item_tax.spec.js @@ -61,7 +61,7 @@ describe('add item tax path', () => { it(`should confirm the item tax class was edited`, () => { return nightmare .click(selectors.itemTags.tagsButton) - .wait(selectors.itemTags.firstTagSelect) + .wait(selectors.itemTags.firstTagDisabled) .waitToClick(selectors.itemTax.taxButton) .waitForTextInInput(selectors.itemTax.firstClassSelect, 'general') .getInputValue(selectors.itemTax.firstClassSelect) diff --git a/e2e/paths/item-module/04_create_item_tags.spec.js b/e2e/paths/item-module/04_create_item_tags.spec.js index 19d9ef26ab..e83725bfaa 100644 --- a/e2e/paths/item-module/04_create_item_tags.spec.js +++ b/e2e/paths/item-module/04_create_item_tags.spec.js @@ -43,22 +43,14 @@ describe('create item tags path', () => { }); }); - it(`should create a new tag, edit another and delete a former one`, () => { + it(`should create a new tag and delete a former one`, () => { return nightmare - .waitToClick(selectors.itemTags.firstTagSelect) - .waitToClick(selectors.itemTags.firstTagSelectOptionOne) - .clearInput(selectors.itemTags.firstValueInput) - .type(selectors.itemTags.firstValueInput, 'Dark Blue') - .clearInput(selectors.itemTags.firstRelevancyInput) - .type(selectors.itemTags.firstRelevancyInput, '2') - .waitToClick(selectors.itemTags.fifthRemoveTagButton) + .waitToClick(selectors.itemTags.firstRemoveTagButton) .waitToClick(selectors.itemTags.addItemTagButton) .waitToClick(selectors.itemTags.fifthTagSelect) .waitToClick(selectors.itemTags.fifthTagSelectOptionFive) .type(selectors.itemTags.fifthValueInput, 'Thanos') .type(selectors.itemTags.fifthRelevancyInput, '1') - .clearInput(selectors.itemTags.secondRelevancyInput) - .type(selectors.itemTags.secondRelevancyInput, '5') .click(selectors.itemTags.submitItemTagsButton) .waitForSnackbar() .then(result => { @@ -71,8 +63,8 @@ describe('create item tags path', () => { .click(selectors.itemBasicData.basicDataButton) .wait(selectors.itemBasicData.nameInput) .click(selectors.itemTags.tagsButton) - .waitForTextInInput(selectors.itemTags.firstTagSelect, 'Owner') - .getInputValue(selectors.itemTags.firstTagSelect) + .waitForTextInInput(selectors.itemTags.firstTagDisabled, 'Owner') + .getInputValue(selectors.itemTags.firstTagDisabled) .then(result => { expect(result).toEqual('Owner'); }); @@ -98,19 +90,19 @@ describe('create item tags path', () => { it(`should confirm the second select is the expected one`, () => { return nightmare - .waitForTextInInput(selectors.itemTags.secondTagSelect, 'Color') - .getInputValue(selectors.itemTags.secondTagSelect) + .waitForTextInInput(selectors.itemTags.secondTagDisabled, 'Location') + .getInputValue(selectors.itemTags.secondTagDisabled) .then(result => { - expect(result).toEqual('Color'); + expect(result).toEqual('Location'); }); }); it(`should confirm the second value is the expected one`, () => { return nightmare - .waitForTextInInput(selectors.itemTags.secondValueInput, 'Dark Blue') + .waitForTextInInput(selectors.itemTags.secondValueInput, 'Gamoras hideout') .getInputValue(selectors.itemTags.secondValueInput) .then(result => { - expect(result).toEqual('Dark Blue'); + expect(result).toEqual('Gamoras hideout'); }); }); @@ -125,8 +117,8 @@ describe('create item tags path', () => { it(`should confirm the third select is the expected one`, () => { return nightmare - .waitForTextInInput(selectors.itemTags.thirdTagSelect, 'Shape') - .getInputValue(selectors.itemTags.thirdTagSelect) + .waitForTextInInput(selectors.itemTags.thirdTagDisabled, 'Shape') + .getInputValue(selectors.itemTags.thirdTagDisabled) .then(result => { expect(result).toEqual('Shape'); }); @@ -152,8 +144,8 @@ describe('create item tags path', () => { it(`should confirm the fourth select is the expected one`, () => { return nightmare - .waitForTextInInput(selectors.itemTags.fourthTagSelect, 'Power') - .getInputValue(selectors.itemTags.fourthTagSelect) + .waitForTextInInput(selectors.itemTags.fourthTagDisabled, 'Power') + .getInputValue(selectors.itemTags.fourthTagDisabled) .then(result => { expect(result).toEqual('Power'); }); @@ -179,19 +171,19 @@ describe('create item tags path', () => { it(`should confirm the fifth select is the expected one`, () => { return nightmare - .waitForTextInInput(selectors.itemTags.fifthTagSelect, 'Location') - .getInputValue(selectors.itemTags.fifthTagSelect) + .waitForTextInInput(selectors.itemTags.fifthTagDisabled, 'Color') + .getInputValue(selectors.itemTags.fifthTagDisabled) .then(result => { - expect(result).toEqual('Location'); + expect(result).toEqual('Color'); }); }); it(`should confirm the fifth value is the expected one`, () => { return nightmare - .waitForTextInInput(selectors.itemTags.fifthValueInput, 'Gamoras hideout') + .waitForTextInInput(selectors.itemTags.fifthValueInput, 'Yellow') .getInputValue(selectors.itemTags.fifthValueInput) .then(result => { - expect(result).toEqual('Gamoras hideout'); + expect(result).toEqual('Yellow'); }); }); diff --git a/e2e/paths/item-module/05_create_item_niche.spec.js b/e2e/paths/item-module/05_create_item_niche.spec.js index 588dad678d..cdadc7e0f1 100644 --- a/e2e/paths/item-module/05_create_item_niche.spec.js +++ b/e2e/paths/item-module/05_create_item_niche.spec.js @@ -43,13 +43,9 @@ describe('create item niche path', () => { }); }); - it(`should click create a new niche, edit another and delete a former one`, () => { + it(`should click create a new niche and delete a former one`, () => { return nightmare .waitToClick(selectors.itemNiches.addNicheButton) - .waitToClick(selectors.itemNiches.firstWarehouseSelect) - .waitToClick(selectors.itemNiches.firstWarehouseSelectSecondOption) - .clearInput(selectors.itemNiches.firstCodeInput) - .type(selectors.itemNiches.firstCodeInput, 'A2') .waitToClick(selectors.itemNiches.secondNicheRemoveButton) .waitToClick(selectors.itemNiches.thirdWarehouseSelect) .waitToClick(selectors.itemNiches.thirdWarehouseSelectFourthOption) @@ -66,21 +62,21 @@ describe('create item niche path', () => { .click(selectors.itemBasicData.basicDataButton) .wait(selectors.itemBasicData.nameInput) .click(selectors.itemNiches.nicheButton) - .waitForTextInInput(selectors.itemNiches.firstWarehouseSelect, 'Warehouse Two') - .getInputValue(selectors.itemNiches.firstWarehouseSelect) + .waitForTextInInput(selectors.itemNiches.firstWarehouseDisabled, 'Warehouse One') + .getInputValue(selectors.itemNiches.firstWarehouseDisabled) .then(result => { - expect(result).toEqual('Warehouse Two'); + expect(result).toEqual('Warehouse One'); return nightmare .getInputValue(selectors.itemNiches.firstCodeInput); }) .then(result => { - expect(result).toEqual('A2'); + expect(result).toEqual('A1'); }); }); it(`should confirm the second niche is the expected one`, () => { return nightmare - .getInputValue(selectors.itemNiches.secondWarehouseSelect) + .getInputValue(selectors.itemNiches.secondWarehouseDisabled) .then(result => { expect(result).toEqual('Warehouse Three'); return nightmare @@ -93,7 +89,7 @@ describe('create item niche path', () => { it(`should confirm the third niche is the expected one`, () => { return nightmare - .getInputValue(selectors.itemNiches.thirdWarehouseSelect) + .getInputValue(selectors.itemNiches.thirdWarehouseDisabled) .then(result => { expect(result).toEqual('Warehouse Four'); return nightmare diff --git a/e2e/paths/ticket-module/01_create_ticket_observations.spec.js b/e2e/paths/ticket-module/01_create_ticket_observations.spec.js new file mode 100644 index 0000000000..dfc7053b2b --- /dev/null +++ b/e2e/paths/ticket-module/01_create_ticket_observations.spec.js @@ -0,0 +1,77 @@ +import selectors from '../../helpers/selectors.js'; +import createNightmare from '../../helpers/helpers'; + +describe('create item niche path', () => { + const nightmare = createNightmare(); + + beforeAll(() => { + return nightmare + .waitForLogin('developer'); + }); + + it('should access to the tickets index by clicking the tickets button', () => { + return nightmare + .click(selectors.moduleAccessView.ticketsSectionButton) + .wait(selectors.ticketsIndex.createTicketButton) + .parsedUrl() + .then(url => { + expect(url.hash).toEqual('#!/ticket/list'); + }); + }); + + it('should search for the ticket with id 1', () => { + return nightmare + .wait(selectors.ticketsIndex.searchTicketInput) + .type(selectors.ticketsIndex.searchTicketInput, '1') + .click(selectors.ticketsIndex.searchButton) + .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) + .countSearchResults(selectors.ticketsIndex.searchResult) + .then(result => { + expect(result).toEqual(1); + }); + }); + + it(`should click on the search result to access to the ticket notes`, () => { + return nightmare + .waitForTextInElement(selectors.ticketsIndex.searchResult, '1') + .waitToClick(selectors.ticketsIndex.searchResult) + .waitToClick(selectors.ticketNotes.notesButton) + .waitForURL('observations') + .url() + .then(url => { + expect(url).toContain('observations'); + }); + }); + + it(`should click create a new note and delete a former one`, () => { + return nightmare + .waitToClick(selectors.ticketNotes.firstNoteRemoveButton) + .waitToClick(selectors.ticketNotes.addNoteButton) + .waitToClick(selectors.ticketNotes.firstNoteSelect) + .waitForTextInElement(selectors.ticketNotes.firstNoteSelectSecondOption, 'observation two') + .waitToClick(selectors.ticketNotes.firstNoteSelectSecondOption) + .type(selectors.ticketNotes.firstDescriptionInput, 'description') + .click(selectors.ticketNotes.submitNotesButton) + .waitForSnackbar() + .then(result => { + expect(result).toContain('Data saved!'); + }); + }); + + it(`should confirm the note is the expected one`, () => { + return nightmare + .click(selectors.ticketPackages.packagesButton) + .wait(selectors.ticketPackages.firstPackageSelect) + .click(selectors.ticketNotes.notesButton) + .waitForTextInInput(selectors.ticketNotes.firstNoteDisabled, 'observation two') + .getInputValue(selectors.ticketNotes.firstNoteDisabled) + .then(result => { + expect(result).toEqual('observation two'); + return nightmare + .getInputValue(selectors.ticketNotes.firstDescriptionInput); + }) + .then(result => { + expect(result).toEqual('description'); + }); + }); +}); diff --git a/services/ticket/common/methods/ticket/crudTicketObservations.js b/services/ticket/common/methods/ticket/crudTicketObservations.js new file mode 100644 index 0000000000..33949e1f40 --- /dev/null +++ b/services/ticket/common/methods/ticket/crudTicketObservations.js @@ -0,0 +1,3 @@ +module.exports = Self => { + Self.installCrudModel('crudTicketObservations'); +}; diff --git a/services/ticket/common/models/ticketObservation.js b/services/ticket/common/models/ticketObservation.js new file mode 100644 index 0000000000..bed837bd35 --- /dev/null +++ b/services/ticket/common/models/ticketObservation.js @@ -0,0 +1,3 @@ +module.exports = function(Self) { + require('../methods/ticket/crudTicketObservations.js')(Self); +}; diff --git a/services/ticket/common/models/ticketObservation.json b/services/ticket/common/models/ticketObservation.json index a6e5e3029b..73fb711396 100644 --- a/services/ticket/common/models/ticketObservation.json +++ b/services/ticket/common/models/ticketObservation.json @@ -2,33 +2,34 @@ "name": "TicketObservation", "base": "VnModel", "options": { - "mysql": { - "table": "ticketObservation" - } + "mysql": { + "table": "ticketObservation", + "database": "vn" + } }, "properties": { - "id": { - "id": true, - "type": "Number", - "description": "Identifier" - }, - "description": { - "type": "String", - "required": true - } + "id": { + "id": true, + "type": "Number", + "description": "Identifier" + }, + "description": { + "type": "String", + "required": true + } }, "relations": { - "ticket": { - "type": "belongsTo", - "model": "Ticket", - "foreignKey": "ticketFk", - "required": true - }, - "observationType": { - "type": "belongsTo", - "model": "ObservationType", - "foreignKey": "observationTypeFk", - "required": true - } + "ticket": { + "type": "belongsTo", + "model": "Ticket", + "foreignKey": "ticketFk", + "required": true + }, + "observationType": { + "type": "belongsTo", + "model": "ObservationType", + "foreignKey": "observationTypeFk", + "required": true + } } - } \ No newline at end of file +}