diff --git a/README.md b/README.md index 9911d47b4..834cac070 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ $ npm install -g karma-cli gulp webpack nodemon Your user must be on the docker group to use it so you will need to run this command: ``` -$ sudo usermod -G docker yourusername +$ sudo usermod -a -G docker yourusername ``` ## Getting Started // Installing diff --git a/client/client/src/address-edit/address-edit.html b/client/client/src/address-edit/address-edit.html index 0497570af..c1b9cb20d 100644 --- a/client/client/src/address-edit/address-edit.html +++ b/client/client/src/address-edit/address-edit.html @@ -41,7 +41,7 @@ @@ -61,6 +61,7 @@ - - + diff --git a/client/client/src/addresses/addresses.html b/client/client/src/addresses/addresses.html index 052b2ab11..699f85cfb 100644 --- a/client/client/src/addresses/addresses.html +++ b/client/client/src/addresses/addresses.html @@ -30,7 +30,7 @@ {{::observation.description}} - + diff --git a/client/client/src/fiscal-data/locale/es.yml b/client/client/src/fiscal-data/locale/es.yml index 7855c382a..632fcc3a1 100644 --- a/client/client/src/fiscal-data/locale/es.yml +++ b/client/client/src/fiscal-data/locale/es.yml @@ -1,4 +1,3 @@ -No: No Yes, notify: Sí, notificar You changed the equalization tax: Has cambiado el recargo de equivalencia Do you want to spread the change: ¿Deseas propagar el cambio a sus consignatarios? diff --git a/client/client/src/index/index.html b/client/client/src/index/index.html index 76953e618..63f502e64 100644 --- a/client/client/src/index/index.html +++ b/client/client/src/index/index.html @@ -2,7 +2,7 @@
- + - + div > .mdl-textfield { & > input { cursor: pointer; - height: 26px; + height: 30px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; diff --git a/client/core/src/components/drop-down/drop-down.js b/client/core/src/components/drop-down/drop-down.js index 07a856273..bfe372b7d 100755 --- a/client/core/src/components/drop-down/drop-down.js +++ b/client/core/src/components/drop-down/drop-down.js @@ -40,7 +40,7 @@ export default class DropDown extends Component { set search(value) { value = value == '' || value == null ? null : value; - if (value === this._search) return; + if (value === this._search && this.$.model.data != null) return; this._search = value; this.$.model.clear(); diff --git a/client/core/src/components/drop-down/model.js b/client/core/src/components/drop-down/model.js index 12888563c..b8237bad7 100644 --- a/client/core/src/components/drop-down/model.js +++ b/client/core/src/components/drop-down/model.js @@ -13,6 +13,17 @@ export default class Model { return this.canceler != null; } + set url(url) { + if (this._url != url) { + this._url = url; + this.clear(); + } + } + + get url() { + return this._url; + } + loadMore() { if (this.moreRows) { let filter = Object.assign({}, this.myFilter); diff --git a/client/core/src/components/drop-down/model.spec.js b/client/core/src/components/drop-down/model.spec.js new file mode 100644 index 000000000..5aff7554f --- /dev/null +++ b/client/core/src/components/drop-down/model.spec.js @@ -0,0 +1,34 @@ +import './model.js'; + +describe('Component vnModel', () => { + let $componentController; + let $httpBackend; + let controller; + + beforeEach(() => { + angular.mock.module('client'); + }); + + beforeEach(angular.mock.inject((_$componentController_, _$httpBackend_) => { + $componentController = _$componentController_; + controller = $componentController('vnModel', {$httpBackend}); + })); + + describe('set url', () => { + it(`should call clear function when the controller _url is undefined`, () => { + spyOn(controller, 'clear'); + controller.url = 'localhost'; + + expect(controller._url).toEqual('localhost'); + expect(controller.clear).toHaveBeenCalledWith(); + }); + + it(`should do nothing when the url is matching`, () => { + controller._url = 'localhost'; + spyOn(controller, 'clear'); + controller.url = 'localhost'; + + expect(controller.clear).not.toHaveBeenCalledWith(); + }); + }); +}); diff --git a/client/core/src/components/grid/style.scss b/client/core/src/components/grid/style.scss index 62365a593..00232e6c3 100644 --- a/client/core/src/components/grid/style.scss +++ b/client/core/src/components/grid/style.scss @@ -21,5 +21,29 @@ } & > tbody > tr { border-bottom: 1px solid #9D9D9D; + transition: background-color 200ms ease-in-out; + + &.clickable { + cursor: pointer; + + &:hover { + background-color: #e5e5e5; + } + } + + &.success { + background-color: rgba(163, 209, 49, 0.3); + + &:hover { + background-color: rgba(163, 209, 49, 0.5); + } + } + &.warning { + background-color: rgba(247, 147, 30, 0.3); + + &:hover { + background-color: rgba(247, 147, 30, 0.5); + } + } } } \ No newline at end of file diff --git a/client/core/src/components/icon-button/icon-button.html b/client/core/src/components/icon-button/icon-button.html index fdd022710..4bd8ad78a 100644 --- a/client/core/src/components/icon-button/icon-button.html +++ b/client/core/src/components/icon-button/icon-button.html @@ -1,5 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/client/core/src/components/icon-button/icon-button.js b/client/core/src/components/icon-button/icon-button.js index c257b9da9..5765fb249 100644 --- a/client/core/src/components/icon-button/icon-button.js +++ b/client/core/src/components/icon-button/icon-button.js @@ -1,6 +1,24 @@ import ngModule from '../../module'; +import './style.scss'; +export default class IconButton { + constructor($element) { + $element[0].tabIndex = 0; + $element.on("keyup", event => this.onKeyDown(event, $element)); + } + + onKeyDown(event, $element) { + if (event.defaultPrevented) return; + if (event.keyCode == 13) { + event.preventDefault(); + $element.triggerHandler('click'); + } + } +} + +IconButton.$inject = ['$element']; ngModule.component('vnIconButton', { + controller: IconButton, template: require('./icon-button.html'), bindings: { icon: '@', diff --git a/client/core/src/components/icon-button/style.scss b/client/core/src/components/icon-button/style.scss new file mode 100644 index 000000000..7754c871a --- /dev/null +++ b/client/core/src/components/icon-button/style.scss @@ -0,0 +1,17 @@ +vn-icon-button { + display: inline-block; + text-align: center; + color: rgba(#f7931e, 0.7); + transition: color 200ms ease-in-out; + cursor: pointer; + + & > i, + & > i.material-icons { + display: block; + font-size: inherit; + color: inherit; + } + &:hover { + color: #f7931e; + } +} diff --git a/client/core/src/components/textfield/textfield.html b/client/core/src/components/textfield/textfield.html index 57837cf09..97501ae8a 100644 --- a/client/core/src/components/textfield/textfield.html +++ b/client/core/src/components/textfield/textfield.html @@ -11,7 +11,8 @@ ng-disabled="$ctrl.disabled" ng-readonly="$ctrl.readonly" ng-focus="$ctrl.hasFocus = true" - ng-blur="$ctrl.hasFocus = false"/> + ng-blur="$ctrl.hasFocus = false" + tabindex="{{$ctrl.input.tabindex}}"/>
+ vn-acl="buyer, replenisher" + vn-focus> - - + diff --git a/client/item/src/list/list.html b/client/item/src/list/list.html index 5604b1039..574ba7b46 100644 --- a/client/item/src/list/list.html +++ b/client/item/src/list/list.html @@ -2,7 +2,7 @@
- + - - + diff --git a/client/item/src/tags/tags.html b/client/item/src/tags/tags.html index c92a13292..bf71966fe 100644 --- a/client/item/src/tags/tags.html +++ b/client/item/src/tags/tags.html @@ -6,32 +6,41 @@
Item tags - + + on-change="$ctrl.checkAutocompleteChanges(itemTag)" + vn-acl="buyer" + vn-focus + disabled="itemTag.id != null"> - - + + - + ng-click="$ctrl.removeItemTag($index)"> - - - + + + + diff --git a/client/item/src/tags/tags.js b/client/item/src/tags/tags.js index 005446f75..1dad06d82 100644 --- a/client/item/src/tags/tags.js +++ b/client/item/src/tags/tags.js @@ -20,10 +20,9 @@ class ItemTags { return true; }); this.instancedItemTags[this.instancedItemTags.length - 1].showAddIcon = true; - } else { - this.addItemTag(); } } + _setDirtyForm() { if (this.$scope.form) { this.$scope.form.$setDirty(); @@ -35,9 +34,13 @@ class ItemTags { } } + checkAutocompleteChanges(itemTag) { + itemTag.value = null; + } + addItemTag() { if (this.instancedItemTags) { - this.instancedItemTags.push({value: null, itemFk: this.params.id, tagFk: null, priority: this.getMaxPriority(this.instancedItemTags) + 1, showAddIcon: true}); + this.instancedItemTags.push({value: null, itemFk: this.params.id, tagFk: null, priority: this.getHighestPriority(this.instancedItemTags), showAddIcon: true}); this._setIconAdd(); } } @@ -54,13 +57,25 @@ class ItemTags { } } - getMaxPriority(instancedItemTags) { + getHighestPriority(instancedItemTags) { let max = 0; instancedItemTags.forEach(tag => { if (tag.priority > max) max = tag.priority; }); - return max; + return max + 1; + } + + getSourceTable(selection) { + if (!selection || selection.isFree === true) + return null; + + if (selection.sourceTable) { + return "/api/" + selection.sourceTable.charAt(0).toUpperCase() + + selection.sourceTable.substring(1) + 's'; + } else if (selection.sourceTable == null) { + return `/api/ItemTags/filterItemTags/${selection.id}`; + } } _equalItemTags(oldTag, newTag) { @@ -147,6 +162,7 @@ ngModule.component('vnItemTags', { template: require('./tags.html'), controller: ItemTags, bindings: { - itemTags: '=' + itemTags: '=', + selection: ' { }); }); + describe('getHighestPriority', () => { + it('should return the highest priority value + 1 from the array', () => { + let tags = [{priority: 1}, {priority: 2}, {priority: 1}]; + let result = controller.getHighestPriority(tags); + + expect(result).toEqual(3); + }); + + it('should return 1 when there is no priority defined', () => { + let tags = []; + let result = controller.getHighestPriority(tags); + + expect(result).toEqual(1); + }); + }); + + describe('getSourceTable', () => { + it('should return null when the property isFree equals true', () => { + let selection = {isFree: true}; + let result = controller.getSourceTable(selection); + + expect(result).toBe(null); + }); + + it('should return the route of the model in loopback with the first char of the string uppercase and adding a s', () => { + let selection = {sourceTable: "ink"}; + let result = controller.getSourceTable(selection); + + expect(result).toBe("/api/Inks"); + }); + + it('should return the route filteritemtags with the id of the selection', () => { + let selection = {id: 3, sourceTable: null, isFree: false}; + let result = controller.getSourceTable(selection); + + expect(result).toBe("/api/ItemTags/filterItemTags/3"); + }); + }); + describe('_equalItemTags()', () => { it('should return true if two tags are equals independent of control attributes', () => { let tag1 = {id: 1, typeFk: 1, value: '1111', showAddIcon: true}; diff --git a/client/salix/src/components/searchbar/searchbar.html b/client/salix/src/components/searchbar/searchbar.html index 9e21968bc..72d5dad90 100644 --- a/client/salix/src/components/searchbar/searchbar.html +++ b/client/salix/src/components/searchbar/searchbar.html @@ -1,18 +1,21 @@ + + + style="cursor: pointer; color: #aaa"> - - - + \ 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 81e71198c..6ff9a8072 100644 --- a/client/salix/src/components/searchbar/searchbar.js +++ b/client/salix/src/components/searchbar/searchbar.js @@ -1,4 +1,5 @@ import ngModule from '../../module'; +import './style.scss'; export default class Controller { constructor($element, $scope, $compile, $timeout, $state, $transitions) { @@ -152,7 +153,6 @@ ngModule.component('vnSearchbar', { onSearch: '&', advanced: '=', popover: '@', - label: '@?', ignoreKeys: ' form > vn-horizontal > vn-icon-button { + color: black; + } +} \ No newline at end of file diff --git a/client/salix/src/styles/colors.scss b/client/salix/src/styles/colors.scss index f48dc9fc6..3e3876337 100644 --- a/client/salix/src/styles/colors.scss +++ b/client/salix/src/styles/colors.scss @@ -1,12 +1,12 @@ - $color-green: #a3d131; $color-orange: #f7931e; $color-white: white; $color-dark: #3d3d3d; $color-dark-grey: #424242; $color-light-grey: #e5e5e5; -$color-medium-grey: #9D9D9D; -$color-medium-green: rgba(163, 209, 49, 0.5); -$color-medium-orange: rgba(247, 147, 30, 0.5); -$color-light-green: rgba(163, 209, 49, 0.3); -$color-light-orange: rgba(247, 147, 30, 0.3); \ No newline at end of file +$color-medium-grey: #9b9b9b; +$color-grey: #c4c4c4; +$color-medium-green: rgba($color-green, 0.5); +$color-medium-orange: rgba($color-orange, 0.5); +$color-light-green: rgba($color-green, 0.3); +$color-light-orange: rgba($color-orange, 0.3); \ No newline at end of file diff --git a/client/ticket/src/list/ticket-list.html b/client/ticket/src/list/ticket-list.html index f06ef58ca..ca5e9eca1 100644 --- a/client/ticket/src/list/ticket-list.html +++ b/client/ticket/src/list/ticket-list.html @@ -1,20 +1,66 @@ -
-
- - +
+
+ + TICKETS + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID TicketComercialDateHoraAliasProvinciaEstadoAgenciaAlmacenFacturaRuta
+ + {{::ticket.id}}{{::ticket.client.salesPerson.name | dashIfEmpty}}{{::ticket.shipped | date:'dd/MM/yyyy'}}{{::ticket.shipped | date:'HH:MM'}}{{::ticket.nickname}}{{::ticket.address.province.name}}{{::ticket.ticketTracking.state.name}}{{::ticket.agencyMode.name}}{{::ticket.warehouse.name}}{{::ticket.refFk | dashIfEmpty}}{{::ticket.routeFk | dashIfEmpty}} + + +
+
diff --git a/client/ticket/src/list/ticket-list.js b/client/ticket/src/list/ticket-list.js index 569a135e0..ee48e2c73 100644 --- a/client/ticket/src/list/ticket-list.js +++ b/client/ticket/src/list/ticket-list.js @@ -8,13 +8,30 @@ export default class Controller { this.ticketSelected = null; } - search(index) { - index.accept(); + compareDate(date) { + let today = new Date(); + today.setHours(0, 0, 0, 0); + let timeTicket = new Date(date); + timeTicket.setHours(0, 0, 0, 0); + + let comparation = today - timeTicket; + + if (comparation == 0) + return 'warning'; + + if (comparation < 0) + return 'success'; } - openSummary(ticket) { - this.ticketSelected = ticket; + preview(event, ticket) { + event.preventDefault(); + event.stopImmediatePropagation(); this.$scope.dialogSummaryTicket.show(); + this.ticketSelected = ticket; + } + + search(index) { + index.accept(); } } diff --git a/client/ticket/src/list/ticket-list.spec.js b/client/ticket/src/list/ticket-list.spec.js new file mode 100644 index 000000000..6a50756a2 --- /dev/null +++ b/client/ticket/src/list/ticket-list.spec.js @@ -0,0 +1,48 @@ +import './ticket-list.js'; + +describe('ticket', () => { + describe('Component vnTicketList', () => { + let $componentController; + let controller; + + beforeEach(() => { + angular.mock.module('ticket'); + }); + + beforeEach(angular.mock.inject(_$componentController_ => { + $componentController = _$componentController_; + controller = $componentController('vnTicketList'); + })); + + describe('compareDate()', () => { + it('should return warning when the date is the present', () => { + let date = new Date(); + let result = controller.compareDate(date); + + expect(result).toEqual('warning'); + }); + + it('should return warning when the date is in the future', () => { + let date = '2518-05-19T00:00:00.000Z'; + let result = controller.compareDate(date); + + expect(result).toEqual('success'); + }); + }); + + describe('preview()', () => { + it('should call preventDefault and stopImmediatePropagation from event and show', () => { + let event = jasmine.createSpyObj('event', ['preventDefault', 'stopImmediatePropagation']); + + controller.$scope = {dialogSummaryTicket: {show: () => {}}}; + spyOn(controller.$scope.dialogSummaryTicket, 'show'); + let ticket = {}; + controller.preview(event, ticket); + + expect(event.preventDefault).toHaveBeenCalledWith(); + expect(event.stopImmediatePropagation).toHaveBeenCalledWith(); + expect(controller.$scope.dialogSummaryTicket.show).toHaveBeenCalledWith(); + }); + }); + }); +}); diff --git a/client/ticket/src/note/ticket-observation.html b/client/ticket/src/note/ticket-observation.html index 7ca256760..5c683ba09 100644 --- a/client/ticket/src/note/ticket-observation.html +++ b/client/ticket/src/note/ticket-observation.html @@ -14,6 +14,7 @@ - - + diff --git a/client/ticket/src/package/index/package.html b/client/ticket/src/package/index/package.html index d1838924e..3f3130f62 100644 --- a/client/ticket/src/package/index/package.html +++ b/client/ticket/src/package/index/package.html @@ -16,6 +16,7 @@ - - + diff --git a/client/ticket/src/volume/ticket-volume.html b/client/ticket/src/volume/ticket-volume.html index 53e6ba87c..935da8f99 100644 --- a/client/ticket/src/volume/ticket-volume.html +++ b/client/ticket/src/volume/ticket-volume.html @@ -15,7 +15,7 @@ - + {{::sale.itemFk}} {{::sale.quantity}} diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 44f145bb7..440090d41 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -17,7 +17,7 @@ export default { }, clientsIndex: { searchClientInput: `${components.vnTextfield}`, - searchButton: `${components.vnSearchBar} > vn-icon-button > button`, + searchButton: `${components.vnSearchBar} > vn-icon-button`, searchResult: `vn-item-client a`, createClientButton: `${components.vnFloatButton}` }, @@ -157,7 +157,7 @@ export default { searchResultCloneButton: `vn-item-product .buttons > [icon="icon-clone"]`, acceptClonationAlertButton: `vn-item-list [vn-id="clone"] [response="ACCEPT"]`, searchItemInput: `${components.vnTextfield}`, - searchButton: `${components.vnSearchBar} > vn-icon-button > button`, + searchButton: `${components.vnSearchBar} > vn-icon-button`, closeItemSummaryPreview: 'vn-item-list [vn-id="preview"] button.close' }, itemCreateView: { @@ -191,27 +191,27 @@ export default { 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`, + firstTagDisabled: `vn-item-tags vn-horizontal:nth-child(2) > vn-autocomplete > div > 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`, + secondTagDisabled: `vn-item-tags vn-horizontal:nth-child(3) > vn-autocomplete > div > 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`, + thirdTagDisabled: `vn-item-tags vn-horizontal:nth-child(4) > vn-autocomplete > div > 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`, + fourthTagDisabled: `vn-item-tags vn-horizontal:nth-child(5) > vn-autocomplete > div > 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`, 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`, + fifthTagDisabled: `vn-item-tags vn-horizontal:nth-child(6) > vn-autocomplete > div > 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`, @@ -264,18 +264,18 @@ export default { submitBotanicalButton: `${components.vnSubmit}` }, itemSummary: { - basicData: `${components.vnItemSummary} > vn-horizontal:nth-child(1) > vn-one:nth-child(2) > vn-vertical`, - vat: `${components.vnItemSummary} > vn-horizontal:nth-child(1) > vn-one:nth-child(3) > vn-vertical > p`, - tags: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(1) > vn-vertical:nth-child(1) > vn-label-value:nth-child(2)`, - niche: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(2) > vn-vertical > vn-label-value:nth-child(2)`, - botanical: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(3) > vn-vertical > vn-label-value:nth-child(2)`, - barcode: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(4) > vn-vertical > p` + basicData: `${components.vnItemSummary} vn-vertical[name="basicData"]`, + vat: `${components.vnItemSummary} vn-vertical[name="tax"]`, + tags: `${components.vnItemSummary} vn-vertical[name="tags"]`, + niche: `${components.vnItemSummary} vn-vertical[name="niche"]`, + botanical: `${components.vnItemSummary} vn-vertical[name="botanical"]`, + barcode: `${components.vnItemSummary} vn-vertical[name="barcode"]` }, ticketsIndex: { createTicketButton: `${components.vnFloatButton}`, - searchResult: `vn-ticket-item a`, + searchResult: `table > tbody > tr`, searchTicketInput: `${components.vnTextfield}`, - searchButton: `${components.vnSearchBar} > vn-icon-button > button` + searchButton: `${components.vnSearchBar} > vn-icon-button` }, ticketNotes: { notesButton: `${components.vnMenuItem}[ui-sref="ticket.card.observation"]`, diff --git a/services/loopback/common/methods/item-tag/filterItemTags.js b/services/loopback/common/methods/item-tag/filterItemTags.js new file mode 100644 index 000000000..8e6b3665f --- /dev/null +++ b/services/loopback/common/methods/item-tag/filterItemTags.js @@ -0,0 +1,26 @@ +module.exports = Self => { + Self.remoteMethod('filterItemTags', { + description: 'Returns the distinct values of a tag property', + accessType: 'READ', + accepts: [{ + arg: 'tagFk', + type: 'number', + required: true, + description: 'The foreign key from tag table', + http: {source: 'path'} + }], + returns: { + root: true, + type: ['object'] + }, + http: { + path: `/filterItemTags/:tagFk`, + verb: 'get' + } + }); + + Self.filterItemTags = async tagFk => { + let query = `SELECT DISTINCT(value) AS name FROM vn.itemTag WHERE tagFk = ?`; + return await Self.rawSql(query, [tagFk]); + }; +}; diff --git a/services/loopback/common/methods/item-tag/specs/filterItemTags.spec.js b/services/loopback/common/methods/item-tag/specs/filterItemTags.spec.js new file mode 100644 index 000000000..3ca35ece1 --- /dev/null +++ b/services/loopback/common/methods/item-tag/specs/filterItemTags.spec.js @@ -0,0 +1,9 @@ +const app = require(`${servicesDir}/item/server/server`); + +describe('item filterItemTags()', () => { + it('should call the filterItemTags method', async() => { + let [result] = await app.models.ItemTag.filterItemTags(1); + + expect(result.name).toEqual('Yellow'); + }); +}); diff --git a/services/loopback/common/methods/ticket/filter.js b/services/loopback/common/methods/ticket/filter.js index 8550d579a..5bada154f 100644 --- a/services/loopback/common/methods/ticket/filter.js +++ b/services/loopback/common/methods/ticket/filter.js @@ -6,7 +6,53 @@ module.exports = Self => { where: {}, skip: (params.page - 1) * params.size, limit: params.size, - order: params.order || 'created DESC' + order: params.order || 'created DESC', + include: [ + { + relation: 'address', + scope: { + fields: ['provinceFk'], + include: { + relation: 'province', + scope: { + fields: ['name'] + } + } + } + }, { + relation: 'warehouse', + scope: { + fields: ['name'] + } + }, { + relation: 'agencyMode', + scope: { + fields: ['name'] + } + }, { + relation: 'ticketTracking', + scope: { + fields: ['stateFk'], + include: { + relation: 'state', + scope: { + fields: ['name'] + } + } + } + }, { + relation: 'client', + scope: { + fields: ['salesPersonFk'], + include: { + relation: 'salesPerson', + scope: { + fields: ['name'] + } + } + } + } + ] }; delete params.page; diff --git a/services/loopback/common/models/ink.json b/services/loopback/common/models/ink.json index 04117aa3b..a3cd857bf 100644 --- a/services/loopback/common/models/ink.json +++ b/services/loopback/common/models/ink.json @@ -8,7 +8,7 @@ }, "properties": { "id": { - "type": "Number", + "type": "String", "id": true, "description": "Identifier" }, diff --git a/services/loopback/common/models/item-tag.js b/services/loopback/common/models/item-tag.js index 411528836..be9c3203a 100644 --- a/services/loopback/common/models/item-tag.js +++ b/services/loopback/common/models/item-tag.js @@ -1,3 +1,4 @@ module.exports = function(Self) { require('../methods/item-tag/crudItemTags.js')(Self); + require('../methods/item-tag/filterItemTags.js')(Self); }; diff --git a/services/loopback/common/models/tag.json b/services/loopback/common/models/tag.json index b327c6588..e35a7eddc 100644 --- a/services/loopback/common/models/tag.json +++ b/services/loopback/common/models/tag.json @@ -18,7 +18,7 @@ "required": true }, "isFree": { - "type": "Number" + "type": "Boolean" }, "sourceTable": { "type": "String"