From e6304d026c6c1892903bc8fa67bd85d055a5aa3c Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 22 Oct 2021 15:01:54 +0200 Subject: [PATCH 001/124] feat(smart-table): added smart-table and smart-table-menu components --- front/core/components/index.js | 1 + .../components/smart-table-menu/index.html | 45 ++++ .../core/components/smart-table-menu/index.js | 48 +++++ .../components/smart-table-menu/style.scss | 24 +++ front/core/directives/index.js | 2 + front/core/directives/smart-table2.js | 54 +++++ modules/ticket/front/index/index.html | 200 ++---------------- 7 files changed, 196 insertions(+), 178 deletions(-) create mode 100644 front/core/components/smart-table-menu/index.html create mode 100644 front/core/components/smart-table-menu/index.js create mode 100644 front/core/components/smart-table-menu/style.scss create mode 100644 front/core/directives/smart-table2.js diff --git a/front/core/components/index.js b/front/core/components/index.js index 3ccc64b899..150fc21585 100644 --- a/front/core/components/index.js +++ b/front/core/components/index.js @@ -52,3 +52,4 @@ import './wday-picker'; import './datalist'; import './contextmenu'; import './rating'; +import './smart-table-menu'; diff --git a/front/core/components/smart-table-menu/index.html b/front/core/components/smart-table-menu/index.html new file mode 100644 index 0000000000..14b94cf48c --- /dev/null +++ b/front/core/components/smart-table-menu/index.html @@ -0,0 +1,45 @@ +
+
+ +
+ + +
+
+ + +
+ + a + + + + + +
+ +
+ + + + +
+
+
+ +
+
\ No newline at end of file diff --git a/front/core/components/smart-table-menu/index.js b/front/core/components/smart-table-menu/index.js new file mode 100644 index 0000000000..9d2b378cc8 --- /dev/null +++ b/front/core/components/smart-table-menu/index.js @@ -0,0 +1,48 @@ +import ngModule from '../../module'; +import Component from '../../lib/component'; +import './style.scss'; + +export default class SmartTableMenu extends Component { + constructor($element, $, $transclude) { + super($element, $); + this.$transclude = $transclude; + // stuff + } + + $onDestroy() { + if (this.$contentScope) + this.$contentScope.$destroy(); + } + + get model() { + return this._model; + } + + set model(value) { + this._model = value; + if (value) + this.transclude(); + } + + transclude() { + const body = this.element.querySelector('.body'); + this.$transclude(($clone, $scope) => { + this.$contentScope = $scope; + $scope.model = this.model; + body.appendChild($clone[0]); + }, null, 'body'); + } +} + +SmartTableMenu.$inject = ['$element', '$scope', '$transclude']; + +ngModule.vnComponent('smartTableMenu', { + template: require('./index.html'), + controller: SmartTableMenu, + transclude: { + body: '?slotBody' + }, + bindings: { + model: ' vn-button { + box-shadow: 0 0 0 0 + } + } + } +} diff --git a/front/core/directives/index.js b/front/core/directives/index.js index e0f42aef56..dfc79d1aac 100644 --- a/front/core/directives/index.js +++ b/front/core/directives/index.js @@ -16,3 +16,5 @@ import './droppable'; import './http-click'; import './http-submit'; import './anchor'; +import './smart-table2'; + diff --git a/front/core/directives/smart-table2.js b/front/core/directives/smart-table2.js new file mode 100644 index 0000000000..187f775692 --- /dev/null +++ b/front/core/directives/smart-table2.js @@ -0,0 +1,54 @@ +import ngModule from '../module'; +import Component from '../lib/component'; +import './smart-table.scss'; + +class Controller extends Component { + constructor($element, $, $attrs) { + super($element, $); + // this.element = $element[0]; + + this.$attrs = $attrs; + + this.registerColumns(); + this.registerEvents(); + } + + registerColumns() { + const header = this.element.querySelector('thead > tr'); + if (!header) return; + const columns = header.querySelectorAll('th'); + + // TODO: Add arrow icon and so on.. + // Click handler + for (let column of columns) + column.addEventListener('click', () => this.orderHandler(column)); + } + + registerEvents() { + this.$.$on('addRow', () => this.addRow()); + this.$.$on('displaySearch', () => this.displaySearch()); + } + + orderHandler(element) { + const field = element.getAttribute('field'); + console.log(`You clicked to ` + field); + } + + displaySearch() { + console.log('Display the search!'); + } + + addRow() { + console.log('Add new row element'); + this.$.model.insert({}); + } +} +Controller.$inject = ['$element', '$scope', '$attrs']; + +ngModule.directive('smartTable', () => { + return { + controller: Controller, + bindings: { + } + }; +}); diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index 63b0b049d1..f3ac18c526 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -1,155 +1,28 @@ - - - - - - - - - - - Id - Salesperson - Date - Hour - Closure - Alias - Province - State - Zone - Warehouse - Total - - - - - - - - - - - - - - - - - - - - - - - - {{::ticket.id}} - - - {{::ticket.userName | dashIfEmpty}} - - - - - {{::ticket.shipped | date: 'dd/MM/yyyy'}} - - - {{::ticket.shipped | date: 'HH:mm'}} - {{::ticket.zoneLanding | date: 'HH:mm'}} - - - {{::ticket.nickname}} - - - {{::ticket.province}} - - - {{::ticket.refFk}} - - - {{ticket.state}} - - - - - {{::ticket.zoneName | dashIfEmpty}} - - - {{::ticket.warehouse}} - - - {{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}} - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + +
Column 1Column 2
{{::ticket.id}}{{::ticket.userName}}
+
+
+ +
- - - - Filter by selection - - - Exclude selection - - - Remove filter - - - Remove all filters - - - Copy value - - - Date: Fri, 22 Oct 2021 15:41:44 +0200 Subject: [PATCH 002/124] Added save function --- front/core/components/smart-table-menu/index.html | 3 +-- front/core/components/smart-table-menu/index.js | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/front/core/components/smart-table-menu/index.html b/front/core/components/smart-table-menu/index.html index 14b94cf48c..6cd90efe8a 100644 --- a/front/core/components/smart-table-menu/index.html +++ b/front/core/components/smart-table-menu/index.html @@ -16,14 +16,13 @@ - a
diff --git a/front/core/components/smart-table-menu/index.js b/front/core/components/smart-table-menu/index.js index 9d2b378cc8..9f0d27852b 100644 --- a/front/core/components/smart-table-menu/index.js +++ b/front/core/components/smart-table-menu/index.js @@ -32,6 +32,11 @@ export default class SmartTableMenu extends Component { body.appendChild($clone[0]); }, null, 'body'); } + + save() { + this.model.save() + .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); + } } SmartTableMenu.$inject = ['$element', '$scope', '$transclude']; From d5264486c7f3a1fba3da44d2834f9f3121de8c6c Mon Sep 17 00:00:00 2001 From: joan Date: Sat, 23 Oct 2021 14:26:42 +0200 Subject: [PATCH 003/124] Simplified to one component --- front/core/components/index.js | 2 +- .../core/components/smart-table-menu/index.js | 53 --------- .../index.html | 19 ++-- front/core/components/smart-table/index.js | 102 ++++++++++++++++++ .../style.scss | 14 ++- front/core/directives/smart-table2.js | 2 +- modules/ticket/front/index/index.html | 47 +++++--- 7 files changed, 163 insertions(+), 76 deletions(-) delete mode 100644 front/core/components/smart-table-menu/index.js rename front/core/components/{smart-table-menu => smart-table}/index.html (69%) create mode 100644 front/core/components/smart-table/index.js rename front/core/components/{smart-table-menu => smart-table}/style.scss (63%) diff --git a/front/core/components/index.js b/front/core/components/index.js index 150fc21585..86ab892122 100644 --- a/front/core/components/index.js +++ b/front/core/components/index.js @@ -52,4 +52,4 @@ import './wday-picker'; import './datalist'; import './contextmenu'; import './rating'; -import './smart-table-menu'; +import './smart-table'; diff --git a/front/core/components/smart-table-menu/index.js b/front/core/components/smart-table-menu/index.js deleted file mode 100644 index 9f0d27852b..0000000000 --- a/front/core/components/smart-table-menu/index.js +++ /dev/null @@ -1,53 +0,0 @@ -import ngModule from '../../module'; -import Component from '../../lib/component'; -import './style.scss'; - -export default class SmartTableMenu extends Component { - constructor($element, $, $transclude) { - super($element, $); - this.$transclude = $transclude; - // stuff - } - - $onDestroy() { - if (this.$contentScope) - this.$contentScope.$destroy(); - } - - get model() { - return this._model; - } - - set model(value) { - this._model = value; - if (value) - this.transclude(); - } - - transclude() { - const body = this.element.querySelector('.body'); - this.$transclude(($clone, $scope) => { - this.$contentScope = $scope; - $scope.model = this.model; - body.appendChild($clone[0]); - }, null, 'body'); - } - - save() { - this.model.save() - .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); - } -} - -SmartTableMenu.$inject = ['$element', '$scope', '$transclude']; - -ngModule.vnComponent('smartTableMenu', { - template: require('./index.html'), - controller: SmartTableMenu, - transclude: { - body: '?slotBody' - }, - bindings: { - model: ' -
+ +
+ +
@@ -40,5 +45,5 @@
-
+
\ No newline at end of file diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js new file mode 100644 index 0000000000..fd22ac9a4e --- /dev/null +++ b/front/core/components/smart-table/index.js @@ -0,0 +1,102 @@ +import ngModule from '../../module'; +import Component from '../../lib/component'; +import './style.scss'; + +export default class SmartTable extends Component { + constructor($element, $, $transclude) { + super($element, $); + this.$transclude = $transclude; + // stuff + } + + /* $onDestroy() { + if (this.$contentScope) + this.$contentScope.$destroy(); + } + */ + get model() { + return this._model; + } + + set model(value) { + this._model = value; + if (value) { + this.$.model = value; + this.transclude(); + } + } + + registerColumns() { + const header = this.element.querySelector('thead > tr'); + if (!header) return; + const columns = header.querySelectorAll('th'); + + // TODO: Add arrow icon and so on.. + // Click handler + for (let column of columns) { + const field = column.getAttribute('field'); + if (field) + column.addEventListener('click', () => this.orderHandler(column)); + } + } + + // Creo que se puede hacer directamente desde ng-transclude + transclude() { + const slotTable = this.element.querySelector('#table'); + this.$transclude(($clone, $scope) => { + const table = $clone[0]; + $scope.hasChanges = this.hasChanges; + slotTable.appendChild(table); + this.registerColumns(); + }, null, 'table'); + } + + orderHandler(element) { + const field = element.getAttribute('field'); + console.log(`You clicked to ` + field); + } + + createRow() { + this.model.insert({ + nickname: 'New row' + }); + } + + deleteAll() { + const data = this.model.data; + const checkedRows = data.filter(row => row.checked); + for (let row of checkedRows) + this.model.remove(row); + + if (this.autoSave) + this.save(); + } + + saveAll() { + const model = this.model; + if (!model.isChanged) + return this.vnApp.showError(this.$t('No changes to save')); + + this.model.save() + .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); + } + + hasChanges() { + return true; + } +} + +SmartTable.$inject = ['$element', '$scope', '$transclude']; + +ngModule.vnComponent('smartTable', { + template: require('./index.html'), + controller: SmartTable, + transclude: { + table: '?slotTable', + actions: '?slotActions' + }, + bindings: { + model: ' { +ngModule.directive('smartTable2', () => { return { controller: Controller, bindings: { diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index f3ac18c526..af59eac7d8 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -1,27 +1,48 @@ - - + --> + + - - - + + + Mas iconos.. + + +
- - + + + - - + + + - + +
Column 1Column 2 + + + IDNickname
+ + + {{::ticket.id}}{{::ticket.userName}}{{::ticket.nickname}}
-
-
- + +
From 301d303cc1b1023b0f4c036d32a1c5f7098c6dbf Mon Sep 17 00:00:00 2001 From: carlosjr Date: Sun, 24 Oct 2021 13:35:37 +0200 Subject: [PATCH 004/124] polished deletions --- front/core/components/smart-table/index.html | 2 +- front/core/components/smart-table/index.js | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/front/core/components/smart-table/index.html b/front/core/components/smart-table/index.html index 53d015dd4d..ccac52b9f2 100644 --- a/front/core/components/smart-table/index.html +++ b/front/core/components/smart-table/index.html @@ -23,7 +23,7 @@ vn-tooltip="Undo"> row.checked); - for (let row of checkedRows) - this.model.remove(row); + + for (let row of checkedRows) { + if (row.id) + this.model.remove(row); + else { + const index = this.model.data.indexOf(row); + this.model.data.splice(index, 1); + } + } if (this.autoSave) - this.save(); + this.saveAll(); } saveAll() { From 7ce58c5f33c74ca7e90a4f2fc8d24a361b3d9486 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Mon, 25 Oct 2021 14:20:17 +0200 Subject: [PATCH 005/124] sorting arrows for multiple columns --- front/core/components/smart-table/index.js | 37 +++++++++++++- front/core/components/smart-table/style.scss | 32 ++++++++++++ front/core/directives/index.js | 1 - front/core/directives/smart-table2.js | 54 -------------------- modules/ticket/front/index/index.html | 8 ++- 5 files changed, 73 insertions(+), 59 deletions(-) delete mode 100644 front/core/directives/smart-table2.js diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index 1ba29b2155..2bf0321951 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -6,7 +6,7 @@ export default class SmartTable extends Component { constructor($element, $, $transclude) { super($element, $); this.$transclude = $transclude; - // stuff + this.sortCriteria = []; } /* $onDestroy() { @@ -53,7 +53,40 @@ export default class SmartTable extends Component { orderHandler(element) { const field = element.getAttribute('field'); - console.log(`You clicked to ` + field); + const existingCriteria = this.sortCriteria.find(criteria => { + return criteria.field == field; + }); + + if (!existingCriteria) { + this.sortCriteria.push({field: field, sortType: 'ASC'}); + element.classList.remove('desc'); + element.classList.add('asc'); + } + + if (existingCriteria && existingCriteria.sortType == 'DESC') { + this.sortCriteria.splice(this.sortCriteria.findIndex(criteria => { + return criteria.field == field; + }), 1); + element.classList.remove('desc'); + element.classList.remove('asc'); + } + if (existingCriteria && existingCriteria.sortType == 'ASC') { + existingCriteria.sortType = 'DESC'; + element.classList.remove('asc'); + element.classList.add('desc'); + } + + this.applySort(); + } + + applySort() { + let order = this.sortCriteria.map(criteria => `${criteria.field} ${criteria.sortType}`); + order = order.join(', '); + + if (order) + this.model.order = order; + + this.model.refresh(); } createRow() { diff --git a/front/core/components/smart-table/style.scss b/front/core/components/smart-table/style.scss index 15a47d3ecf..a9a5c4bb0c 100644 --- a/front/core/components/smart-table/style.scss +++ b/front/core/components/smart-table/style.scss @@ -2,6 +2,38 @@ @import "variables"; smart-table { + th[field] { + overflow: visible; + cursor: pointer; + + &.asc > :after, &.desc > :after { + color: $color-font; + opacity: 1; + } + + &.asc > :after { + content: 'arrow_drop_up'; + } + + &.desc > :after { + content: 'arrow_drop_down'; + } + + & > :after { + font-family: 'Material Icons'; + content: 'arrow_drop_down'; + position: absolute; + color: $color-spacer; + font-size: 1.5em; + margin-top: -2px; + opacity: 0 + + } + &:hover > :after { + opacity: 1; + } + } + .actions-left { display: flex; justify-content: flex-start; diff --git a/front/core/directives/index.js b/front/core/directives/index.js index dfc79d1aac..e77917285d 100644 --- a/front/core/directives/index.js +++ b/front/core/directives/index.js @@ -16,5 +16,4 @@ import './droppable'; import './http-click'; import './http-submit'; import './anchor'; -import './smart-table2'; diff --git a/front/core/directives/smart-table2.js b/front/core/directives/smart-table2.js deleted file mode 100644 index 916ff130fe..0000000000 --- a/front/core/directives/smart-table2.js +++ /dev/null @@ -1,54 +0,0 @@ -import ngModule from '../module'; -import Component from '../lib/component'; -import './smart-table.scss'; - -class Controller extends Component { - constructor($element, $, $attrs) { - super($element, $); - // this.element = $element[0]; - - this.$attrs = $attrs; - - this.registerColumns(); - this.registerEvents(); - } - - registerColumns() { - const header = this.element.querySelector('thead > tr'); - if (!header) return; - const columns = header.querySelectorAll('th'); - - // TODO: Add arrow icon and so on.. - // Click handler - for (let column of columns) - column.addEventListener('click', () => this.orderHandler(column)); - } - - registerEvents() { - this.$.$on('addRow', () => this.addRow()); - this.$.$on('displaySearch', () => this.displaySearch()); - } - - orderHandler(element) { - const field = element.getAttribute('field'); - console.log(`You clicked to ` + field); - } - - displaySearch() { - console.log('Display the search!'); - } - - addRow() { - console.log('Add new row element'); - this.$.model.insert({}); - } -} -Controller.$inject = ['$element', '$scope', '$attrs']; - -ngModule.directive('smartTable2', () => { - return { - controller: Controller, - bindings: { - } - }; -}); diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index af59eac7d8..017a25a6ce 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -22,8 +22,12 @@ model="model"> - ID - Nickname + + #ID + + + Nickname + From bf386929d3de9678c9df6b38e4a9c2bdc6f9ae1e Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 25 Oct 2021 17:18:57 +0200 Subject: [PATCH 006/124] Deletion ammends and selection fixed --- .../components/multi-check/multi-check.js | 2 +- front/core/components/smart-table/index.html | 20 ++++++++++-- front/core/components/smart-table/index.js | 30 ++++++++--------- .../core/components/smart-table/locale/es.yml | 5 +++ front/core/components/smart-table/style.scss | 32 +++++++++++++++---- modules/ticket/front/index/index.html | 27 +++++++++++++--- 6 files changed, 85 insertions(+), 31 deletions(-) create mode 100644 front/core/components/smart-table/locale/es.yml diff --git a/front/core/components/multi-check/multi-check.js b/front/core/components/multi-check/multi-check.js index d8fda64047..97b86f03d5 100644 --- a/front/core/components/multi-check/multi-check.js +++ b/front/core/components/multi-check/multi-check.js @@ -156,7 +156,7 @@ ngModule.vnComponent('vnMultiCheck', { controller: MultiCheck, bindings: { model: '<', - checkField: '
-
+
@@ -23,7 +23,8 @@ vn-tooltip="Undo">
-
\ No newline at end of file + + + +
+ + + \ No newline at end of file diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index 2bf0321951..81c8572e6b 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -7,13 +7,9 @@ export default class SmartTable extends Component { super($element, $); this.$transclude = $transclude; this.sortCriteria = []; + this.autoSave = false; } - /* $onDestroy() { - if (this.$contentScope) - this.$contentScope.$destroy(); - } - */ get model() { return this._model; } @@ -26,12 +22,19 @@ export default class SmartTable extends Component { } } + get checkedRows() { + const model = this.model; + if (model && model.data) + return model.data.filter(row => row.$checked); + + return null; + } + registerColumns() { const header = this.element.querySelector('thead > tr'); if (!header) return; const columns = header.querySelectorAll('th'); - // TODO: Add arrow icon and so on.. // Click handler for (let column of columns) { const field = column.getAttribute('field'); @@ -96,17 +99,9 @@ export default class SmartTable extends Component { } deleteAll() { - const data = this.model.data; - const checkedRows = data.filter(row => row.checked); - - for (let row of checkedRows) { - if (row.id) - this.model.remove(row); - else { - const index = this.model.data.indexOf(row); - this.model.data.splice(index, 1); - } - } + const rowsChecked = this.checkedRows(); + for (let row of rowsChecked) + this.model.removeRow(row); if (this.autoSave) this.saveAll(); @@ -114,6 +109,7 @@ export default class SmartTable extends Component { saveAll() { const model = this.model; + if (!model.isChanged) return this.vnApp.showError(this.$t('No changes to save')); diff --git a/front/core/components/smart-table/locale/es.yml b/front/core/components/smart-table/locale/es.yml new file mode 100644 index 0000000000..1cf39daa14 --- /dev/null +++ b/front/core/components/smart-table/locale/es.yml @@ -0,0 +1,5 @@ +Remove selected rows: Eliminar líneas seleccionadas +Add new row: Añadir nueva fila +Undo: Deshacer +Save data: Guardar datos +Shown columns: Columnas visibles \ No newline at end of file diff --git a/front/core/components/smart-table/style.scss b/front/core/components/smart-table/style.scss index a9a5c4bb0c..5d5244fcf2 100644 --- a/front/core/components/smart-table/style.scss +++ b/front/core/components/smart-table/style.scss @@ -34,19 +34,17 @@ smart-table { } } - .actions-left { - display: flex; - justify-content: flex-start; + tr[vn-anchor] { + @extend %clickable; } - .actions { + .actions-left, + .actions-right { display: flex; - justify-content: flex-end; .button-group { display: flex; box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .3); - margin-left: 10px; & > vn-button { box-shadow: 0 0 0 0 @@ -54,6 +52,28 @@ smart-table { } } + .actions-left { + justify-content: flex-start; + + slot-actions > vn-button, + & > vn-button, + .button-group { + margin-right: 10px + } + + slot-actions { + display: flex + } + } + + .actions-right { + justify-content: flex-end; + & > vn-button, + .button-group { + margin-left: 10px + } + } + vn-tbody a[ng-repeat].vn-tr:focus { background-color: $color-primary-light } diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index 017a25a6ce..25f437011a 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -11,7 +11,21 @@ - Mas iconos.. + + + +
+ + + + +
@@ -19,7 +33,8 @@ + ng-class="{'new-row': ticket.$isNew, 'changed-row': ticket.$oldData}" + vn-anchor="::{ + state: 'ticket.card.summary', + params: {id: ticket.id} + }"> From e4fe125627dad78df857febcd81a2b50302c5156 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Tue, 26 Oct 2021 09:18:31 +0200 Subject: [PATCH 007/124] deleteAll uses checkedRows getter now --- front/core/components/smart-table/index.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index 81c8572e6b..fa40443dca 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -60,20 +60,23 @@ export default class SmartTable extends Component { return criteria.field == field; }); + const isASC = existingCriteria && existingCriteria.sortType == 'ASC'; + const isDESC = existingCriteria && existingCriteria.sortType == 'DESC'; + if (!existingCriteria) { this.sortCriteria.push({field: field, sortType: 'ASC'}); element.classList.remove('desc'); element.classList.add('asc'); } - if (existingCriteria && existingCriteria.sortType == 'DESC') { + if (isDESC) { this.sortCriteria.splice(this.sortCriteria.findIndex(criteria => { return criteria.field == field; }), 1); element.classList.remove('desc'); element.classList.remove('asc'); } - if (existingCriteria && existingCriteria.sortType == 'ASC') { + if (isASC) { existingCriteria.sortType = 'DESC'; element.classList.remove('asc'); element.classList.add('desc'); @@ -99,8 +102,8 @@ export default class SmartTable extends Component { } deleteAll() { - const rowsChecked = this.checkedRows(); - for (let row of rowsChecked) + const checkedRows = this.checkedRows; + for (let row of checkedRows) this.model.removeRow(row); if (this.autoSave) From c976f1ed07a04375da58dc30bf5c822b23c3a59a Mon Sep 17 00:00:00 2001 From: carlosjr Date: Tue, 26 Oct 2021 17:16:01 +0200 Subject: [PATCH 008/124] multiple search by column feature --- front/core/components/smart-table/index.js | 115 ++++++++++++++++++++- modules/ticket/front/index/index.html | 11 +- modules/ticket/front/index/index.js | 45 ++++---- modules/ticket/front/index/style.scss | 12 +-- 4 files changed, 154 insertions(+), 29 deletions(-) diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index fa40443dca..628f25e476 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -1,5 +1,6 @@ import ngModule from '../../module'; import Component from '../../lib/component'; +import {buildFilter} from 'vn-loopback/util/filter'; import './style.scss'; export default class SmartTable extends Component { @@ -76,6 +77,7 @@ export default class SmartTable extends Component { element.classList.remove('desc'); element.classList.remove('asc'); } + if (isASC) { existingCriteria.sortType = 'DESC'; element.classList.remove('asc'); @@ -85,6 +87,65 @@ export default class SmartTable extends Component { this.applySort(); } + displaySearch() { + const header = this.element.querySelector('thead > tr'); + if (!header) return; + + const tbody = this.element.querySelector('tbody'); + const columns = header.querySelectorAll('th'); + + const hasSearchRow = tbody.querySelector('tr#searchRow'); + if (hasSearchRow) return hasSearchRow.remove(); + + const searchRow = document.createElement('tr'); + searchRow.setAttribute('id', 'searchRow'); + for (let column of columns) { + const field = column.getAttribute('field'); + const cell = document.createElement('td'); + if (field) { + const input = this.$compile(` + `)(this.$); + cell.appendChild(input[0]); + } + searchRow.appendChild(cell); + } + + tbody.prepend(searchRow); + } + + searchByColumn($event, scope, field) { + if ($event.key != 'Enter') return; + + const searchCriteria = scope.searchProps[field]; + const emptySearch = searchCriteria == '' || null; + + const filters = this.filterSanitizer(field); + + if (filters && filters.userFilter) + this.model.userFilter = filters.userFilter; + + if (!emptySearch) + this.addFilter(field, scope.searchProps[field]); + else this.model.refresh(); + } + + addFilter(field, value) { + let where = {[field]: value}; + + if (this.exprBuilder) { + where = buildFilter(where, (param, value) => + this.exprBuilder({param, value}) + ); + } + + this.model.addFilter({where}); + } + applySort() { let order = this.sortCriteria.map(criteria => `${criteria.field} ${criteria.sortType}`); order = order.join(', '); @@ -95,6 +156,54 @@ export default class SmartTable extends Component { this.model.refresh(); } + filterSanitizer(field) { + // tenemos que eliminar ands vacios al ir borrando filtros + const userFilter = this.model.userFilter; + const userParams = this.model.userParams; + const where = userFilter && userFilter.where; + + if (this.exprBuilder) { + const param = this.exprBuilder({ + param: field, + value: null + }); + if (param) [field] = Object.keys(param); + } + + if (!where) return; + + const whereKeys = Object.keys(where); + for (let key of whereKeys) { + removeProp(where, field, key); + + if (!Object.keys(where)) + delete userFilter.where; + } + + function removeProp(instance, findProp, prop) { + if (prop == findProp) + delete instance[prop]; + + if (prop === 'and') { + for (let [index, param] of instance[prop].entries()) { + const [key] = Object.keys(param); + if (key == findProp) + instance[prop].splice(index, 1); + + if (param[key] instanceof Array) + removeProp(param, field, key); + } + } + } + + return {userFilter, userParams}; + } + + removeFilter(field) { + // + this.model.applyFilter(userFilter, userParams); + } + createRow() { this.model.insert({ nickname: 'New row' @@ -102,8 +211,7 @@ export default class SmartTable extends Component { } deleteAll() { - const checkedRows = this.checkedRows; - for (let row of checkedRows) + for (let row of this.checkedRows) this.model.removeRow(row); if (this.autoSave) @@ -136,6 +244,7 @@ ngModule.vnComponent('smartTable', { }, bindings: { model: ' - + Nickname + @@ -60,7 +67,7 @@ - +
+ model="model" + check-field="$checked"> @@ -32,10 +47,14 @@
+ Pepinillos +
{{::ticket.id}} {{::ticket.nickname}}
diff --git a/modules/ticket/front/index/index.js b/modules/ticket/front/index/index.js index 2df4de0a50..59d297b3cd 100644 --- a/modules/ticket/front/index/index.js +++ b/modules/ticket/front/index/index.js @@ -130,28 +130,37 @@ export default class Controller extends Section { exprBuilder(param, value) { switch (param) { - case 'stateFk': - return {'ts.stateFk': value}; - case 'salesPersonFk': - return {'c.salesPersonFk': value}; - case 'provinceFk': - return {'a.provinceFk': value}; - case 'hour': - return {'z.hour': value}; - case 'shipped': - return {'t.shipped': { - between: this.dateRange(value)} - }; - case 'id': - case 'refFk': - case 'zoneFk': case 'nickname': - case 'agencyModeFk': - case 'warehouseFk': - return {[`t.${param}`]: value}; + return {'nickname': {like: `%${value}%`}}; + case 'id': + return {[param]: value}; } } + // exprBuilder(param, value) { + // switch (param) { + // case 'stateFk': + // return {'ts.stateFk': value}; + // case 'salesPersonFk': + // return {'c.salesPersonFk': value}; + // case 'provinceFk': + // return {'a.provinceFk': value}; + // case 'hour': + // return {'z.hour': value}; + // case 'shipped': + // return {'t.shipped': { + // between: this.dateRange(value)} + // }; + // case 'id': + // case 'refFk': + // case 'zoneFk': + // case 'nickname': + // case 'agencyModeFk': + // case 'warehouseFk': + // return {[`t.${param}`]: value}; + // } + // } + dateRange(value) { const minHour = new Date(value); minHour.setHours(0, 0, 0, 0); diff --git a/modules/ticket/front/index/style.scss b/modules/ticket/front/index/style.scss index 23c4b88b85..36409ab671 100644 --- a/modules/ticket/front/index/style.scss +++ b/modules/ticket/front/index/style.scss @@ -7,19 +7,19 @@ vn-ticket-index { } } - vn-th.icon-field, - vn-th.icon-field *, - vn-td.icon-field, - vn-td.icon-field * { + th.icon-field, + th.icon-field *, + td.icon-field, + td.icon-field * { padding: 0 } - vn-td.icon-field > vn-icon { + td.icon-field > vn-icon { margin-left: 3px; margin-right: 3px; } - vn-tbody a[ng-repeat].vn-tr:focus { + tbody a[ng-repeat].vn-tr:focus { background-color: $color-primary-light } } \ No newline at end of file From d94e2900d0e4795a96f6c2ed3e9e6afa4942924d Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 27 Oct 2021 12:16:37 +0200 Subject: [PATCH 009/124] feat(ticket-request): send rocket message when ticket-reques is denied --- loopback/locale/es.json | 1 + .../ticket/back/methods/ticket-request/deny.js | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index cdf15c6744..afa349684f 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -133,6 +133,7 @@ "reserved": "reservado", "Changed sale reserved state": "He cambiado el estado reservado de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", "Bought units from buy request": "Se ha comprado {{quantity}} unidades de [{{itemId}} {{concept}}]({{{urlItem}}}) para el ticket id [{{ticketId}}]({{{url}}})", + "Deny buy request":"Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}", "MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*", "Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})", "Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})", diff --git a/modules/ticket/back/methods/ticket-request/deny.js b/modules/ticket/back/methods/ticket-request/deny.js index 5b79a57cb2..6d7df32aa1 100644 --- a/modules/ticket/back/methods/ticket-request/deny.js +++ b/modules/ticket/back/methods/ticket-request/deny.js @@ -24,6 +24,8 @@ module.exports = Self => { }); Self.deny = async(ctx, options) => { + const models = Self.app.models; + const $t = ctx.req.__; // $translate const myOptions = {}; let tx; @@ -48,6 +50,20 @@ module.exports = Self => { const request = await Self.app.models.TicketRequest.findById(ctx.args.id, null, myOptions); await request.updateAttributes(params, myOptions); + // const salesPerson = ticket.client().salesPersonUser(); + // if (salesPerson) { + // const origin = ctx.req.headers.origin; + const origin = ctx.req.headers.origin; + + const message = $t('Deny buy request', { + ticketId: request.ticketFk, + url: `${origin}/#!/ticket/${request.ticketFk}/request/index`, + observation: params.response + }); + // await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); + await models.Chat.send(ctx, '@vicent', message, myOptions); + // } + if (tx) await tx.commit(); return request; From f60fa5a852be9ed8b0ace63897b4cfec122aa25c Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 27 Oct 2021 12:22:32 +0200 Subject: [PATCH 010/124] change receiver to requesterId --- modules/ticket/back/methods/ticket-request/deny.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/modules/ticket/back/methods/ticket-request/deny.js b/modules/ticket/back/methods/ticket-request/deny.js index 6d7df32aa1..35de765d71 100644 --- a/modules/ticket/back/methods/ticket-request/deny.js +++ b/modules/ticket/back/methods/ticket-request/deny.js @@ -50,19 +50,16 @@ module.exports = Self => { const request = await Self.app.models.TicketRequest.findById(ctx.args.id, null, myOptions); await request.updateAttributes(params, myOptions); - // const salesPerson = ticket.client().salesPersonUser(); - // if (salesPerson) { - // const origin = ctx.req.headers.origin; const origin = ctx.req.headers.origin; + const requesterId = request.requesterFk; const message = $t('Deny buy request', { ticketId: request.ticketFk, url: `${origin}/#!/ticket/${request.ticketFk}/request/index`, observation: params.response }); - // await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions); - await models.Chat.send(ctx, '@vicent', message, myOptions); - // } + + await models.Chat.sendCheckingPresence(ctx, requesterId, message, myOptions); if (tx) await tx.commit(); From b1b6d93c8e5228680b2cd97ab6bde1c97e496e75 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 27 Oct 2021 13:39:38 +0200 Subject: [PATCH 011/124] change column value : checkbox for text --- modules/ticket/front/request/index/index.html | 12 ++++-------- modules/ticket/front/request/index/locale/es.yml | 5 ++++- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/modules/ticket/front/request/index/index.html b/modules/ticket/front/request/index/index.html index 39a290d8c3..71c8d88ce8 100644 --- a/modules/ticket/front/request/index/index.html +++ b/modules/ticket/front/request/index/index.html @@ -25,7 +25,7 @@ Quantity Price Item id - Ok + State @@ -78,13 +78,9 @@ {{::request.saleFk | zeroFill:6}} - - - + + {{$ctrl.getRequestState(request.isOk)}} Date: Wed, 27 Oct 2021 13:41:59 +0200 Subject: [PATCH 012/124] test --- modules/ticket/front/request/index/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/front/request/index/index.html b/modules/ticket/front/request/index/index.html index 71c8d88ce8..054f0c76a0 100644 --- a/modules/ticket/front/request/index/index.html +++ b/modules/ticket/front/request/index/index.html @@ -89,7 +89,7 @@ ng-click="$ctrl.removeLine($index)" vn-tooltip="Remove request" tabindex="-1"> - + From b27a44372941265ee95e8cb17b6a90b5caaf3a7a Mon Sep 17 00:00:00 2001 From: carlosjr Date: Wed, 27 Oct 2021 17:11:33 +0200 Subject: [PATCH 013/124] show/hide columns and load default view --- back/methods/user-config-view/save.js | 5 +- back/model-config.json | 3 + back/models/default-view-config.json | 25 ++++ .../10380-allsaints/00-defaultViewConfig.sql | 6 + front/core/components/smart-table/index.html | 32 ++++- front/core/components/smart-table/index.js | 117 ++++++++++++++++-- front/salix/components/log/index.html | 10 +- modules/ticket/front/index/index.html | 3 +- modules/ticket/front/index/index.js | 6 + 9 files changed, 188 insertions(+), 19 deletions(-) create mode 100644 back/models/default-view-config.json create mode 100644 db/changes/10380-allsaints/00-defaultViewConfig.sql diff --git a/back/methods/user-config-view/save.js b/back/methods/user-config-view/save.js index da8a270833..b2144c01eb 100644 --- a/back/methods/user-config-view/save.js +++ b/back/methods/user-config-view/save.js @@ -7,8 +7,7 @@ module.exports = function(Self) { required: true, description: `Code of the table you ask its configuration`, http: {source: 'body'} - } - ], + }], returns: { type: 'object', root: true @@ -29,6 +28,6 @@ module.exports = function(Self) { config.userFk = ctx.req.accessToken.userId; - return await Self.app.models.UserConfigView.create(config); + return Self.app.models.UserConfigView.create(config); }; }; diff --git a/back/model-config.json b/back/model-config.json index 18bf4cf98d..8ad15a16a7 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -29,6 +29,9 @@ "ChatConfig": { "dataSource": "vn" }, + "DefaultViewConfig": { + "dataSource": "vn" + }, "Delivery": { "dataSource": "vn" }, diff --git a/back/models/default-view-config.json b/back/models/default-view-config.json new file mode 100644 index 0000000000..88164692d4 --- /dev/null +++ b/back/models/default-view-config.json @@ -0,0 +1,25 @@ +{ + "name": "DefaultViewConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "salix.defaultViewConfig" + } + }, + "properties": { + "tableCode": { + "id": true, + "type": "string", + "required": true + }, + "columns": { + "type": "object" + } + }, + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] +} diff --git a/db/changes/10380-allsaints/00-defaultViewConfig.sql b/db/changes/10380-allsaints/00-defaultViewConfig.sql new file mode 100644 index 0000000000..6f66bd6ebc --- /dev/null +++ b/db/changes/10380-allsaints/00-defaultViewConfig.sql @@ -0,0 +1,6 @@ +CREATE TABLE `salix`.`defaultViewConfig` +( + tableCode VARCHAR(25) not null, + columns JSON not null +) +comment 'The default configuration of columns for views'; \ No newline at end of file diff --git a/front/core/components/smart-table/index.html b/front/core/components/smart-table/index.html index 2a7a45b18e..68c29dcb51 100644 --- a/front/core/components/smart-table/index.html +++ b/front/core/components/smart-table/index.html @@ -2,10 +2,9 @@
-
@@ -32,7 +31,6 @@ vn-tooltip="Save data">
-
- \ No newline at end of file + + + + + + +
+ + + + + + + + +
+
+
\ No newline at end of file diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index 628f25e476..353cbb050f 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -2,12 +2,15 @@ import ngModule from '../../module'; import Component from '../../lib/component'; import {buildFilter} from 'vn-loopback/util/filter'; import './style.scss'; +import angular from 'angular'; export default class SmartTable extends Component { constructor($element, $, $transclude) { super($element, $); + this.currentUserId = window.localStorage.currentUserWorkerId; this.$transclude = $transclude; this.sortCriteria = []; + this.columns = []; this.autoSave = false; } @@ -23,6 +26,52 @@ export default class SmartTable extends Component { } } + get viewConfigId() { + return this._viewConfigId; + } + + set viewConfigId(value) { + this._viewConfigId = value; + + if (value) { + this.defaultViewConfig = {}; + + const url = 'DefaultViewConfigs'; + this.$http.get(url, {where: {tableCode: value}}) + .then(res => { + if (res && res.data.length) { + const columns = res.data[0].columns; + this.defaultViewConfig = columns; + } + }); + } + } + + get viewConfig() { + return this._viewConfig; + } + + set viewConfig(value) { + this._viewConfig = value; + + if (!value) return; + + if (!value.length) { + const userViewModel = this.$.userViewModel; + + for (const column of this.columns) { + if (this.defaultViewConfig[column.field] == undefined) + this.defaultViewConfig[column.field] = true; + } + userViewModel.insert({ + userFk: this.currentUserId, + tableConfig: this.viewConfigId, + configuration: this.defaultViewConfig ? this.defaultViewConfig : {} + }); + } + this.applyViewConfig(); + } + get checkedRows() { const model = this.model; if (model && model.data) @@ -31,16 +80,63 @@ export default class SmartTable extends Component { return null; } + saveViewConfig() { + const userViewModel = this.$.userViewModel; + const [viewConfig] = userViewModel.data; + viewConfig.configuration = Object.assign({}, viewConfig.configuration); + userViewModel.save() + .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))) + .then(() => this.applyViewConfig()); + } + + applyViewConfig() { + const userViewModel = this.$.userViewModel; + const [viewConfig] = userViewModel.data; + + const selectors = []; + for (const column of this.columns) { + if (viewConfig.configuration[column.field] == false) { + const baseSelector = `smart-table[view-config-id="${this.viewConfigId}"] table`; + selectors.push(`${baseSelector} thead > tr > th:nth-child(${column.index + 1})`); + selectors.push(`${baseSelector} tbody > tr > td:nth-child(${column.index + 1})`); + } + } + + const styleElement = document.querySelector('style[id="smart-table"]'); + + if (styleElement) + styleElement.parentNode.removeChild(styleElement); + + if (selectors.length) { + const rule = selectors.join(', ') + '{display: none}'; + this.$.css = document.createElement('style'); + this.$.css.setAttribute('id', 'smart-table'); + document.head.appendChild(this.$.css); + this.$.css.appendChild(document.createTextNode(rule)); + } + + this.$.$on('$destroy', () => { + if (this.$.css && styleElement) + styleElement.parentNode.removeChild(styleElement); + }); + } + registerColumns() { const header = this.element.querySelector('thead > tr'); if (!header) return; const columns = header.querySelectorAll('th'); // Click handler - for (let column of columns) { + for (const [index, column] of columns.entries()) { const field = column.getAttribute('field'); - if (field) + if (field) { + const columnElement = angular.element(column); + const caption = columnElement.text().trim(); + + this.columns.push({field, caption, index}); + column.addEventListener('click', () => this.orderHandler(column)); + } } } @@ -157,7 +253,6 @@ export default class SmartTable extends Component { } filterSanitizer(field) { - // tenemos que eliminar ands vacios al ir borrando filtros const userFilter = this.model.userFilter; const userParams = this.model.userParams; const where = userFilter && userFilter.where; @@ -199,15 +294,17 @@ export default class SmartTable extends Component { return {userFilter, userParams}; } - removeFilter(field) { - // + removeFilter() { this.model.applyFilter(userFilter, userParams); } createRow() { - this.model.insert({ - nickname: 'New row' - }); + let data = {}; + + if (this.defaultNewData) + data = this.defaultNewData(); + + this.model.insert(data); } deleteAll() { @@ -244,7 +341,9 @@ ngModule.vnComponent('smartTable', { }, bindings: { model: ' + diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index f5e3e15917..dc0f493693 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -11,9 +11,10 @@ + default-new-data="$ctrl.defaultNewData()"> Date: Thu, 28 Oct 2021 09:06:03 +0200 Subject: [PATCH 014/124] Restored ticket table and added table compatibility on contextmenu --- front/core/components/contextmenu/index.js | 12 +- modules/ticket/front/index/index.html | 180 +++++++++++++++++++-- modules/ticket/front/index/index.js | 45 +++--- 3 files changed, 194 insertions(+), 43 deletions(-) diff --git a/front/core/components/contextmenu/index.js b/front/core/components/contextmenu/index.js index 646df1a0a8..76a25e701d 100755 --- a/front/core/components/contextmenu/index.js +++ b/front/core/components/contextmenu/index.js @@ -49,7 +49,7 @@ export default class Contextmenu { get rowIndex() { if (!this.row) return null; - const table = this.row.closest('vn-table, .vn-table'); + const table = this.row.closest('table, vn-table, .vn-table'); const rows = table.querySelectorAll('[ng-repeat]'); return Array.from(rows).findIndex( @@ -67,13 +67,13 @@ export default class Contextmenu { get cell() { if (!this.target) return null; - return this.target.closest('vn-td, .vn-td, vn-td-editable'); + return this.target.closest('td, vn-td, .vn-td, vn-td-editable'); } get cellIndex() { if (!this.row) return null; - const cells = this.row.querySelectorAll('vn-td, .vn-td, vn-td-editable'); + const cells = this.row.querySelectorAll('td, vn-td, .vn-td, vn-td-editable'); return Array.from(cells).findIndex( cellItem => cellItem == this.cell ); @@ -82,8 +82,8 @@ export default class Contextmenu { get rowHeader() { if (!this.row) return null; - const table = this.row.closest('vn-table, .vn-table'); - const headerCells = table && table.querySelectorAll('vn-thead vn-th'); + const table = this.row.closest('table, vn-table, .vn-table'); + const headerCells = table && table.querySelectorAll('thead th, vn-thead vn-th'); const headerCell = headerCells && headerCells[this.cellIndex]; return headerCell; @@ -147,7 +147,7 @@ export default class Contextmenu { */ isActionAllowed() { if (!this.target) return false; - const isTableCell = this.target.closest('vn-td, .vn-td'); + const isTableCell = this.target.closest('td, vn-td, .vn-td'); return isTableCell && this.fieldName; } diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index dc0f493693..e0062fc1fe 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -1,12 +1,12 @@ - - + + #ID - - Nickname + + Salesperson + + + Date - Pepinillos + Hour + + Closure + + + Alias + + + Province + + + State + + + Zone + + + Warehouse + + + Total + + @@ -66,9 +92,113 @@ vn-click-stop> - {{::ticket.id}} - {{::ticket.nickname}} - + + + + + + + + + + + + + + + {{::ticket.id}} + + + {{::ticket.userName | dashIfEmpty}} + + + + + {{::ticket.shipped | date: 'dd/MM/yyyy'}} + + + {{::ticket.shipped | date: 'HH:mm'}} + {{::ticket.zoneLanding | date: 'HH:mm'}} + + + {{::ticket.nickname}} + + + {{::ticket.province}} + + + {{::ticket.refFk}} + + + {{ticket.state}} + + + + + {{::ticket.zoneName | dashIfEmpty}} + + + {{::ticket.warehouse}} + + + {{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}} + + + + + + + + @@ -131,6 +261,36 @@ vn-id="invoiceOutDescriptor"> + + + + Filter by selection + + + Exclude selection + + + Remove filter + + + Remove all filters + + + Copy value + + + + Date: Thu, 28 Oct 2021 09:09:52 +0200 Subject: [PATCH 015/124] Updated checked property --- modules/ticket/front/index/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticket/front/index/index.js b/modules/ticket/front/index/index.js index dd16d4bff2..329d9785b5 100644 --- a/modules/ticket/front/index/index.js +++ b/modules/ticket/front/index/index.js @@ -64,7 +64,7 @@ export default class Controller extends Section { const tickets = this.$.model.data || []; const checkedLines = []; for (let ticket of tickets) { - if (ticket.checked) + if (ticket.$checked) checkedLines.push(ticket); } From 5beeab36b10ddb17893e0f7da6ce595dcee54634 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 28 Oct 2021 09:25:46 +0200 Subject: [PATCH 016/124] Changed shown fields form to two columns --- front/core/components/smart-table/index.html | 9 +++++---- front/core/components/smart-table/style.scss | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/front/core/components/smart-table/index.html b/front/core/components/smart-table/index.html index 68c29dcb51..263d2a6588 100644 --- a/front/core/components/smart-table/index.html +++ b/front/core/components/smart-table/index.html @@ -67,11 +67,12 @@ data="$ctrl.viewConfig" auto-load="true"> - + -
- - +
Check the columns you want to see
+ + diff --git a/front/core/components/smart-table/style.scss b/front/core/components/smart-table/style.scss index 5d5244fcf2..0207ce0807 100644 --- a/front/core/components/smart-table/style.scss +++ b/front/core/components/smart-table/style.scss @@ -86,3 +86,19 @@ smart-table { background-color: $color-primary-light } } + +.smart-table-columns { + h6 { + color: $color-font-secondary + } + + & > vn-horizontal { + align-items: flex-start; + flex-wrap: wrap; + } + + vn-check { + flex: initial; + width: 50% + } +} \ No newline at end of file From a1970c6fc8881be2f37afd4df7f40d0700023f70 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 28 Oct 2021 15:22:26 +0200 Subject: [PATCH 017/124] translation for hide show columns --- front/core/components/smart-table/index.html | 2 +- front/core/components/smart-table/locale/es.yml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/front/core/components/smart-table/index.html b/front/core/components/smart-table/index.html index 263d2a6588..90d5d4dd3d 100644 --- a/front/core/components/smart-table/index.html +++ b/front/core/components/smart-table/index.html @@ -70,7 +70,7 @@
-
Check the columns you want to see
+
Check the columns you want to see
Date: Fri, 29 Oct 2021 15:52:04 +0200 Subject: [PATCH 018/124] autocomplete options added to smart table --- front/core/components/smart-table/index.html | 1 + front/core/components/smart-table/index.js | 44 ++++++++++++++++---- modules/ticket/front/index/index.html | 2 +- modules/ticket/front/index/index.js | 38 +++++++++++++++++ 4 files changed, 77 insertions(+), 8 deletions(-) diff --git a/front/core/components/smart-table/index.html b/front/core/components/smart-table/index.html index 90d5d4dd3d..291bff6139 100644 --- a/front/core/components/smart-table/index.html +++ b/front/core/components/smart-table/index.html @@ -2,6 +2,7 @@
diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index 353cbb050f..0498bc2e96 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -3,6 +3,7 @@ import Component from '../../lib/component'; import {buildFilter} from 'vn-loopback/util/filter'; import './style.scss'; import angular from 'angular'; +import {camelToKebab} from '../../lib/string'; export default class SmartTable extends Component { constructor($element, $, $transclude) { @@ -199,13 +200,37 @@ export default class SmartTable extends Component { const field = column.getAttribute('field'); const cell = document.createElement('td'); if (field) { - const input = this.$compile(` - column.field == field); + + if (options && options.autocomplete) { + let props = ``; + + const autocomplete = options.autocomplete; + for (const prop in autocomplete) + props += `${camelToKebab(prop)}="${autocomplete[prop]}"\n`; + + input = this.$compile(` + `)(this.$); + } else { + input = this.$compile(` + `)(this.$); + } cell.appendChild(input[0]); } searchRow.appendChild(cell); @@ -214,10 +239,14 @@ export default class SmartTable extends Component { tbody.prepend(searchRow); } - searchByColumn($event, scope, field) { + searchWithEvent($event, field) { if ($event.key != 'Enter') return; - const searchCriteria = scope.searchProps[field]; + this.searchByColumn(field); + } + + searchByColumn(field) { + const searchCriteria = this.$.searchProps[field]; const emptySearch = searchCriteria == '' || null; const filters = this.filterSanitizer(field); @@ -226,7 +255,7 @@ export default class SmartTable extends Component { this.model.userFilter = filters.userFilter; if (!emptySearch) - this.addFilter(field, scope.searchProps[field]); + this.addFilter(field, this.$.searchProps[field]); else this.model.refresh(); } @@ -344,6 +373,7 @@ ngModule.vnComponent('smartTable', { viewConfigId: '@?', autoSave: ' @@ -20,7 +21,6 @@ ng-click="$ctrl.test()" vn-tooltip="Info"> -
Date: Fri, 29 Oct 2021 16:55:19 +0200 Subject: [PATCH 019/124] vn table now receives show buttons options --- front/core/components/smart-table/index.html | 23 +++++++++----------- front/core/components/smart-table/index.js | 14 ++++++++++++ modules/ticket/front/index/index.html | 23 -------------------- modules/ticket/front/index/index.js | 5 +++++ 4 files changed, 29 insertions(+), 36 deletions(-) diff --git a/front/core/components/smart-table/index.html b/front/core/components/smart-table/index.html index 291bff6139..e4b1df1ec9 100644 --- a/front/core/components/smart-table/index.html +++ b/front/core/components/smart-table/index.html @@ -2,7 +2,7 @@
@@ -10,10 +10,12 @@
-
+
@@ -32,16 +34,10 @@ vn-tooltip="Save data">
-
- - - - -
+ +
@@ -61,7 +57,8 @@ message="Remove selected rows"> - - - - - - -
- - - - -
-
diff --git a/modules/ticket/front/index/index.js b/modules/ticket/front/index/index.js index cec47baebf..d076fec5a5 100644 --- a/modules/ticket/front/index/index.js +++ b/modules/ticket/front/index/index.js @@ -8,6 +8,11 @@ export default class Controller extends Section { super($element, $); this.vnReport = vnReport; this.smartTableOptions = { + activeButtons: { + search: true, + crud: true, + shownColumns: true, + }, columns: [ { field: 'salesPersonFk', From fbf1c50f97323ff84a68a949ff109e096565f1f8 Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 8 Nov 2021 14:13:28 +0100 Subject: [PATCH 020/124] Added total rows and a message for no results --- front/core/components/smart-table/index.html | 9 +++- front/core/components/smart-table/index.js | 42 +++++++++++++------ .../core/components/smart-table/locale/es.yml | 4 +- front/core/components/smart-table/style.scss | 5 +++ 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/front/core/components/smart-table/index.html b/front/core/components/smart-table/index.html index e4b1df1ec9..a4c26459fb 100644 --- a/front/core/components/smart-table/index.html +++ b/front/core/components/smart-table/index.html @@ -1,5 +1,5 @@
- +
+
+ < + Showing + {{model.data.length}} + rows + > +
{ + const table = $clone[0]; + slotTable.appendChild(table); + this.registerColumns(); + + const header = this.element.querySelector('thead > tr'); + const columns = header.querySelectorAll('th'); + const tbody = this.element.querySelector('tbody'); + if (tbody) { + const noSearch = this.$compile(` +
+ + + `)($scope); + tbody.appendChild(noSearch[0]); + + const noRows = this.$compile(` + + + + `)($scope); + tbody.appendChild(noRows[0]); + } + }, null, 'table'); + } + saveViewConfig() { const userViewModel = this.$.userViewModel; const [viewConfig] = userViewModel.data; @@ -155,17 +184,6 @@ export default class SmartTable extends Component { } } - // Creo que se puede hacer directamente desde ng-transclude - transclude() { - const slotTable = this.element.querySelector('#table'); - this.$transclude(($clone, $scope) => { - const table = $clone[0]; - $scope.hasChanges = this.hasChanges; - slotTable.appendChild(table); - this.registerColumns(); - }, null, 'table'); - } - orderHandler(element) { const field = element.getAttribute('field'); const existingCriteria = this.sortCriteria.find(criteria => { diff --git a/front/core/components/smart-table/locale/es.yml b/front/core/components/smart-table/locale/es.yml index a681d8be56..b5cc554ee0 100644 --- a/front/core/components/smart-table/locale/es.yml +++ b/front/core/components/smart-table/locale/es.yml @@ -3,4 +3,6 @@ Add new row: Añadir nueva fila Undo: Deshacer Save data: Guardar datos Shown columns: Columnas visibles -Check the columns you want to see: Marca las columnas que quieres ver \ No newline at end of file +Check the columns you want to see: Marca las columnas que quieres ver +Showing: Mostrando +rows: filas \ No newline at end of file diff --git a/front/core/components/smart-table/style.scss b/front/core/components/smart-table/style.scss index 0207ce0807..b1e93486e2 100644 --- a/front/core/components/smart-table/style.scss +++ b/front/core/components/smart-table/style.scss @@ -38,9 +38,14 @@ smart-table { @extend %clickable; } + .totalRows { + color: $color-font-secondary; + } + .actions-left, .actions-right { display: flex; + align-items: center; .button-group { display: flex; From eb36f86b9d27df391347688d4c50d0955986083d Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 8 Nov 2021 14:46:23 +0100 Subject: [PATCH 021/124] Added smart-table to item index --- modules/item/front/index/index.html | 253 ++++++++++++++++------------ modules/item/front/index/index.js | 23 ++- modules/item/front/index/style.scss | 2 +- 3 files changed, 166 insertions(+), 112 deletions(-) diff --git a/modules/item/front/index/index.html b/modules/item/front/index/index.html index 0232950426..9fa03eabb8 100644 --- a/modules/item/front/index/index.html +++ b/modules/item/front/index/index.html @@ -1,115 +1,148 @@ - - - - - - - Id - Grouping - Packing - Description - Stems - Size - Type - Category - Intrastat - Origin - Buyer - Density - Multiplier - Active - Landed - - - - - - - - - - - {{::item.id}} - - - {{::item.grouping | dashIfEmpty}} - {{::item.packing | dashIfEmpty}} - -
- {{::item.name}} - -

{{::item.subName}}

-
-
- - -
- {{::item.stems}} - {{::item.size}} - - {{::item.typeName}} - - - {{::item.category}} - - - {{::item.intrastat}} - - {{::item.origin}} - - - {{::item.userName}} - - - {{::item.density}} - {{::item.stemMultiplier}} - - - - - {{::item.landed | date:'dd/MM/yyyy'}} - - - - - - - - -
-
-
-
-
+ + + +
Enter a new search
No data
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Id + + Grouping + + Packing + + Description + + Stems + + Size + + Type + + Category + + Intrastat + + Origin + + Buyer + + Density + + Multiplier + + Active + + Landed +
+ + + + {{::item.id}} + + {{::item.grouping | dashIfEmpty}}{{::item.packing | dashIfEmpty}} +
+ {{::item.name}} + +

{{::item.subName}}

+
+
+ + +
{{::item.stems}}{{::item.size}} + {{::item.typeName}} + + {{::item.category}} + + {{::item.intrastat}} + {{::item.origin}} + + {{::item.userName}} + + {{::item.density}}{{::item.stemMultiplier}} + + + {{::item.landed | date:'dd/MM/yyyy'}} + + + + + + +
+
+
+
@@ -133,7 +166,7 @@ diff --git a/modules/item/front/index/index.js b/modules/item/front/index/index.js index 3235d684e4..86e67f919e 100644 --- a/modules/item/front/index/index.js +++ b/modules/item/front/index/index.js @@ -5,9 +5,30 @@ import './style.scss'; class Controller extends Section { constructor($element, $) { super($element, $); - this.showFields = { + /* this.showFields = { id: false, actions: false + }; */ + + this.smartTableOptions = { + activeButtons: { + search: true, + shownColumns: true, + }, + columns: [ + { + field: 'category', + autocomplete: { + url: 'ItemCategories', + } + }, + { + field: 'origin', + autocomplete: { + url: 'Origins', + } + }, + ] }; } diff --git a/modules/item/front/index/style.scss b/modules/item/front/index/style.scss index b0b94c19d3..eaa1a16ed4 100644 --- a/modules/item/front/index/style.scss +++ b/modules/item/front/index/style.scss @@ -23,7 +23,7 @@ vn-item-product { } } -vn-table { +table { img { border-radius: 50%; width: 50px; From 395ad1c76d879d705dd4b002548eb6ebad63c852 Mon Sep 17 00:00:00 2001 From: vicent Date: Mon, 8 Nov 2021 15:04:33 +0100 Subject: [PATCH 022/124] fix(ibanRequired): set different ibanRequired for Client and Supplier --- db/changes/10370-pickles/payMethod.sql | 4 ++++ db/dump/fixtures.sql | 14 +++++++------- db/dump/structure.sql | 3 ++- modules/client/back/models/client.js | 2 +- modules/client/back/models/pay-method.json | 5 ++++- modules/client/front/billing-data/index.html | 2 +- modules/supplier/back/models/supplier.js | 2 +- modules/supplier/front/billing-data/index.html | 2 +- 8 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 db/changes/10370-pickles/payMethod.sql diff --git a/db/changes/10370-pickles/payMethod.sql b/db/changes/10370-pickles/payMethod.sql new file mode 100644 index 0000000000..ac6429b99b --- /dev/null +++ b/db/changes/10370-pickles/payMethod.sql @@ -0,0 +1,4 @@ +ALTER TABLE vn.payMethod CHANGE ibanRequired ibanRequiredForClients tinyint(3) DEFAULT 0 NULL; +ALTER TABLE vn.payMethod ADD ibanRequiredForSuppliers tinyint(3) DEFAULT 0 NULL; +ALTER TABLE vn.payMethod CHANGE ibanRequiredForSuppliers ibanRequiredForSuppliers tinyint(3) DEFAULT 0 NULL AFTER ibanRequiredForClients; +UPDATE vn.payMethod SET ibanRequiredForSuppliers = 1 WHERE code = 'wireTransfer'; \ No newline at end of file diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 4c82be9097..fe2da1f38d 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -217,14 +217,14 @@ UPDATE `vn`.`agencyMode` SET `web` = 1, `reportMail` = 'no-reply@gothamcity.com' UPDATE `vn`.`agencyMode` SET `code` = 'refund' WHERE `id` = 23; -INSERT INTO `vn`.`payMethod`(`id`,`code`, `name`, `graceDays`, `outstandingDebt`, `ibanRequired`) +INSERT INTO `vn`.`payMethod`(`id`,`code`, `name`, `graceDays`, `outstandingDebt`, `ibanRequiredForClients`, `ibanRequiredForSuppliers`) VALUES - (1, NULL, 'PayMethod one', 0, 001, 0), - (2, NULL, 'PayMethod two', 10, 001, 0), - (3, 'compensation', 'PayMethod three', 0, 001, 0), - (4, NULL, 'PayMethod with IBAN', 0, 001, 1), - (5, NULL, 'PayMethod five', 10, 001, 0), - (8,'wireTransfer', 'WireTransfer', 5, 001, 1); + (1, NULL, 'PayMethod one', 0, 001, 0, 0), + (2, NULL, 'PayMethod two', 10, 001, 0, 0), + (3, 'compensation', 'PayMethod three', 0, 001, 0, 0), + (4, NULL, 'PayMethod with IBAN', 0, 001, 1, 0), + (5, NULL, 'PayMethod five', 10, 001, 0, 0), + (8,'wireTransfer', 'WireTransfer', 5, 001, 1, 1); INSERT INTO `vn`.`payDem`(`id`, `payDem`) VALUES diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 734a926d19..5a2f9055ff 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -34324,7 +34324,8 @@ CREATE TABLE `payMethod` ( `solution` varchar(1) COLLATE utf8_unicode_ci DEFAULT NULL, `outstandingDebt` tinyint(3) unsigned zerofill NOT NULL DEFAULT '000', `graceDays` int(11) unsigned NOT NULL DEFAULT '0', - `ibanRequired` tinyint(3) DEFAULT '0', + `ibanRequiredForClients` tinyint(3) DEFAULT '0', + `ibanRequiredForSuppliers` tinyint(3) DEFAULT '0', `isNotified` tinyint(3) NOT NULL DEFAULT '1', PRIMARY KEY (`id`) ) ENGINE=InnoDBDEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index 6519cb979d..4cac16358f 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -129,7 +129,7 @@ module.exports = Self => { function hasIban(err, done) { Self.app.models.PayMethod.findById(this.payMethodFk, (_, instance) => { - if (instance && instance.ibanRequired && !this.iban) + if (instance && instance.ibanRequiredForClients && !this.iban) err(); done(); }); diff --git a/modules/client/back/models/pay-method.json b/modules/client/back/models/pay-method.json index a025bee477..0666be7a5b 100644 --- a/modules/client/back/models/pay-method.json +++ b/modules/client/back/models/pay-method.json @@ -25,7 +25,10 @@ "outstandingDebt": { "type": "Number" }, - "ibanRequired": { + "ibanRequiredForClients": { + "type": "boolean" + }, + "ibanRequiredForSuppliers": { "type": "boolean" } } diff --git a/modules/client/front/billing-data/index.html b/modules/client/front/billing-data/index.html index ff2e2f157b..8c7c6cfe9d 100644 --- a/modules/client/front/billing-data/index.html +++ b/modules/client/front/billing-data/index.html @@ -19,7 +19,7 @@ vn-acl="salesAssistant" ng-model="$ctrl.client.payMethodFk" data="paymethods" - fields="['ibanRequired']" + fields="['ibanRequiredForClients']" initial-data="$ctrl.client.payMethod"> { const supplierAccount = await Self.app.models.SupplierAccount.findOne({where: {supplierFk: this.id}}); const hasIban = supplierAccount && supplierAccount.iban; - if (payMethod && payMethod.ibanRequired && !hasIban) + if (payMethod && payMethod.ibanRequiredForSuppliers && !hasIban) err(); done(); diff --git a/modules/supplier/front/billing-data/index.html b/modules/supplier/front/billing-data/index.html index 12d3b84b38..c1c57e1357 100644 --- a/modules/supplier/front/billing-data/index.html +++ b/modules/supplier/front/billing-data/index.html @@ -24,7 +24,7 @@ vn-acl="salesAssistant" ng-model="$ctrl.supplier.payMethodFk" data="paymethods" - fields="['ibanRequired']" + fields="['ibanRequiredForSuppliers']" initial-data="$ctrl.supplier.payMethod"> Date: Mon, 8 Nov 2021 17:46:40 +0100 Subject: [PATCH 023/124] added autocompletes to item index --- front/core/components/smart-table/index.html | 2 +- .../core/components/smart-table/locale/es.yml | 2 +- modules/item/back/methods/item/filter.js | 2 +- modules/item/back/models/intrastat.json | 4 +-- modules/item/back/models/origin.json | 6 ++-- modules/item/front/index/index.html | 2 +- modules/item/front/index/index.js | 33 ++++++++++++++++--- modules/item/front/search-panel/index.html | 2 +- 8 files changed, 38 insertions(+), 15 deletions(-) diff --git a/front/core/components/smart-table/index.html b/front/core/components/smart-table/index.html index a4c26459fb..9cfcf78496 100644 --- a/front/core/components/smart-table/index.html +++ b/front/core/components/smart-table/index.html @@ -11,7 +11,7 @@ < Showing {{model.data.length}} - rows + results >
diff --git a/front/core/components/smart-table/locale/es.yml b/front/core/components/smart-table/locale/es.yml index b5cc554ee0..f65df07b7d 100644 --- a/front/core/components/smart-table/locale/es.yml +++ b/front/core/components/smart-table/locale/es.yml @@ -5,4 +5,4 @@ Save data: Guardar datos Shown columns: Columnas visibles Check the columns you want to see: Marca las columnas que quieres ver Showing: Mostrando -rows: filas \ No newline at end of file +results: resultados \ No newline at end of file diff --git a/modules/item/back/methods/item/filter.js b/modules/item/back/methods/item/filter.js index cff36a2233..8cfefac9f0 100644 --- a/modules/item/back/methods/item/filter.js +++ b/modules/item/back/methods/item/filter.js @@ -113,7 +113,7 @@ module.exports = Self => { return {'i.typeFk': value}; case 'categoryFk': return {'ic.id': value}; - case 'salesPersonFk': + case 'buyerFk': return {'it.workerFk': value}; case 'origin': return {'ori.code': value}; diff --git a/modules/item/back/models/intrastat.json b/modules/item/back/models/intrastat.json index e536e2581a..18a964e7b2 100644 --- a/modules/item/back/models/intrastat.json +++ b/modules/item/back/models/intrastat.json @@ -8,12 +8,12 @@ }, "properties": { "id": { - "type": "Number", + "type": "number", "id": true, "description": "Identifier" }, "description": { - "type": "String" + "type": "string" } }, "relations": { diff --git a/modules/item/back/models/origin.json b/modules/item/back/models/origin.json index c381600bf6..d2fe3fdf0b 100644 --- a/modules/item/back/models/origin.json +++ b/modules/item/back/models/origin.json @@ -8,15 +8,15 @@ }, "properties": { "id": { - "type": "Number", + "type": "number", "id": true, "description": "Identifier" }, "code": { - "type": "String" + "type": "string" }, "name": { - "type": "String" + "type": "string" } }, "acls": [ diff --git a/modules/item/front/index/index.html b/modules/item/front/index/index.html index 9fa03eabb8..6fa3ae8c2a 100644 --- a/modules/item/front/index/index.html +++ b/modules/item/front/index/index.html @@ -42,7 +42,7 @@ Origin - + Buyer diff --git a/modules/item/front/index/index.js b/modules/item/front/index/index.js index 86e67f919e..3b2b71af80 100644 --- a/modules/item/front/index/index.js +++ b/modules/item/front/index/index.js @@ -5,10 +5,6 @@ import './style.scss'; class Controller extends Section { constructor($element, $) { super($element, $); - /* this.showFields = { - id: false, - actions: false - }; */ this.smartTableOptions = { activeButtons: { @@ -20,12 +16,39 @@ class Controller extends Section { field: 'category', autocomplete: { url: 'ItemCategories', + valueField: 'name', } }, { field: 'origin', autocomplete: { url: 'Origins', + showField: 'name', + valueField: 'code' + } + }, + { + field: 'typeFk', + autocomplete: { + url: 'ItemTypes', + } + }, + { + field: 'intrastat', + autocomplete: { + url: 'Intrastats', + showField: 'description', + valueField: 'description' + } + }, + { + field: 'buyerFk', + autocomplete: { + url: 'Workers/activeWithRole', + where: `{role: {inq: ['logistic', 'buyer']}}`, + searchFunction: '{firstName: $search}', + showField: 'nickname', + valueField: 'id', } }, ] @@ -36,7 +59,7 @@ class Controller extends Section { switch (param) { case 'category': return {'ic.name': value}; - case 'salesPersonFk': + case 'buyerFk': return {'it.workerFk': value}; case 'grouping': return {'b.grouping': value}; diff --git a/modules/item/front/search-panel/index.html b/modules/item/front/search-panel/index.html index 518062ebaf..94e4b6d070 100644 --- a/modules/item/front/search-panel/index.html +++ b/modules/item/front/search-panel/index.html @@ -41,7 +41,7 @@ Date: Tue, 9 Nov 2021 11:44:00 +0100 Subject: [PATCH 024/124] refactor(contextmenu): excludes now ensures negation --- front/core/components/contextmenu/index.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/front/core/components/contextmenu/index.js b/front/core/components/contextmenu/index.js index 76a25e701d..9c1206865f 100755 --- a/front/core/components/contextmenu/index.js +++ b/front/core/components/contextmenu/index.js @@ -172,9 +172,14 @@ export default class Contextmenu { excludeSelection() { let where = {[this.fieldName]: {neq: this.fieldValue}}; if (this.exprBuilder) { - where = buildFilter(where, (param, value) => - this.exprBuilder({param, value}) - ); + where = buildFilter(where, (param, value) => { + const expr = this.exprBuilder({param, value}); + const props = Object.keys(expr); + const newExpr = {}; + for (let prop of props) + newExpr[prop] = {neq: this.fieldValue}; + return newExpr; + }); } this.model.addFilter({where}); From 469c544536d6b7ebea66e1227790a6622232c236 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Tue, 9 Nov 2021 11:47:54 +0100 Subject: [PATCH 025/124] item.index default columns and filter with like --- .../10380-allsaints/00-defaultViewConfig.sql | 8 ++- front/core/components/smart-table/index.js | 8 ++- modules/item/front/index/index.html | 60 +++++++++---------- modules/item/front/index/index.js | 13 +++- 4 files changed, 54 insertions(+), 35 deletions(-) diff --git a/db/changes/10380-allsaints/00-defaultViewConfig.sql b/db/changes/10380-allsaints/00-defaultViewConfig.sql index 6f66bd6ebc..2e1c552881 100644 --- a/db/changes/10380-allsaints/00-defaultViewConfig.sql +++ b/db/changes/10380-allsaints/00-defaultViewConfig.sql @@ -3,4 +3,10 @@ CREATE TABLE `salix`.`defaultViewConfig` tableCode VARCHAR(25) not null, columns JSON not null ) -comment 'The default configuration of columns for views'; \ No newline at end of file +comment 'The default configuration of columns for views'; + +INSERT INTO `salix`.`defaultViewConfig` (tableCode, columns) + VALUES ( + 'itemIndex', + '{"id":true,"grouping":true,"packing":true,"name":true,"stems":true,"size":true,"typeFk":true,"category":true,"intrastat":false,"origin":true,"buyerFk":true,"density":false,"stemMultiplier":false,"active":false,"landed":true}' + ); \ No newline at end of file diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index bfeab63cec..918bbca18f 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -37,9 +37,8 @@ export default class SmartTable extends Component { set model(value) { this._model = value; - if (value) { + if (value) this.$.model = value; - } } get viewConfigId() { @@ -239,6 +238,11 @@ export default class SmartTable extends Component { if (columnOptions) options = columnOptions.find(column => column.field == field); + if (options && options.searchable == false) { + searchRow.appendChild(cell); + continue; + } + if (options && options.autocomplete) { let props = ``; diff --git a/modules/item/front/index/index.html b/modules/item/front/index/index.html index 6fa3ae8c2a..75de5733cc 100644 --- a/modules/item/front/index/index.html +++ b/modules/item/front/index/index.html @@ -12,49 +12,49 @@ - - Id + + Identifier - + Grouping - + Packing Description - + Stems - + Size - + Type - + Category - + Intrastat - + Origin - + Buyer - + Density - + Multiplier - + Active - + Landed @@ -66,22 +66,22 @@ state: 'item.card.summary', params: {id: item.id} }"> - + - + {{::item.id}} - {{::item.grouping | dashIfEmpty}} - {{::item.packing | dashIfEmpty}} + {{::item.grouping | dashIfEmpty}} + {{::item.packing | dashIfEmpty}}
{{::item.name}} @@ -95,35 +95,35 @@ tabindex="-1"> - {{::item.stems}} - {{::item.size}} - + {{::item.stems}} + {{::item.size}} + {{::item.typeName}} - + {{::item.category}} - + {{::item.intrastat}} - {{::item.origin}} - + {{::item.origin}} + {{::item.userName}} - {{::item.density}} - {{::item.stemMultiplier}} - + {{::item.density}} + {{::item.stemMultiplier}} + {{::item.landed | date:'dd/MM/yyyy'}} - + Date: Tue, 9 Nov 2021 15:10:43 +0100 Subject: [PATCH 026/124] feat(invoiceOut): separate descriptor --- .../front/descriptor-menu/index.html | 137 +++++++++++++++++ .../invoiceOut/front/descriptor-menu/index.js | 111 ++++++++++++++ .../front/descriptor-menu/index.spec.js | 109 ++++++++++++++ .../front/descriptor-menu/locale/es.yml | 20 +++ .../front/descriptor-menu/style.scss | 24 +++ .../invoiceOut/front/descriptor/index.html | 138 +----------------- modules/invoiceOut/front/descriptor/index.js | 65 --------- modules/invoiceOut/front/index.js | 1 + modules/invoiceOut/front/summary/index.html | 4 + 9 files changed, 413 insertions(+), 196 deletions(-) create mode 100644 modules/invoiceOut/front/descriptor-menu/index.html create mode 100644 modules/invoiceOut/front/descriptor-menu/index.js create mode 100644 modules/invoiceOut/front/descriptor-menu/index.spec.js create mode 100644 modules/invoiceOut/front/descriptor-menu/locale/es.yml create mode 100644 modules/invoiceOut/front/descriptor-menu/style.scss diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html new file mode 100644 index 0000000000..8daea79005 --- /dev/null +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -0,0 +1,137 @@ + + + + + + + Show invoice... + + + + + Show as PDF + + + Show as CSV + + + + + + Send invoice... + + + + + Send PDF + + + Send CSV + + + + + + Delete Invoice + + + Book invoice + + + {{!$ctrl.invoiceOut.hasPdf ? 'Generate PDF invoice': 'Regenerate PDF invoice'}} + + + Show CIES letter + + + + + + + + + + + + + + + + + + Are you sure you want to send it? + + + + + + + + + + + + + Are you sure you want to send it? + + + + + + + + \ No newline at end of file diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js new file mode 100644 index 0000000000..864e21ab2b --- /dev/null +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -0,0 +1,111 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; +import './style.scss'; + +class Controller extends Section { + constructor($element, $) { + super($element, $); + } + + get invoiceOut() { + return this._invoiceOut; + } + + set invoiceOut(value) { + this._invoiceOut = value; + } + + loadData() { + const filter = { + include: [ + { + relation: 'company', + scope: { + fields: ['id', 'code'] + } + }, { + relation: 'client', + scope: { + fields: ['id', 'name', 'email'] + } + } + ] + }; + return this.getData(`InvoiceOuts/${this.invoiceOut.id}`, {filter}) + .then(res => this.invoice = res.data); + } + reload() { + return this.loadData().then(() => { + if (this.parentReload) + this.parentReload(); + }); + } + + cardReload() { + // Prevents error when not defined + } + + deleteInvoiceOut() { + return this.$http.post(`InvoiceOuts/${this.invoiceOut.id}/delete`) + .then(() => this.$state.go('invoiceOut.index')) + .then(() => this.vnApp.showSuccess(this.$t('InvoiceOut deleted'))) + .then(() => this.close()); + } + + bookInvoiceOut() { + return this.$http.post(`InvoiceOuts/${this.invoiceOut.ref}/book`) + .then(() => this.$state.reload()) + .then(() => this.vnApp.showSuccess(this.$t('InvoiceOut booked'))); + } + + createPdfInvoice() { + const invoiceId = this.invoiceOut.id; + return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`) + .then(() => this.reload()) + .then(() => { + const snackbarMessage = this.$t( + `The invoice PDF document has been regenerated`); + this.vnApp.showSuccess(snackbarMessage); + }); + } + + showCsvInvoice() { + this.vnReport.showCsv('invoice', { + recipientId: this.invoiceOut.client.id, + invoiceId: this.id, + }); + } + + sendPdfInvoice($data) { + return this.vnEmail.send('invoice', { + recipientId: this.invoiceOut.client.id, + recipient: $data.email, + invoiceId: this.id + }); + } + + sendCsvInvoice($data) { + return this.vnEmail.sendCsv('invoice', { + recipientId: this.invoiceOut.client.id, + recipient: $data.email, + invoiceId: this.id + }); + } + + showExportationLetter() { + this.vnReport.show('exportation', { + recipientId: this.invoiceOut.client.id, + invoiceId: this.id, + }); + } +} + +Controller.$inject = ['$element', '$scope']; + +ngModule.vnComponent('vnInvoiceOutDescriptorMenu', { + template: require('./index.html'), + controller: Controller, + bindings: { + invoiceOut: '<', + } +}); diff --git a/modules/invoiceOut/front/descriptor-menu/index.spec.js b/modules/invoiceOut/front/descriptor-menu/index.spec.js new file mode 100644 index 0000000000..12430d44db --- /dev/null +++ b/modules/invoiceOut/front/descriptor-menu/index.spec.js @@ -0,0 +1,109 @@ +import './index'; + +describe('vnInvoiceOutDescriptor', () => { + let controller; + let $httpBackend; + let $httpParamSerializer; + const invoiceOut = { + id: 1, + client: {id: 1101} + }; + + beforeEach(ngModule('invoiceOut')); + + beforeEach(inject(($componentController, _$httpParamSerializer_, _$httpBackend_) => { + $httpBackend = _$httpBackend_; + $httpParamSerializer = _$httpParamSerializer_; + controller = $componentController('vnInvoiceOutDescriptor', {$element: null}); + })); + + describe('loadData()', () => { + it(`should perform a get query to store the invoice in data into the controller`, () => { + const id = 1; + const response = {id: 1}; + + $httpBackend.expectGET(`InvoiceOuts/${id}`).respond(response); + controller.id = id; + $httpBackend.flush(); + + expect(controller.invoiceOut).toEqual(response); + }); + }); + + describe('createPdfInvoice()', () => { + it('should make a query to the createPdf() endpoint and show a success snackbar', () => { + jest.spyOn(controller.vnApp, 'showSuccess'); + + controller.invoiceOut = invoiceOut; + + $httpBackend.whenGET(`InvoiceOuts/${invoiceOut.id}`).respond(); + $httpBackend.expectPOST(`InvoiceOuts/${invoiceOut.id}/createPdf`).respond(); + controller.createPdfInvoice(); + $httpBackend.flush(); + + expect(controller.vnApp.showSuccess).toHaveBeenCalled(); + }); + }); + + describe('showCsvInvoice()', () => { + it('should make a query to the csv invoice download endpoint and show a message snackbar', () => { + jest.spyOn(window, 'open').mockReturnThis(); + + controller.invoiceOut = invoiceOut; + + const expectedParams = { + invoiceId: invoiceOut.id, + recipientId: invoiceOut.client.id + }; + const serializedParams = $httpParamSerializer(expectedParams); + const expectedPath = `api/csv/invoice/download?${serializedParams}`; + controller.showCsvInvoice(); + + expect(window.open).toHaveBeenCalledWith(expectedPath); + }); + }); + + describe('sendPdfInvoice()', () => { + it('should make a query to the email invoice endpoint and show a message snackbar', () => { + jest.spyOn(controller.vnApp, 'showMessage'); + + controller.invoiceOut = invoiceOut; + + const $data = {email: 'brucebanner@gothamcity.com'}; + const expectedParams = { + invoiceId: invoiceOut.id, + recipient: $data.email, + recipientId: invoiceOut.client.id + }; + const serializedParams = $httpParamSerializer(expectedParams); + + $httpBackend.expectGET(`email/invoice?${serializedParams}`).respond(); + controller.sendPdfInvoice($data); + $httpBackend.flush(); + + expect(controller.vnApp.showMessage).toHaveBeenCalled(); + }); + }); + + describe('sendCsvInvoice()', () => { + it('should make a query to the csv invoice send endpoint and show a message snackbar', () => { + jest.spyOn(controller.vnApp, 'showMessage'); + + controller.invoiceOut = invoiceOut; + + const $data = {email: 'brucebanner@gothamcity.com'}; + const expectedParams = { + invoiceId: invoiceOut.id, + recipient: $data.email, + recipientId: invoiceOut.client.id + }; + const serializedParams = $httpParamSerializer(expectedParams); + + $httpBackend.expectGET(`csv/invoice/send?${serializedParams}`).respond(); + controller.sendCsvInvoice($data); + $httpBackend.flush(); + + expect(controller.vnApp.showMessage).toHaveBeenCalled(); + }); + }); +}); diff --git a/modules/invoiceOut/front/descriptor-menu/locale/es.yml b/modules/invoiceOut/front/descriptor-menu/locale/es.yml new file mode 100644 index 0000000000..8a4a09db19 --- /dev/null +++ b/modules/invoiceOut/front/descriptor-menu/locale/es.yml @@ -0,0 +1,20 @@ +Volume exceded: Volumen excedido +Volume: Volumen +Client card: Ficha del cliente +Invoice ticket list: Listado de tickets de la factura +Show invoice...: Ver factura... +Send invoice...: Enviar factura... +Send PDF invoice: Enviar factura en PDF +Send CSV invoice: Enviar factura en CSV +Delete Invoice: Eliminar factura +Clone Invoice: Clonar factura +Book invoice: Asentar factura +Generate PDF invoice: Generar PDF factura +Show CIES letter: Ver carta CIES +InvoiceOut deleted: Factura eliminada +Are you sure you want to delete this invoice?: Estas seguro de eliminar esta factura? +Are you sure you want to clone this invoice?: Estas seguro de clonar esta factura? +InvoiceOut booked: Factura asentada +Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura? +Regenerate PDF invoice: Regenerar PDF factura +The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado \ No newline at end of file diff --git a/modules/invoiceOut/front/descriptor-menu/style.scss b/modules/invoiceOut/front/descriptor-menu/style.scss new file mode 100644 index 0000000000..b683019613 --- /dev/null +++ b/modules/invoiceOut/front/descriptor-menu/style.scss @@ -0,0 +1,24 @@ +@import "./effects"; +@import "variables"; + +vn-invoice-out-descriptor-menu { + & > vn-icon-button[icon="more_vert"] { + display: flex; + min-width: 45px; + height: 45px; + box-sizing: border-box; + align-items: center; + justify-content: center; + } + & > vn-icon-button[icon="more_vert"] { + @extend %clickable; + color: inherit; + + & > vn-icon { + padding: 10px; + } + vn-icon { + font-size: 1.75rem; + } + } +} \ No newline at end of file diff --git a/modules/invoiceOut/front/descriptor/index.html b/modules/invoiceOut/front/descriptor/index.html index d5522f6a9a..9c3685338e 100644 --- a/modules/invoiceOut/front/descriptor/index.html +++ b/modules/invoiceOut/front/descriptor/index.html @@ -1,81 +1,12 @@ - - - Show invoice... - - - - - Show as PDF - - - Show as CSV - - - - - - Send invoice... - - - - - Send PDF - - - Send CSV - - - - - - Delete Invoice - - - Book invoice - - - {{!$ctrl.invoiceOut.hasPdf ? 'Generate PDF invoice': 'Regenerate PDF invoice'}} - - - Show CIES letter - - + + +
-
- - - - - - - - - - - - - - - Are you sure you want to send it? - - - - - - - - - - - - - Are you sure you want to send it? - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/modules/invoiceOut/front/descriptor/index.js b/modules/invoiceOut/front/descriptor/index.js index f4f8c07bd0..7eeb85ea6d 100644 --- a/modules/invoiceOut/front/descriptor/index.js +++ b/modules/invoiceOut/front/descriptor/index.js @@ -41,70 +41,6 @@ class Controller extends Descriptor { return this.getData(`InvoiceOuts/${this.id}`, {filter}) .then(res => this.entity = res.data); } - - reload() { - return this.loadData().then(() => { - if (this.cardReload) - this.cardReload(); - }); - } - - cardReload() { - // Prevents error when not defined - } - - deleteInvoiceOut() { - return this.$http.post(`InvoiceOuts/${this.id}/delete`) - .then(() => this.$state.go('invoiceOut.index')) - .then(() => this.vnApp.showSuccess(this.$t('InvoiceOut deleted'))); - } - - bookInvoiceOut() { - return this.$http.post(`InvoiceOuts/${this.invoiceOut.ref}/book`) - .then(() => this.$state.reload()) - .then(() => this.vnApp.showSuccess(this.$t('InvoiceOut booked'))); - } - - createPdfInvoice() { - const invoiceId = this.invoiceOut.id; - return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`) - .then(() => this.reload()) - .then(() => { - const snackbarMessage = this.$t( - `The invoice PDF document has been regenerated`); - this.vnApp.showSuccess(snackbarMessage); - }); - } - - showCsvInvoice() { - this.vnReport.showCsv('invoice', { - recipientId: this.invoiceOut.client.id, - invoiceId: this.id, - }); - } - - sendPdfInvoice($data) { - return this.vnEmail.send('invoice', { - recipientId: this.invoiceOut.client.id, - recipient: $data.email, - invoiceId: this.id - }); - } - - sendCsvInvoice($data) { - return this.vnEmail.sendCsv('invoice', { - recipientId: this.invoiceOut.client.id, - recipient: $data.email, - invoiceId: this.id - }); - } - - showExportationLetter() { - this.vnReport.show('exportation', { - recipientId: this.invoiceOut.client.id, - invoiceId: this.id, - }); - } } ngModule.vnComponent('vnInvoiceOutDescriptor', { @@ -112,6 +48,5 @@ ngModule.vnComponent('vnInvoiceOutDescriptor', { controller: Controller, bindings: { invoiceOut: '<', - cardReload: '&' } }); diff --git a/modules/invoiceOut/front/index.js b/modules/invoiceOut/front/index.js index 3bb6d54d2a..0307b2b4bd 100644 --- a/modules/invoiceOut/front/index.js +++ b/modules/invoiceOut/front/index.js @@ -7,5 +7,6 @@ import './summary'; import './card'; import './descriptor'; import './descriptor-popover'; +import './descriptor-menu'; import './index/manual'; import './index/global-invoicing'; diff --git a/modules/invoiceOut/front/summary/index.html b/modules/invoiceOut/front/summary/index.html index 6a117052e9..a0d050efdd 100644 --- a/modules/invoiceOut/front/summary/index.html +++ b/modules/invoiceOut/front/summary/index.html @@ -13,6 +13,10 @@ {{$ctrl.summary.invoiceOut.ref}} - {{$ctrl.summary.invoiceOut.client.socialName}} + From 18aec14fe9f9852bbfc4df5da8240c1be3ef5dae Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 10 Nov 2021 08:46:09 +0100 Subject: [PATCH 027/124] update backTest --- db/changes/10370-pickles/{payMethod.sql => 00-payMethod.sql} | 0 modules/supplier/back/models/specs/supplier.spec.js | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename db/changes/10370-pickles/{payMethod.sql => 00-payMethod.sql} (100%) diff --git a/db/changes/10370-pickles/payMethod.sql b/db/changes/10370-pickles/00-payMethod.sql similarity index 100% rename from db/changes/10370-pickles/payMethod.sql rename to db/changes/10370-pickles/00-payMethod.sql diff --git a/modules/supplier/back/models/specs/supplier.spec.js b/modules/supplier/back/models/specs/supplier.spec.js index c3c99e6765..8d022f9b3e 100644 --- a/modules/supplier/back/models/specs/supplier.spec.js +++ b/modules/supplier/back/models/specs/supplier.spec.js @@ -20,7 +20,7 @@ describe('loopback model Supplier', () => { const expectedError = 'You can not select this payment method without a registered bankery account'; const supplier = await app.models.Supplier.findById(1); - await supplier.updateAttribute('payMethodFk', 4) + await supplier.updateAttribute('payMethodFk', 8) .catch(e => { error = e; @@ -37,6 +37,7 @@ describe('loopback model Supplier', () => { .catch(e => { error = e; }); + console.log(error); expect(error).toBeDefined(); }); From 0849f40df7737f2d9e65de7e44663c1ffa74a359 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 10 Nov 2021 11:44:29 +0100 Subject: [PATCH 028/124] feat: update backTest --- .../back/methods/ticket-request/specs/deny.spec.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/modules/ticket/back/methods/ticket-request/specs/deny.spec.js b/modules/ticket/back/methods/ticket-request/specs/deny.spec.js index 523c5f0650..95fd0e84dc 100644 --- a/modules/ticket/back/methods/ticket-request/specs/deny.spec.js +++ b/modules/ticket/back/methods/ticket-request/specs/deny.spec.js @@ -1,13 +1,23 @@ const models = require('vn-loopback/server/server').models; describe('ticket-request deny()', () => { - it('should return the dinied ticket request', async() => { + it('should return the denied ticket request', async() => { const tx = await models.TicketRequest.beginTransaction({}); try { const options = {transaction: tx}; - const ctx = {req: {accessToken: {userId: 9}}, args: {id: 4, observation: 'my observation'}}; + const ctx = { + req: { + accessToken: {userId: 9}, + headers: {origin: 'http://localhost'} + }, + args: {id: 4, observation: 'my observation'}, + }; + + ctx.req.__ = value => { + return value; + }; const result = await models.TicketRequest.deny(ctx, options); From 9b46b310108c54fb062cc0dc34eee6c1924628b8 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 10 Nov 2021 12:03:53 +0100 Subject: [PATCH 029/124] translate --- loopback/locale/en.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 8890e911f5..c4226a2c87 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -117,5 +117,6 @@ "INACTIVE_PROVIDER": "Inactive provider", "reference duplicated": "reference duplicated", "The PDF document does not exists": "The PDF document does not exists. Try regenerating it from 'Regenerate invoice PDF' option", - "This item is not available": "This item is not available" + "This item is not available": "This item is not available", + "Deny buy request": "Deny buy request" } \ No newline at end of file From f34130cbd774c6cd9b28024ad1e61d81e0cd4527 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 10 Nov 2021 14:48:17 +0100 Subject: [PATCH 030/124] feat(invoiceOut): separate index.js and jest test --- .../invoiceOut/front/descriptor-menu/index.js | 24 +++--- .../front/descriptor-menu/index.spec.js | 17 +--- .../invoiceOut/front/descriptor/index.html | 2 +- .../invoiceOut/front/descriptor/index.spec.js | 85 +------------------ 4 files changed, 18 insertions(+), 110 deletions(-) diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index 864e21ab2b..6f764a3d09 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -3,8 +3,10 @@ import Section from 'salix/components/section'; import './style.scss'; class Controller extends Section { - constructor($element, $) { + constructor($element, $, vnReport, vnEmail) { super($element, $); + this.vnReport = vnReport; + this.vnEmail = vnEmail; } get invoiceOut() { @@ -13,6 +15,8 @@ class Controller extends Section { set invoiceOut(value) { this._invoiceOut = value; + if (value) + this.id = value.id; } loadData() { @@ -31,8 +35,8 @@ class Controller extends Section { } ] }; - return this.getData(`InvoiceOuts/${this.invoiceOut.id}`, {filter}) - .then(res => this.invoice = res.data); + return this.$http.get(`InvoiceOuts/${this.invoiceOut.id}`, {filter}) + .then(res => this.invoiceOut = res.data); } reload() { return this.loadData().then(() => { @@ -48,8 +52,8 @@ class Controller extends Section { deleteInvoiceOut() { return this.$http.post(`InvoiceOuts/${this.invoiceOut.id}/delete`) .then(() => this.$state.go('invoiceOut.index')) - .then(() => this.vnApp.showSuccess(this.$t('InvoiceOut deleted'))) - .then(() => this.close()); + .then(() => this.$state.reload()) + .then(() => this.vnApp.showSuccess(this.$t('InvoiceOut deleted'))); } bookInvoiceOut() { @@ -59,8 +63,7 @@ class Controller extends Section { } createPdfInvoice() { - const invoiceId = this.invoiceOut.id; - return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`) + return this.$http.post(`InvoiceOuts/${this.id}/createPdf`) .then(() => this.reload()) .then(() => { const snackbarMessage = this.$t( @@ -72,7 +75,7 @@ class Controller extends Section { showCsvInvoice() { this.vnReport.showCsv('invoice', { recipientId: this.invoiceOut.client.id, - invoiceId: this.id, + invoiceId: this.id }); } @@ -95,17 +98,18 @@ class Controller extends Section { showExportationLetter() { this.vnReport.show('exportation', { recipientId: this.invoiceOut.client.id, - invoiceId: this.id, + invoiceId: this.id }); } } -Controller.$inject = ['$element', '$scope']; +Controller.$inject = ['$element', '$scope', 'vnReport', 'vnEmail']; ngModule.vnComponent('vnInvoiceOutDescriptorMenu', { template: require('./index.html'), controller: Controller, bindings: { invoiceOut: '<', + parentReload: '&' } }); diff --git a/modules/invoiceOut/front/descriptor-menu/index.spec.js b/modules/invoiceOut/front/descriptor-menu/index.spec.js index 12430d44db..19822f0947 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.spec.js +++ b/modules/invoiceOut/front/descriptor-menu/index.spec.js @@ -1,6 +1,6 @@ import './index'; -describe('vnInvoiceOutDescriptor', () => { +describe('vnInvoiceOutDescriptorMenu', () => { let controller; let $httpBackend; let $httpParamSerializer; @@ -14,22 +14,9 @@ describe('vnInvoiceOutDescriptor', () => { beforeEach(inject(($componentController, _$httpParamSerializer_, _$httpBackend_) => { $httpBackend = _$httpBackend_; $httpParamSerializer = _$httpParamSerializer_; - controller = $componentController('vnInvoiceOutDescriptor', {$element: null}); + controller = $componentController('vnInvoiceOutDescriptorMenu', {$element: null}); })); - describe('loadData()', () => { - it(`should perform a get query to store the invoice in data into the controller`, () => { - const id = 1; - const response = {id: 1}; - - $httpBackend.expectGET(`InvoiceOuts/${id}`).respond(response); - controller.id = id; - $httpBackend.flush(); - - expect(controller.invoiceOut).toEqual(response); - }); - }); - describe('createPdfInvoice()', () => { it('should make a query to the createPdf() endpoint and show a success snackbar', () => { jest.spyOn(controller.vnApp, 'showSuccess'); diff --git a/modules/invoiceOut/front/descriptor/index.html b/modules/invoiceOut/front/descriptor/index.html index 9c3685338e..135eae0e1b 100644 --- a/modules/invoiceOut/front/descriptor/index.html +++ b/modules/invoiceOut/front/descriptor/index.html @@ -4,7 +4,7 @@ diff --git a/modules/invoiceOut/front/descriptor/index.spec.js b/modules/invoiceOut/front/descriptor/index.spec.js index 12430d44db..987763b0a6 100644 --- a/modules/invoiceOut/front/descriptor/index.spec.js +++ b/modules/invoiceOut/front/descriptor/index.spec.js @@ -3,17 +3,11 @@ import './index'; describe('vnInvoiceOutDescriptor', () => { let controller; let $httpBackend; - let $httpParamSerializer; - const invoiceOut = { - id: 1, - client: {id: 1101} - }; beforeEach(ngModule('invoiceOut')); - beforeEach(inject(($componentController, _$httpParamSerializer_, _$httpBackend_) => { + beforeEach(inject(($componentController, _$httpBackend_) => { $httpBackend = _$httpBackend_; - $httpParamSerializer = _$httpParamSerializer_; controller = $componentController('vnInvoiceOutDescriptor', {$element: null}); })); @@ -29,81 +23,4 @@ describe('vnInvoiceOutDescriptor', () => { expect(controller.invoiceOut).toEqual(response); }); }); - - describe('createPdfInvoice()', () => { - it('should make a query to the createPdf() endpoint and show a success snackbar', () => { - jest.spyOn(controller.vnApp, 'showSuccess'); - - controller.invoiceOut = invoiceOut; - - $httpBackend.whenGET(`InvoiceOuts/${invoiceOut.id}`).respond(); - $httpBackend.expectPOST(`InvoiceOuts/${invoiceOut.id}/createPdf`).respond(); - controller.createPdfInvoice(); - $httpBackend.flush(); - - expect(controller.vnApp.showSuccess).toHaveBeenCalled(); - }); - }); - - describe('showCsvInvoice()', () => { - it('should make a query to the csv invoice download endpoint and show a message snackbar', () => { - jest.spyOn(window, 'open').mockReturnThis(); - - controller.invoiceOut = invoiceOut; - - const expectedParams = { - invoiceId: invoiceOut.id, - recipientId: invoiceOut.client.id - }; - const serializedParams = $httpParamSerializer(expectedParams); - const expectedPath = `api/csv/invoice/download?${serializedParams}`; - controller.showCsvInvoice(); - - expect(window.open).toHaveBeenCalledWith(expectedPath); - }); - }); - - describe('sendPdfInvoice()', () => { - it('should make a query to the email invoice endpoint and show a message snackbar', () => { - jest.spyOn(controller.vnApp, 'showMessage'); - - controller.invoiceOut = invoiceOut; - - const $data = {email: 'brucebanner@gothamcity.com'}; - const expectedParams = { - invoiceId: invoiceOut.id, - recipient: $data.email, - recipientId: invoiceOut.client.id - }; - const serializedParams = $httpParamSerializer(expectedParams); - - $httpBackend.expectGET(`email/invoice?${serializedParams}`).respond(); - controller.sendPdfInvoice($data); - $httpBackend.flush(); - - expect(controller.vnApp.showMessage).toHaveBeenCalled(); - }); - }); - - describe('sendCsvInvoice()', () => { - it('should make a query to the csv invoice send endpoint and show a message snackbar', () => { - jest.spyOn(controller.vnApp, 'showMessage'); - - controller.invoiceOut = invoiceOut; - - const $data = {email: 'brucebanner@gothamcity.com'}; - const expectedParams = { - invoiceId: invoiceOut.id, - recipient: $data.email, - recipientId: invoiceOut.client.id - }; - const serializedParams = $httpParamSerializer(expectedParams); - - $httpBackend.expectGET(`csv/invoice/send?${serializedParams}`).respond(); - controller.sendCsvInvoice($data); - $httpBackend.flush(); - - expect(controller.vnApp.showMessage).toHaveBeenCalled(); - }); - }); }); From 41974669e5c82eb1106c15c7e6c495883a978c35 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 10 Nov 2021 15:11:42 +0100 Subject: [PATCH 031/124] fix(testBack): add context --- .../back/models/specs/supplier.spec.js | 27 ++++++++++++++----- .../supplier/back/models/supplier-log.json | 22 +++++++-------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/modules/supplier/back/models/specs/supplier.spec.js b/modules/supplier/back/models/specs/supplier.spec.js index 8d022f9b3e..27bd873ad4 100644 --- a/modules/supplier/back/models/specs/supplier.spec.js +++ b/modules/supplier/back/models/specs/supplier.spec.js @@ -1,12 +1,13 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('loopback model Supplier', () => { let supplierOne; let supplierTwo; beforeAll(async() => { - supplierOne = await app.models.Supplier.findById(1); - supplierTwo = await app.models.Supplier.findById(442); + supplierOne = await models.Supplier.findById(1); + supplierTwo = await models.Supplier.findById(442); }); afterAll(async() => { @@ -18,7 +19,7 @@ describe('loopback model Supplier', () => { it('should throw an error when attempting to set an invalid payMethod id in the supplier', async() => { let error; const expectedError = 'You can not select this payment method without a registered bankery account'; - const supplier = await app.models.Supplier.findById(1); + const supplier = await models.Supplier.findById(1); await supplier.updateAttribute('payMethodFk', 8) .catch(e => { @@ -31,15 +32,27 @@ describe('loopback model Supplier', () => { }); it('should not throw if the payMethod id is valid', async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + let error; - const supplier = await app.models.Supplier.findById(442); + const supplier = await models.Supplier.findById(442); await supplier.updateAttribute('payMethodFk', 4) .catch(e => { error = e; }); - console.log(error); - expect(error).toBeDefined(); + expect(error).not.toBeDefined(); }); }); }); diff --git a/modules/supplier/back/models/supplier-log.json b/modules/supplier/back/models/supplier-log.json index 9b66bdf740..7c07fa9d44 100644 --- a/modules/supplier/back/models/supplier-log.json +++ b/modules/supplier/back/models/supplier-log.json @@ -9,40 +9,40 @@ "properties": { "id": { "id": true, - "type": "Number", + "type": "number", "forceId": false }, "originFk": { - "type": "Number", + "type": "number", "required": true }, "userFk": { - "type": "Number" + "type": "number" }, "action": { - "type": "String", + "type": "string", "required": true }, "changedModel": { - "type": "String" + "type": "string" }, "oldInstance": { - "type": "Object" + "type": "object" }, "newInstance": { - "type": "Object" + "type": "object" }, "creationDate": { - "type": "Date" + "type": "date" }, "changedModelId": { - "type": "String" + "type": "string" }, "changedModelValue": { - "type": "String" + "type": "string" }, "description": { - "type": "String" + "type": "string" } }, "relations": { From d87e8ac2261fe8a787e2e958e39b2c3b14f91d92 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Wed, 10 Nov 2021 17:07:16 +0100 Subject: [PATCH 032/124] refactor(entry.lastBuys): usage of smart table on latests buys --- .../10380-allsaints/00-defaultViewConfig.sql | 9 +- front/core/components/smart-table/index.js | 8 +- front/core/components/smart-table/style.scss | 4 + front/core/components/smart-table/table.scss | 102 ++++++ modules/entry/front/latest-buys/index.html | 334 ++++++++++-------- modules/entry/front/latest-buys/index.js | 99 +++++- modules/item/back/model-config.json | 3 + modules/item/back/models/item-category.json | 8 +- modules/item/back/models/item-family.json | 27 ++ modules/item/back/models/item-type.json | 10 +- modules/item/front/index/index.html | 2 +- modules/ticket/back/models/packaging.json | 16 +- 12 files changed, 454 insertions(+), 168 deletions(-) create mode 100644 front/core/components/smart-table/table.scss create mode 100644 modules/item/back/models/item-family.json diff --git a/db/changes/10380-allsaints/00-defaultViewConfig.sql b/db/changes/10380-allsaints/00-defaultViewConfig.sql index 2e1c552881..f7e29f45fe 100644 --- a/db/changes/10380-allsaints/00-defaultViewConfig.sql +++ b/db/changes/10380-allsaints/00-defaultViewConfig.sql @@ -6,7 +6,8 @@ CREATE TABLE `salix`.`defaultViewConfig` comment 'The default configuration of columns for views'; INSERT INTO `salix`.`defaultViewConfig` (tableCode, columns) - VALUES ( - 'itemIndex', - '{"id":true,"grouping":true,"packing":true,"name":true,"stems":true,"size":true,"typeFk":true,"category":true,"intrastat":false,"origin":true,"buyerFk":true,"density":false,"stemMultiplier":false,"active":false,"landed":true}' - ); \ No newline at end of file + VALUES + ('itemIndex', '{"intrastat":false,"density":false,"stemMultiplier":false,"active":false}'), + ('latestBuys', '{"intrastat":false,"description":false,"density":false,"isActive":false,"freightValue":false,"packageValue":false,"isIgnored":false,"price2":false,"minPrice":false,"ektFk":false,"weight":false,"packageFk":false,"packingOut":false}'); + + \ No newline at end of file diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index 918bbca18f..f8a35d491f 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -1,9 +1,10 @@ import ngModule from '../../module'; import Component from '../../lib/component'; import {buildFilter} from 'vn-loopback/util/filter'; -import './style.scss'; import angular from 'angular'; import {camelToKebab} from '../../lib/string'; +import './style.scss'; +import './table.scss'; export default class SmartTable extends Component { constructor($element, $, $transclude) { @@ -52,7 +53,8 @@ export default class SmartTable extends Component { this.defaultViewConfig = {}; const url = 'DefaultViewConfigs'; - this.$http.get(url, {where: {tableCode: value}}) + const filter = {where: {tableCode: value}}; + this.$http.get(url, {filter}) .then(res => { if (res && res.data.length) { const columns = res.data[0].columns; @@ -252,6 +254,7 @@ export default class SmartTable extends Component { input = this.$compile(` thead { + border-bottom: 2px solid $color-spacer; + + & > * > th { + font-weight: normal; + } + } + & > tfoot { + border-top: 2px solid $color-spacer; + } + thead, tbody, tfoot { + & > * { + & > th { + color: $color-font-light; + } + & > th, + & > td { + overflow: hidden; + } + & > th, + & > td { + text-align: left; + padding: 9px 8px; + white-space: nowrap; + text-overflow: ellipsis; + + &[number] { + text-align: right; + width: 96px; + } + &[center] { + text-align: center; + } + &[shrink] { + width: 1px; + text-align: center; + } + &[shrink-date] { + width: 100px; + max-width: 100px; + } + &[shrink-datetime] { + width: 150px; + max-width: 150px; + } + &[expand] { + max-width: 400px; + min-width: 0; + } + vn-icon.bright, i.bright { + color: #f7931e; + } + } + } + } + tbody > * { + border-bottom: 1px solid $color-spacer-light; + + &:last-child { + border-bottom: none; + } + & > td { + .chip { + padding: 4px; + border-radius: 4px; + color: $color-font-bg; + + &.notice { + background-color: $color-notice-medium + } + &.success { + background-color: $color-success-medium; + } + &.warning { + background-color: $color-main-medium; + } + &.alert { + background-color: $color-alert-medium; + } + &.message { + color: $color-font-dark; + background-color: $color-bg-dark + } + } + } + } + .vn-check { + margin: 0; + } + .empty-rows { + color: $color-font-secondary; + font-size: 1.375rem; + text-align: center; + } +} \ No newline at end of file diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html index 9281c1b797..ce1dcbaa01 100644 --- a/modules/entry/front/latest-buys/index.html +++ b/modules/entry/front/latest-buys/index.html @@ -16,146 +16,202 @@ auto-state="false"> - - - + - - - - - - - Picture - Id - Packing - Grouping - Quantity - Description - Size - Tags - Type - Intrastat - Origin - Density - Active - Family - Entry - Buying value - Freight value - Commission value - Package value - Is ignored - Grouping price - Packing price - Min price - Ekt - Weight - PackageName - PackingOut - - - - - - - - - - - - - - {{::buy.itemFk | zeroFill:6}} - - - - - {{::buy.packing | dashIfEmpty}} - - - - - {{::buy.grouping | dashIfEmpty}} - - - {{::buy.quantity}} - - {{::buy.description | dashIfEmpty}} - - {{::buy.size}} - -
- {{::buy.name}} - -

{{::buy.subName}}

-
-
- - -
- - {{::buy.code}} - - - {{::buy.intrastat}} - - {{::buy.origin}} - {{::buy.density}} - - - - - {{::buy.family}} - - - {{::buy.entryFk}} - - - {{::buy.buyingValue | currency: 'EUR':2}} - {{::buy.freightValue | currency: 'EUR':2}} - {{::buy.comissionValue | currency: 'EUR':2}} - {{::buy.packageValue | currency: 'EUR':2}} - - - - - {{::buy.price2 | currency: 'EUR':2}} - {{::buy.price3 | currency: 'EUR':2}} - {{::buy.minPrice | currency: 'EUR':2}} - {{::buy.ektFk | dashIfEmpty}} - {{::buy.weight}} - {{::buy.packageFk}} - {{::buy.packingOut}} -
-
-
-
-
+ view-config-id="latestBuys" + options="$ctrl.smartTableOptions" + expr-builder="$ctrl.exprBuilder(param, value)"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Picture + Identifier + + Packing + + Grouping + + Quantity + + Description + + Size + + Tags + + Type + + Intrastat + + Origin + + Density + + Active + + Family + + Entry + + Buying value + + Freight value + + Commission value + + Package value + + Is ignored + + Grouping price + + Packing price + + Min price + + Ekt + + Weight + + Package name + + Packing out +
+ + + + + + + {{::buy.itemFk | zeroFill:6}} + + + + {{::buy.packing | dashIfEmpty}} + + + + {{::buy.grouping | dashIfEmpty}} + + {{::buy.quantity}} + {{::buy.description | dashIfEmpty}} + {{::buy.size}} +
+ {{::buy.name}} + +

{{::buy.subName}}

+
+
+ + +
+ {{::buy.code}} + + {{::buy.intrastat}} + {{::buy.origin}}{{::buy.density}} + + + {{::buy.family}} + + {{::buy.entryFk}} + + {{::buy.buyingValue | currency: 'EUR':2}}{{::buy.freightValue | currency: 'EUR':2}}{{::buy.comissionValue | currency: 'EUR':2}}{{::buy.packageValue | currency: 'EUR':2}} + + + {{::buy.price2 | currency: 'EUR':2}}{{::buy.price3 | currency: 'EUR':2}}{{::buy.minPrice | currency: 'EUR':2}}{{::buy.ektFk | dashIfEmpty}}{{::buy.weight}}{{::buy.packageFk}}{{::buy.packingOut}}
+
+ +
- +
diff --git a/modules/ticket/back/models/packaging.json b/modules/ticket/back/models/packaging.json index 9d5c098dfa..0605ae06ae 100644 --- a/modules/ticket/back/models/packaging.json +++ b/modules/ticket/back/models/packaging.json @@ -9,29 +9,29 @@ "properties": { "id": { "id": true, - "type": "String", + "type": "string", "description": "Identifier" }, "volume": { - "type": "Number" + "type": "number" }, "width": { - "type": "Date" + "type": "date" }, "height": { - "type": "Number" + "type": "number" }, "depth": { - "type": "Number" + "type": "number" }, "isPackageReturnable": { - "type": "Number" + "type": "boolean" }, "created": { - "type": "Date" + "type": "date" }, "price": { - "type": "Number" + "type": "number" } }, "relations": { From 8b31322fa196780376a149924679e0ec3d7a0651 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 11 Nov 2021 10:16:44 +0100 Subject: [PATCH 033/124] fix(contextmenu): exclusion by date range and removed empty or/and arrays --- front/core/components/contextmenu/index.js | 31 ++++++++++++++++++---- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/front/core/components/contextmenu/index.js b/front/core/components/contextmenu/index.js index 9c1206865f..fa1db6887f 100755 --- a/front/core/components/contextmenu/index.js +++ b/front/core/components/contextmenu/index.js @@ -172,12 +172,26 @@ export default class Contextmenu { excludeSelection() { let where = {[this.fieldName]: {neq: this.fieldValue}}; if (this.exprBuilder) { + where = {[this.fieldName]: this.fieldValue}; where = buildFilter(where, (param, value) => { const expr = this.exprBuilder({param, value}); const props = Object.keys(expr); - const newExpr = {}; - for (let prop of props) - newExpr[prop] = {neq: this.fieldValue}; + let newExpr = {}; + for (let prop of props) { + if (expr[prop].like) { + const operator = expr[prop].like; + newExpr[prop] = {nlike: operator}; + } else if (expr[prop].between) { + const operator = expr[prop].between; + newExpr = { + or: [ + {[prop]: {lt: operator[0]}}, + {[prop]: {gt: operator[1]}}, + ] + }; + } else + newExpr[prop] = {neq: this.fieldValue}; + } return newExpr; }); } @@ -213,15 +227,22 @@ export default class Contextmenu { if (prop == findProp) delete instance[prop]; - if (prop === 'and') { - for (let [index, param] of instance[prop].entries()) { + if (prop === 'and' || prop === 'or') { + const instanceCopy = instance[prop].slice(); + for (let param of instanceCopy) { const [key] = Object.keys(param); + const index = instance[prop].findIndex(param => { + return Object.keys(param)[0] == key; + }); if (key == findProp) instance[prop].splice(index, 1); if (param[key] instanceof Array) removeProp(param, filterKey, key); } + + if (instance[prop].length == 0) + delete instance[prop]; } } From 5c7efbb838ff4ac2b103b67ca95208b4df6a14f0 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 11 Nov 2021 10:33:21 +0100 Subject: [PATCH 034/124] feat(item): back filter buyer in search panel ans test --- .../10370-pickles/00-item_getBalance.sql | 4 +- db/dump/fixtures.sql | 2 +- modules/item/back/methods/item/active.js | 42 +++++++++++++++++++ .../item/back/methods/item/activeWithBuyer.js | 31 ++++++++++++++ .../item/specs/activeWithBuyer.spec.js | 14 +++++++ modules/item/back/models/item.js | 2 + modules/item/front/search-panel/index.html | 4 +- 7 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 modules/item/back/methods/item/active.js create mode 100644 modules/item/back/methods/item/activeWithBuyer.js create mode 100644 modules/item/back/methods/item/specs/activeWithBuyer.spec.js diff --git a/db/changes/10370-pickles/00-item_getBalance.sql b/db/changes/10370-pickles/00-item_getBalance.sql index 91e5c36815..90e3ee2bb2 100644 --- a/db/changes/10370-pickles/00-item_getBalance.sql +++ b/db/changes/10370-pickles/00-item_getBalance.sql @@ -1,9 +1,9 @@ -DROP PROCEDURE IF EXISTS vn.item_getBalance; +DROP PROCEDURE IF EXISTS `vn`.`item_getBalance`; DELIMITER $$ $$ CREATE - definer = root@`%` procedure vn.item_getBalance(IN vItemId int, IN vWarehouse int) + definer = root@`%` procedure `vn`.`item_getBalance`(IN vItemId int, IN vWarehouse int) BEGIN DECLARE vDateInventory DATETIME; DECLARE vCurdate DATE DEFAULT CURDATE(); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 49a78ec982..28b8e91818 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -739,7 +739,7 @@ INSERT INTO `vn`.`itemType`(`id`, `code`, `name`, `categoryFk`, `warehouseFk`, ` (3, 'WPN', 'Paniculata', 2, 1, 31, 35, 0), (4, 'PRT', 'Delivery ports', 3, 1, NULL, 35, 1), (5, 'CON', 'Container', 3, 1, NULL, 35, 1), - (6, 'ALS', 'Alstroemeria', 1, 1, 31, 35, 0); + (6, 'ALS', 'Alstroemeria', 1, 1, 31, 16, 0); INSERT INTO `vn`.`ink`(`id`, `name`, `picture`, `showOrder`, `hex`) VALUES diff --git a/modules/item/back/methods/item/active.js b/modules/item/back/methods/item/active.js new file mode 100644 index 0000000000..4537ab9943 --- /dev/null +++ b/modules/item/back/methods/item/active.js @@ -0,0 +1,42 @@ +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; +const buildFilter = require('vn-loopback/util/filter').buildFilter; +const mergeFilters = require('vn-loopback/util/filter').mergeFilters; + +module.exports = Self => { + Self.activeWorkers = async(query, filter) => { + let conn = Self.dataSource.connector; + if (filter.where && filter.where.and && Array.isArray(filter.where.and)) { + let where = {}; + filter.where.and.forEach(element => { + where[Object.keys(element)[0]] = Object.values(element)[0]; + }); + filter.where = where; + } + let clientFilter = Object.assign({}, filter); + clientFilter.where = buildFilter(filter.where, (param, value) => { + switch (param) { + case 'role': + return {'r.name': value}; + case 'firstName': + return {or: [ + {'w.firstName': {like: `%${value}%`}}, + {'w.lastName': {like: `%${value}%`}}, + {'u.name': {like: `%${value}%`}}, + {'u.nickname': {like: `%${value}%`}} + ]}; + case 'id': + return {'w.id': value}; + } + }); + + let myFilter = { + where: {'u.active': true} + }; + + myFilter = mergeFilters(myFilter, clientFilter); + + let stmt = new ParameterizedSQL(query); + stmt.merge(conn.makeSuffix(myFilter)); + return conn.executeStmt(stmt); + }; +}; diff --git a/modules/item/back/methods/item/activeWithBuyer.js b/modules/item/back/methods/item/activeWithBuyer.js new file mode 100644 index 0000000000..ca2c9329d5 --- /dev/null +++ b/modules/item/back/methods/item/activeWithBuyer.js @@ -0,0 +1,31 @@ + +module.exports = Self => { + Self.remoteMethod('activeWithBuyer', { + description: 'Returns active workers in itemType', + accessType: 'READ', + accepts: [{ + arg: 'filter', + type: 'Object', + description: 'Filter defining where and paginated data', + required: false + }], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/activeWithBuyer`, + verb: 'GET' + } + }); + + Self.activeWithBuyer = async filter => { + const query = + `SELECT DISTINCT w.id, w.firstName, w.lastName, u.name, u.nickname + FROM worker w + JOIN itemType i ON i.workerFk = w.id + JOIN account.user u ON u.id = w.id`; + + return Self.activeWorkers(query, filter); + }; +}; diff --git a/modules/item/back/methods/item/specs/activeWithBuyer.spec.js b/modules/item/back/methods/item/specs/activeWithBuyer.spec.js new file mode 100644 index 0000000000..f894e431a8 --- /dev/null +++ b/modules/item/back/methods/item/specs/activeWithBuyer.spec.js @@ -0,0 +1,14 @@ +const models = require('vn-loopback/server/server').models; + +describe('Worker activeWithBuyer', () => { + it('should return the buyers in itemType as result', async() => { + const filter = {}; + const result = await models.Item.activeWithBuyer(filter); + const firstWorker = result[0]; + const secondWorker = result[1]; + + expect(result.length).toEqual(2); + expect(firstWorker.nickname).toEqual('logisticBossNick'); + expect(secondWorker.nickname).toEqual('buyerNick'); + }); +}); diff --git a/modules/item/back/models/item.js b/modules/item/back/models/item.js index 6cf5ba6258..887aa0a116 100644 --- a/modules/item/back/models/item.js +++ b/modules/item/back/models/item.js @@ -14,6 +14,8 @@ module.exports = Self => { require('../methods/item/getWasteByWorker')(Self); require('../methods/item/getWasteByItem')(Self); require('../methods/item/createIntrastat')(Self); + require('../methods/item/active')(Self); + require('../methods/item/activeWithBuyer')(Self); Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'}); diff --git a/modules/item/front/search-panel/index.html b/modules/item/front/search-panel/index.html index 518062ebaf..425df3d4f9 100644 --- a/modules/item/front/search-panel/index.html +++ b/modules/item/front/search-panel/index.html @@ -41,12 +41,10 @@ From f99e0c56487bea48c867ec564d76286c33ae9435 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 11 Nov 2021 10:40:21 +0100 Subject: [PATCH 035/124] Updated default hidden columns --- db/changes/10380-allsaints/00-defaultViewConfig.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/changes/10380-allsaints/00-defaultViewConfig.sql b/db/changes/10380-allsaints/00-defaultViewConfig.sql index f7e29f45fe..440bf98508 100644 --- a/db/changes/10380-allsaints/00-defaultViewConfig.sql +++ b/db/changes/10380-allsaints/00-defaultViewConfig.sql @@ -7,7 +7,7 @@ comment 'The default configuration of columns for views'; INSERT INTO `salix`.`defaultViewConfig` (tableCode, columns) VALUES - ('itemIndex', '{"intrastat":false,"density":false,"stemMultiplier":false,"active":false}'), - ('latestBuys', '{"intrastat":false,"description":false,"density":false,"isActive":false,"freightValue":false,"packageValue":false,"isIgnored":false,"price2":false,"minPrice":false,"ektFk":false,"weight":false,"packageFk":false,"packingOut":false}'); + ('itemsIndex', '{"intrastat":false,"stemMultiplier":false}'), + ('latestBuys', '{"intrastat":false,"description":false,"density":false,"isActive":false,"freightValue":false,"packageValue":false,"isIgnored":false,"price2":false,"minPrice":false,"ektFk":false,"weight":false}'); \ No newline at end of file From 509e002e34e8f5f9b235e55897a65a934c274cd1 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 11 Nov 2021 13:14:34 +0100 Subject: [PATCH 036/124] feat(summary): get email --- modules/invoiceOut/back/methods/invoiceOut/summary.js | 2 +- modules/invoiceOut/front/descriptor-menu/index.html | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/summary.js b/modules/invoiceOut/back/methods/invoiceOut/summary.js index 5a87dd4a30..a95016ff28 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/summary.js +++ b/modules/invoiceOut/back/methods/invoiceOut/summary.js @@ -56,7 +56,7 @@ module.exports = Self => { { relation: 'client', scope: { - fields: ['id', 'socialName'] + fields: ['id', 'socialName', 'email'] } } ] diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index 8daea79005..be1fa7b219 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -110,7 +110,9 @@ Are you sure you want to send it? + label="Email" + ng-model="sendPdfConfirmation.data.email" + required> @@ -127,7 +129,9 @@ Are you sure you want to send it? + label="Email" + ng-model="sendCsvConfirmation.data.email" + required> From dd47f209a2c40176848e3707688c58b2e6945a0e Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 11 Nov 2021 14:46:05 +0100 Subject: [PATCH 037/124] feat(descriptor-menu): handle error empty input --- modules/invoiceOut/front/descriptor-menu/index.html | 6 ++---- modules/invoiceOut/front/descriptor-menu/index.js | 6 ++++++ modules/invoiceOut/front/descriptor-menu/locale/es.yml | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index be1fa7b219..dbfd5fe826 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -111,8 +111,7 @@ Are you sure you want to send it? + ng-model="sendPdfConfirmation.data.email"> @@ -130,8 +129,7 @@ Are you sure you want to send it? + ng-model="sendCsvConfirmation.data.email"> diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index 6f764a3d09..b6e7e02616 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -80,6 +80,9 @@ class Controller extends Section { } sendPdfInvoice($data) { + if (!$data.email) + return this.vnApp.showError(this.$t(`The email can't be empty`)); + return this.vnEmail.send('invoice', { recipientId: this.invoiceOut.client.id, recipient: $data.email, @@ -88,6 +91,9 @@ class Controller extends Section { } sendCsvInvoice($data) { + if (!$data.email) + return this.vnApp.showError(this.$t(`The email can't be empty`)); + return this.vnEmail.sendCsv('invoice', { recipientId: this.invoiceOut.client.id, recipient: $data.email, diff --git a/modules/invoiceOut/front/descriptor-menu/locale/es.yml b/modules/invoiceOut/front/descriptor-menu/locale/es.yml index 8a4a09db19..616fb2fa0d 100644 --- a/modules/invoiceOut/front/descriptor-menu/locale/es.yml +++ b/modules/invoiceOut/front/descriptor-menu/locale/es.yml @@ -17,4 +17,5 @@ Are you sure you want to clone this invoice?: Estas seguro de clonar esta factur InvoiceOut booked: Factura asentada Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura? Regenerate PDF invoice: Regenerar PDF factura -The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado \ No newline at end of file +The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado +The email can't be empty: El correo no puede estar vacío \ No newline at end of file From d2dc0bd14764b888e5b54c3812410cbcc9903c40 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 11 Nov 2021 16:38:41 +0100 Subject: [PATCH 038/124] multi check now behaves properly --- db/changes/10380-allsaints/00-defaultViewConfig.sql | 2 +- front/core/components/multi-check/multi-check.js | 4 ++-- gulpfile.js | 3 ++- modules/entry/front/latest-buys/index.html | 3 ++- modules/entry/front/latest-buys/index.js | 7 ++----- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/db/changes/10380-allsaints/00-defaultViewConfig.sql b/db/changes/10380-allsaints/00-defaultViewConfig.sql index 440bf98508..6530fe2268 100644 --- a/db/changes/10380-allsaints/00-defaultViewConfig.sql +++ b/db/changes/10380-allsaints/00-defaultViewConfig.sql @@ -8,6 +8,6 @@ comment 'The default configuration of columns for views'; INSERT INTO `salix`.`defaultViewConfig` (tableCode, columns) VALUES ('itemsIndex', '{"intrastat":false,"stemMultiplier":false}'), - ('latestBuys', '{"intrastat":false,"description":false,"density":false,"isActive":false,"freightValue":false,"packageValue":false,"isIgnored":false,"price2":false,"minPrice":false,"ektFk":false,"weight":false}'); + ('latestBuys', '{"intrastat":false,"description":false,"density":false,"isActive":false,"freightValue":false,"packageValue":false,"isIgnored":false,"price2":false,"minPrice":true,"ektFk":false,"weight":false,"id":true,"packing":true,"grouping":true,"quantity":true,"size":false,"name":true,"code":true,"origin":true,"family":true,"entryFk":true,"buyingValue":true,"comissionValue":false,"price3":true,"packageFk":true,"packingOut":true}'); \ No newline at end of file diff --git a/front/core/components/multi-check/multi-check.js b/front/core/components/multi-check/multi-check.js index 97b86f03d5..afa1bc3c45 100644 --- a/front/core/components/multi-check/multi-check.js +++ b/front/core/components/multi-check/multi-check.js @@ -145,9 +145,8 @@ export default class MultiCheck extends FormInput { toggle() { const data = this.model.data; if (!data) return; - data.forEach(el => { + for (let el of data) el[this.checkField] = this.checkAll; - }); } } @@ -158,6 +157,7 @@ ngModule.vnComponent('vnMultiCheck', { model: '<', checkField: '@?', checkAll: '=?', + checked: '=?', disabled: ' - - - - - - - - - - @@ -139,21 +139,21 @@ {{::buy.itemFk | zeroFill:6}} - - - + - + - - - - + + + + - - - + + + diff --git a/modules/entry/front/latest-buys/locale/es.yml b/modules/entry/front/latest-buys/locale/es.yml index cb45724f81..21eae03078 100644 --- a/modules/entry/front/latest-buys/locale/es.yml +++ b/modules/entry/front/latest-buys/locale/es.yml @@ -14,4 +14,4 @@ Field to edit: Campo a editar PackageName: Cubo Edit: Editar buy(s): compra(s) -PackingOut: Packing envíos \ No newline at end of file +Package out: Embalaje envíos \ No newline at end of file diff --git a/modules/monitor/front/index/tickets/index.html b/modules/monitor/front/index/tickets/index.html index 04f7f339fe..87fdd407a7 100644 --- a/modules/monitor/front/index/tickets/index.html +++ b/modules/monitor/front/index/tickets/index.html @@ -34,141 +34,180 @@ - - - - Problems - Client - Salesperson - Date - Prep. - Theoretical - Practical - Province - State - Zone - Total - - - - - - - - - - - - - - - - - - - - - - {{::ticket.nickname}} - - - - - {{::ticket.userName | dashIfEmpty}} - - - - - {{::ticket.shipped | date: 'dd/MM/yyyy'}} - - - {{::ticket.shipped | date: 'HH:mm'}} - {{::ticket.zoneLanding | date: 'HH:mm'}} - {{::ticket.practicalHour | date: 'HH:mm'}} - {{::ticket.province}} - - - {{::ticket.refFk}} - - - {{::ticket.state}} - - - - - {{::ticket.zoneName | dashIfEmpty}} - - - - - {{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}} - - - - + +
- diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js index e15d4a16b2..f59b12b5de 100644 --- a/modules/entry/front/latest-buys/index.js +++ b/modules/entry/front/latest-buys/index.js @@ -6,6 +6,7 @@ export default class Controller extends Section { constructor($element, $) { super($element, $); this.editedColumn; + this.$checkAll = false; this.smartTableOptions = { activeButtons: { @@ -130,11 +131,7 @@ export default class Controller extends Section { } uncheck() { - const lines = this.checked; - for (let line of lines) { - if (line.checked) - line.checked = false; - } + this.checkAll = false; } get totalChecked() { From 4fe7d4f566d3224f5e67661c0b197574125aa725 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 11 Nov 2021 17:17:48 +0100 Subject: [PATCH 039/124] ticket index rollback --- modules/ticket/front/index/index.html | 333 ++++++++++++-------------- modules/ticket/front/index/index.js | 51 +--- modules/ticket/front/index/style.scss | 12 +- 3 files changed, 157 insertions(+), 239 deletions(-) diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index a1c34c43b6..63b0b049d1 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -1,187 +1,155 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - #ID - - Salesperson - - Date - - Hour - - Closure - - Alias - - Province - - State - - Zone - - Warehouse - - Total -
- - - - - - - - - - - - - - - - {{::ticket.id}} - - {{::ticket.userName | dashIfEmpty}} - - - - {{::ticket.shipped | date: 'dd/MM/yyyy'}} - - {{::ticket.shipped | date: 'HH:mm'}}{{::ticket.zoneLanding | date: 'HH:mm'}} - - {{::ticket.nickname}} - - {{::ticket.province}} - - {{::ticket.refFk}} - - - {{ticket.state}} - - - - {{::ticket.zoneName | dashIfEmpty}} - - {{::ticket.warehouse}} - - {{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}} - - - - - - -
-
-
-
+ + + + + + + + + + + Id + Salesperson + Date + Hour + Closure + Alias + Province + State + Zone + Warehouse + Total + + + + + + + + + + + + + + + + + + + + + + + + {{::ticket.id}} + + + {{::ticket.userName | dashIfEmpty}} + + + + + {{::ticket.shipped | date: 'dd/MM/yyyy'}} + + + {{::ticket.shipped | date: 'HH:mm'}} + {{::ticket.zoneLanding | date: 'HH:mm'}} + + + {{::ticket.nickname}} + + + {{::ticket.province}} + + + {{::ticket.refFk}} + + + {{ticket.state}} + + + + + {{::ticket.zoneName | dashIfEmpty}} + + + {{::ticket.warehouse}} + + + {{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}} + + + + + + + + + + + + +
- - vn-icon { + vn-td.icon-field > vn-icon { margin-left: 3px; margin-right: 3px; } - tbody a[ng-repeat].vn-tr:focus { + vn-tbody a[ng-repeat].vn-tr:focus { background-color: $color-primary-light } } \ No newline at end of file From acd2d2e51f12b5b4381f4ca5719268125867a252 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 11 Nov 2021 17:18:19 +0100 Subject: [PATCH 040/124] front unit tests fix for lastests buys --- modules/entry/front/buy/import/index.spec.js | 74 ++++++++++++++++--- modules/entry/front/latest-buys/index.js | 2 +- modules/entry/front/latest-buys/index.spec.js | 42 ++--------- 3 files changed, 72 insertions(+), 46 deletions(-) diff --git a/modules/entry/front/buy/import/index.spec.js b/modules/entry/front/buy/import/index.spec.js index c948304c77..bf100dc83f 100644 --- a/modules/entry/front/buy/import/index.spec.js +++ b/modules/entry/front/buy/import/index.spec.js @@ -63,8 +63,21 @@ describe('Entry', () => { } ]}`; const expectedBuys = [ - {'buyingValue': 5.77, 'description': 'Bow', 'grouping': 1, 'packing': 1, 'size': 1, 'volume': 1200}, - {'buyingValue': 2.16, 'description': 'Arrow', 'grouping': 1, 'packing': 1, 'size': 25, 'volume': 1125} + { + 'buyingValue': 5.77, + 'description': 'Bow', + 'grouping': 1, + 'packing': 1, + 'size': 1, + 'volume': 1200}, + + { + 'buyingValue': 2.16, + 'description': 'Arrow', + 'grouping': 1, + 'packing': 1, + 'size': 25, + 'volume': 1125} ]; controller.fillData(rawData); controller.$.$apply(); @@ -81,8 +94,21 @@ describe('Entry', () => { describe('fetchBuys()', () => { it(`should perform a query to fetch the buys data`, () => { const buys = [ - {'buyingValue': 5.77, 'description': 'Bow', 'grouping': 1, 'packing': 1, 'size': 1, 'volume': 1200}, - {'buyingValue': 2.16, 'description': 'Arrow', 'grouping': 1, 'packing': 1, 'size': 25, 'volume': 1125} + { + 'buyingValue': 5.77, + 'description': 'Bow', + 'grouping': 1, + 'packing': 1, + 'size': 1, + 'volume': 1200}, + + { + 'buyingValue': 2.16, + 'description': 'Arrow', + 'grouping': 1, + 'packing': 1, + 'size': 25, + 'volume': 1125} ]; const serializedParams = $httpParamSerializer({buys}); @@ -105,17 +131,31 @@ describe('Entry', () => { observation: '123456', ref: '1, 2', buys: [ - {'buyingValue': 5.77, 'description': 'Bow', 'grouping': 1, 'packing': 1, 'size': 1, 'volume': 1200}, - {'buyingValue': 2.16, 'description': 'Arrow', 'grouping': 1, 'packing': 1, 'size': 25, 'volume': 1125} + { + 'buyingValue': 5.77, + 'description': 'Bow', + 'grouping': 1, + 'packing': 1, + 'size': 1, + 'volume': 1200}, + { + 'buyingValue': 2.16, + 'description': 'Arrow', + 'grouping': 1, + 'packing': 1, + 'size': 25, + 'volume': 1125} ] }; controller.onSubmit(); - expect(controller.vnApp.showError).toHaveBeenCalledWith(`Some of the imported buys doesn't have an item`); + const message = `Some of the imported buys doesn't have an item`; + + expect(controller.vnApp.showError).toHaveBeenCalledWith(message); }); - it(`should perform a query to update columns`, () => { + it(`should now perform a query to update columns`, () => { jest.spyOn(controller.vnApp, 'showSuccess'); controller.$state.go = jest.fn(); @@ -123,8 +163,22 @@ describe('Entry', () => { observation: '123456', ref: '1, 2', buys: [ - {'itemFk': 10, 'buyingValue': 5.77, 'description': 'Bow', 'grouping': 1, 'packing': 1, 'size': 1, 'volume': 1200}, - {'itemFk': 11, 'buyingValue': 2.16, 'description': 'Arrow', 'grouping': 1, 'packing': 1, 'size': 25, 'volume': 1125} + { + 'itemFk': 10, + 'buyingValue': 5.77, + 'description': 'Bow', + 'grouping': 1, + 'packing': 1, + 'size': 1, + 'volume': 1200}, + { + 'itemFk': 11, + 'buyingValue': 2.16, + 'description': 'Arrow', + 'grouping': 1, + 'packing': 1, + 'size': 25, + 'volume': 1125} ] }; const params = controller.import; diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js index f59b12b5de..e899c50fad 100644 --- a/modules/entry/front/latest-buys/index.js +++ b/modules/entry/front/latest-buys/index.js @@ -143,7 +143,7 @@ export default class Controller extends Section { for (let row of this.checked) rowsToEdit.push({id: row.id, itemFk: row.itemFk}); - let data = { + const data = { field: this.editedColumn.field, newValue: this.editedColumn.newValue, lines: rowsToEdit diff --git a/modules/entry/front/latest-buys/index.spec.js b/modules/entry/front/latest-buys/index.spec.js index 6f86650c9d..e9392a7972 100644 --- a/modules/entry/front/latest-buys/index.spec.js +++ b/modules/entry/front/latest-buys/index.spec.js @@ -7,9 +7,9 @@ describe('Entry', () => { beforeEach(ngModule('entry')); - beforeEach(angular.mock.inject(($componentController, $compile, $rootScope, _$httpBackend_) => { + beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => { $httpBackend = _$httpBackend_; - let $element = $compile(' {}}, @@ -31,10 +31,10 @@ describe('Entry', () => { describe('get checked', () => { it(`should return a set of checked lines`, () => { controller.$.model.data = [ - {checked: true, id: 1}, - {checked: true, id: 2}, - {checked: true, id: 3}, - {checked: false, id: 4}, + {$checked: true, id: 1}, + {$checked: true, id: 2}, + {$checked: true, id: 3}, + {$checked: false, id: 4}, ]; let result = controller.checked; @@ -43,38 +43,10 @@ describe('Entry', () => { }); }); - describe('uncheck()', () => { - it(`should clear the selection of lines on the controller`, () => { - controller.$.model.data = [ - {checked: true, id: 1}, - {checked: true, id: 2}, - {checked: true, id: 3}, - {checked: false, id: 4}, - ]; - - let result = controller.checked; - - expect(result.length).toEqual(3); - - controller.uncheck(); - - result = controller.checked; - - expect(result.length).toEqual(0); - }); - }); - describe('onEditAccept()', () => { it(`should perform a query to update columns`, () => { - $httpBackend.whenGET('UserConfigViews/getConfig?tableCode=latestBuys').respond([]); - $httpBackend.whenGET('Buys/latestBuysFilter?filter=%7B%22limit%22:20%7D').respond([ - {entryFk: 1}, - {entryFk: 2}, - {entryFk: 3}, - {entryFk: 4} - ]); controller.editedColumn = {field: 'my field', newValue: 'the new value'}; - let query = 'Buys/editLatestBuys'; + const query = 'Buys/editLatestBuys'; $httpBackend.expectPOST(query).respond(); controller.onEditAccept(); From 04da06d778cdef5fc27be2df0c40977c44573291 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 11 Nov 2021 17:18:44 +0100 Subject: [PATCH 041/124] refactor(smart-table): style changes and added smart-table to sales monitor --- front/core/components/smart-table/index.html | 28 +- front/core/components/smart-table/index.js | 13 + .../core/components/smart-table/locale/es.yml | 3 +- front/core/components/smart-table/style.scss | 62 +++- front/core/components/smart-table/table.scss | 9 +- modules/entry/front/latest-buys/index.html | 52 +-- modules/entry/front/latest-buys/locale/es.yml | 2 +- .../monitor/front/index/tickets/index.html | 307 ++++++++++-------- modules/monitor/front/index/tickets/index.js | 55 ++++ 9 files changed, 346 insertions(+), 185 deletions(-) diff --git a/front/core/components/smart-table/index.html b/front/core/components/smart-table/index.html index 9cfcf78496..8051502a7f 100644 --- a/front/core/components/smart-table/index.html +++ b/front/core/components/smart-table/index.html @@ -7,15 +7,12 @@ vn-tooltip="Shown columns">
-
- < - Showing - {{model.data.length}} - results - > -
+
+ {{model.data.length}} + results +
-
-
Check the columns you want to see
+
+ +
Shown columns
+ +
+
+ + +
+ { diff --git a/front/core/components/smart-table/locale/es.yml b/front/core/components/smart-table/locale/es.yml index f65df07b7d..422871fbfb 100644 --- a/front/core/components/smart-table/locale/es.yml +++ b/front/core/components/smart-table/locale/es.yml @@ -5,4 +5,5 @@ Save data: Guardar datos Shown columns: Columnas visibles Check the columns you want to see: Marca las columnas que quieres ver Showing: Mostrando -results: resultados \ No newline at end of file +results: resultados +Tick all: Marcar todas \ No newline at end of file diff --git a/front/core/components/smart-table/style.scss b/front/core/components/smart-table/style.scss index ed6b6d41ff..6b973c5b06 100644 --- a/front/core/components/smart-table/style.scss +++ b/front/core/components/smart-table/style.scss @@ -5,6 +5,51 @@ smart-table { th[field] { overflow: visible; cursor: pointer; + align-items: center; + + & > * { + display: flex + } + } + th[field][number] { + & > :before { + display: flex; + font-family: 'Material Icons'; + content: 'arrow_downward'; + color: $color-spacer; + margin: 2px 2px 0 0; + opacity: 0 + + } + + &.asc > :before, &.desc > :before { + color: $color-font; + opacity: 1; + } + + &.asc > :before { + content: 'arrow_upward'; + } + + &.desc > :before { + content: 'arrow_downward'; + } + + &:hover > :before { + opacity: 1; + } + } + + th[field]:not([number]) { + & > :after { + display: flex; + font-family: 'Material Icons'; + content: 'arrow_downward'; + color: $color-spacer; + margin: 2px 0 0 2px; + opacity: 0 + + } &.asc > :after, &.desc > :after { color: $color-font; @@ -12,23 +57,13 @@ smart-table { } &.asc > :after { - content: 'arrow_drop_up'; + content: 'arrow_upward'; } &.desc > :after { - content: 'arrow_drop_down'; + content: 'arrow_downward'; } - & > :after { - font-family: 'Material Icons'; - content: 'arrow_drop_down'; - position: absolute; - color: $color-spacer; - font-size: 1.5em; - margin-top: -2px; - opacity: 0 - - } &:hover > :after { opacity: 1; } @@ -81,6 +116,7 @@ smart-table { #table { overflow-x: auto; + margin-top: 15px } vn-tbody a[ng-repeat].vn-tr:focus { @@ -108,6 +144,6 @@ smart-table { vn-check { flex: initial; - width: 50% + width: 33% } } \ No newline at end of file diff --git a/front/core/components/smart-table/table.scss b/front/core/components/smart-table/table.scss index 377c3bf8ea..d3b9fa9909 100644 --- a/front/core/components/smart-table/table.scss +++ b/front/core/components/smart-table/table.scss @@ -35,7 +35,7 @@ smart-table table { text-align: right; width: 96px; } - &[center] { + &[centered] { text-align: center; } &[shrink] { @@ -54,6 +54,13 @@ smart-table table { max-width: 400px; min-width: 0; } + &[actions] { + width: 1px; + + & > * { + vertical-align: middle; + } + } vn-icon.bright, i.bright { color: #f7931e; } diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html index ce1dcbaa01..61f4ce6fc9 100644 --- a/modules/entry/front/latest-buys/index.html +++ b/modules/entry/front/latest-buys/index.html @@ -36,13 +36,13 @@
Identifier + Packing + Grouping + Quantity @@ -75,29 +75,29 @@ Entry + Buying value + Freight value + Commission value + Package value Is ignored - Grouping price + + Grouping - Packing price + + Packing - Min price + + Min Ekt @@ -106,10 +106,10 @@ Weight - Package name + Package - Packing out + Package out
+ {{::buy.packing | dashIfEmpty}} + {{::buy.grouping | dashIfEmpty}} {{::buy.quantity}}{{::buy.quantity}} {{::buy.description | dashIfEmpty}} {{::buy.size}}{{::buy.size}}
{{::buy.name}} @@ -189,19 +189,19 @@ {{::buy.entryFk}}
{{::buy.buyingValue | currency: 'EUR':2}}{{::buy.freightValue | currency: 'EUR':2}}{{::buy.comissionValue | currency: 'EUR':2}}{{::buy.packageValue | currency: 'EUR':2}}{{::buy.buyingValue | currency: 'EUR':2}}{{::buy.freightValue | currency: 'EUR':2}}{{::buy.comissionValue | currency: 'EUR':2}}{{::buy.packageValue | currency: 'EUR':2}} {{::buy.price2 | currency: 'EUR':2}}{{::buy.price3 | currency: 'EUR':2}}{{::buy.minPrice | currency: 'EUR':2}}{{::buy.price2 | currency: 'EUR':2}}{{::buy.price3 | currency: 'EUR':2}}{{::buy.minPrice | currency: 'EUR':2}} {{::buy.ektFk | dashIfEmpty}} {{::buy.weight}} {{::buy.packageFk}}
+ + + + + + + + + + + + + + + + + + + - - - - - - - - - + }"> + + + + + + + + + + + + + + + +
+ Problems + + Identifier + + Client + + Salesperson + + Date + + Preparation + + Theoretical + + Practical + + Province + + State + + Zone + + Total +
+ + + + + + + + + + + + + + + {{::ticket.id}} + + + + {{::ticket.nickname}} + + + + {{::ticket.userName | dashIfEmpty}} + + + + {{::ticket.shipped | date: 'dd/MM/yyyy'}} + + {{::ticket.shipped | date: 'HH:mm'}}{{::ticket.zoneLanding | date: 'HH:mm'}}{{::ticket.practicalHour | date: 'HH:mm'}}{{::ticket.province}} + + {{::ticket.refFk}} + + + {{::ticket.state}} + + + + {{::ticket.zoneName | dashIfEmpty}} + + + + {{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}} + + + + + + +
+
+ @@ -185,7 +224,7 @@ model="model"> - Date: Fri, 12 Nov 2021 08:32:15 +0100 Subject: [PATCH 042/124] refactor(descriptor): separate es.yml --- .../front/descriptor-menu/locale/es.yml | 4 ---- .../invoiceOut/front/descriptor/locale/es.yml | 20 +------------------ 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/modules/invoiceOut/front/descriptor-menu/locale/es.yml b/modules/invoiceOut/front/descriptor-menu/locale/es.yml index 616fb2fa0d..01e58633b8 100644 --- a/modules/invoiceOut/front/descriptor-menu/locale/es.yml +++ b/modules/invoiceOut/front/descriptor-menu/locale/es.yml @@ -1,7 +1,3 @@ -Volume exceded: Volumen excedido -Volume: Volumen -Client card: Ficha del cliente -Invoice ticket list: Listado de tickets de la factura Show invoice...: Ver factura... Send invoice...: Enviar factura... Send PDF invoice: Enviar factura en PDF diff --git a/modules/invoiceOut/front/descriptor/locale/es.yml b/modules/invoiceOut/front/descriptor/locale/es.yml index 8a4a09db19..0e88a7dc7a 100644 --- a/modules/invoiceOut/front/descriptor/locale/es.yml +++ b/modules/invoiceOut/front/descriptor/locale/es.yml @@ -1,20 +1,2 @@ -Volume exceded: Volumen excedido -Volume: Volumen Client card: Ficha del cliente -Invoice ticket list: Listado de tickets de la factura -Show invoice...: Ver factura... -Send invoice...: Enviar factura... -Send PDF invoice: Enviar factura en PDF -Send CSV invoice: Enviar factura en CSV -Delete Invoice: Eliminar factura -Clone Invoice: Clonar factura -Book invoice: Asentar factura -Generate PDF invoice: Generar PDF factura -Show CIES letter: Ver carta CIES -InvoiceOut deleted: Factura eliminada -Are you sure you want to delete this invoice?: Estas seguro de eliminar esta factura? -Are you sure you want to clone this invoice?: Estas seguro de clonar esta factura? -InvoiceOut booked: Factura asentada -Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura? -Regenerate PDF invoice: Regenerar PDF factura -The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado \ No newline at end of file +Invoice ticket list: Listado de tickets de la factura \ No newline at end of file From 6fe7875d73d2dbf0d2496629e7d9e250aa7d61f7 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 12 Nov 2021 09:28:19 +0100 Subject: [PATCH 043/124] change route --- modules/item/front/diary/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/item/front/diary/index.html b/modules/item/front/diary/index.html index 2f5bce1973..0f00f58546 100644 --- a/modules/item/front/diary/index.html +++ b/modules/item/front/diary/index.html @@ -50,7 +50,7 @@ on-last="$ctrl.scrollToLine(sale.lastPreparedLineFk)" ng-attr-id="vnItemDiary-{{::sale.lineFk}}"> - + From ab7e1c9f110c0c9623990ba149d20c3981c1f5ae Mon Sep 17 00:00:00 2001 From: carlosjr Date: Fri, 12 Nov 2021 10:21:54 +0100 Subject: [PATCH 044/124] item summary e2e fix --- e2e/helpers/selectors.js | 4 ++-- e2e/paths/04-item/01_summary.spec.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index d4d5d33aaa..3860ecc254 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -313,8 +313,8 @@ export default { itemsIndex: { createItemButton: `vn-float-button`, firstSearchResult: 'vn-item-index a:nth-child(1)', - searchResult: 'vn-item-index a.vn-tr', - firstResultPreviewButton: 'vn-item-index vn-tbody > :nth-child(1) .buttons > [icon="preview"]', + searchResult: 'vn-item-index tbody tr', + firstResultPreviewButton: 'vn-item-index tbody > :nth-child(1) .buttons > [icon="preview"]', searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]', acceptClonationAlertButton: '.vn-confirm.shown [response="accept"]', closeItemSummaryPreview: '.vn-popup.shown', diff --git a/e2e/paths/04-item/01_summary.spec.js b/e2e/paths/04-item/01_summary.spec.js index a7526accb5..e24fa6a9f1 100644 --- a/e2e/paths/04-item/01_summary.spec.js +++ b/e2e/paths/04-item/01_summary.spec.js @@ -16,13 +16,13 @@ describe('Item summary path', () => { it('should search for an item', async() => { await page.doSearch('Ranged weapon'); - const nResults = await page.countElement(selectors.itemsIndex.searchResult); + const resultsCount = await page.countElement(selectors.itemsIndex.searchResult); await page.waitForTextInElement(selectors.itemsIndex.searchResult, 'Ranged weapon'); await page.waitToClick(selectors.itemsIndex.firstResultPreviewButton); const isVisible = await page.isVisible(selectors.itemSummary.basicData); - expect(nResults).toBe(3); + expect(resultsCount).toBe(3); expect(isVisible).toBeTruthy(); }); @@ -61,12 +61,12 @@ describe('Item summary path', () => { it('should search for other item', async() => { await page.doSearch('Melee Reinforced'); - const nResults = await page.countElement(selectors.itemsIndex.searchResult); + const resultsCount = await page.countElement(selectors.itemsIndex.searchResult); await page.waitToClick(selectors.itemsIndex.firstResultPreviewButton); await page.waitForSelector(selectors.itemSummary.basicData, {visible: true}); - expect(nResults).toBe(2); + expect(resultsCount).toBe(2); }); it(`should now check the item summary preview shows fields from basic data`, async() => { From 62e03f4752ca3dc55ef12138ff0d19175c8d871d Mon Sep 17 00:00:00 2001 From: carlosjr Date: Fri, 12 Nov 2021 11:03:23 +0100 Subject: [PATCH 045/124] item create e2e fix --- e2e/helpers/selectors.js | 2 +- e2e/paths/04-item/07_create.spec.js | 71 ++++++++++++ e2e/paths/04-item/07_create_and_clone.spec.js | 105 ------------------ front/core/components/smart-table/index.js | 3 +- modules/item/front/last-entries/index.html | 1 - 5 files changed, 74 insertions(+), 108 deletions(-) create mode 100644 e2e/paths/04-item/07_create.spec.js delete mode 100644 e2e/paths/04-item/07_create_and_clone.spec.js diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 3860ecc254..a97f20a006 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -313,7 +313,7 @@ export default { itemsIndex: { createItemButton: `vn-float-button`, firstSearchResult: 'vn-item-index a:nth-child(1)', - searchResult: 'vn-item-index tbody tr', + searchResult: 'vn-item-index tbody tr td:not(.empty-rows)', firstResultPreviewButton: 'vn-item-index tbody > :nth-child(1) .buttons > [icon="preview"]', searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]', acceptClonationAlertButton: '.vn-confirm.shown [response="accept"]', diff --git a/e2e/paths/04-item/07_create.spec.js b/e2e/paths/04-item/07_create.spec.js new file mode 100644 index 0000000000..0820f2db70 --- /dev/null +++ b/e2e/paths/04-item/07_create.spec.js @@ -0,0 +1,71 @@ +import selectors from '../../helpers/selectors.js'; +import getBrowser from '../../helpers/puppeteer'; + +describe('Item Create', () => { + let browser; + let page; + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + await page.loginAndModule('buyer', 'item'); + }); + + afterAll(async() => { + await browser.close(); + }); + + it(`should search for the item Infinity Gauntlet to confirm it isn't created yet`, async() => { + await page.doSearch('Infinity Gauntlet'); + const resultsCount = await page.countElement(selectors.itemsIndex.searchResult); + + expect(resultsCount).toEqual(0); + }); + + it('should access to the create item view by clicking the create floating button', async() => { + await page.waitToClick(selectors.itemsIndex.createItemButton); + await page.waitForState('item.create'); + }); + + it('should return to the item index by clickig the cancel button', async() => { + await page.waitToClick(selectors.itemCreateView.cancelButton); + await page.waitForState('item.index'); + }); + + it('should now access to the create item view by clicking the create floating button', async() => { + await page.waitToClick(selectors.itemsIndex.createItemButton); + await page.waitForState('item.create'); + }); + + it('should create the Infinity Gauntlet item', async() => { + await page.write(selectors.itemCreateView.temporalName, 'Infinity Gauntlet'); + await page.autocompleteSearch(selectors.itemCreateView.type, 'Crisantemo'); + await page.autocompleteSearch(selectors.itemCreateView.intrastat, 'Coral y materiales similares'); + await page.autocompleteSearch(selectors.itemCreateView.origin, 'Holand'); + await page.waitToClick(selectors.itemCreateView.createButton); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain('Data saved!'); + }); + + it('should confirm Infinity Gauntlet item was created', async() => { + let result = await page + .waitToGetProperty(selectors.itemBasicData.name, 'value'); + + expect(result).toEqual('Infinity Gauntlet'); + + result = await page + .waitToGetProperty(selectors.itemBasicData.type, 'value'); + + expect(result).toEqual('Crisantemo'); + + result = await page + .waitToGetProperty(selectors.itemBasicData.intrastat, 'value'); + + expect(result).toEqual('5080000 Coral y materiales similares'); + + result = await page + .waitToGetProperty(selectors.itemBasicData.origin, 'value'); + + expect(result).toEqual('Holand'); + }); +}); diff --git a/e2e/paths/04-item/07_create_and_clone.spec.js b/e2e/paths/04-item/07_create_and_clone.spec.js deleted file mode 100644 index 938f15e3f9..0000000000 --- a/e2e/paths/04-item/07_create_and_clone.spec.js +++ /dev/null @@ -1,105 +0,0 @@ -import selectors from '../../helpers/selectors.js'; -import getBrowser from '../../helpers/puppeteer'; - -describe('Item Create/Clone path', () => { - let browser; - let page; - beforeAll(async() => { - browser = await getBrowser(); - page = browser.page; - await page.loginAndModule('buyer', 'item'); - }); - - afterAll(async() => { - await browser.close(); - }); - - describe('create', () => { - it(`should search for the item Infinity Gauntlet to confirm it isn't created yet`, async() => { - await page.doSearch('Infinity Gauntlet'); - const nResults = await page.countElement(selectors.itemsIndex.searchResult); - - expect(nResults).toEqual(0); - }); - - it('should access to the create item view by clicking the create floating button', async() => { - await page.waitToClick(selectors.itemsIndex.createItemButton); - await page.waitForState('item.create'); - }); - - it('should return to the item index by clickig the cancel button', async() => { - await page.waitToClick(selectors.itemCreateView.cancelButton); - await page.waitForState('item.index'); - }); - - it('should now access to the create item view by clicking the create floating button', async() => { - await page.waitToClick(selectors.itemsIndex.createItemButton); - await page.waitForState('item.create'); - }); - - it('should create the Infinity Gauntlet item', async() => { - await page.write(selectors.itemCreateView.temporalName, 'Infinity Gauntlet'); - await page.autocompleteSearch(selectors.itemCreateView.type, 'Crisantemo'); - await page.autocompleteSearch(selectors.itemCreateView.intrastat, 'Coral y materiales similares'); - await page.autocompleteSearch(selectors.itemCreateView.origin, 'Holand'); - await page.waitToClick(selectors.itemCreateView.createButton); - const message = await page.waitForSnackbar(); - - expect(message.text).toContain('Data saved!'); - }); - - it('should confirm Infinity Gauntlet item was created', async() => { - let result = await page - .waitToGetProperty(selectors.itemBasicData.name, 'value'); - - expect(result).toEqual('Infinity Gauntlet'); - - result = await page - .waitToGetProperty(selectors.itemBasicData.type, 'value'); - - expect(result).toEqual('Crisantemo'); - - result = await page - .waitToGetProperty(selectors.itemBasicData.intrastat, 'value'); - - expect(result).toEqual('5080000 Coral y materiales similares'); - - result = await page - .waitToGetProperty(selectors.itemBasicData.origin, 'value'); - - expect(result).toEqual('Holand'); - }); - }); - - // Issue #2201 - // When there is just one result you're redirected automatically to it, so - // it's not possible to use the clone option. - xdescribe('clone', () => { - it('should return to the items index by clicking the return to items button', async() => { - await page.waitToClick(selectors.itemBasicData.goToItemIndexButton); - await page.waitForSelector(selectors.itemsIndex.createItemButton); - await page.waitForState('item.index'); - }); - - it(`should search for the item Infinity Gauntlet`, async() => { - await page.doSearch('Infinity Gauntlet'); - const nResults = await page.countElement(selectors.itemsIndex.searchResult); - - expect(nResults).toEqual(1); - }); - - it(`should clone the Infinity Gauntlet`, async() => { - await page.waitForTextInElement(selectors.itemsIndex.searchResult, 'Infinity Gauntlet'); - await page.waitToClick(selectors.itemsIndex.searchResultCloneButton); - await page.waitToClick(selectors.itemsIndex.acceptClonationAlertButton); - await page.waitForState('item.tags'); - }); - - it('should search for the item Infinity Gauntlet and find two', async() => { - await page.doSearch('Infinity Gauntlet'); - const nResults = await page.countElement(selectors.itemsIndex.searchResult); - - expect(nResults).toEqual(2); - }); - }); -}); diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index 89a50bb271..d93d704dd2 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -160,7 +160,7 @@ export default class SmartTable extends Component { } } - const styleElement = document.querySelector('style[id="smart-table"]'); + let styleElement = document.querySelector('style[id="smart-table"]'); if (styleElement) styleElement.parentNode.removeChild(styleElement); @@ -174,6 +174,7 @@ export default class SmartTable extends Component { } this.$.$on('$destroy', () => { + styleElement = document.querySelector('style[id="smart-table"]'); if (this.$.css && styleElement) styleElement.parentNode.removeChild(styleElement); }); diff --git a/modules/item/front/last-entries/index.html b/modules/item/front/last-entries/index.html index af7bbd751b..29047c6131 100644 --- a/modules/item/front/last-entries/index.html +++ b/modules/item/front/last-entries/index.html @@ -23,7 +23,6 @@ - From 259c192c8b70c7f39f27f3d1c951d5e6fbabee35 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Fri, 12 Nov 2021 11:33:34 +0100 Subject: [PATCH 046/124] empty rows class moved to the tr from td --- e2e/helpers/selectors.js | 4 ++-- front/core/components/smart-table/index.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index a97f20a006..9705df60ad 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -312,8 +312,8 @@ export default { }, itemsIndex: { createItemButton: `vn-float-button`, - firstSearchResult: 'vn-item-index a:nth-child(1)', - searchResult: 'vn-item-index tbody tr td:not(.empty-rows)', + firstSearchResult: 'vn-item-index tr:nth-child(2)', + searchResult: 'vn-item-index tbody tr:not(.empty-rows)', firstResultPreviewButton: 'vn-item-index tbody > :nth-child(1) .buttons > [icon="preview"]', searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]', acceptClonationAlertButton: '.vn-confirm.shown [response="accept"]', diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index d93d704dd2..32a66f9bc0 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -122,15 +122,15 @@ export default class SmartTable extends Component { const tbody = this.element.querySelector('tbody'); if (tbody) { const noSearch = this.$compile(` - - Enter a new search + + Enter a new search `)($scope); tbody.appendChild(noSearch[0]); const noRows = this.$compile(` - - No data + + No data `)($scope); tbody.appendChild(noRows[0]); From 3a655d393bb81c1e51363ee67f205eafad6aa2c9 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 12 Nov 2021 12:13:50 +0100 Subject: [PATCH 047/124] Remove search inputs scope on element removal --- front/core/components/smart-table/index.js | 32 ++++++++++++---------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index 89a50bb271..700171609e 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -12,12 +12,18 @@ export default class SmartTable extends Component { this.currentUserId = window.localStorage.currentUserWorkerId; this.$transclude = $transclude; this.sortCriteria = []; + this.$inputScopes = []; this.columns = []; this.autoSave = false; - this.transclude(); } + $onDestroy() { + const styleElement = document.querySelector('style[id="smart-table"]'); + if (this.$.css && styleElement) + styleElement.parentNode.removeChild(styleElement); + } + get options() { return this._options; } @@ -172,11 +178,6 @@ export default class SmartTable extends Component { document.head.appendChild(this.$.css); this.$.css.appendChild(document.createTextNode(rule)); } - - this.$.$on('$destroy', () => { - if (this.$.css && styleElement) - styleElement.parentNode.removeChild(styleElement); - }); } registerColumns() { @@ -238,7 +239,13 @@ export default class SmartTable extends Component { const columns = header.querySelectorAll('th'); const hasSearchRow = tbody.querySelector('tr#searchRow'); - if (hasSearchRow) return hasSearchRow.remove(); + if (hasSearchRow) { + if (this.$inputScopes) { + for (let $inputScope of this.$inputScopes) + $inputScope.$destroy(); + } + return hasSearchRow.remove(); + } const searchRow = document.createElement('tr'); searchRow.setAttribute('id', 'searchRow'); @@ -258,13 +265,13 @@ export default class SmartTable extends Component { continue; } + const $inputScope = this.$.$new(); if (options && options.autocomplete) { let props = ``; const autocomplete = options.autocomplete; for (const prop in autocomplete) props += `${camelToKebab(prop)}="${autocomplete[prop]}"\n`; - input = this.$compile(` `)(this.$); + />`)($inputScope); } else { input = this.$compile(` `)(this.$); + />`)($inputScope); } + this.$inputScopes.push($inputScope); cell.appendChild(input[0]); } searchRow.appendChild(cell); @@ -406,10 +414,6 @@ export default class SmartTable extends Component { this.model.save() .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); } - - hasChanges() { - return true; - } } SmartTable.$inject = ['$element', '$scope', '$transclude']; From 5faef913ebc9e319fe85c001d9d6ef3a807ddfb3 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 12 Nov 2021 13:10:11 +0100 Subject: [PATCH 048/124] feat(client): add field businessTypeFk and modify her tests --- e2e/helpers/selectors.js | 1 + e2e/paths/02-client/01_create_client.spec.js | 32 +++++++++++++------ .../back/methods/client/createWithUser.js | 3 +- .../client/specs/createWithUser.spec.js | 4 ++- modules/client/back/models/client.json | 7 ++++ modules/client/front/create/index.html | 10 +++++- 6 files changed, 44 insertions(+), 13 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index d4d5d33aaa..d3e4da99a0 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -119,6 +119,7 @@ export default { name: 'vn-client-create vn-textfield[ng-model="$ctrl.client.name"]', taxNumber: 'vn-client-create vn-textfield[ng-model="$ctrl.client.fi"]', socialName: 'vn-client-create vn-textfield[ng-model="$ctrl.client.socialName"]', + businessType: 'vn-client-create vn-autocomplete[ng-model="$ctrl.client.businessTypeFk"]', street: 'vn-client-create vn-textfield[ng-model="$ctrl.client.street"]', addPostCode: 'vn-client-create vn-datalist[ng-model="$ctrl.client.postcode"] vn-icon-button[icon="add_circle"]', addProvince: 'vn-autocomplete[ng-model="$ctrl.location.provinceFk"] vn-icon-button[icon="add_circle"]', diff --git a/e2e/paths/02-client/01_create_client.spec.js b/e2e/paths/02-client/01_create_client.spec.js index 5860eca49d..698e782cde 100644 --- a/e2e/paths/02-client/01_create_client.spec.js +++ b/e2e/paths/02-client/01_create_client.spec.js @@ -27,16 +27,18 @@ describe('Client create path', () => { await page.waitForState('client.create'); }); - it('should receive an error when clicking the create button having name and Business name fields empty', async() => { - await page.write(selectors.createClientView.taxNumber, '74451390E'); - await page.write(selectors.createClientView.userName, 'CaptainMarvel'); - await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es'); - await page.autocompleteSearch(selectors.createClientView.salesPerson, 'salesPerson'); - await page.waitToClick(selectors.createClientView.createButton); - const message = await page.waitForSnackbar(); + it('should receive an error when clicking the create button having name and Business name fields empty', + async() => { + await page.write(selectors.createClientView.taxNumber, '74451390E'); + await page.write(selectors.createClientView.userName, 'CaptainMarvel'); + await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es'); + await page.autocompleteSearch(selectors.createClientView.salesPerson, 'salesPerson'); + await page.waitToClick(selectors.createClientView.createButton); + const message = await page.waitForSnackbar(); - expect(message.text).toContain('Some fields are invalid'); - }); + expect(message.text).toContain('Some fields are invalid'); + } + ); it(`should create a new province`, async() => { await page.waitToClick(selectors.createClientView.addPostCode); @@ -72,6 +74,7 @@ describe('Client create path', () => { await page.write(selectors.createClientView.name, 'Carol Danvers'); await page.write(selectors.createClientView.socialName, 'AVG tax'); await page.write(selectors.createClientView.street, 'Many places'); + await page.autocompleteSearch(selectors.createClientView.businessType, 'florist'); await page.clearInput(selectors.createClientView.email); await page.write(selectors.createClientView.email, 'incorrect email format'); await page.waitToClick(selectors.createClientView.createButton); @@ -80,9 +83,18 @@ describe('Client create path', () => { expect(message.text).toContain('Some fields are invalid'); }); - it(`should attempt to create a new user with all it's data but wrong postal code`, async() => { + it(`should attempt to create a new user with all it's data but wrong business type`, async() => { await page.clearInput(selectors.createClientView.email); await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es'); + await page.clearInput(selectors.createClientView.businessType); + await page.waitToClick(selectors.createClientView.createButton); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain('Some fields are invalid'); + }); + + it(`should attempt to create a new user with all it's data but wrong postal code`, async() => { + await page.autocompleteSearch(selectors.createClientView.businessType, 'florist'); await page.clearInput(selectors.createClientView.postcode); await page.write(selectors.createClientView.postcode, '479999'); await page.waitToClick(selectors.createClientView.createButton); diff --git a/modules/client/back/methods/client/createWithUser.js b/modules/client/back/methods/client/createWithUser.js index f32979d52b..cb97d5d59d 100644 --- a/modules/client/back/methods/client/createWithUser.js +++ b/modules/client/back/methods/client/createWithUser.js @@ -50,7 +50,8 @@ module.exports = function(Self) { city: data.city, provinceFk: data.provinceFk, countryFk: data.countryFk, - isEqualizated: data.isEqualizated + isEqualizated: data.isEqualizated, + businessTypeFk: data.businessTypeFk }, myOptions); const address = await models.Address.create({ diff --git a/modules/client/back/methods/client/specs/createWithUser.spec.js b/modules/client/back/methods/client/specs/createWithUser.spec.js index f85ad19297..4c827c7453 100644 --- a/modules/client/back/methods/client/specs/createWithUser.spec.js +++ b/modules/client/back/methods/client/specs/createWithUser.spec.js @@ -8,7 +8,8 @@ describe('Client Create', () => { name: 'Wade', socialName: 'Deadpool Marvel', street: 'Wall Street', - city: 'New York' + city: 'New York', + businessTypeFk: 'florist' }; it(`should not find Deadpool as he's not created yet`, async() => { @@ -45,6 +46,7 @@ describe('Client Create', () => { expect(client.email).toEqual(newAccount.email); expect(client.fi).toEqual(newAccount.fi); expect(client.socialName).toEqual(newAccount.socialName); + expect(client.businessTypeFk).toEqual(newAccount.businessTypeFk); await tx.rollback(); } catch (e) { diff --git a/modules/client/back/models/client.json b/modules/client/back/models/client.json index 1cf539439c..76e1bffdbe 100644 --- a/modules/client/back/models/client.json +++ b/modules/client/back/models/client.json @@ -130,6 +130,13 @@ "mysql": { "columnName": "transactionTypeSageFk" } + }, + "businessTypeFk": { + "type": "string", + "mysql": { + "columnName": "businessTypeFk" + }, + "required": true } }, "relations": { diff --git a/modules/client/front/create/index.html b/modules/client/front/create/index.html index c5fa356587..cf57d30ef6 100644 --- a/modules/client/front/create/index.html +++ b/modules/client/front/create/index.html @@ -27,11 +27,19 @@ + + Date: Fri, 12 Nov 2021 13:21:07 +0100 Subject: [PATCH 049/124] add field in one e2e --- e2e/paths/02-client/01_create_client.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/paths/02-client/01_create_client.spec.js b/e2e/paths/02-client/01_create_client.spec.js index 698e782cde..37b39798dc 100644 --- a/e2e/paths/02-client/01_create_client.spec.js +++ b/e2e/paths/02-client/01_create_client.spec.js @@ -33,6 +33,7 @@ describe('Client create path', () => { await page.write(selectors.createClientView.userName, 'CaptainMarvel'); await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es'); await page.autocompleteSearch(selectors.createClientView.salesPerson, 'salesPerson'); + await page.autocompleteSearch(selectors.createClientView.businessType, 'florist'); await page.waitToClick(selectors.createClientView.createButton); const message = await page.waitForSnackbar(); @@ -74,7 +75,6 @@ describe('Client create path', () => { await page.write(selectors.createClientView.name, 'Carol Danvers'); await page.write(selectors.createClientView.socialName, 'AVG tax'); await page.write(selectors.createClientView.street, 'Many places'); - await page.autocompleteSearch(selectors.createClientView.businessType, 'florist'); await page.clearInput(selectors.createClientView.email); await page.write(selectors.createClientView.email, 'incorrect email format'); await page.waitToClick(selectors.createClientView.createButton); From 3e35e7e0b836d4002a9f293b99e224decdab1d78 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 12 Nov 2021 14:15:35 +0100 Subject: [PATCH 050/124] Changed to single scope for all inputs --- front/core/components/smart-table/index.js | 68 +++++++++++--------- front/core/components/smart-table/table.scss | 6 +- modules/entry/front/latest-buys/index.html | 2 +- 3 files changed, 42 insertions(+), 34 deletions(-) diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index 530d2fd15b..0365520868 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -12,7 +12,7 @@ export default class SmartTable extends Component { this.currentUserId = window.localStorage.currentUserWorkerId; this.$transclude = $transclude; this.sortCriteria = []; - this.$inputScopes = []; + this.$inputsScope; this.columns = []; this.autoSave = false; this.transclude(); @@ -118,29 +118,11 @@ export default class SmartTable extends Component { transclude() { const slotTable = this.element.querySelector('#table'); - this.$transclude(($clone, $scope) => { + this.$transclude($clone => { const table = $clone[0]; slotTable.appendChild(table); this.registerColumns(); - - const header = this.element.querySelector('thead > tr'); - const columns = header.querySelectorAll('th'); - const tbody = this.element.querySelector('tbody'); - if (tbody) { - const noSearch = this.$compile(` - - Enter a new search - - `)($scope); - tbody.appendChild(noSearch[0]); - - const noRows = this.$compile(` - - No data - - `)($scope); - tbody.appendChild(noRows[0]); - } + this.emptyDataRows(); }, null, 'table'); } @@ -150,7 +132,8 @@ export default class SmartTable extends Component { viewConfig.configuration = Object.assign({}, viewConfig.configuration); userViewModel.save() .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))) - .then(() => this.applyViewConfig()); + .then(() => this.applyViewConfig()) + .then(() => this.$.smartTableColumns.hide()); } applyViewConfig() { @@ -199,6 +182,27 @@ export default class SmartTable extends Component { } } + emptyDataRows() { + const header = this.element.querySelector('thead > tr'); + const columns = header.querySelectorAll('th'); + const tbody = this.element.querySelector('tbody'); + if (tbody) { + const noSearch = this.$compile(` + + Enter a new search + + `)(this.$); + tbody.appendChild(noSearch[0]); + + const noRows = this.$compile(` + + No data + + `)(this.$); + tbody.appendChild(noRows[0]); + } + } + orderHandler(element) { const field = element.getAttribute('field'); const existingCriteria = this.sortCriteria.find(criteria => { @@ -240,15 +244,17 @@ export default class SmartTable extends Component { const hasSearchRow = tbody.querySelector('tr#searchRow'); if (hasSearchRow) { - if (this.$inputScopes) { - for (let $inputScope of this.$inputScopes) - $inputScope.$destroy(); - } + if (this.$inputsScope) + this.$inputsScope.$destroy(); + return hasSearchRow.remove(); } const searchRow = document.createElement('tr'); searchRow.setAttribute('id', 'searchRow'); + + this.$inputsScope = this.$.$new(); + for (let column of columns) { const field = column.getAttribute('field'); const cell = document.createElement('td'); @@ -265,7 +271,6 @@ export default class SmartTable extends Component { continue; } - const $inputScope = this.$.$new(); if (options && options.autocomplete) { let props = ``; @@ -280,7 +285,7 @@ export default class SmartTable extends Component { ${props} on-change="$ctrl.searchByColumn('${field}')" clear-disabled="true" - />`)($inputScope); + />`)(this.$inputsScope); } else { input = this.$compile(` `)($inputScope); + />`)(this.$inputsScope); } - this.$inputScopes.push($inputScope); cell.appendChild(input[0]); } searchRow.appendChild(cell); @@ -307,7 +311,7 @@ export default class SmartTable extends Component { } searchByColumn(field) { - const searchCriteria = this.$.searchProps[field]; + const searchCriteria = this.$inputsScope.searchProps[field]; const emptySearch = searchCriteria == '' || null; const filters = this.filterSanitizer(field); @@ -316,7 +320,7 @@ export default class SmartTable extends Component { this.model.userFilter = filters.userFilter; if (!emptySearch) - this.addFilter(field, this.$.searchProps[field]); + this.addFilter(field, this.$inputsScope.searchProps[field]); else this.model.refresh(); } diff --git a/front/core/components/smart-table/table.scss b/front/core/components/smart-table/table.scss index d3b9fa9909..b5dc631a33 100644 --- a/front/core/components/smart-table/table.scss +++ b/front/core/components/smart-table/table.scss @@ -32,8 +32,12 @@ smart-table table { text-overflow: ellipsis; &[number] { + flex-direction: column; text-align: right; - width: 96px; + align-items:flex-end; + align-content: flex-end; + + justify-content: right; } &[centered] { text-align: center; diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html index a416db00bd..25bff0d561 100644 --- a/modules/entry/front/latest-buys/index.html +++ b/modules/entry/front/latest-buys/index.html @@ -137,7 +137,7 @@ - {{::buy.itemFk | zeroFill:6}} + {{::buy.itemFk}} From 906fce5ae35ec0815020f0d6d01665725d7fcad8 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Fri, 12 Nov 2021 15:17:09 +0100 Subject: [PATCH 051/124] extensions refactor and item index e2e fix --- e2e/helpers/extensions.js | 58 +++++++------------ e2e/helpers/selectors.js | 31 +++++----- e2e/paths/01-salix/01_login.spec.js | 8 ++- .../02-client/03_edit_fiscal_data.spec.js | 2 +- e2e/paths/04-item/09_index.spec.js | 12 ++-- e2e/paths/05-ticket/04_packages.spec.js | 2 +- front/core/components/smart-table/index.html | 1 + 7 files changed, 52 insertions(+), 62 deletions(-) diff --git a/e2e/helpers/extensions.js b/e2e/helpers/extensions.js index 1539aca85a..789c800b59 100644 --- a/e2e/helpers/extensions.js +++ b/e2e/helpers/extensions.js @@ -341,48 +341,32 @@ let actions = { }, waitForTextInElement: async function(selector, text) { - const expectedText = text.toLowerCase(); - return new Promise((resolve, reject) => { - let attempts = 0; - const interval = setInterval(async() => { - const currentText = await this.evaluate(selector => { - return document.querySelector(selector).innerText.toLowerCase(); - }, selector); - - if (currentText === expectedText || attempts === 40) { - clearInterval(interval); - resolve(currentText); - } - attempts += 1; - }, 100); - }).then(result => { - return expect(result).toContain(expectedText); - }); + await this.waitForFunction((selector, text) => { + if (document.querySelector(selector)) { + const innerText = document.querySelector(selector).innerText.toLowerCase(); + const expectedText = text.toLowerCase(); + if (innerText.includes(expectedText)) + return innerText; + } + }, {}, selector, text); }, waitForTextInField: async function(selector, text) { - let builtSelector = await this.selectorFormater(selector); - await this.waitForSelector(builtSelector); - const expectedText = text.toLowerCase(); - return new Promise((resolve, reject) => { - let attempts = 0; - const interval = setInterval(async() => { - const currentText = await this.evaluate(selector => { - return document.querySelector(selector).value.toLowerCase(); - }, builtSelector); + const builtSelector = await this.selectorFormater(selector); + const expectedValue = text.toLowerCase(); - if (currentText === expectedText || attempts === 40) { - clearInterval(interval); - resolve(currentText); + try { + await this.waitForFunction((selector, text) => { + const element = document.querySelector(selector); + if (element) { + const value = element.value.toLowerCase(); + if (value.includes(text)) + return true; } - attempts += 1; - }, 100); - }).then(result => { - if (result === '') - return expect(result).toEqual(expectedText); - - return expect(result).toContain(expectedText); - }); + }, {}, builtSelector, expectedValue); + } catch (error) { + throw new Error(`${text} wasn't the value of ${builtSelector}, ${error}`); + } }, selectorFormater: function(selector) { diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 9705df60ad..0dc26e7640 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -312,27 +312,26 @@ export default { }, itemsIndex: { createItemButton: `vn-float-button`, - firstSearchResult: 'vn-item-index tr:nth-child(2)', + firstSearchResult: 'vn-item-index tbody tr:nth-child(1)', searchResult: 'vn-item-index tbody tr:not(.empty-rows)', firstResultPreviewButton: 'vn-item-index tbody > :nth-child(1) .buttons > [icon="preview"]', searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]', acceptClonationAlertButton: '.vn-confirm.shown [response="accept"]', closeItemSummaryPreview: '.vn-popup.shown', - fieldsToShowButton: 'vn-item-index vn-table > div > div > vn-icon-button[icon="more_vert"]', - fieldsToShowForm: '.vn-popover.shown .content', - firstItemImage: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(1) > img', - firstItemImageTd: 'vn-item-index vn-table a:nth-child(1) vn-td:nth-child(1)', - firstItemId: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(2)', - idCheckbox: '.vn-popover.shown vn-horizontal:nth-child(1) > vn-check', - stemsCheckbox: '.vn-popover.shown vn-horizontal:nth-child(2) > vn-check', - sizeCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check', - typeCheckbox: '.vn-popover.shown vn-horizontal:nth-child(5) > vn-check', - categoryCheckbox: '.vn-popover.shown vn-horizontal:nth-child(6) > vn-check', - intrastadCheckbox: '.vn-popover.shown vn-horizontal:nth-child(7) > vn-check', - originCheckbox: '.vn-popover.shown vn-horizontal:nth-child(8) > vn-check', - buyerCheckbox: '.vn-popover.shown vn-horizontal:nth-child(9) > vn-check', - destinyCheckbox: '.vn-popover.shown vn-horizontal:nth-child(10) > vn-check', - taxClassCheckbox: '.vn-popover.shown vn-horizontal:nth-child(11) > vn-check', + shownColumns: 'vn-item-index vn-button[id="shownColumns"]', + shownColumnsList: '.vn-popover.shown .content', + firstItemImage: 'vn-item-index tbody > tr:nth-child(1) > td:nth-child(1) > img', + firstItemImageTd: 'vn-item-index smart-table tr:nth-child(1) td:nth-child(1)', + firstItemId: 'vn-item-index tbody > tr:nth-child(1) > td:nth-child(2)', + idCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check[label="Identifier"]', + stemsCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check[label="Stems"]', + sizeCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check[label="Size"]', + typeCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check[label="Type"]', + categoryCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check[label="Category"]', + intrastadCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check[label="Intrastat"]', + originCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check[label="Origin"]', + buyerCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check[label="Buyer"]', + densityCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check[label="Density"]', saveFieldsButton: '.vn-popover.shown vn-button[label="Save"] > button' }, itemFixedPrice: { diff --git a/e2e/paths/01-salix/01_login.spec.js b/e2e/paths/01-salix/01_login.spec.js index 7414856daa..9dba61379e 100644 --- a/e2e/paths/01-salix/01_login.spec.js +++ b/e2e/paths/01-salix/01_login.spec.js @@ -19,7 +19,9 @@ describe('Login path', async() => { const message = await page.waitForSnackbar(); const state = await page.getState(); - expect(message.text).toContain('Invalid login, remember that distinction is made between uppercase and lowercase'); + const errorMessage = 'Invalid login, remember that distinction is made between uppercase and lowercase'; + + expect(message.text).toContain(errorMessage); expect(state).toBe('login'); }); @@ -28,7 +30,9 @@ describe('Login path', async() => { const message = await page.waitForSnackbar(); const state = await page.getState(); - expect(message.text).toContain('Invalid login, remember that distinction is made between uppercase and lowercase'); + const errorMessage = 'Invalid login, remember that distinction is made between uppercase and lowercase'; + + expect(message.text).toContain(errorMessage); expect(state).toBe('login'); }); diff --git a/e2e/paths/02-client/03_edit_fiscal_data.spec.js b/e2e/paths/02-client/03_edit_fiscal_data.spec.js index ab0a61ddc9..4ae1d4eca5 100644 --- a/e2e/paths/02-client/03_edit_fiscal_data.spec.js +++ b/e2e/paths/02-client/03_edit_fiscal_data.spec.js @@ -112,7 +112,7 @@ describe('Client Edit fiscalData path', () => { expect(message.text).toContain('Cannot check Equalization Tax in this NIF/CIF'); }); - it('should finally edit the fixcal data correctly as VIES isnt checked and fiscal id is valid for EQtax', async() => { + it('should edit the fiscal data correctly as VIES isnt checked and fiscal id is valid for EQtax', async() => { await page.clearInput(selectors.clientFiscalData.fiscalId); await page.write(selectors.clientFiscalData.fiscalId, '94980061C'); await page.waitToClick(selectors.clientFiscalData.saveButton); diff --git a/e2e/paths/04-item/09_index.spec.js b/e2e/paths/04-item/09_index.spec.js index 262627e996..f9262863db 100644 --- a/e2e/paths/04-item/09_index.spec.js +++ b/e2e/paths/04-item/09_index.spec.js @@ -16,8 +16,8 @@ describe('Item index path', () => { }); it('should click on the fields to show button to open the list of columns to show', async() => { - await page.waitToClick(selectors.itemsIndex.fieldsToShowButton); - const visible = await page.isVisible(selectors.itemsIndex.fieldsToShowForm); + await page.waitToClick(selectors.itemsIndex.shownColumns); + const visible = await page.isVisible(selectors.itemsIndex.shownColumnsList); expect(visible).toBeTruthy(); }); @@ -31,7 +31,7 @@ describe('Item index path', () => { await page.waitToClick(selectors.itemsIndex.intrastadCheckbox); await page.waitToClick(selectors.itemsIndex.originCheckbox); await page.waitToClick(selectors.itemsIndex.buyerCheckbox); - await page.waitToClick(selectors.itemsIndex.destinyCheckbox); + await page.waitToClick(selectors.itemsIndex.densityCheckbox); await page.waitToClick(selectors.itemsIndex.saveFieldsButton); const message = await page.waitForSnackbar(); @@ -39,6 +39,7 @@ describe('Item index path', () => { }); it('should navigate forth and back to see the images column is still visible', async() => { + await page.closePopup(); await page.waitToClick(selectors.itemsIndex.firstSearchResult); await page.waitToClick(selectors.itemDescriptor.goBackToModuleIndexButton); await page.waitToClick(selectors.globalItems.searchButton); @@ -54,7 +55,7 @@ describe('Item index path', () => { }); it('should mark all unchecked boxes to leave the index as it was', async() => { - await page.waitToClick(selectors.itemsIndex.fieldsToShowButton); + await page.waitToClick(selectors.itemsIndex.shownColumns); await page.waitToClick(selectors.itemsIndex.idCheckbox); await page.waitToClick(selectors.itemsIndex.stemsCheckbox); await page.waitToClick(selectors.itemsIndex.sizeCheckbox); @@ -63,7 +64,7 @@ describe('Item index path', () => { await page.waitToClick(selectors.itemsIndex.intrastadCheckbox); await page.waitToClick(selectors.itemsIndex.originCheckbox); await page.waitToClick(selectors.itemsIndex.buyerCheckbox); - await page.waitToClick(selectors.itemsIndex.destinyCheckbox); + await page.waitToClick(selectors.itemsIndex.densityCheckbox); await page.waitToClick(selectors.itemsIndex.saveFieldsButton); const message = await page.waitForSnackbar(); @@ -71,6 +72,7 @@ describe('Item index path', () => { }); it('should now navigate forth and back to see the ids column is now visible', async() => { + await page.closePopup(); await page.waitToClick(selectors.itemsIndex.firstSearchResult); await page.waitToClick(selectors.itemDescriptor.goBackToModuleIndexButton); await page.waitToClick(selectors.globalItems.searchButton); diff --git a/e2e/paths/05-ticket/04_packages.spec.js b/e2e/paths/05-ticket/04_packages.spec.js index 06720ed7af..f874307a87 100644 --- a/e2e/paths/05-ticket/04_packages.spec.js +++ b/e2e/paths/05-ticket/04_packages.spec.js @@ -62,7 +62,7 @@ describe('Ticket Create packages path', () => { expect(result).toEqual('7 : Container medical box 1m'); }); - it(`should confirm the first quantity is just a number and the string part was ignored by the imput number`, async() => { + it(`should confirm quantity is just a number and the string part was ignored by the imput number`, async() => { await page.waitForTextInField(selectors.ticketPackages.firstQuantity, '-99'); const result = await page.waitToGetProperty(selectors.ticketPackages.firstQuantity, 'value'); diff --git a/front/core/components/smart-table/index.html b/front/core/components/smart-table/index.html index 8051502a7f..993774ed01 100644 --- a/front/core/components/smart-table/index.html +++ b/front/core/components/smart-table/index.html @@ -2,6 +2,7 @@
From 86f8e81251d48871ad27f8e67a39d0494e7b6251 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 12 Nov 2021 15:17:30 +0100 Subject: [PATCH 052/124] Fixed alignment for number columns --- front/core/components/smart-table/style.scss | 11 ++++------- front/core/components/smart-table/table.scss | 5 ----- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/front/core/components/smart-table/style.scss b/front/core/components/smart-table/style.scss index 6b973c5b06..1e882f6797 100644 --- a/front/core/components/smart-table/style.scss +++ b/front/core/components/smart-table/style.scss @@ -7,17 +7,14 @@ smart-table { cursor: pointer; align-items: center; - & > * { - display: flex - } } th[field][number] { & > :before { - display: flex; + vertical-align: middle; font-family: 'Material Icons'; content: 'arrow_downward'; color: $color-spacer; - margin: 2px 2px 0 0; + margin-right: 2px; opacity: 0 } @@ -42,11 +39,11 @@ smart-table { th[field]:not([number]) { & > :after { - display: flex; + vertical-align: middle; font-family: 'Material Icons'; content: 'arrow_downward'; color: $color-spacer; - margin: 2px 0 0 2px; + margin-left: 2px; opacity: 0 } diff --git a/front/core/components/smart-table/table.scss b/front/core/components/smart-table/table.scss index b5dc631a33..a654939db4 100644 --- a/front/core/components/smart-table/table.scss +++ b/front/core/components/smart-table/table.scss @@ -32,12 +32,7 @@ smart-table table { text-overflow: ellipsis; &[number] { - flex-direction: column; text-align: right; - align-items:flex-end; - align-content: flex-end; - - justify-content: right; } &[centered] { text-align: center; From 58f329c561dbe0866cd9ece8c89ea1ab68e8e695 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 12 Nov 2021 15:54:07 +0100 Subject: [PATCH 053/124] Updated empty-rows style --- front/core/components/smart-table/table.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/core/components/smart-table/table.scss b/front/core/components/smart-table/table.scss index a654939db4..370027d3e5 100644 --- a/front/core/components/smart-table/table.scss +++ b/front/core/components/smart-table/table.scss @@ -100,7 +100,7 @@ smart-table table { .vn-check { margin: 0; } - .empty-rows { + .empty-rows > td { color: $color-font-secondary; font-size: 1.375rem; text-align: center; From 0cd04040f18ccd6703d379bd71b75610fd0b62b7 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Fri, 12 Nov 2021 16:13:47 +0100 Subject: [PATCH 054/124] e2e fixed for client billing data and entry latests buys --- e2e/helpers/selectors.js | 6 +++--- .../02-client/04_edit_billing_data.spec.js | 3 +++ e2e/paths/12-entry/03_latestBuys.spec.js | 2 +- e2e/paths/12-entry/07_buys.spec.js | 21 ++++++++++--------- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 0dc26e7640..544437836a 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -1107,9 +1107,9 @@ export default { importBuysButton: 'vn-entry-buy-import button[type="submit"]' }, entryLatestBuys: { - firstBuy: 'vn-entry-latest-buys vn-tbody > a:nth-child(1)', - allBuysCheckBox: 'vn-entry-latest-buys vn-thead vn-check', - secondBuyCheckBox: 'vn-entry-latest-buys a:nth-child(2) vn-check[ng-model="buy.checked"]', + firstBuy: 'vn-entry-latest-buys tbody > tr:nth-child(1)', + allBuysCheckBox: 'vn-entry-latest-buys thead vn-check', + secondBuyCheckBox: 'vn-entry-latest-buys tbody tr:nth-child(2) vn-check[ng-model="buy.$checked"]', editBuysButton: 'vn-entry-latest-buys vn-button[icon="edit"]', fieldAutocomplete: 'vn-autocomplete[ng-model="$ctrl.editedColumn.field"]', newValueInput: 'vn-textfield[ng-model="$ctrl.editedColumn.newValue"]', diff --git a/e2e/paths/02-client/04_edit_billing_data.spec.js b/e2e/paths/02-client/04_edit_billing_data.spec.js index 6bc48093e3..de3270f934 100644 --- a/e2e/paths/02-client/04_edit_billing_data.spec.js +++ b/e2e/paths/02-client/04_edit_billing_data.spec.js @@ -38,10 +38,13 @@ describe('Client Edit billing data path', () => { await page.autocompleteSearch(selectors.clientBillingData.newBankEntityCountry, 'España'); await page.write(selectors.clientBillingData.newBankEntityCode, '9999'); await page.waitToClick(selectors.clientBillingData.acceptBankEntityButton); + const message = await page.waitForSnackbar(); await page.waitForTextInField(selectors.clientBillingData.swiftBic, 'Gotham City Bank'); const newcode = await page.waitToGetProperty(selectors.clientBillingData.swiftBic, 'value'); expect(newcode).toEqual('GTHMCT Gotham City Bank'); + + expect(message.text).toContain('Data saved!'); }); it(`should confirm the IBAN pay method was sucessfully saved`, async() => { diff --git a/e2e/paths/12-entry/03_latestBuys.spec.js b/e2e/paths/12-entry/03_latestBuys.spec.js index f7dc07ca99..553d41b958 100644 --- a/e2e/paths/12-entry/03_latestBuys.spec.js +++ b/e2e/paths/12-entry/03_latestBuys.spec.js @@ -31,7 +31,7 @@ describe('Entry lastest buys path', () => { await page.waitForSelector(selectors.entryLatestBuys.fieldAutocomplete, {visible: true}); }); - it('should search for the "Description" field and type a new description for the items in each selected buy', async() => { + it('should search for the "Description" and type a new one for the items in each selected buy', async() => { await page.autocompleteSearch(selectors.entryLatestBuys.fieldAutocomplete, 'Description'); await page.write(selectors.entryLatestBuys.newValueInput, 'Crafted item'); await page.waitToClick(selectors.entryLatestBuys.acceptEditBuysDialog); diff --git a/e2e/paths/12-entry/07_buys.spec.js b/e2e/paths/12-entry/07_buys.spec.js index 4042c99b6c..a39e88ce67 100644 --- a/e2e/paths/12-entry/07_buys.spec.js +++ b/e2e/paths/12-entry/07_buys.spec.js @@ -28,7 +28,7 @@ describe('Entry import, create and edit buys path', () => { await page.waitForState('entry.card.buy.import'); }); - it('should fill the form, import the designated JSON file and select items for each import and confirm import', async() => { + it('should fill the form, import the a JSON file and select items for each import and confirm import', async() => { let currentDir = process.cwd(); let filePath = `${currentDir}/e2e/assets/07_import_buys.json`; @@ -42,7 +42,8 @@ describe('Entry import, create and edit buys path', () => { await page.waitForTextInField(selectors.entryBuys.observation, '729-6340 2846'); await page.autocompleteSearch(selectors.entryBuys.firstImportedItem, 'Ranged Reinforced weapon pistol 9mm'); - await page.autocompleteSearch(selectors.entryBuys.secondImportedItem, 'Melee Reinforced weapon heavy shield 1x0.5m'); + const itemName = 'Melee Reinforced weapon heavy shield 1x0.5m'; + await page.autocompleteSearch(selectors.entryBuys.secondImportedItem, itemName); await page.autocompleteSearch(selectors.entryBuys.thirdImportedItem, 'Container medical box 1m'); await page.autocompleteSearch(selectors.entryBuys.fourthImportedItem, 'Container ammo box 1m'); @@ -88,37 +89,37 @@ describe('Entry import, create and edit buys path', () => { it('should edit the newest buy', async() => { await page.clearInput(selectors.entryBuys.secondBuyPackingPrice); - await page.waitForTextInField(selectors.entryBuys.secondBuyPackingPrice, ''); + await page.waitForTimeout(250); await page.write(selectors.entryBuys.secondBuyPackingPrice, '100'); await page.waitForSnackbar(); await page.clearInput(selectors.entryBuys.secondBuyGroupingPrice); - await page.waitForTextInField(selectors.entryBuys.secondBuyGroupingPrice, ''); + await page.waitForTimeout(250); await page.write(selectors.entryBuys.secondBuyGroupingPrice, '200'); await page.waitForSnackbar(); await page.clearInput(selectors.entryBuys.secondBuyPrice); - await page.waitForTextInField(selectors.entryBuys.secondBuyPrice, ''); + await page.waitForTimeout(250); await page.write(selectors.entryBuys.secondBuyPrice, '300'); await page.waitForSnackbar(); await page.clearInput(selectors.entryBuys.secondBuyGrouping); - await page.waitForTextInField(selectors.entryBuys.secondBuyGrouping, ''); + await page.waitForTimeout(250); await page.write(selectors.entryBuys.secondBuyGrouping, '400'); await page.waitForSnackbar(); await page.clearInput(selectors.entryBuys.secondBuyPacking); - await page.waitForTextInField(selectors.entryBuys.secondBuyPacking, ''); + await page.waitForTimeout(250); await page.write(selectors.entryBuys.secondBuyPacking, '500'); await page.waitForSnackbar(); await page.clearInput(selectors.entryBuys.secondBuyWeight); - await page.waitForTextInField(selectors.entryBuys.secondBuyWeight, ''); + await page.waitForTimeout(250); await page.write(selectors.entryBuys.secondBuyWeight, '600'); await page.waitForSnackbar(); await page.clearInput(selectors.entryBuys.secondBuyStickers); - await page.waitForTextInField(selectors.entryBuys.secondBuyStickers, ''); + await page.waitForTimeout(250); await page.write(selectors.entryBuys.secondBuyStickers, '700'); await page.waitForSnackbar(); @@ -126,7 +127,7 @@ describe('Entry import, create and edit buys path', () => { await page.waitForSnackbar(); await page.clearInput(selectors.entryBuys.secondBuyQuantity); - await page.waitForTextInField(selectors.entryBuys.secondBuyQuantity, ''); + await page.waitForTimeout(250); await page.write(selectors.entryBuys.secondBuyQuantity, '800'); }); From b83f0fb52fd2d1bf6a41dd231a48c16f8d1ece35 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 12 Nov 2021 17:51:27 +0100 Subject: [PATCH 055/124] fix(smart-table): load default viewConfig --- .../10380-allsaints/00-defaultViewConfig.sql | 5 ++- front/core/components/smart-table/index.js | 43 +++++++++++++------ front/core/components/smart-table/table.scss | 2 +- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/db/changes/10380-allsaints/00-defaultViewConfig.sql b/db/changes/10380-allsaints/00-defaultViewConfig.sql index 6530fe2268..e4b2f6c3d6 100644 --- a/db/changes/10380-allsaints/00-defaultViewConfig.sql +++ b/db/changes/10380-allsaints/00-defaultViewConfig.sql @@ -7,7 +7,8 @@ comment 'The default configuration of columns for views'; INSERT INTO `salix`.`defaultViewConfig` (tableCode, columns) VALUES - ('itemsIndex', '{"intrastat":false,"stemMultiplier":false}'), - ('latestBuys', '{"intrastat":false,"description":false,"density":false,"isActive":false,"freightValue":false,"packageValue":false,"isIgnored":false,"price2":false,"minPrice":true,"ektFk":false,"weight":false,"id":true,"packing":true,"grouping":true,"quantity":true,"size":false,"name":true,"code":true,"origin":true,"family":true,"entryFk":true,"buyingValue":true,"comissionValue":false,"price3":true,"packageFk":true,"packingOut":true}'); + ('itemsIndex', '{"intrastat":false,"stemMultiplier":false,"landed":false}'), + ('latestBuys', '{"intrastat":false,"description":false,"density":false,"isActive":false,"freightValue":false,"packageValue":false,"isIgnored":false,"price2":false,"minPrice":true,"ektFk":false,"weight":false,"id":true,"packing":true,"grouping":true,"quantity":true,"size":false,"name":true,"code":true,"origin":true,"family":true,"entryFk":true,"buyingValue":true,"comissionValue":false,"price3":true,"packageFk":true,"packingOut":true}'), + ('ticketsMonitor', '{"id":false}'); \ No newline at end of file diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index 0365520868..8193791345 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -55,7 +55,7 @@ export default class SmartTable extends Component { set viewConfigId(value) { this._viewConfigId = value; - if (value) { + /* if (value) { this.defaultViewConfig = {}; const url = 'DefaultViewConfigs'; @@ -67,7 +67,18 @@ export default class SmartTable extends Component { this.defaultViewConfig = columns; } }); - } + } */ + } + + getDefaultViewConfig() { + // this.defaultViewConfig = {}; + const url = 'DefaultViewConfigs'; + const filter = {where: {tableCode: this.viewConfigId}}; + return this.$http.get(url, {filter}) + .then(res => { + if (res && res.data.length) + return res.data[0].columns; + }); } get viewConfig() { @@ -80,19 +91,23 @@ export default class SmartTable extends Component { if (!value) return; if (!value.length) { - const userViewModel = this.$.userViewModel; + this.getDefaultViewConfig().then(columns => { + const defaultViewConfig = columns ? columns : {}; - for (const column of this.columns) { - if (this.defaultViewConfig[column.field] == undefined) - this.defaultViewConfig[column.field] = true; - } - userViewModel.insert({ - userFk: this.currentUserId, - tableConfig: this.viewConfigId, - configuration: this.defaultViewConfig ? this.defaultViewConfig : {} - }); - } - this.applyViewConfig(); + const userViewModel = this.$.userViewModel; + for (const column of this.columns) { + if (defaultViewConfig[column.field] == undefined) + defaultViewConfig[column.field] = true; + } + + userViewModel.insert({ + userFk: this.currentUserId, + tableConfig: this.viewConfigId, + configuration: defaultViewConfig + }); + }).finally(() => this.applyViewConfig()); + } else + this.applyViewConfig(); } get checkedRows() { diff --git a/front/core/components/smart-table/table.scss b/front/core/components/smart-table/table.scss index 370027d3e5..e0464465ae 100644 --- a/front/core/components/smart-table/table.scss +++ b/front/core/components/smart-table/table.scss @@ -27,7 +27,7 @@ smart-table table { & > th, & > td { text-align: left; - padding: 9px 8px; + padding: 9px 5px; white-space: nowrap; text-overflow: ellipsis; From 8a5ed6782a76efeeac89fa38a6579cca88c747a4 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 15 Nov 2021 08:32:16 +0100 Subject: [PATCH 056/124] feat(ticket): change default ticketUpdateOption for salesAssistant --- modules/ticket/front/basic-data/step-two/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index ebb93bb3d1..bb6e6958f3 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -24,6 +24,8 @@ class Controller extends Component { loadDefaultTicketAction() { let filter = {where: {code: 'changePrice'}}; + if (this.aclService.hasAny(['salesAssistant'])) + filter = {where: {code: 'turnInMana'}}; this.$http.get(`TicketUpdateActions`, {filter}).then(response => { return this.ticket.option = response.data[0].id; From e62e57bcdef205fcb994e74af72f53039ab675e1 Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 15 Nov 2021 08:45:21 +0100 Subject: [PATCH 057/124] Monitor smart-table ammends --- front/core/components/smart-table/index.html | 2 +- modules/entry/front/latest-buys/index.html | 2 +- modules/monitor/front/index/locale/es.yml | 1 + .../monitor/front/index/tickets/index.html | 31 ++++---- modules/monitor/front/index/tickets/index.js | 71 ++++++++++--------- 5 files changed, 53 insertions(+), 54 deletions(-) diff --git a/front/core/components/smart-table/index.html b/front/core/components/smart-table/index.html index 993774ed01..010cff235a 100644 --- a/front/core/components/smart-table/index.html +++ b/front/core/components/smart-table/index.html @@ -7,7 +7,7 @@ ng-click="smartTableColumns.show($event)" vn-tooltip="Shown columns"> -
+
diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html index 25bff0d561..a01d6f303c 100644 --- a/modules/entry/front/latest-buys/index.html +++ b/modules/entry/front/latest-buys/index.html @@ -33,7 +33,7 @@ check-field="$checked"> - Picture + Picture Identifier diff --git a/modules/monitor/front/index/locale/es.yml b/modules/monitor/front/index/locale/es.yml index b17861e9f0..3a115797de 100644 --- a/modules/monitor/front/index/locale/es.yml +++ b/modules/monitor/front/index/locale/es.yml @@ -9,5 +9,6 @@ Minimize/Maximize: Minimizar/Maximizar Problems: Problemas Theoretical: Teórica Practical: Práctica +Preparation: Preparación Auto-refresh: Auto-refresco Toggle auto-refresh every 2 minutes: Conmuta el refresco automático cada 2 minutos \ No newline at end of file diff --git a/modules/monitor/front/index/tickets/index.html b/modules/monitor/front/index/tickets/index.html index 87fdd407a7..34f2841fd3 100644 --- a/modules/monitor/front/index/tickets/index.html +++ b/modules/monitor/front/index/tickets/index.html @@ -20,18 +20,6 @@ Tickets monitor - - - - - - + + @@ -58,15 +51,15 @@ - + @@ -156,9 +149,9 @@ {{::ticket.shipped | date: 'dd/MM/yyyy'}} - - - + + + From 7efb19ab8373bad4b5ebf8b00cb5b62f93d54e56 Mon Sep 17 00:00:00 2001 From: vicent Date: Mon, 15 Nov 2021 14:49:14 +0100 Subject: [PATCH 063/124] =?UTF-8?q?feat(worker=5Fcalendar):=20add=20restri?= =?UTF-8?q?ction=20to=20choose=20"Vacaciones=201/2=20d=C3=ADa"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- loopback/locale/es.json | 1 + modules/worker/back/methods/worker/createAbsence.js | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index afa349684f..f7377300a3 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -193,6 +193,7 @@ "Client assignment has changed": "He cambiado el comercial ~*\"<{{previousWorkerName}}>\"*~ por *\"<{{currentWorkerName}}>\"* del cliente [{{clientName}} ({{clientId}})]({{{url}}})", "None": "Ninguno", "The contract was not active during the selected date": "El contrato no estaba activo durante la fecha seleccionada", + "Cannot add more than one '1/2 day vacation'": "No puedes añadir más de un 'Vacaciones 1/2 dia'", "This document already exists on this ticket": "Este documento ya existe en el ticket", "Some of the selected tickets are not billable": "Algunos de los tickets seleccionados no son facturables", "You can't invoice tickets from multiple clients": "No puedes facturar tickets de multiples clientes", diff --git a/modules/worker/back/methods/worker/createAbsence.js b/modules/worker/back/methods/worker/createAbsence.js index 549ba7fd15..3045a31690 100644 --- a/modules/worker/back/methods/worker/createAbsence.js +++ b/modules/worker/back/methods/worker/createAbsence.js @@ -65,6 +65,14 @@ module.exports = Self => { if (args.dated < labour.started || (labour.ended != null && args.dated > labour.ended)) throw new UserError(`The contract was not active during the selected date`); + let result = await Self.rawSql( + `SELECT COUNT(*) halfDayHolidayCounter + FROM vn.calendar c + WHERE c.dayOffTypeFk = 6 AND c.businessFk = ?`, [args.businessFk]); + + if (args.absenceTypeId == 6 && result[0].halfDayHolidayCounter > 0) + throw new UserError(`Cannot add more than one '1/2 day vacation'`); + const absence = await models.Calendar.create({ businessFk: labour.businessFk, dayOffTypeFk: args.absenceTypeId, From ec25df39e49eb4b6defdea11be2935e603480b38 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 15 Nov 2021 14:50:02 +0100 Subject: [PATCH 064/124] transaction activeWithBuyer.js --- db/dump/fixtures.sql | 2 +- .../item/back/methods/item/activeWithBuyer.js | 20 +++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index e31c873c49..9a83f41636 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -813,7 +813,7 @@ INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `d (13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 0, 2, 'VT'), (14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT'), (15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB'), - (16, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB'), + (16, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB'), (71, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT'); -- Update the taxClass after insert of the items diff --git a/modules/item/back/methods/item/activeWithBuyer.js b/modules/item/back/methods/item/activeWithBuyer.js index ca2c9329d5..121079aaa3 100644 --- a/modules/item/back/methods/item/activeWithBuyer.js +++ b/modules/item/back/methods/item/activeWithBuyer.js @@ -1,4 +1,3 @@ - module.exports = Self => { Self.remoteMethod('activeWithBuyer', { description: 'Returns active workers in itemType', @@ -19,13 +18,18 @@ module.exports = Self => { } }); - Self.activeWithBuyer = async filter => { - const query = - `SELECT DISTINCT w.id, w.firstName, w.lastName, u.name, u.nickname - FROM worker w - JOIN itemType i ON i.workerFk = w.id - JOIN account.user u ON u.id = w.id`; + Self.activeWithBuyer = async(filter, options) => { + const myOptions = {}; - return Self.activeWorkers(query, filter); + if (typeof options == 'object') + Object.assign(myOptions, options); + + const query = + `SELECT DISTINCT w.id, w.firstName, w.lastName, u.name, u.nickname + FROM worker w + JOIN itemType i ON i.workerFk = w.id + JOIN account.user u ON u.id = w.id`; + + return Self.activeWorkers(query, filter, myOptions); }; }; From 3f6e1ce9aa4c3295f8ee8007e902b84147d5d0c9 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Mon, 15 Nov 2021 18:24:01 +0100 Subject: [PATCH 065/124] refactor(entry.buy): moved add button --- e2e/helpers/selectors.js | 2 +- modules/entry/front/buy/index/index.html | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 40d0fb5e26..d8ebaa069e 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -1086,7 +1086,7 @@ export default { allBuyCheckbox: 'vn-entry-buy-index thead vn-check', firstBuyCheckbox: 'vn-entry-buy-index tbody:nth-child(2) vn-check', deleteBuysButton: 'vn-entry-buy-index vn-button[icon="delete"]', - addBuyButton: 'vn-entry-buy-index vn-icon[icon="add_circle"]', + addBuyButton: 'vn-entry-buy-index vn-icon[icon="add"]', secondBuyPackingPrice: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-input-number[ng-model="buy.price3"]', secondBuyGroupingPrice: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-input-number[ng-model="buy.price2"]', secondBuyPrice: 'vn-entry-buy-index tbody:nth-child(3) > tr:nth-child(1) vn-input-number[ng-model="buy.buyingValue"]', diff --git a/modules/entry/front/buy/index/index.html b/modules/entry/front/buy/index/index.html index dbe43c4670..bb33b98b3c 100644 --- a/modules/entry/front/buy/index/index.html +++ b/modules/entry/front/buy/index/index.html @@ -188,22 +188,19 @@
Date - Preparation - Theoretical Practical + Preparation + Province {{::ticket.shipped | date: 'HH:mm'}}{{::ticket.zoneLanding | date: 'HH:mm'}}{{::ticket.practicalHour | date: 'HH:mm'}}{{::ticket.zoneLanding | date: 'HH:mm'}}{{::ticket.practicalHour | date: 'HH:mm'}}{{::ticket.shipped | date: 'HH:mm'}} {{::ticket.province}} - Date: Mon, 15 Nov 2021 10:10:57 +0100 Subject: [PATCH 058/124] translate to english --- loopback/locale/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index c4226a2c87..271c3fd4f2 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -118,5 +118,5 @@ "reference duplicated": "reference duplicated", "The PDF document does not exists": "The PDF document does not exists. Try regenerating it from 'Regenerate invoice PDF' option", "This item is not available": "This item is not available", - "Deny buy request": "Deny buy request" + "Deny buy request": "Purchase request for ticket id [{{ticketId}}]({{{url}}}) has been rejected. Reason: {{observation}}" } \ No newline at end of file From df7980f2f9a7e1562b07313a53ff3a44a3195a14 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 15 Nov 2021 10:16:23 +0100 Subject: [PATCH 059/124] separate in two vn-horizontal --- modules/client/front/create/index.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/client/front/create/index.html b/modules/client/front/create/index.html index cf57d30ef6..3e7fdd9497 100644 --- a/modules/client/front/create/index.html +++ b/modules/client/front/create/index.html @@ -26,11 +26,6 @@ - - + + + + Date: Mon, 15 Nov 2021 12:14:34 +0100 Subject: [PATCH 060/124] fix(item): add ng-model, add fixture and transaction back test --- db/dump/fixtures.sql | 2 +- .../item/specs/activeWithBuyer.spec.js | 24 +++++++++++++------ modules/item/front/search-panel/index.html | 1 + 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 28b8e91818..08f6643e73 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -814,7 +814,7 @@ INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `d (14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT'), (15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB'), (16, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB'), - (71, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT'); + (71, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT'); -- Update the taxClass after insert of the items UPDATE `vn`.`itemTaxCountry` SET `taxClassFk` = 2 diff --git a/modules/item/back/methods/item/specs/activeWithBuyer.spec.js b/modules/item/back/methods/item/specs/activeWithBuyer.spec.js index f894e431a8..58860c2043 100644 --- a/modules/item/back/methods/item/specs/activeWithBuyer.spec.js +++ b/modules/item/back/methods/item/specs/activeWithBuyer.spec.js @@ -2,13 +2,23 @@ const models = require('vn-loopback/server/server').models; describe('Worker activeWithBuyer', () => { it('should return the buyers in itemType as result', async() => { - const filter = {}; - const result = await models.Item.activeWithBuyer(filter); - const firstWorker = result[0]; - const secondWorker = result[1]; + const tx = await models.Item.beginTransaction({}); - expect(result.length).toEqual(2); - expect(firstWorker.nickname).toEqual('logisticBossNick'); - expect(secondWorker.nickname).toEqual('buyerNick'); + try { + const options = {transaction: tx}; + const filter = {}; + const result = await models.Item.activeWithBuyer(filter, options); + const firstWorker = result[0]; + const secondWorker = result[1]; + + expect(result.length).toEqual(2); + expect(firstWorker.nickname).toEqual('logisticBossNick'); + expect(secondWorker.nickname).toEqual('buyerNick'); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); diff --git a/modules/item/front/search-panel/index.html b/modules/item/front/search-panel/index.html index 425df3d4f9..29b2a24fc5 100644 --- a/modules/item/front/search-panel/index.html +++ b/modules/item/front/search-panel/index.html @@ -41,6 +41,7 @@ Date: Mon, 15 Nov 2021 13:53:18 +0100 Subject: [PATCH 061/124] feat(item): add checkbox isFloramondo in search-panel --- db/dump/fixtures.sql | 36 +++++++++---------- modules/item/back/methods/item/filter.js | 8 +++++ .../back/methods/item/specs/filter.spec.js | 19 ++++++++++ modules/item/back/models/item.json | 3 ++ modules/item/front/search-panel/index.html | 8 +++++ 5 files changed, 56 insertions(+), 18 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 49ff08db98..1c044b4311 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -796,25 +796,25 @@ INSERT INTO `vn`.`itemFamily`(`code`, `description`) ('SER', 'Services'), ('VT', 'Sales'); -INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`, `comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`) +INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`, `comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`, `isFloramondo`) VALUES - (1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT'), - (2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT'), - (3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT'), - (4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT'), - (5, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 3, 'VT'), - (6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT'), - (7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT'), - (8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT'), - (9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT'), - (10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT'), - (11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT'), - (12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT'), - (13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 0, 2, 'VT'), - (14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT'), - (15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB'), - (16, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB'), - (71, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT'); + (1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT', 0), + (2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT', 0), + (3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT', 0), + (4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT', 0), + (5, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 3, 'VT', 0), + (6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT', 0), + (7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT', 0), + (8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT', 0), + (9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 0), + (10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT', 0), + (11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT', 0), + (12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT', 0), + (13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 0, 2, 'VT', 1), + (14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT', 1), + (15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0), + (16, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0), + (71, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT', 0); -- Update the taxClass after insert of the items UPDATE `vn`.`itemTaxCountry` SET `taxClassFk` = 2 diff --git a/modules/item/back/methods/item/filter.js b/modules/item/back/methods/item/filter.js index cff36a2233..bdd5e1ecc7 100644 --- a/modules/item/back/methods/item/filter.js +++ b/modules/item/back/methods/item/filter.js @@ -62,6 +62,11 @@ module.exports = Self => { arg: 'landed', type: 'date', description: 'The item last buy landed date', + }, + { + arg: 'isFloramondo', + type: 'boolean', + description: 'Whether the the item is or not floramondo', } ], returns: { @@ -121,6 +126,8 @@ module.exports = Self => { return {'intr.description': value}; case 'landed': return {'lb.landed': value}; + case 'isFloramondo': + return {'i.isFloramondo': value}; } }); @@ -146,6 +153,7 @@ module.exports = Self => { i.density, i.stemMultiplier, i.typeFk, + i.isFloramondo, it.name AS typeName, it.workerFk AS buyerFk, u.name AS userName, diff --git a/modules/item/back/methods/item/specs/filter.spec.js b/modules/item/back/methods/item/specs/filter.spec.js index 572aa0167c..7b1fac9ac0 100644 --- a/modules/item/back/methods/item/specs/filter.spec.js +++ b/modules/item/back/methods/item/specs/filter.spec.js @@ -60,4 +60,23 @@ describe('item filter()', () => { throw e; } }); + + it('should return 2 result filtering by isFloramondo checkbox', async() => { + const tx = await models.Item.beginTransaction({}); + const options = {transaction: tx}; + + try { + const filter = {}; + const ctx = {args: {filter: filter, isFloramondo: true}}; + const result = await models.Item.filter(ctx, filter, options); + + expect(result.length).toEqual(2); + expect(result[0].id).toEqual(13); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json index d39b39178b..fd4b6b0794 100644 --- a/modules/item/back/models/item.json +++ b/modules/item/back/models/item.json @@ -140,6 +140,9 @@ }, "isFragile": { "type": "boolean" + }, + "isFloramondo": { + "type": "boolean" } }, "relations": { diff --git a/modules/item/front/search-panel/index.html b/modules/item/front/search-panel/index.html index 518062ebaf..1be4102f40 100644 --- a/modules/item/front/search-panel/index.html +++ b/modules/item/front/search-panel/index.html @@ -155,6 +155,14 @@ tabindex="-1"> + + + + From bdff28a465e3f0f3172610fa1eb8c53d7da396e7 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Mon, 15 Nov 2021 14:40:35 +0100 Subject: [PATCH 062/124] removed unused code --- front/core/components/smart-table/index.html | 2 -- front/core/components/smart-table/index.js | 1 - modules/entry/front/latest-buys/index.html | 2 +- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/front/core/components/smart-table/index.html b/front/core/components/smart-table/index.html index 010cff235a..c2af9b41e7 100644 --- a/front/core/components/smart-table/index.html +++ b/front/core/components/smart-table/index.html @@ -45,9 +45,7 @@ -
- + check-field="$checked">
Picture
-
- - -
+ +
Date: Tue, 16 Nov 2021 08:41:27 +0100 Subject: [PATCH 067/124] fix(fixed-price): confirm on deletion --- modules/item/front/fixed-price/index.html | 13 ++++++++++--- modules/item/front/fixed-price/locale/es.yml | 3 ++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/modules/item/front/fixed-price/index.html b/modules/item/front/fixed-price/index.html index 29053d58e4..6f98ba65b3 100644 --- a/modules/item/front/fixed-price/index.html +++ b/modules/item/front/fixed-price/index.html @@ -116,7 +116,8 @@ class="dense" vn-focus ng-model="price.minPrice" - on-change="$ctrl.upsertPrice(price)"> + on-change="$ctrl.upsertPrice(price)" + step="0.01"> @@ -140,7 +141,7 @@ + ng-click="deleteFixedPrice.show({$index})">
@@ -163,4 +164,10 @@ - \ No newline at end of file + + + \ No newline at end of file diff --git a/modules/item/front/fixed-price/locale/es.yml b/modules/item/front/fixed-price/locale/es.yml index c19b7703c6..f52aef02cb 100644 --- a/modules/item/front/fixed-price/locale/es.yml +++ b/modules/item/front/fixed-price/locale/es.yml @@ -1,4 +1,5 @@ Fixed prices: Precios fijados Search prices by item ID or code: Buscar por ID de artículo o código Search fixed prices: Buscar precios fijados -Add fixed price: Añadir precio fijado \ No newline at end of file +Add fixed price: Añadir precio fijado +This row will be removed: Esta linea se eliminará \ No newline at end of file From 180fb95a0004dd360c8af130f93e30a39b8d3370 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 16 Nov 2021 10:09:42 +0100 Subject: [PATCH 068/124] feat(createAbsence): add backTest --- db/dump/fixtures.sql | 1 + .../back/methods/worker/createAbsence.js | 9 ++++-- .../worker/specs/createAbsence.spec.js | 31 +++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 49ff08db98..745a2ee07a 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1882,6 +1882,7 @@ INSERT INTO `postgresql`.`calendar_state` (`calendar_state_id`, `type`, `rgb`, ` INSERT INTO `postgresql`.`calendar_employee` (`business_id`, `calendar_state_id`, `date`) VALUES + (1, 6, IF(MONTH(CURDATE()) = 12 AND DAY(CURDATE()) > 10, DATE_ADD(CURDATE(), INTERVAL -10 DAY), DATE_ADD(CURDATE(), INTERVAL 10 DAY))), (1106, 1, IF(MONTH(CURDATE()) = 12 AND DAY(CURDATE()) > 10, DATE_ADD(CURDATE(), INTERVAL -10 DAY), DATE_ADD(CURDATE(), INTERVAL 10 DAY))), (1106, 1, IF(MONTH(CURDATE()) = 12 AND DAY(CURDATE()) > 10, DATE_ADD(CURDATE(), INTERVAL -11 DAY), DATE_ADD(CURDATE(), INTERVAL 11 DAY))), (1106, 1, IF(MONTH(CURDATE()) = 12 AND DAY(CURDATE()) > 10, DATE_ADD(CURDATE(), INTERVAL -12 DAY), DATE_ADD(CURDATE(), INTERVAL 12 DAY))), diff --git a/modules/worker/back/methods/worker/createAbsence.js b/modules/worker/back/methods/worker/createAbsence.js index 3045a31690..217191a306 100644 --- a/modules/worker/back/methods/worker/createAbsence.js +++ b/modules/worker/back/methods/worker/createAbsence.js @@ -65,12 +65,15 @@ module.exports = Self => { if (args.dated < labour.started || (labour.ended != null && args.dated > labour.ended)) throw new UserError(`The contract was not active during the selected date`); - let result = await Self.rawSql( - `SELECT COUNT(*) halfDayHolidayCounter + const result = await Self.rawSql( + `SELECT COUNT(*) halfHolidayCounter FROM vn.calendar c WHERE c.dayOffTypeFk = 6 AND c.businessFk = ?`, [args.businessFk]); - if (args.absenceTypeId == 6 && result[0].halfDayHolidayCounter > 0) + const hasHalfHoliday = result[0].halfHolidayCounter > 0; + const isHalfHoliday = args.absenceTypeId == 6; + + if (isHalfHoliday && hasHalfHoliday) throw new UserError(`Cannot add more than one '1/2 day vacation'`); const absence = await models.Calendar.create({ diff --git a/modules/worker/back/methods/worker/specs/createAbsence.spec.js b/modules/worker/back/methods/worker/specs/createAbsence.spec.js index f2c00e8040..e5387c379d 100644 --- a/modules/worker/back/methods/worker/specs/createAbsence.spec.js +++ b/modules/worker/back/methods/worker/specs/createAbsence.spec.js @@ -74,4 +74,35 @@ describe('Worker createAbsence()', () => { throw e; } }); + + it('should return an error trying to create a "Half holiday" absence', async() => { + const ctx = { + req: {accessToken: {userId: 19}}, + args: { + businessFk: 1, + absenceTypeId: 6, + dated: new Date() + } + }; + + const tx = await app.models.Calendar.beginTransaction({}); + + try { + const options = {transaction: tx}; + + let error; + await app.models.Worker.createAbsence(ctx, workerId, options).catch(e => { + error = e; + }).finally(() => { + expect(error.message).toEqual(`Cannot add more than one '1/2 day vacation'`); + }); + + expect(error).toBeDefined(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); From b7e58aa9cdec965c303483059f77ce6db257f54b Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 16 Nov 2021 11:00:48 +0100 Subject: [PATCH 069/124] fix(smtp): log attachment files sent through email --- print/core/smtp.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/print/core/smtp.js b/print/core/smtp.js index 5fb5c4a2ce..0017739da6 100644 --- a/print/core/smtp.js +++ b/print/core/smtp.js @@ -24,13 +24,24 @@ module.exports = { throw err; }).finally(async() => { + const attachments = []; + for (let attachment of options.attachments) { + const fileName = attachment.filename; + const filePath = attachment.path; + // if (fileName.includes('.png')) return; + + if (fileName || filePath) + attachments.push(filePath ? filePath : fileName); + } + const fileNames = attachments.join(',\n'); await db.rawSql(` - INSERT INTO vn.mail (receiver, replyTo, sent, subject, body, status) - VALUES (?, ?, 1, ?, ?, ?)`, [ + INSERT INTO vn.mail (receiver, replyTo, sent, subject, body, attachment, status) + VALUES (?, ?, 1, ?, ?, ?, ?)`, [ options.to, options.replyTo, options.subject, options.text || options.html, + fileNames, error && error.message || 'Sent' ]); }); From 2bc20242e633f77592a86c99ded816237c7f21f9 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 16 Nov 2021 13:43:30 +0100 Subject: [PATCH 070/124] fix(salesMonitor): allow scope days to zero --- modules/monitor/front/index/tickets/index.js | 2 +- modules/ticket/front/main/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/monitor/front/index/tickets/index.js b/modules/monitor/front/index/tickets/index.js index 54f9966948..2614fd2dc4 100644 --- a/modules/monitor/front/index/tickets/index.js +++ b/modules/monitor/front/index/tickets/index.js @@ -84,7 +84,7 @@ export default class Controller extends Section { ]; const hasExcludedParams = excludedParams.some(param => { - return $params && $params[param]; + return $params && $params[param] != undefined; }); const hasParams = Object.entries($params).length; if (!hasParams || !hasExcludedParams) diff --git a/modules/ticket/front/main/index.js b/modules/ticket/front/main/index.js index 3c6318b5d5..35a955e553 100644 --- a/modules/ticket/front/main/index.js +++ b/modules/ticket/front/main/index.js @@ -14,7 +14,7 @@ export default class Ticket extends ModuleMain { ]; const hasExcludedParams = excludedParams.some(param => { - return $params && $params[param]; + return $params && $params[param] != undefined; }); const hasParams = Object.entries($params).length; if (!hasParams || !hasExcludedParams) From f27420c14aa21db5cbb0dde0fe0366ad9479cc2a Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 16 Nov 2021 13:56:09 +0100 Subject: [PATCH 071/124] refactor(item): activeBuyers --- modules/item/back/methods/item/active.js | 42 ----------------- .../item/back/methods/item/activeBuyers.js | 45 +++++++++++++++++++ .../item/back/methods/item/activeWithBuyer.js | 35 --------------- modules/item/back/methods/item/filter.js | 2 +- modules/item/back/models/item.js | 3 +- modules/item/front/search-panel/index.html | 7 ++- 6 files changed, 50 insertions(+), 84 deletions(-) delete mode 100644 modules/item/back/methods/item/active.js create mode 100644 modules/item/back/methods/item/activeBuyers.js delete mode 100644 modules/item/back/methods/item/activeWithBuyer.js diff --git a/modules/item/back/methods/item/active.js b/modules/item/back/methods/item/active.js deleted file mode 100644 index 4537ab9943..0000000000 --- a/modules/item/back/methods/item/active.js +++ /dev/null @@ -1,42 +0,0 @@ -const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; -const buildFilter = require('vn-loopback/util/filter').buildFilter; -const mergeFilters = require('vn-loopback/util/filter').mergeFilters; - -module.exports = Self => { - Self.activeWorkers = async(query, filter) => { - let conn = Self.dataSource.connector; - if (filter.where && filter.where.and && Array.isArray(filter.where.and)) { - let where = {}; - filter.where.and.forEach(element => { - where[Object.keys(element)[0]] = Object.values(element)[0]; - }); - filter.where = where; - } - let clientFilter = Object.assign({}, filter); - clientFilter.where = buildFilter(filter.where, (param, value) => { - switch (param) { - case 'role': - return {'r.name': value}; - case 'firstName': - return {or: [ - {'w.firstName': {like: `%${value}%`}}, - {'w.lastName': {like: `%${value}%`}}, - {'u.name': {like: `%${value}%`}}, - {'u.nickname': {like: `%${value}%`}} - ]}; - case 'id': - return {'w.id': value}; - } - }); - - let myFilter = { - where: {'u.active': true} - }; - - myFilter = mergeFilters(myFilter, clientFilter); - - let stmt = new ParameterizedSQL(query); - stmt.merge(conn.makeSuffix(myFilter)); - return conn.executeStmt(stmt); - }; -}; diff --git a/modules/item/back/methods/item/activeBuyers.js b/modules/item/back/methods/item/activeBuyers.js new file mode 100644 index 0000000000..ed19dd46be --- /dev/null +++ b/modules/item/back/methods/item/activeBuyers.js @@ -0,0 +1,45 @@ +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; +const mergeFilters = require('vn-loopback/util/filter').mergeFilters; + +module.exports = Self => { + Self.remoteMethod('activeBuyers', { + description: 'Returns a list of agencies from a warehouse', + accepts: [{ + arg: 'filter', + type: 'object', + description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string` + }], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/activeBuyers`, + verb: 'GET' + } + }); + + Self.activeBuyers = async(filter, options) => { + const conn = Self.dataSource.connector; + const where = {isActive: true}; + let myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + filter = mergeFilters(filter, {where}); + + let stmt = new ParameterizedSQL( + `SELECT DISTINCT w.id workerFk, w.firstName, w.lastName, u.name, u.nickname + FROM worker w + JOIN itemType it ON it.workerFk = w.id + JOIN account.user u ON u.id = w.id + JOIN item i ON i.typeFk = it.id`, + null, myOptions); + + stmt.merge(conn.makeSuffix(filter)); + console.log(stmt); + + return conn.executeStmt(stmt); + }; +}; diff --git a/modules/item/back/methods/item/activeWithBuyer.js b/modules/item/back/methods/item/activeWithBuyer.js deleted file mode 100644 index 121079aaa3..0000000000 --- a/modules/item/back/methods/item/activeWithBuyer.js +++ /dev/null @@ -1,35 +0,0 @@ -module.exports = Self => { - Self.remoteMethod('activeWithBuyer', { - description: 'Returns active workers in itemType', - accessType: 'READ', - accepts: [{ - arg: 'filter', - type: 'Object', - description: 'Filter defining where and paginated data', - required: false - }], - returns: { - type: ['object'], - root: true - }, - http: { - path: `/activeWithBuyer`, - verb: 'GET' - } - }); - - Self.activeWithBuyer = async(filter, options) => { - const myOptions = {}; - - if (typeof options == 'object') - Object.assign(myOptions, options); - - const query = - `SELECT DISTINCT w.id, w.firstName, w.lastName, u.name, u.nickname - FROM worker w - JOIN itemType i ON i.workerFk = w.id - JOIN account.user u ON u.id = w.id`; - - return Self.activeWorkers(query, filter, myOptions); - }; -}; diff --git a/modules/item/back/methods/item/filter.js b/modules/item/back/methods/item/filter.js index 8cfefac9f0..99152467a7 100644 --- a/modules/item/back/methods/item/filter.js +++ b/modules/item/back/methods/item/filter.js @@ -44,7 +44,7 @@ module.exports = Self => { description: 'Whether the the item is or not active', }, { - arg: 'salesPersonFk', + arg: 'buyerFk', type: 'integer', description: 'The buyer of the item', }, diff --git a/modules/item/back/models/item.js b/modules/item/back/models/item.js index 887aa0a116..457cce4f2f 100644 --- a/modules/item/back/models/item.js +++ b/modules/item/back/models/item.js @@ -14,8 +14,7 @@ module.exports = Self => { require('../methods/item/getWasteByWorker')(Self); require('../methods/item/getWasteByItem')(Self); require('../methods/item/createIntrastat')(Self); - require('../methods/item/active')(Self); - require('../methods/item/activeWithBuyer')(Self); + require('../methods/item/activeBuyers')(Self); Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'}); diff --git a/modules/item/front/search-panel/index.html b/modules/item/front/search-panel/index.html index 29b2a24fc5..2a8f52827f 100644 --- a/modules/item/front/search-panel/index.html +++ b/modules/item/front/search-panel/index.html @@ -40,12 +40,11 @@ From 6fa60e597ab4201675f00c088693ee9d60747354 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 16 Nov 2021 14:13:15 +0100 Subject: [PATCH 072/124] refactor(item): activeBuyer.spec.js --- modules/item/back/methods/item/activeBuyers.js | 1 - .../specs/{activeWithBuyer.spec.js => activeBuyers.spec.js} | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) rename modules/item/back/methods/item/specs/{activeWithBuyer.spec.js => activeBuyers.spec.js} (84%) diff --git a/modules/item/back/methods/item/activeBuyers.js b/modules/item/back/methods/item/activeBuyers.js index ed19dd46be..6489ae74f2 100644 --- a/modules/item/back/methods/item/activeBuyers.js +++ b/modules/item/back/methods/item/activeBuyers.js @@ -38,7 +38,6 @@ module.exports = Self => { null, myOptions); stmt.merge(conn.makeSuffix(filter)); - console.log(stmt); return conn.executeStmt(stmt); }; diff --git a/modules/item/back/methods/item/specs/activeWithBuyer.spec.js b/modules/item/back/methods/item/specs/activeBuyers.spec.js similarity index 84% rename from modules/item/back/methods/item/specs/activeWithBuyer.spec.js rename to modules/item/back/methods/item/specs/activeBuyers.spec.js index 58860c2043..5bf36756fc 100644 --- a/modules/item/back/methods/item/specs/activeWithBuyer.spec.js +++ b/modules/item/back/methods/item/specs/activeBuyers.spec.js @@ -1,13 +1,13 @@ const models = require('vn-loopback/server/server').models; -describe('Worker activeWithBuyer', () => { +describe('Worker activeBuyers', () => { it('should return the buyers in itemType as result', async() => { const tx = await models.Item.beginTransaction({}); try { const options = {transaction: tx}; const filter = {}; - const result = await models.Item.activeWithBuyer(filter, options); + const result = await models.Item.activeBuyers(filter, options); const firstWorker = result[0]; const secondWorker = result[1]; From 4981a41d0cd2ec0a60f8c803c8a39dc86ce77340 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 16 Nov 2021 14:36:53 +0100 Subject: [PATCH 073/124] fix(supplier): delete verified supplier icon --- modules/supplier/front/descriptor/index.html | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/supplier/front/descriptor/index.html b/modules/supplier/front/descriptor/index.html index 9781c95b87..dcc065eff8 100644 --- a/modules/supplier/front/descriptor/index.html +++ b/modules/supplier/front/descriptor/index.html @@ -28,11 +28,6 @@ icon="icon-disabled" ng-if="$ctrl.supplier.isActive == false"> - - Date: Tue, 16 Nov 2021 15:23:54 +0100 Subject: [PATCH 074/124] fix(client): businessTypeFk is not longer a required field --- e2e/paths/05-ticket/01_observations.spec.js | 2 +- modules/client/back/models/client.json | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/e2e/paths/05-ticket/01_observations.spec.js b/e2e/paths/05-ticket/01_observations.spec.js index 45b4ebb3ea..f1faa60740 100644 --- a/e2e/paths/05-ticket/01_observations.spec.js +++ b/e2e/paths/05-ticket/01_observations.spec.js @@ -1,7 +1,7 @@ import selectors from '../../helpers/selectors.js'; import getBrowser from '../../helpers/puppeteer'; -describe('Ticket Create notes path', () => { +fdescribe('Ticket Create notes path', () => { let browser; let page; diff --git a/modules/client/back/models/client.json b/modules/client/back/models/client.json index 76e1bffdbe..d6a98d83c2 100644 --- a/modules/client/back/models/client.json +++ b/modules/client/back/models/client.json @@ -135,8 +135,7 @@ "type": "string", "mysql": { "columnName": "businessTypeFk" - }, - "required": true + } } }, "relations": { From b59cabe41af875cf131c8680bcb69c89a41f29e6 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 17 Nov 2021 09:11:26 +0100 Subject: [PATCH 075/124] feat(item): add filterParams in main --- modules/item/front/main/index.html | 7 +++++-- modules/item/front/main/index.js | 10 +++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/modules/item/front/main/index.html b/modules/item/front/main/index.html index a57d4fb2df..44d1257587 100644 --- a/modules/item/front/main/index.html +++ b/modules/item/front/main/index.html @@ -1,16 +1,19 @@ + data="items" + auto-load="true"> diff --git a/modules/item/front/main/index.js b/modules/item/front/main/index.js index f343699824..1d99c91a10 100644 --- a/modules/item/front/main/index.js +++ b/modules/item/front/main/index.js @@ -1,7 +1,15 @@ import ngModule from '../module'; import ModuleMain from 'salix/components/module-main'; +export default class Items extends ModuleMain { + constructor($element, $) { + super($element, $); -export default class Items extends ModuleMain {} + this.filterParams = { + isActive: true, + isFloramondo: false + }; + } +} ngModule.vnComponent('vnItems', { controller: Items, From 72c724c1e7fb69a3eced82e36ccda26c3dad5331 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 17 Nov 2021 09:59:34 +0100 Subject: [PATCH 076/124] refactor(ticket): loadDefaultTicketAction() --- modules/ticket/front/basic-data/step-two/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index bb6e6958f3..7ffdb8315d 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -23,9 +23,9 @@ class Controller extends Component { } loadDefaultTicketAction() { - let filter = {where: {code: 'changePrice'}}; - if (this.aclService.hasAny(['salesAssistant'])) - filter = {where: {code: 'turnInMana'}}; + const isSalesAssistant = this.aclService.hasAny(['salesAssistant']); + const defaultOption = isSalesAssistant ? 'turnInMana' : 'changePrice'; + const filter = {where: {code: defaultOption}}; this.$http.get(`TicketUpdateActions`, {filter}).then(response => { return this.ticket.option = response.data[0].id; From acb4c2731c2e07bd6129fd62e91831a95a1ba01a Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 17 Nov 2021 10:12:23 +0100 Subject: [PATCH 077/124] Removed focus --- e2e/paths/05-ticket/01_observations.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/paths/05-ticket/01_observations.spec.js b/e2e/paths/05-ticket/01_observations.spec.js index f1faa60740..45b4ebb3ea 100644 --- a/e2e/paths/05-ticket/01_observations.spec.js +++ b/e2e/paths/05-ticket/01_observations.spec.js @@ -1,7 +1,7 @@ import selectors from '../../helpers/selectors.js'; import getBrowser from '../../helpers/puppeteer'; -fdescribe('Ticket Create notes path', () => { +describe('Ticket Create notes path', () => { let browser; let page; From 6dfd237e1ba71f0eab8137d1ede850fa19619994 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 17 Nov 2021 13:01:50 +0100 Subject: [PATCH 078/124] comment test client create businessType --- e2e/paths/02-client/01_create_client.spec.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/e2e/paths/02-client/01_create_client.spec.js b/e2e/paths/02-client/01_create_client.spec.js index 37b39798dc..bde4203b47 100644 --- a/e2e/paths/02-client/01_create_client.spec.js +++ b/e2e/paths/02-client/01_create_client.spec.js @@ -83,6 +83,7 @@ describe('Client create path', () => { expect(message.text).toContain('Some fields are invalid'); }); + /* Tarea #3370 it(`should attempt to create a new user with all it's data but wrong business type`, async() => { await page.clearInput(selectors.createClientView.email); await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es'); @@ -91,9 +92,12 @@ describe('Client create path', () => { const message = await page.waitForSnackbar(); expect(message.text).toContain('Some fields are invalid'); - }); + });*/ it(`should attempt to create a new user with all it's data but wrong postal code`, async() => { + await page.clearInput(selectors.createClientView.email); + await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es'); + await page.autocompleteSearch(selectors.createClientView.businessType, 'florist'); await page.clearInput(selectors.createClientView.postcode); await page.write(selectors.createClientView.postcode, '479999'); From a35d36b84fd2c32d9a98f478b27f275433bc3527 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 17 Nov 2021 13:15:59 +0100 Subject: [PATCH 079/124] fix(zone): calendar event --- modules/zone/front/calendar/index.js | 2 ++ modules/zone/front/events/index.html | 1 + 2 files changed, 3 insertions(+) diff --git a/modules/zone/front/calendar/index.js b/modules/zone/front/calendar/index.js index 00b6176c7f..a24d10aef6 100644 --- a/modules/zone/front/calendar/index.js +++ b/modules/zone/front/calendar/index.js @@ -45,6 +45,8 @@ class Controller extends Component { let date = new Date(this.date.getTime()); date.setMonth(date.getMonth() + (this.nMonths * direction)); this.date = date; + + this.emit('step'); } get data() { diff --git a/modules/zone/front/events/index.html b/modules/zone/front/events/index.html index 25ec2827f0..e71a1ae262 100644 --- a/modules/zone/front/events/index.html +++ b/modules/zone/front/events/index.html @@ -3,6 +3,7 @@ vn-id="calendar" data="data" on-selection="$ctrl.onSelection($days, $type, $weekday, $events, $exclusions)" + on-step="$ctrl.refresh()" class="vn-w-md"> From 146337b30f87e5dde3e9f3c93ad227a815513c60 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 17 Nov 2021 13:19:22 +0100 Subject: [PATCH 080/124] change for error --- modules/ticket/front/basic-data/step-two/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index 7ffdb8315d..ebb93bb3d1 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -23,9 +23,7 @@ class Controller extends Component { } loadDefaultTicketAction() { - const isSalesAssistant = this.aclService.hasAny(['salesAssistant']); - const defaultOption = isSalesAssistant ? 'turnInMana' : 'changePrice'; - const filter = {where: {code: defaultOption}}; + let filter = {where: {code: 'changePrice'}}; this.$http.get(`TicketUpdateActions`, {filter}).then(response => { return this.ticket.option = response.data[0].id; From 40656da7251852b23fd463399cae9822b68bf452 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 17 Nov 2021 13:15:59 +0100 Subject: [PATCH 081/124] fix(zone): calendar event --- modules/zone/front/calendar/index.js | 2 ++ modules/zone/front/events/index.html | 1 + 2 files changed, 3 insertions(+) diff --git a/modules/zone/front/calendar/index.js b/modules/zone/front/calendar/index.js index 00b6176c7f..a24d10aef6 100644 --- a/modules/zone/front/calendar/index.js +++ b/modules/zone/front/calendar/index.js @@ -45,6 +45,8 @@ class Controller extends Component { let date = new Date(this.date.getTime()); date.setMonth(date.getMonth() + (this.nMonths * direction)); this.date = date; + + this.emit('step'); } get data() { diff --git a/modules/zone/front/events/index.html b/modules/zone/front/events/index.html index 25ec2827f0..e71a1ae262 100644 --- a/modules/zone/front/events/index.html +++ b/modules/zone/front/events/index.html @@ -3,6 +3,7 @@ vn-id="calendar" data="data" on-selection="$ctrl.onSelection($days, $type, $weekday, $events, $exclusions)" + on-step="$ctrl.refresh()" class="vn-w-md"> From 651a9257085c0970087f541114d5a1634a24c0b5 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 17 Nov 2021 14:20:26 +0100 Subject: [PATCH 082/124] feat(worker_calendar): only can choose one halfHoliday by year --- modules/worker/back/methods/worker/createAbsence.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/worker/back/methods/worker/createAbsence.js b/modules/worker/back/methods/worker/createAbsence.js index 217191a306..ba13a8a104 100644 --- a/modules/worker/back/methods/worker/createAbsence.js +++ b/modules/worker/back/methods/worker/createAbsence.js @@ -68,7 +68,13 @@ module.exports = Self => { const result = await Self.rawSql( `SELECT COUNT(*) halfHolidayCounter FROM vn.calendar c - WHERE c.dayOffTypeFk = 6 AND c.businessFk = ?`, [args.businessFk]); + JOIN postgresql.business b ON b.business_id = c.businessFk + JOIN postgresql.profile p ON p.profile_id = b.client_id + JOIN vn.person pe ON pe.id = p.person_id + WHERE c.dayOffTypeFk = 6 + AND pe.workerFk = ? + AND c.dated BETWEEN util.firstDayOfYear(CURDATE()) + AND LAST_DAY(DATE_ADD(NOW(), INTERVAL 12-MONTH(NOW()) MONTH))`, [args.id]); const hasHalfHoliday = result[0].halfHolidayCounter > 0; const isHalfHoliday = args.absenceTypeId == 6; From 00a33fabb39775176addec37f82a5815a2305051 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 17 Nov 2021 14:38:12 +0100 Subject: [PATCH 083/124] update backTest --- modules/worker/back/methods/worker/specs/createAbsence.spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/worker/back/methods/worker/specs/createAbsence.spec.js b/modules/worker/back/methods/worker/specs/createAbsence.spec.js index e5387c379d..03467347a3 100644 --- a/modules/worker/back/methods/worker/specs/createAbsence.spec.js +++ b/modules/worker/back/methods/worker/specs/createAbsence.spec.js @@ -79,6 +79,7 @@ describe('Worker createAbsence()', () => { const ctx = { req: {accessToken: {userId: 19}}, args: { + id: 1, businessFk: 1, absenceTypeId: 6, dated: new Date() From f87f60f00ac45d025c3b3ea708802265e7c13e8f Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 18 Nov 2021 09:16:36 +0100 Subject: [PATCH 084/124] feat(item-itemPackingType): add model and dumpedFixtures --- db/export-data.sh | 13 +++++----- .../item/back/models/item-packing-type.json | 26 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 modules/item/back/models/item-packing-type.json diff --git a/db/export-data.sh b/db/export-data.sh index 96adc7ab68..f696208123 100755 --- a/db/export-data.sh +++ b/db/export-data.sh @@ -47,19 +47,20 @@ TABLES=( cplusSubjectOp cplusTaxBreak cplusTrascendency472 - pgc - time claimResponsible claimReason claimRedelivery claimResult - ticketUpdateAction - state - sample - department component componentType continent + department + itemPackingType + pgc + sample + state + ticketUpdateAction + time volumeConfig ) dump_tables ${TABLES[@]} diff --git a/modules/item/back/models/item-packing-type.json b/modules/item/back/models/item-packing-type.json new file mode 100644 index 0000000000..d77c37dd86 --- /dev/null +++ b/modules/item/back/models/item-packing-type.json @@ -0,0 +1,26 @@ +{ + "name": "ItemPackingType", + "base": "VnModel", + "options": { + "mysql": { + "table": "itemPackingType" + } + }, + "properties": { + "code": { + "type": "string", + "id": true + }, + "description": { + "type": "string" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } + ] +} \ No newline at end of file From e9342af3f5cf5d4108a9d744a64f24b933b88984 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 18 Nov 2021 10:12:21 +0100 Subject: [PATCH 085/124] refactor(theme): enabled dark theme --- front/core/components/field/style.scss | 2 +- front/core/components/smart-table/table.scss | 11 +++-- front/core/components/table/style.scss | 2 +- front/core/styles/variables.scss | 49 ++++++++++++------- front/salix/components/summary/style.scss | 5 +- modules/entry/front/buy/index/style.scss | 8 +-- modules/entry/front/main/index.html | 3 +- modules/entry/front/summary/style.scss | 6 +-- modules/monitor/front/index/orders/style.scss | 2 +- modules/supplier/front/contact/style.scss | 2 +- 10 files changed, 52 insertions(+), 38 deletions(-) diff --git a/front/core/components/field/style.scss b/front/core/components/field/style.scss index 5f77e904ee..c611773e35 100644 --- a/front/core/components/field/style.scss +++ b/front/core/components/field/style.scss @@ -222,7 +222,7 @@ } } &.focused { - background-color: $color-bg-panel; + background-color: $color-font-dark; & > .container { & > .infix > .control > * { diff --git a/front/core/components/smart-table/table.scss b/front/core/components/smart-table/table.scss index e0464465ae..8555340116 100644 --- a/front/core/components/smart-table/table.scss +++ b/front/core/components/smart-table/table.scss @@ -27,7 +27,7 @@ smart-table table { & > th, & > td { text-align: left; - padding: 9px 5px; + padding: 5px; white-space: nowrap; text-overflow: ellipsis; @@ -76,23 +76,26 @@ smart-table table { .chip { padding: 4px; border-radius: 4px; - color: $color-font-bg; &.notice { - background-color: $color-notice-medium + background-color: $color-notice-medium; + color: $color-font-bg; } &.success { background-color: $color-success-medium; + color: $color-font-bg; } &.warning { background-color: $color-main-medium; + color: $color-font-bg; } &.alert { background-color: $color-alert-medium; + color: $color-font-bg; } &.message { + background-color: $color-bg-dark; color: $color-font-dark; - background-color: $color-bg-dark } } } diff --git a/front/core/components/table/style.scss b/front/core/components/table/style.scss index 2864ea8a1c..c73a7f0b08 100644 --- a/front/core/components/table/style.scss +++ b/front/core/components/table/style.scss @@ -195,7 +195,7 @@ vn-table.scrollable > .vn-table, thead vn-th, thead th { border-bottom: 2px solid $color-spacer; - background-color: #FFF; + background-color: $color-bg-panel; position: sticky; z-index: 9; top: 0 diff --git a/front/core/styles/variables.scss b/front/core/styles/variables.scss index 8883c54802..0c25aa8736 100644 --- a/front/core/styles/variables.scss +++ b/front/core/styles/variables.scss @@ -1,6 +1,6 @@ @import "./util"; -$font-size: 12pt; +$font-size: 11pt; $menu-width: 256px; $topbar-height: 56px; $mobile-width: 800px; @@ -24,7 +24,7 @@ $spacing-xl: 70px; // Light theme -$color-primary: #f7931e; +/* $color-primary: #f7931e; $color-secondary: $color-primary; $color-font: #222; @@ -72,28 +72,36 @@ $color-success-light: lighten($color-success, 35%); $color-notice-medium: lighten($color-notice, 20%); $color-notice-light: lighten($color-notice, 35%); $color-alert-medium: lighten($color-alert, 20%); -$color-alert-light: lighten($color-alert, 35%); +$color-alert-light: lighten($color-alert, 35%); */ /**/ // Dark theme -/* -$color-header: #3d3d3d; -$color-bg: #222; -$color-bg-dark: #222; +$color-primary: #f7931e; +$color-secondary: $color-primary; + $color-font: #eee; $color-font-light: #aaa; $color-font-secondary: #777; $color-font-dark: white; +$color-font-link: $color-primary; $color-font-bg: rgba(0, 0, 0, .8); -$color-font-link: #005a9a; +$color-font-bg-marginal: rgba(0, 0, 0, .4); +$color-font-bg-dark: rgba(255, 255, 255, .7); +$color-font-bg-dark-marginal: rgba(255, 255, 255, .4); + +$color-header: #3d3d3d; +$color-menu-header: #3d3d3d; +$color-bg: #222; +$color-bg-dark: #222; $color-active: #666; $color-active-font: white; $color-bg-panel: #3c3b3b; -$color-main: #f7931e; -$color-marginal: #ccc; +$color-main: $color-primary; +$color-marginal: #111; $color-success: #a3d131; $color-notice: #32b1ce; $color-alert: #f42121; +$color-button: $color-secondary; $color-spacer: rgba(255, 255, 255, .3); $color-spacer-light: rgba(255, 255, 255, .12); @@ -105,15 +113,18 @@ $color-hover-cd: rgba(255, 255, 255, .1); $color-hover-dc: .7; $color-disabled: .6; -$color-font-link: lighten($color-main, 10%); -$color-main-medium: darken($color-main, 20%); -$color-main-light: darken($color-main, 35%); -$color-success-medium: darken($color-success, 20%); -$color-success-light: darken($color-success, 35%); -$color-notice-medium: darken($color-notice, 20%); -$color-notice-light: darken($color-notice, 35%); -$color-alert-medium: darken($color-alert, 20%); -$color-alert-light: darken($color-alert, 35%); +$color-primary-medium: lighten($color-primary, 20%); +$color-primary-light: lighten($color-primary, 35%); +$color-font-link-medium: lighten($color-font-link, 20%); +$color-font-link-light: lighten($color-font-link, 35%); +$color-main-medium: lighten($color-main, 20%); +$color-main-light: lighten($color-main, 35%); +$color-success-medium: lighten($color-success, 20%); +$color-success-light: lighten($color-success, 35%); +$color-notice-medium: lighten($color-notice, 20%); +$color-notice-light: lighten($color-notice, 35%); +$color-alert-medium: lighten($color-alert, 20%); +$color-alert-light: lighten($color-alert, 35%); /**/ // Border diff --git a/front/salix/components/summary/style.scss b/front/salix/components/summary/style.scss index 99854fa9d6..2db3d961e0 100644 --- a/front/salix/components/summary/style.scss +++ b/front/salix/components/summary/style.scss @@ -68,7 +68,6 @@ ui-view > .vn-summary { padding: 7px; padding-bottom: 4px; /* Bottom line-height fix */ font-weight: lighter; - background-color: $color-main-light; border-bottom: 1px solid $color-main; white-space: nowrap; overflow: hidden; @@ -78,7 +77,7 @@ ui-view > .vn-summary { display: block; } a { - color: $color-font; + color: $color-font-link; } } h4 span:after { @@ -87,7 +86,7 @@ ui-view > .vn-summary { position: absolute; right: 5px; text-transform: none; - color: $color-spacer + color: $color-font-link; } & > * { margin: $spacing-sm; diff --git a/modules/entry/front/buy/index/style.scss b/modules/entry/front/buy/index/style.scss index 55df72f1c3..04c8d130a0 100644 --- a/modules/entry/front/buy/index/style.scss +++ b/modules/entry/front/buy/index/style.scss @@ -15,16 +15,16 @@ vn-entry-buy-index vn-card { tbody tr:nth-child(1), tbody tr:nth-child(2) { - border-left: 1px solid $color-marginal; - border-right: 1px solid $color-marginal; + border-left: 1px solid $color-spacer; + border-right: 1px solid $color-spacer; } tbody tr:nth-child(2) { - border-bottom: 1px solid $color-marginal; + border-bottom: 1px solid $color-spacer; } tbody{ - border-bottom: 1px solid $color-marginal; + border-bottom: 1px solid $color-spacer; } tbody:last-child { diff --git a/modules/entry/front/main/index.html b/modules/entry/front/main/index.html index 6c08cd0c42..f6a4c61fcf 100644 --- a/modules/entry/front/main/index.html +++ b/modules/entry/front/main/index.html @@ -2,7 +2,8 @@ vn-id="model" url="Entries/filter" limit="20" - auto-load="true"> + auto-load="true" + order="landed DESC, id DESC"> vn-td { - border-bottom: 2px solid $color-marginal; + border-bottom: 2px solid $color-spacer; font-size: 13px; } } diff --git a/modules/supplier/front/contact/style.scss b/modules/supplier/front/contact/style.scss index 84e98050df..becc66dcf5 100644 --- a/modules/supplier/front/contact/style.scss +++ b/modules/supplier/front/contact/style.scss @@ -6,5 +6,5 @@ margin-bottom: 10px; padding-right: 10px; padding-left: 10px; - border: 1px solid $color-marginal; + border: 1px solid $color-spacer; } From f49d66d9af822f04ff66018641303028e153f4f9 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 18 Nov 2021 10:36:12 +0100 Subject: [PATCH 086/124] fix(theme): chip color issues --- front/core/components/table/style.scss | 9 ++++++--- front/core/styles/variables.scss | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/front/core/components/table/style.scss b/front/core/components/table/style.scss index c73a7f0b08..edb40d385b 100644 --- a/front/core/components/table/style.scss +++ b/front/core/components/table/style.scss @@ -132,23 +132,26 @@ vn-table { .chip { padding: 4px; border-radius: 4px; - color: $color-font-bg; &.notice { - background-color: $color-notice-medium + background-color: $color-notice-medium; + color: $color-font-bg; } &.success { background-color: $color-success-medium; + color: $color-font-bg; } &.warning { background-color: $color-main-medium; + color: $color-font-bg; } &.alert { background-color: $color-alert-medium; + color: $color-font-bg; } &.message { + background-color: $color-bg-dark; color: $color-font-dark; - background-color: $color-bg-dark } } vn-icon-menu { diff --git a/front/core/styles/variables.scss b/front/core/styles/variables.scss index 0c25aa8736..4a00d716d1 100644 --- a/front/core/styles/variables.scss +++ b/front/core/styles/variables.scss @@ -83,7 +83,7 @@ $color-font: #eee; $color-font-light: #aaa; $color-font-secondary: #777; $color-font-dark: white; -$color-font-link: $color-primary; +$color-font-link: #66bfff; $color-font-bg: rgba(0, 0, 0, .8); $color-font-bg-marginal: rgba(0, 0, 0, .4); $color-font-bg-dark: rgba(255, 255, 255, .7); @@ -100,7 +100,7 @@ $color-main: $color-primary; $color-marginal: #111; $color-success: #a3d131; $color-notice: #32b1ce; -$color-alert: #f42121; +$color-alert: #fa3939; $color-button: $color-secondary; $color-spacer: rgba(255, 255, 255, .3); From e53af13b3ce94d1a2362c4f2807e4fc48355a068 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 18 Nov 2021 11:04:51 +0100 Subject: [PATCH 087/124] unit tests for smart table and ticket index --- front/core/components/smart-table/index.js | 16 +-- .../core/components/smart-table/index.spec.js | 97 +++++++++++++++++++ .../monitor/front/index/tickets/index.spec.js | 18 ++++ 3 files changed, 116 insertions(+), 15 deletions(-) create mode 100644 front/core/components/smart-table/index.spec.js diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index f32d8aa4fd..cc359e41fc 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -54,20 +54,6 @@ export default class SmartTable extends Component { set viewConfigId(value) { this._viewConfigId = value; - - /* if (value) { - this.defaultViewConfig = {}; - - const url = 'DefaultViewConfigs'; - const filter = {where: {tableCode: value}}; - this.$http.get(url, {filter}) - .then(res => { - if (res && res.data.length) { - const columns = res.data[0].columns; - this.defaultViewConfig = columns; - } - }); - } */ } getDefaultViewConfig() { @@ -163,7 +149,7 @@ export default class SmartTable extends Component { } } - let styleElement = document.querySelector('style[id="smart-table"]'); + const styleElement = document.querySelector('style[id="smart-table"]'); if (styleElement) styleElement.parentNode.removeChild(styleElement); diff --git a/front/core/components/smart-table/index.spec.js b/front/core/components/smart-table/index.spec.js new file mode 100644 index 0000000000..d0ff2f53fd --- /dev/null +++ b/front/core/components/smart-table/index.spec.js @@ -0,0 +1,97 @@ +describe('Component smartTable', () => { + let $element; + let controller; + let $httpBackend; + + beforeEach(ngModule('vnCore')); + + beforeEach(inject(($compile, $rootScope, _$httpBackend_) => { + $httpBackend = _$httpBackend_; + $element = $compile(``)($rootScope); + controller = $element.controller('smartTable'); + })); + + afterEach(() => { + $element.remove(); + }); + + describe('options setter()', () => { + it(`should throw an error if the table doesn't have an identifier`, () => { + const options = {activeButtons: {shownColumns: []}}; + + expect(() => controller.options = options).toThrowError(/View identifier not defined/); + }); + + it('should not throw an error if the table does have an identifier', () => { + const options = {activeButtons: {shownColumns: []}}; + controller.viewConfigId = 'test'; + + expect(() => controller.options = options).not.toThrow(); + }); + }); + + describe('getDefaultViewConfig()', () => { + it('should perform a query and return the default view columns', done => { + const expectedResponse = [{ + columns: {} + }]; + + $httpBackend.expectGET('DefaultViewConfigs').respond(expectedResponse); + controller.getDefaultViewConfig().then(columns => { + expect(columns).toEqual(expectedResponse[0].columns); + done(); + }).catch(done.fail); + $httpBackend.flush(); + }); + }); + + describe('viewConfig setter', () => { + it('should just call applyViewConfig() if a viewConfig was provided', () => { + spyOn(controller, 'applyViewConfig'); + controller.viewConfig = [{}]; + + expect(controller.applyViewConfig).toHaveBeenCalled(); + }); + + it('should not get a defaultConfig then insert a new one', () => { + spyOn(controller, 'applyViewConfig'); + + controller.$.userViewModel = { + insert: jest.fn() + }; + + const emptyResponse = [{ + columns: {} + }]; + + controller.columns = [ + {field: 'test1'}, + {field: 'test2'} + ]; + + $httpBackend.expectGET('DefaultViewConfigs').respond(emptyResponse); + controller.viewConfig = []; + $httpBackend.flush(); + + const expectedObject = {configuration: {'test1': true, 'test2': true}}; + + expect(controller.$.userViewModel.insert).toHaveBeenCalledWith(expect.objectContaining(expectedObject)); + expect(controller.applyViewConfig).toHaveBeenCalled(); + }); + }); + + describe('applyViewConfig()', () => { + it('should ', () => { + controller.$.userViewModel = { + viewConfig: {'test1': true, 'test2': false} + }; + + controller._columns = [ + {field: 'test1'}, + {field: 'test2'} + ]; + + controller.applyViewConfig(); + }); + }); +}); diff --git a/modules/monitor/front/index/tickets/index.spec.js b/modules/monitor/front/index/tickets/index.spec.js index 8d06b8d7d1..fb507dbbc3 100644 --- a/modules/monitor/front/index/tickets/index.spec.js +++ b/modules/monitor/front/index/tickets/index.spec.js @@ -123,6 +123,24 @@ describe('Component vnMonitorSalesTickets', () => { }); }); + describe('dateRange()', () => { + it('should return two dates with the hours at the start and end of the given date', () => { + const now = new Date(); + + const today = now.getDate(); + + const dateRange = controller.dateRange(now); + const start = dateRange[0].toString(); + const end = dateRange[1].toString(); + + expect(start).toContain(today); + expect(start).toContain('00:00:00'); + + expect(end).toContain(today); + expect(end).toContain('23:59:59'); + }); + }); + describe('preview()', () => { it('should show the dialog summary', () => { controller.$.summary = {show: () => {}}; From 03c7b3f743ca7779023e0ddef8b6a5105bbb1720 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 18 Nov 2021 11:13:10 +0100 Subject: [PATCH 088/124] fix(smtp): exclude png files on attachments --- print/core/smtp.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/print/core/smtp.js b/print/core/smtp.js index 0017739da6..36a76dbafc 100644 --- a/print/core/smtp.js +++ b/print/core/smtp.js @@ -28,7 +28,7 @@ module.exports = { for (let attachment of options.attachments) { const fileName = attachment.filename; const filePath = attachment.path; - // if (fileName.includes('.png')) return; + if (fileName.includes('.png')) return; if (fileName || filePath) attachments.push(filePath ? filePath : fileName); From 1d253fc53db391989ce5a171be6fa953c783f2ee Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 18 Nov 2021 11:17:30 +0100 Subject: [PATCH 089/124] definitions corrected for myOptions of endpoints --- back/methods/chat/sendCheckingPresence.js | 2 +- back/methods/dms/updateFile.js | 2 +- back/methods/dms/uploadFile.js | 2 +- back/methods/starred-module/getStarredModules.js | 2 +- back/methods/starred-module/setPosition.js | 2 +- back/methods/starred-module/toggleStarredModule.js | 2 +- .../back/methods/claim-beginning/importToNewRefundTicket.js | 2 +- modules/claim/back/methods/claim-dms/removeFile.js | 2 +- modules/claim/back/methods/claim-end/importTicketSales.js | 2 +- modules/claim/back/methods/claim/regularizeClaim.js | 2 +- modules/claim/back/methods/claim/updateClaim.js | 2 +- modules/claim/back/methods/claim/updateClaimAction.js | 2 +- modules/claim/back/methods/claim/uploadFile.js | 2 +- modules/client/back/methods/client/canBeInvoiced.js | 2 +- modules/entry/back/methods/entry/addBuy.js | 2 +- modules/entry/back/methods/entry/deleteBuys.js | 2 +- modules/entry/back/methods/entry/editLatestBuys.js | 2 +- modules/entry/back/methods/entry/filter.js | 2 +- modules/entry/back/methods/entry/getBuys.js | 2 +- modules/entry/back/methods/entry/getEntry.js | 2 +- modules/entry/back/methods/entry/importBuysPreview.js | 2 +- modules/entry/back/methods/entry/latestBuysFilter.js | 2 +- modules/invoiceIn/back/methods/invoice-in/filter.js | 2 +- modules/invoiceIn/back/methods/invoice-in/summary.js | 2 +- modules/invoiceOut/back/methods/invoiceOut/book.js | 2 +- modules/invoiceOut/back/methods/invoiceOut/createPdf.js | 2 +- modules/invoiceOut/back/methods/invoiceOut/filter.js | 2 +- modules/invoiceOut/back/methods/invoiceOut/getTickets.js | 2 +- modules/invoiceOut/back/methods/invoiceOut/summary.js | 2 +- modules/item/back/methods/item/activeBuyers.js | 4 ++-- modules/route/back/methods/route/getSuggestedTickets.js | 2 +- modules/route/back/methods/route/getTickets.js | 3 ++- modules/route/back/methods/route/insertTicket.js | 2 +- modules/route/back/methods/route/updateVolume.js | 2 +- modules/worker/back/methods/calendar/absences.js | 2 +- .../worker/back/methods/worker-time-control/addTimeEntry.js | 2 +- .../back/methods/worker-time-control/deleteTimeEntry.js | 2 +- .../back/methods/worker-time-control/updateTimeEntry.js | 2 +- modules/worker/back/methods/worker/createAbsence.js | 2 +- modules/worker/back/methods/worker/deleteAbsence.js | 2 +- modules/worker/back/methods/worker/holidays.js | 2 +- modules/worker/back/methods/worker/isSubordinate.js | 2 +- modules/worker/back/methods/worker/mySubordinates.js | 2 +- modules/zone/back/methods/agency-mode/byWarehouse.js | 2 +- modules/zone/back/methods/agency/getAgenciesWithWarehouse.js | 2 +- modules/zone/back/methods/agency/landsThatDay.js | 2 +- modules/zone/back/methods/zone/clone.js | 2 +- modules/zone/back/methods/zone/getEvents.js | 2 +- modules/zone/back/methods/zone/getLeaves.js | 2 +- modules/zone/back/methods/zone/getUpcomingDeliveries.js | 2 +- modules/zone/back/methods/zone/includingExpired.js | 2 +- modules/zone/back/methods/zone/toggleIsIncluded.js | 2 +- 52 files changed, 54 insertions(+), 53 deletions(-) diff --git a/back/methods/chat/sendCheckingPresence.js b/back/methods/chat/sendCheckingPresence.js index c1bc565eb2..fcde20130c 100644 --- a/back/methods/chat/sendCheckingPresence.js +++ b/back/methods/chat/sendCheckingPresence.js @@ -27,7 +27,7 @@ module.exports = Self => { Self.sendCheckingPresence = async(ctx, recipientId, message, options) => { if (!recipientId) return false; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/back/methods/dms/updateFile.js b/back/methods/dms/updateFile.js index 161f4728c9..cfc4c322fc 100644 --- a/back/methods/dms/updateFile.js +++ b/back/methods/dms/updateFile.js @@ -60,7 +60,7 @@ module.exports = Self => { const args = ctx.args; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/back/methods/dms/uploadFile.js b/back/methods/dms/uploadFile.js index 6bda1e6db2..fb4b2e5b81 100644 --- a/back/methods/dms/uploadFile.js +++ b/back/methods/dms/uploadFile.js @@ -54,7 +54,7 @@ module.exports = Self => { const args = ctx.args; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/back/methods/starred-module/getStarredModules.js b/back/methods/starred-module/getStarredModules.js index 7b0f0e945d..5d399f16e1 100644 --- a/back/methods/starred-module/getStarredModules.js +++ b/back/methods/starred-module/getStarredModules.js @@ -16,7 +16,7 @@ module.exports = function(Self) { const models = Self.app.models; const userId = ctx.req.accessToken.userId; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/back/methods/starred-module/setPosition.js b/back/methods/starred-module/setPosition.js index c72de10834..d993f18e92 100644 --- a/back/methods/starred-module/setPosition.js +++ b/back/methods/starred-module/setPosition.js @@ -31,7 +31,7 @@ module.exports = function(Self) { const userId = ctx.req.accessToken.userId; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/back/methods/starred-module/toggleStarredModule.js b/back/methods/starred-module/toggleStarredModule.js index 16e14740ba..9cc496f44a 100644 --- a/back/methods/starred-module/toggleStarredModule.js +++ b/back/methods/starred-module/toggleStarredModule.js @@ -23,7 +23,7 @@ module.exports = function(Self) { const userId = ctx.req.accessToken.userId; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js b/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js index 0e358678ea..de812417a0 100644 --- a/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js +++ b/modules/claim/back/methods/claim-beginning/importToNewRefundTicket.js @@ -63,7 +63,7 @@ module.exports = Self => { }; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/claim/back/methods/claim-dms/removeFile.js b/modules/claim/back/methods/claim-dms/removeFile.js index 310d2b941e..edc714235f 100644 --- a/modules/claim/back/methods/claim-dms/removeFile.js +++ b/modules/claim/back/methods/claim-dms/removeFile.js @@ -20,7 +20,7 @@ module.exports = Self => { Self.removeFile = async(ctx, id, options) => { let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/claim/back/methods/claim-end/importTicketSales.js b/modules/claim/back/methods/claim-end/importTicketSales.js index 106313f142..6dd64be363 100644 --- a/modules/claim/back/methods/claim-end/importTicketSales.js +++ b/modules/claim/back/methods/claim-end/importTicketSales.js @@ -22,7 +22,7 @@ module.exports = Self => { let userId = ctx.req.accessToken.userId; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/claim/back/methods/claim/regularizeClaim.js b/modules/claim/back/methods/claim/regularizeClaim.js index 2106ab2108..d1fe7c13ef 100644 --- a/modules/claim/back/methods/claim/regularizeClaim.js +++ b/modules/claim/back/methods/claim/regularizeClaim.js @@ -24,7 +24,7 @@ module.exports = Self => { const resolvedState = 3; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js index 68df9481c6..a646db3556 100644 --- a/modules/claim/back/methods/claim/updateClaim.js +++ b/modules/claim/back/methods/claim/updateClaim.js @@ -44,7 +44,7 @@ module.exports = Self => { const userId = ctx.req.accessToken.userId; const args = ctx.args; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/claim/back/methods/claim/updateClaimAction.js b/modules/claim/back/methods/claim/updateClaimAction.js index 12749fb6ba..23d1d417da 100644 --- a/modules/claim/back/methods/claim/updateClaimAction.js +++ b/modules/claim/back/methods/claim/updateClaimAction.js @@ -30,7 +30,7 @@ module.exports = Self => { Self.updateClaimAction = async(ctx, id, options) => { let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/claim/back/methods/claim/uploadFile.js b/modules/claim/back/methods/claim/uploadFile.js index daab9341af..81ad402198 100644 --- a/modules/claim/back/methods/claim/uploadFile.js +++ b/modules/claim/back/methods/claim/uploadFile.js @@ -54,7 +54,7 @@ module.exports = Self => { Self.uploadFile = async(ctx, id, options) => { let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/client/back/methods/client/canBeInvoiced.js b/modules/client/back/methods/client/canBeInvoiced.js index d8a126ed20..567d491f1f 100644 --- a/modules/client/back/methods/client/canBeInvoiced.js +++ b/modules/client/back/methods/client/canBeInvoiced.js @@ -25,7 +25,7 @@ module.exports = function(Self) { Self.canBeInvoiced = async(id, options) => { const models = Self.app.models; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/entry/back/methods/entry/addBuy.js b/modules/entry/back/methods/entry/addBuy.js index f21c1650ce..f612c16518 100644 --- a/modules/entry/back/methods/entry/addBuy.js +++ b/modules/entry/back/methods/entry/addBuy.js @@ -68,7 +68,7 @@ module.exports = Self => { Self.addBuy = async(ctx, options) => { const conn = Self.dataSource.connector; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/entry/back/methods/entry/deleteBuys.js b/modules/entry/back/methods/entry/deleteBuys.js index ce5ff6a7d9..ac6d30ce67 100644 --- a/modules/entry/back/methods/entry/deleteBuys.js +++ b/modules/entry/back/methods/entry/deleteBuys.js @@ -21,7 +21,7 @@ module.exports = Self => { Self.deleteBuys = async(ctx, options) => { const models = Self.app.models; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/entry/back/methods/entry/editLatestBuys.js b/modules/entry/back/methods/entry/editLatestBuys.js index 53b92d966e..fb0397d2b4 100644 --- a/modules/entry/back/methods/entry/editLatestBuys.js +++ b/modules/entry/back/methods/entry/editLatestBuys.js @@ -32,7 +32,7 @@ module.exports = Self => { Self.editLatestBuys = async(field, newValue, lines, options) => { let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/entry/back/methods/entry/filter.js b/modules/entry/back/methods/entry/filter.js index 24c518de87..13690d3acf 100644 --- a/modules/entry/back/methods/entry/filter.js +++ b/modules/entry/back/methods/entry/filter.js @@ -108,7 +108,7 @@ module.exports = Self => { }); Self.filter = async(ctx, filter, options) => { - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/entry/back/methods/entry/getBuys.js b/modules/entry/back/methods/entry/getBuys.js index 8adcc950d8..6da9ec53e6 100644 --- a/modules/entry/back/methods/entry/getBuys.js +++ b/modules/entry/back/methods/entry/getBuys.js @@ -29,7 +29,7 @@ module.exports = Self => { Self.getBuys = async(id, filter, options) => { const models = Self.app.models; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/entry/back/methods/entry/getEntry.js b/modules/entry/back/methods/entry/getEntry.js index 74ccc88c51..66238d0dc4 100644 --- a/modules/entry/back/methods/entry/getEntry.js +++ b/modules/entry/back/methods/entry/getEntry.js @@ -21,7 +21,7 @@ module.exports = Self => { Self.getEntry = async(id, options) => { const models = Self.app.models; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/entry/back/methods/entry/importBuysPreview.js b/modules/entry/back/methods/entry/importBuysPreview.js index 790d33364c..5b88b587ca 100644 --- a/modules/entry/back/methods/entry/importBuysPreview.js +++ b/modules/entry/back/methods/entry/importBuysPreview.js @@ -26,7 +26,7 @@ module.exports = Self => { Self.importBuysPreview = async(id, buys, options) => { const models = Self.app.models; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js index cbf9e3b6a4..7711bc0f10 100644 --- a/modules/entry/back/methods/entry/latestBuysFilter.js +++ b/modules/entry/back/methods/entry/latestBuysFilter.js @@ -76,7 +76,7 @@ module.exports = Self => { }); Self.latestBuysFilter = async(ctx, filter, options) => { - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/invoiceIn/back/methods/invoice-in/filter.js b/modules/invoiceIn/back/methods/invoice-in/filter.js index e2e759fb8b..b5fc904872 100644 --- a/modules/invoiceIn/back/methods/invoice-in/filter.js +++ b/modules/invoiceIn/back/methods/invoice-in/filter.js @@ -95,7 +95,7 @@ module.exports = Self => { const conn = Self.dataSource.connector; const args = ctx.args; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/invoiceIn/back/methods/invoice-in/summary.js b/modules/invoiceIn/back/methods/invoice-in/summary.js index f09be4add1..3693245cc6 100644 --- a/modules/invoiceIn/back/methods/invoice-in/summary.js +++ b/modules/invoiceIn/back/methods/invoice-in/summary.js @@ -20,7 +20,7 @@ module.exports = Self => { }); Self.summary = async(id, options) => { - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/invoiceOut/back/methods/invoiceOut/book.js b/modules/invoiceOut/back/methods/invoiceOut/book.js index 0371d4f746..7aa0eac1f0 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/book.js +++ b/modules/invoiceOut/back/methods/invoiceOut/book.js @@ -23,7 +23,7 @@ module.exports = Self => { Self.book = async(ref, options) => { const models = Self.app.models; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index ac79f0d5d0..3f577c9b09 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -35,7 +35,7 @@ module.exports = Self => { throw new UserError(`Action not allowed on the test environment`); let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/invoiceOut/back/methods/invoiceOut/filter.js b/modules/invoiceOut/back/methods/invoiceOut/filter.js index 3496c92963..192490090d 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/filter.js +++ b/modules/invoiceOut/back/methods/invoiceOut/filter.js @@ -87,7 +87,7 @@ module.exports = Self => { Self.filter = async(ctx, filter, options) => { const conn = Self.dataSource.connector; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/invoiceOut/back/methods/invoiceOut/getTickets.js b/modules/invoiceOut/back/methods/invoiceOut/getTickets.js index dc3296aba9..dc94f0f0f5 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/getTickets.js +++ b/modules/invoiceOut/back/methods/invoiceOut/getTickets.js @@ -29,7 +29,7 @@ module.exports = Self => { Self.getTickets = async(id, filter, options) => { const models = Self.app.models; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/invoiceOut/back/methods/invoiceOut/summary.js b/modules/invoiceOut/back/methods/invoiceOut/summary.js index a95016ff28..db01a41895 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/summary.js +++ b/modules/invoiceOut/back/methods/invoiceOut/summary.js @@ -21,7 +21,7 @@ module.exports = Self => { Self.summary = async(id, options) => { let summary = {}; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/item/back/methods/item/activeBuyers.js b/modules/item/back/methods/item/activeBuyers.js index 6489ae74f2..e16ff877b0 100644 --- a/modules/item/back/methods/item/activeBuyers.js +++ b/modules/item/back/methods/item/activeBuyers.js @@ -3,7 +3,7 @@ const mergeFilters = require('vn-loopback/util/filter').mergeFilters; module.exports = Self => { Self.remoteMethod('activeBuyers', { - description: 'Returns a list of agencies from a warehouse', + description: 'Returns a list of buyers for the given item type', accepts: [{ arg: 'filter', type: 'object', @@ -22,7 +22,7 @@ module.exports = Self => { Self.activeBuyers = async(filter, options) => { const conn = Self.dataSource.connector; const where = {isActive: true}; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/route/back/methods/route/getSuggestedTickets.js b/modules/route/back/methods/route/getSuggestedTickets.js index fe268f8ccc..49d7c1977e 100644 --- a/modules/route/back/methods/route/getSuggestedTickets.js +++ b/modules/route/back/methods/route/getSuggestedTickets.js @@ -20,7 +20,7 @@ module.exports = Self => { }); Self.getSuggestedTickets = async(id, options) => { - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/route/back/methods/route/getTickets.js b/modules/route/back/methods/route/getTickets.js index 5705d89050..9a2f5289a4 100644 --- a/modules/route/back/methods/route/getTickets.js +++ b/modules/route/back/methods/route/getTickets.js @@ -26,7 +26,8 @@ module.exports = Self => { Self.getTickets = async(filter, options) => { const conn = Self.dataSource.connector; - let myOptions = {}; + const myOptions = {}; + if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/route/back/methods/route/insertTicket.js b/modules/route/back/methods/route/insertTicket.js index d716bd8ba1..f78e1cb831 100644 --- a/modules/route/back/methods/route/insertTicket.js +++ b/modules/route/back/methods/route/insertTicket.js @@ -30,7 +30,7 @@ module.exports = Self => { const models = Self.app.models; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/route/back/methods/route/updateVolume.js b/modules/route/back/methods/route/updateVolume.js index ce6e16b5c2..f3b8da1301 100644 --- a/modules/route/back/methods/route/updateVolume.js +++ b/modules/route/back/methods/route/updateVolume.js @@ -24,7 +24,7 @@ module.exports = Self => { const models = Self.app.models; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/worker/back/methods/calendar/absences.js b/modules/worker/back/methods/calendar/absences.js index 96293c931b..32d311cdb6 100644 --- a/modules/worker/back/methods/calendar/absences.js +++ b/modules/worker/back/methods/calendar/absences.js @@ -40,7 +40,7 @@ module.exports = Self => { ended.setMonth(12); ended.setDate(0); - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/worker/back/methods/worker-time-control/addTimeEntry.js b/modules/worker/back/methods/worker-time-control/addTimeEntry.js index 2079a62a39..80786b7236 100644 --- a/modules/worker/back/methods/worker-time-control/addTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/addTimeEntry.js @@ -34,8 +34,8 @@ module.exports = Self => { const models = Self.app.models; const args = ctx.args; const currentUserId = ctx.req.accessToken.userId; + const myOptions = {}; - let myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js b/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js index 23e4c5fffd..c80dcab81b 100644 --- a/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/deleteTimeEntry.js @@ -25,7 +25,7 @@ module.exports = Self => { const currentUserId = ctx.req.accessToken.userId; const models = Self.app.models; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/worker/back/methods/worker-time-control/updateTimeEntry.js b/modules/worker/back/methods/worker-time-control/updateTimeEntry.js index abeda7f8e4..a99a617704 100644 --- a/modules/worker/back/methods/worker-time-control/updateTimeEntry.js +++ b/modules/worker/back/methods/worker-time-control/updateTimeEntry.js @@ -31,7 +31,7 @@ module.exports = Self => { const models = Self.app.models; const args = ctx.args; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/worker/back/methods/worker/createAbsence.js b/modules/worker/back/methods/worker/createAbsence.js index 549ba7fd15..b276cf1f7c 100644 --- a/modules/worker/back/methods/worker/createAbsence.js +++ b/modules/worker/back/methods/worker/createAbsence.js @@ -41,7 +41,7 @@ module.exports = Self => { const userId = ctx.req.accessToken.userId; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/worker/back/methods/worker/deleteAbsence.js b/modules/worker/back/methods/worker/deleteAbsence.js index 18427424df..72e9243d9f 100644 --- a/modules/worker/back/methods/worker/deleteAbsence.js +++ b/modules/worker/back/methods/worker/deleteAbsence.js @@ -28,7 +28,7 @@ module.exports = Self => { const userId = ctx.req.accessToken.userId; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/worker/back/methods/worker/holidays.js b/modules/worker/back/methods/worker/holidays.js index f3ce0c6615..e11d130020 100644 --- a/modules/worker/back/methods/worker/holidays.js +++ b/modules/worker/back/methods/worker/holidays.js @@ -34,7 +34,7 @@ module.exports = Self => { const models = Self.app.models; const args = ctx.args; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/worker/back/methods/worker/isSubordinate.js b/modules/worker/back/methods/worker/isSubordinate.js index 13cc365c63..f051cf7685 100644 --- a/modules/worker/back/methods/worker/isSubordinate.js +++ b/modules/worker/back/methods/worker/isSubordinate.js @@ -27,7 +27,7 @@ module.exports = Self => { const models = Self.app.models; const myUserId = ctx.req.accessToken.userId; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/worker/back/methods/worker/mySubordinates.js b/modules/worker/back/methods/worker/mySubordinates.js index 07a22291da..b6711e3827 100644 --- a/modules/worker/back/methods/worker/mySubordinates.js +++ b/modules/worker/back/methods/worker/mySubordinates.js @@ -25,7 +25,7 @@ module.exports = Self => { const userId = ctx.req.accessToken.userId; const stmts = []; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/agency-mode/byWarehouse.js b/modules/zone/back/methods/agency-mode/byWarehouse.js index 30716d145b..945e79320e 100644 --- a/modules/zone/back/methods/agency-mode/byWarehouse.js +++ b/modules/zone/back/methods/agency-mode/byWarehouse.js @@ -22,7 +22,7 @@ module.exports = Self => { Self.byWarehouse = async(filter, options) => { const conn = Self.dataSource.connector; const where = {isActive: true}; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/agency/getAgenciesWithWarehouse.js b/modules/zone/back/methods/agency/getAgenciesWithWarehouse.js index 296b9ee8d4..846ad6a3db 100644 --- a/modules/zone/back/methods/agency/getAgenciesWithWarehouse.js +++ b/modules/zone/back/methods/agency/getAgenciesWithWarehouse.js @@ -29,7 +29,7 @@ module.exports = Self => { }); Self.getAgenciesWithWarehouse = async(addressFk, landed, warehouseFk, options) => { - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/agency/landsThatDay.js b/modules/zone/back/methods/agency/landsThatDay.js index 5a9efefe8f..b7f13dddae 100644 --- a/modules/zone/back/methods/agency/landsThatDay.js +++ b/modules/zone/back/methods/agency/landsThatDay.js @@ -23,7 +23,7 @@ module.exports = Self => { }); Self.landsThatDay = async(addressFk, landed, options) => { - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/zone/clone.js b/modules/zone/back/methods/zone/clone.js index 64dc5aa553..391b3762a6 100644 --- a/modules/zone/back/methods/zone/clone.js +++ b/modules/zone/back/methods/zone/clone.js @@ -22,7 +22,7 @@ module.exports = Self => { Self.clone = async(id, options) => { const models = Self.app.models; let tx; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/zone/getEvents.js b/modules/zone/back/methods/zone/getEvents.js index c76a38ea50..a8ee8bb7be 100644 --- a/modules/zone/back/methods/zone/getEvents.js +++ b/modules/zone/back/methods/zone/getEvents.js @@ -26,7 +26,7 @@ module.exports = Self => { }); Self.getEvents = async(geoFk, agencyModeFk, options) => { - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/zone/getLeaves.js b/modules/zone/back/methods/zone/getLeaves.js index cda5d7ff9a..db17beb1bb 100644 --- a/modules/zone/back/methods/zone/getLeaves.js +++ b/modules/zone/back/methods/zone/getLeaves.js @@ -32,7 +32,7 @@ module.exports = Self => { }); Self.getLeaves = async(id, parentId = null, search, options) => { - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/zone/getUpcomingDeliveries.js b/modules/zone/back/methods/zone/getUpcomingDeliveries.js index 6aceb694b4..2a1c39ed6d 100644 --- a/modules/zone/back/methods/zone/getUpcomingDeliveries.js +++ b/modules/zone/back/methods/zone/getUpcomingDeliveries.js @@ -14,7 +14,7 @@ module.exports = Self => { }); Self.getUpcomingDeliveries = async options => { - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/zone/includingExpired.js b/modules/zone/back/methods/zone/includingExpired.js index 75aa41e1c8..cd951b6d08 100644 --- a/modules/zone/back/methods/zone/includingExpired.js +++ b/modules/zone/back/methods/zone/includingExpired.js @@ -19,7 +19,7 @@ module.exports = Self => { }); Self.includingExpired = async(ctx, filter, options) => { - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); diff --git a/modules/zone/back/methods/zone/toggleIsIncluded.js b/modules/zone/back/methods/zone/toggleIsIncluded.js index 32144ab971..bf8c86f464 100644 --- a/modules/zone/back/methods/zone/toggleIsIncluded.js +++ b/modules/zone/back/methods/zone/toggleIsIncluded.js @@ -29,7 +29,7 @@ module.exports = Self => { Self.toggleIsIncluded = async(id, geoId, isIncluded, options) => { const models = Self.app.models; - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); From 4fc01e6a0da575641ab8f08569628269c83d8f6a Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 18 Nov 2021 11:18:45 +0100 Subject: [PATCH 090/124] typos corrected --- modules/invoiceIn/back/methods/invoice-in/filter.js | 2 +- modules/invoiceOut/back/methods/invoiceOut/filter.js | 2 +- modules/item/back/methods/item/filter.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/invoiceIn/back/methods/invoice-in/filter.js b/modules/invoiceIn/back/methods/invoice-in/filter.js index b5fc904872..7e497d39a0 100644 --- a/modules/invoiceIn/back/methods/invoice-in/filter.js +++ b/modules/invoiceIn/back/methods/invoice-in/filter.js @@ -78,7 +78,7 @@ module.exports = Self => { { arg: 'isBooked', type: 'boolean', - description: 'Whether the the invoice is booked or not', + description: 'Whether the invoice is booked or not', }, ], returns: { diff --git a/modules/invoiceOut/back/methods/invoiceOut/filter.js b/modules/invoiceOut/back/methods/invoiceOut/filter.js index 192490090d..99a80c169f 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/filter.js +++ b/modules/invoiceOut/back/methods/invoiceOut/filter.js @@ -35,7 +35,7 @@ module.exports = Self => { { arg: 'hasPdf', type: 'boolean', - description: 'Whether the the invoiceOut has PDF or not', + description: 'Whether the invoiceOut has PDF or not', http: {source: 'query'} }, { diff --git a/modules/item/back/methods/item/filter.js b/modules/item/back/methods/item/filter.js index 99152467a7..53948c46e7 100644 --- a/modules/item/back/methods/item/filter.js +++ b/modules/item/back/methods/item/filter.js @@ -41,7 +41,7 @@ module.exports = Self => { { arg: 'isActive', type: 'boolean', - description: 'Whether the the item is or not active', + description: 'Whether the item is or not active', }, { arg: 'buyerFk', From 8676a1df90922be69e2c1115116d8d7919d762a4 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 18 Nov 2021 11:28:11 +0100 Subject: [PATCH 091/124] updated method description --- modules/zone/back/methods/zone/includingExpired.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/zone/back/methods/zone/includingExpired.js b/modules/zone/back/methods/zone/includingExpired.js index cd951b6d08..e93b864712 100644 --- a/modules/zone/back/methods/zone/includingExpired.js +++ b/modules/zone/back/methods/zone/includingExpired.js @@ -2,7 +2,7 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; module.exports = Self => { Self.remoteMethodCtx('includingExpired', { - description: 'Returns a list of agencies from a warehouse', + description: 'Returns a list of zones for the given warehouse and user', accepts: [{ arg: 'filter', type: 'Object', From 3ffbdc3fde1be7215c514a8fa214d75a7e40f4b1 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 18 Nov 2021 11:48:13 +0100 Subject: [PATCH 092/124] Updated fonts --- front/core/styles/icons/salixfont.css | 45 ++++++++++++++++--------- front/core/styles/icons/salixfont.svg | 18 ++++++---- front/core/styles/icons/salixfont.ttf | Bin 35916 -> 39328 bytes front/core/styles/icons/salixfont.woff | Bin 35992 -> 39404 bytes modules/item/front/routes.json | 2 +- modules/supplier/front/routes.json | 2 +- 6 files changed, 44 insertions(+), 23 deletions(-) diff --git a/front/core/styles/icons/salixfont.css b/front/core/styles/icons/salixfont.css index d6466a0ebd..48dd91a826 100644 --- a/front/core/styles/icons/salixfont.css +++ b/front/core/styles/icons/salixfont.css @@ -23,30 +23,30 @@ -moz-osx-font-smoothing: grayscale; } -.icon-basketadd:before { - content: "\e901"; +.icon-preserved:before { + content: "\e963"; } -.icon-addperson:before { - content: "\e955"; +.icon-treatments:before { + content: "\e964"; } -.icon-supplierfalse:before { +.icon-funeral:before { + content: "\e965"; +} +.icon-handmadeArtificial:before { + content: "\e966"; +} +.icon-fixedPrice:before { content: "\e962"; } -.icon-invoice-in-create:before { - content: "\e948"; +.icon-accounts:before { + content: "\e95f"; } -.icon-invoiceOut:before { +.icon-clientConsumption:before { content: "\e960"; } -.icon-invoiceIn:before { +.icon-lastBuy:before { content: "\e961"; } -.icon-supplier:before { - content: "\e936"; -} -.icon-latestBuy:before { - content: "\e95f"; -} .icon-zone:before { content: "\e95d"; } @@ -86,6 +86,9 @@ .icon-deliveryprices:before { content: "\e956"; } +.icon-basketadd:before { + content: "\e955"; +} .icon-catalog:before { content: "\e952"; } @@ -128,9 +131,15 @@ .icon-actions:before { content: "\e900"; } +.icon-addperson:before { + content: "\e901"; +} .icon-albaran:before { content: "\e902"; } +.icon-apps:before { + content: "\e948"; +} .icon-artificial:before { content: "\e903"; } @@ -239,6 +248,9 @@ .icon-mandatory:before { content: "\e921"; } +.icon-niche:before { + content: "\e922"; +} .icon-no036:before { content: "\e923"; } @@ -302,6 +314,9 @@ .icon-stowaway:before { content: "\e92c"; } +.icon-supplier:before { + content: "\e936"; +} .icon-tags:before { content: "\e937"; } diff --git a/front/core/styles/icons/salixfont.svg b/front/core/styles/icons/salixfont.svg index 7ff0f037d9..42129b284d 100644 --- a/front/core/styles/icons/salixfont.svg +++ b/front/core/styles/icons/salixfont.svg @@ -10,16 +10,16 @@ - + - + - + @@ -29,7 +29,7 @@ - + @@ -41,6 +41,7 @@ + @@ -49,7 +50,7 @@ - + @@ -66,7 +67,7 @@ - + @@ -104,6 +105,11 @@ + + + + + diff --git a/front/core/styles/icons/salixfont.ttf b/front/core/styles/icons/salixfont.ttf index 106994f836a214edb4f5a62ff62fb51725c1bd64..f0e5ad047402962787849d7583699640640f8158 100644 GIT binary patch delta 13204 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 Q{`g+~KI`Nk-TOTGKkKAt?f?J) delta 10051 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 delta 10072 zcmeHtd2k%pd1t?VeM}!S(>*=iJ(!uE8{KnbFed=wBzS-a2vGz@5#k}z5)YX)C6N+o zS=LYvElMicF+CPTDJ3bfU5X>AY$|ZF@~)JyHnI|XC;02CS9Nw%`Jf21<#?*x$~+`t8F9PToyX=#QYvvvMkjkA3(Mlzoe$9)Yq)JWo9z+ zlbn&SpLUKwAw@kJgnWja{O>c)k>jV%K-m!V{{lImIWOIR?8FD4-DB@Sn>We%zrXVB z4aX0hxw}YFkG}#13HLll-~XWl$M1x)??A_A$+>UWcQ@XB;^Zlq{h13(zlsiaE} zTs4*!|06O{h@+^hR~QQa9_6QE)NRyZ>Kt`}qO{HfhhvhK#>sJ1s~Tpb(>PoTtU+bu zXpOp^PH`3*N3H(OSSr#^YkFEwH`0w-qo&v1kbR0GV%aOxL2;KN%c?5N%9j69LTAhO zjK_u}0pBN1vWV?BLQ#gb^@Z*;3!#2YM-8|#_|y}mgHgkZ_!EYw=T%8oB}+x>H**R2gxSs!H8A(Vk3J z^rYng{XPPBdCIId6b4SsIgZYw|jkJWb78y z!LZN{MuBY8oq}B_RpVqX2&$j~G=qU!*Tx$`s2R#A{*d6@Wb+@zJ*=!{L*c5`*X|2dLw$XbhSjLo4nZ6AKMFS$hfj?<>r%W) zTQ#e2Q#N~Z&L|kVnF)`?NADZW&gH_b5SG|*BWxJqp$Ox_p?Y`g#D^!~_>G{gX?8k3 zmXS?SWVD&bW<*m~W2%}`tP!hzS3_n!vhGif#^V#Iwi@$=Dxr~+!+w>Q`+RCrEftEp ziiLtNra}{h5cWcY>b^>4Up17~XvCEFRG)ZT+yHY+sXWN-b#m@`8A$mL>KhN`+p%anP?X~HTkJ~xkC(DK?imaFML{pWct<3sx z_s38W6eWQThw2|{Sxwk{=tuhUGC#9%<0m(6oS_$tv|75gJol?x)wm*u1~NIbp;tp5^H7 zH>TH3e|&m+Z8+xf2|Vi;u*R3m<-G&tfx>O2peP_&G9D3i2DI6uL|DZ`vox!)K}lp- zmXq1O(BeNx4Ab@iGGe@pk5ike`>0P+zfQeOy-xix1t3iDtLbhHY{AMFalJk0Z423% z6e+mwNS9sZv74sRT* z85+WaSobk2TJN@K^}FCpT0wW14#5NRT-$++&((W)Tsmbp>Pj8KaX;U3O+0slbm@?+YXhNg~cDhvIS=zsU zD=V_CheJ?ODzn|Ml`4j%hf-xx9?f7n7SRV}+CvwshK}R$vM5euc+-j(LzbxX*eB<1 zE($)H^|fI)*}HDOhhDU1hLST*C@X6z6|}N;W_|bW&|uh^we9t(kzbywZest=YJ@Ta z0!w4qO#kMxX3AqDc5Y}$sDA=!vVr}{Hl8RK|3l8QGY zqo;?BFt6*pWo*8*MQHmOIU8jq^?VheYs)S_&EaZdy+^?Ec=ectjrf|VT(EOK5L4dD z@gVEGbmu)je(IrdpTf#A?U%DVbJkcQ6biR?Tbdw?md1N{ zF(_wj{%?F9#Ne1wuzm8)cH=TEhV9E~8H4vQQA#nYjXC;nw;84M^q(BhZlYN zWww2F`RY6PJ^V}5ICY-tP|tygg0#7?-4jG20znr%f<#_drGcbt29c6xtL}=OD7n6~`$yOy58%-#mZmffNvzRS6QZa` zt>PU3+o0@Px>7liV!dq!AjH{|$rvgl@oLy#onV>G4bn(t)c#`OVB8ZB1&y~36pFSF zKmqWkHL-rE`_}9Sj&7bga&&X1f$OPMy-I(S)|hq29Ggw?e8v+`-Z>5SAb#ii(L3XE z$e2EyNU{kUW5Hq+WxP~s@?KVJ_lNQW1G^n3(!GokmQA5?ARLNR1cg@I9W+#{?8xNdqV2VS~xO0Xa(|{P(iV`gxC!Tbf%<;g>gQfw62h|91Dc>r<*S;yA^L zLtzwuc4%_)cqT))f7pE-OG$}?AAWfyu{8I%os2}wfq?gWXiMbKL@DcxsOogH`~B^l zsxj5 zU)Yw#<+Fl3UZT$y$4P!tkY(W(QnGZB-YE;qZ-#C9dF)|XiQ~O|oA>deDu4wB8wETk zDF%=sC^W}1GS4f55R{aNEU8=yfC__=_Aqd85+EMKKna6x7Pq3!!WvfccvP`h&2S7z zT!x+`Q|t1e z4Ux5&f}izrEHE${lL|Jt7)?#E*GYU87}E^3AG{9`WiDtUz%_uUX59fGOcOr@Ag4gU zDNe**t=j`oL1c$Vnh7d0hH%p9nZuSt#E2zw0PTp7ko=19IlLcm9KX!@JbarZm*yZz zv-kOfL4Ua}DfFi?BTKJJmh$67387HpPcJLxU!mcPBmSUQda0a1YWD%fG!(^z^h=6q zD)tuQ8r=dj+Whe-RtS627l43As|4wAi)HJ0{{Yg5Z;psOTK=w*Vc;H z#xncY3!%{ZVsS9DF81Ng2UV4z0ea}hg-rHVvMhyW@*57bWycv-R82XdoZ41&2nqn4 ziPscALLH*MPJNsDbLw5{r-(&<6zz=fxmJ80gc3df93Kj(Su-{W(ru}#ts7Y_knqX@Zn%NKAz}kwZ(IxHblp}}3p8ag zW@gnuh=1--=i&VJhA29bXnNTW4<{52FXCFoYgh21>P?KFP@0LcyYgnsV!~B}$=}}8 zk_s2#-eNyph|_eebEVxkYB8Ws5*yVLk}T_b+!q8w4W!)k`%}Rv2j*1dqrsHlX9^w< zRO#NhuFJ9<57JWSvxTirZLqp0pYLBU2f5nm(G8D}E`PQ8OB+WHSHwPMcp;%}sK~lN z4|M#+0h*!~FBg}Y_B%j6G(P*xsX%{+AEc;K-usB)Q%*>p!sCwtb* zbTPRBoTMKbjw3|nW=Ax?ZtPt*b*^DoYbSyeREd~IrapP_s8 z(JeV33?A?qLb82pAvF=V+9?*~$_sB3T`m_(w-$>107OR02$=OukW$G|ZX^yIqF zWXB&yPZxI@Qy-gLw@X(8rD}ga5D;5!w?eE>+|-}JiR6?XhHjqF{JP1HO=-836JyrM z-NXKv81~U#!IMvA^SSv#zG%oC3qS(%+I(?VH&{Vn%}{omUA(D`?k3*2Wkq?e`$|EI zVqHmvXycGCqgueO(|RGB9Sa0#L!a!oli_+u2DHr-wf|tJT5@FZLNm-?gOv(Zr?yfM zTLNoINCxa`%>ge5Jc?G$fz3|qwVvui0`|*22r4_c)<_ez>;;Gji3E@a?14TeA|&M> z6Bqh5C85^$W}PARH``NZz(AnzNmjt;&Je{sb571%v6(`CZw(yr`7;l`c3d>%?B4qN zd&`@nYqQy1mFnI?VohjU_fueV@XM>5W`*7SGRBc;WTrGFg=DWOos|2$Q+`trO#f7A zE}d*>nkIYa(d|>m#DFJ~j#Mg}Vgm|bndY<2n^1-Wnsg)aSv)fSQ`}|&+`a+M{g)_A zO;FR+90fr<)G~Q+_jndwN59E};IF!2EnEiFbBJ%K!CS(1a{>*a!4^52Rr2~Y!l!w& zg?nbnB|8Z7ru(}52oxj*c8%BiaqOUeu>Cdc;kt{MW00%cyEzIzI|IU3as zWBG6Gp&=N)j;d%jR^z_cB)F9ru7bL9is`>l40V%Lr zAVNK-r3XJfPn?Jmk;O6^BmmMY>-GAb1C`=v z`*<1AMpm!Y>PMT+q2Xrpj`Bdh-Vo(XO7@23AjArmhee46+q2op=0W>&vleE7oD5C? zp6w_W2ey1_1~~r*z%z~KdBGGUuP<$e;-$l*Gyt_C8UfX0fzyamHWtfO&(3V`%!D`| zdqB8zbVUfTRybS;sA4d#3h^ZIZ09?}NyD@Ni*O>yh#+6oZ_Rzv)8?;PQHe@Y74QO| zhhW9;g30gkXP4(XHBihrsFojbKzBe?27w2g)n=_Hfn$U-fl3lOkaYP{y8lLk>~iQP zi8z`hYTz<#qPT622OAA8-x^{U@-D4%iFHr=ucO{8+qLR~TqELSHe)CW+m%Gu2ZW!V z+`W5pa$zC7o#PL3+(Dk(F7gt$zz7VXn;<#A3;N$iXpFE?L|voMglEAJvznaT{n-M?;&zJ>@epSDyue9cLq8&O`D=t;1X~UKn@sda*U0gBX$qk!mq&Mh zpXY-CApk_(pVA2FhNx!$`j|_r8CH%)=PH9uh{0`)S^+fYlI*1`c32M=6x3Mgg^n?7 z{o?Uk-;vuA^}YibqWVDy)=^skbM{e3spHf=zli?<=J%&7I)s*jB!t|+U_yIznTOP> zg9!WD4=rQhKBi4T=>A4pC)&lQ0gf8P8n+z>n3<#20L~jot*IuQKbJtFFP=q(oq<%W+KYY^Lc_ao&D{f%Gv)xi~_J%#1(cdk5`P1E*2@qxhIHDsi9%Dc0kpU3?)uwVo$@kZxaBRRMH*ed<)Q&;G(WCd2~uj~zQLv@7e!`IW_ zfF&igDxtq>AO9SkdX)#SG{rm(-d@MQu(mxLWkrrqq+lEfs%|8_`t@9v7a1&Zgv0su5l!1Bcx&P4dgDp0qF5gkG%)@+XgI-- zb5dUk;CEh8szHNe3Y=GSZpQqa*IQH+0e>mKf0MUw!7J3f-c2^$vcf^*VHkX_m_MQ% z$`3HyIW4$J^j0i$JUr^OC-H_pbAu?@UhlTtNySmZdm$hIOhYkZ3LaQl!u!i(9A|dR z{(Y~*Vwbm1r&DwyF?DTyX~?ae+OY%HxBhSKdqr+u`CdQK>6^A61lTPTZdFZg=)@-h$V-%PWs?%z7K;;lovB z%PB>hP>hI@B2Q>?VpuaZk<+zrcz1iv0*?(j*t8NeT=!{j-f*_wqbX|@#a0&5+m(bz z^ggU;8yP$X-xLU9fArWZUMy0nPUfNSOMjj)&1BLvAvDlY+GnHNAzE^7=|POp6?CP0 zQ1CDRjhS%Upl3QSweQ<5T!SGm)kh6bPlLR_Lj5WA17w24_fTLpF4nW;Zk(S7OK(h| zW_$GR|yimcdvpsqkKoE2B0%Vhtf8FhvW&pwOA<2%3C9q9y_@=urb6cmc2jemf_51pQjT z>|YTtYyWcrvs=1fbz^;_;E4c;Fe{w5fM#IC{uv3rQG{I<+AA{C0LCD`br55a7(!GkT>9UZ2!q?U67&6c5&pjn z694}cVGrTkz{RdW5HkT^V+a@9L){MFiYcvXwBs}YnI8dd0E`?!aJ@#*8ZEwunJzXH zhaS9s;2h*%Ib0F}0Nv7{*kv0H;0=zQ@?#Ss2M$YGL#X6uV%&cK-?D|HO>Jk%M>oFc zZ-ZAJJGMEI-8;E%fnlGsU5CDfPChWWubW1*;L8i()1QRT`53FSr@vVKGC1KFU4WPY zDE*@+&o_Th7=`bV5J*`1^mRe+_v64PHNScE$x>G4mcH}F0!BNI{c&((e)_h3lki1z zJGzg!_$?>bKt_2mjrP#7nkW}wc)&a2>8~wMk&KMdC&-g=tx#>w8M^*@YBWW!|JjK6 z;sZ}S?}>gz|HI^d|L8wZ5^!<&y}k3Ph1Gj!^vTxxyL#nrB}KvrkiS66;M@l%UP(U& z_jPcdgL7e}%XY!`WznUgXgRh*_ VUGym+H{?gdf6Qr%1D9Sy{|EVDR5Jho diff --git a/modules/item/front/routes.json b/modules/item/front/routes.json index 8f3e037469..6d39083b43 100644 --- a/modules/item/front/routes.json +++ b/modules/item/front/routes.json @@ -9,7 +9,7 @@ {"state": "item.index", "icon": "icon-item"}, {"state": "item.request", "icon": "pan_tool"}, {"state": "item.waste.index", "icon": "icon-claims"}, - {"state": "item.fixedPrice", "icon": "contact_support"} + {"state": "item.fixedPrice", "icon": "icon-fixedPrice"} ], "card": [ {"state": "item.card.basicData", "icon": "settings"}, diff --git a/modules/supplier/front/routes.json b/modules/supplier/front/routes.json index 9a0dee48b1..9be6b7a850 100644 --- a/modules/supplier/front/routes.json +++ b/modules/supplier/front/routes.json @@ -13,7 +13,7 @@ {"state": "supplier.card.fiscalData", "icon": "account_balance"}, {"state": "supplier.card.billingData", "icon": "icon-payment"}, {"state": "supplier.card.address.index", "icon": "icon-delivery"}, - {"state": "supplier.card.account", "icon": "contact_support"}, + {"state": "supplier.card.account", "icon": "icon-accounts"}, {"state": "supplier.card.contact", "icon": "contact_phone"}, {"state": "supplier.card.log", "icon": "history"}, {"state": "supplier.card.consumption", "icon": "show_chart"} From 16c28cfa56079bdd11ba4856158783b7572558b6 Mon Sep 17 00:00:00 2001 From: alexm Date: Thu, 18 Nov 2021 12:15:37 +0100 Subject: [PATCH 093/124] fix(client): validate businessType --- e2e/paths/02-client/01_create_client.spec.js | 12 ++++-------- loopback/locale/en.json | 3 ++- loopback/locale/es.json | 5 +++-- modules/client/back/models/client.js | 9 +++++++++ modules/client/front/create/locale/es.yml | 3 ++- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/e2e/paths/02-client/01_create_client.spec.js b/e2e/paths/02-client/01_create_client.spec.js index bde4203b47..ff2aac6b9f 100644 --- a/e2e/paths/02-client/01_create_client.spec.js +++ b/e2e/paths/02-client/01_create_client.spec.js @@ -29,11 +29,11 @@ describe('Client create path', () => { it('should receive an error when clicking the create button having name and Business name fields empty', async() => { + await page.autocompleteSearch(selectors.createClientView.salesPerson, 'salesPerson'); + await page.autocompleteSearch(selectors.createClientView.businessType, 'florist'); await page.write(selectors.createClientView.taxNumber, '74451390E'); await page.write(selectors.createClientView.userName, 'CaptainMarvel'); await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es'); - await page.autocompleteSearch(selectors.createClientView.salesPerson, 'salesPerson'); - await page.autocompleteSearch(selectors.createClientView.businessType, 'florist'); await page.waitToClick(selectors.createClientView.createButton); const message = await page.waitForSnackbar(); @@ -83,7 +83,6 @@ describe('Client create path', () => { expect(message.text).toContain('Some fields are invalid'); }); - /* Tarea #3370 it(`should attempt to create a new user with all it's data but wrong business type`, async() => { await page.clearInput(selectors.createClientView.email); await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es'); @@ -91,13 +90,10 @@ describe('Client create path', () => { await page.waitToClick(selectors.createClientView.createButton); const message = await page.waitForSnackbar(); - expect(message.text).toContain('Some fields are invalid'); - });*/ + expect(message.text).toContain('The type of business must be filled in basic data'); + }); it(`should attempt to create a new user with all it's data but wrong postal code`, async() => { - await page.clearInput(selectors.createClientView.email); - await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es'); - await page.autocompleteSearch(selectors.createClientView.businessType, 'florist'); await page.clearInput(selectors.createClientView.postcode); await page.write(selectors.createClientView.postcode, '479999'); diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 271c3fd4f2..15c65fd89a 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -118,5 +118,6 @@ "reference duplicated": "reference duplicated", "The PDF document does not exists": "The PDF document does not exists. Try regenerating it from 'Regenerate invoice PDF' option", "This item is not available": "This item is not available", - "Deny buy request": "Purchase request for ticket id [{{ticketId}}]({{{url}}}) has been rejected. Reason: {{observation}}" + "Deny buy request": "Purchase request for ticket id [{{ticketId}}]({{{url}}}) has been rejected. Reason: {{observation}}", + "The type of business must be filled in basic data": "The type of business must be filled in basic data" } \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index afa349684f..4a5448d34c 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -133,7 +133,7 @@ "reserved": "reservado", "Changed sale reserved state": "He cambiado el estado reservado de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}", "Bought units from buy request": "Se ha comprado {{quantity}} unidades de [{{itemId}} {{concept}}]({{{urlItem}}}) para el ticket id [{{ticketId}}]({{{url}}})", - "Deny buy request":"Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}", + "Deny buy request": "Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}", "MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*", "Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})", "Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})", @@ -211,5 +211,6 @@ "Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio", "You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito", "You can't change the credit set to zero from a manager": "No puedes cambiar el cŕedito establecido a cero por un gerente", - "The PDF document does not exists": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'" + "The PDF document does not exists": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'", + "The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos" } \ No newline at end of file diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index 4cac16358f..f3591750da 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -55,6 +55,15 @@ module.exports = Self => { with: /^[\w|.|-]+@[\w|-]+(\.[\w|-]+)*(,[\w|.|-]+@[\w|-]+(\.[\w|-]+)*)*$/ }); + Self.validate('businessTypeFk', hasBusinessType, { + message: `The type of business must be filled in basic data` + }); + + function hasBusinessType(err) { + if (!this.businessTypeFk) + err(); + } + Self.validatesLengthOf('postcode', { allowNull: true, allowBlank: true, diff --git a/modules/client/front/create/locale/es.yml b/modules/client/front/create/locale/es.yml index 6922ba917b..31b7cd4037 100644 --- a/modules/client/front/create/locale/es.yml +++ b/modules/client/front/create/locale/es.yml @@ -7,4 +7,5 @@ Create and edit: Crear y editar You can save multiple emails: >- Puede guardar varios correos electrónicos encadenándolos mediante comas sin espacios, ejemplo: user@dominio.com, user2@dominio.com siendo el primer - correo electrónico el principal \ No newline at end of file + correo electrónico el principal +The type of business must be filled in basic data: El tipo de negocio debe estar rellenado en datos básicos From 5d2693f949ab465d84e5c584303ddef4b2938931 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 18 Nov 2021 12:23:21 +0100 Subject: [PATCH 094/124] Updated latest buys icon --- modules/entry/front/routes.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/entry/front/routes.json b/modules/entry/front/routes.json index 37dda7584c..3b2a8f146d 100644 --- a/modules/entry/front/routes.json +++ b/modules/entry/front/routes.json @@ -7,7 +7,7 @@ "menus": { "main": [ {"state": "entry.index", "icon": "icon-entry"}, - {"state": "entry.latestBuys", "icon": "contact_support"} + {"state": "entry.latestBuys", "icon": "icon-lastBuy"} ], "card": [ {"state": "entry.card.basicData", "icon": "settings"}, From 924e6d063d92cbebb5313a631ef7b54563438631 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 18 Nov 2021 12:42:31 +0100 Subject: [PATCH 095/124] moved getBalance modifications to correct version --- .../00-item_getBalance.sql | 0 db/dump/fixtures.sql | 34 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) rename db/changes/{10370-pickles => 10390-constitution}/00-item_getBalance.sql (100%) diff --git a/db/changes/10370-pickles/00-item_getBalance.sql b/db/changes/10390-constitution/00-item_getBalance.sql similarity index 100% rename from db/changes/10370-pickles/00-item_getBalance.sql rename to db/changes/10390-constitution/00-item_getBalance.sql diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index d52c5beef0..b460561358 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -798,23 +798,23 @@ INSERT INTO `vn`.`itemFamily`(`code`, `description`) INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`, `comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`, `isFloramondo`) VALUES - (1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT', 0), - (2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT', 0), - (3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT', 0), - (4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT', 0), - (5, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 3, 'VT', 0), - (6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT', 0), - (7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT', 0), - (8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT', 0), - (9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 0), - (10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT', 0), - (11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT', 0), - (12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT', 0), - (13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 0, 2, 'VT', 1), - (14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT', 1), - (15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0), - (16, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0), - (71, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT', 0); + (1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT', 0), + (2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT', 0), + (3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT', 0), + (4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT', 0), + (5, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 3, 'VT', 0), + (6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT', 0), + (7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT', 0), + (8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT', 0), + (9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 0), + (10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT', 0), + (11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT', 0), + (12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT', 0), + (13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 0, 2, 'VT', 1), + (14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT', 1), + (15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0), + (16, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0), + (71, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT', 0); -- Update the taxClass after insert of the items UPDATE `vn`.`itemTaxCountry` SET `taxClassFk` = 2 From c98730e6b9b673682bac66ddea9974164fb6f652 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 18 Nov 2021 14:00:45 +0100 Subject: [PATCH 096/124] Updated styles --- front/core/components/calendar/style.scss | 4 ++-- front/core/components/chip/style.scss | 2 +- front/core/components/smart-table/table.scss | 2 +- front/core/components/table/style.scss | 2 +- front/core/directives/no-image-dark.png | Bin 0 -> 6990 bytes front/core/directives/on-error-src.js | 2 +- front/core/styles/variables.scss | 6 +++--- modules/worker/front/calendar/style.scss | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 front/core/directives/no-image-dark.png diff --git a/front/core/components/calendar/style.scss b/front/core/components/calendar/style.scss index aecc3eecbc..6a7995ea5f 100644 --- a/front/core/components/calendar/style.scss +++ b/front/core/components/calendar/style.scss @@ -86,12 +86,12 @@ align-items: center; &.today { - color: $color-font-bg; + color: $color-font; & > .day-number { border: 2px solid $color-font-link; &:hover { - background-color: lighten($color-font-link, 20%); + background-color: $color-marginal; opacity: .8 } } diff --git a/front/core/components/chip/style.scss b/front/core/components/chip/style.scss index d1632890c6..cc0554509d 100644 --- a/front/core/components/chip/style.scss +++ b/front/core/components/chip/style.scss @@ -50,7 +50,7 @@ vn-chip { &.alert, &.alert.clickable:hover, &.alert.clickable:focus { - background-color: $color-alert-medium; + background-color: lighten($color-alert, 5%); } &.message, &.message.clickable:hover, diff --git a/front/core/components/smart-table/table.scss b/front/core/components/smart-table/table.scss index 8555340116..21ac20c811 100644 --- a/front/core/components/smart-table/table.scss +++ b/front/core/components/smart-table/table.scss @@ -90,7 +90,7 @@ smart-table table { color: $color-font-bg; } &.alert { - background-color: $color-alert-medium; + background-color: lighten($color-alert, 5%); color: $color-font-bg; } &.message { diff --git a/front/core/components/table/style.scss b/front/core/components/table/style.scss index edb40d385b..b1ff51d6ad 100644 --- a/front/core/components/table/style.scss +++ b/front/core/components/table/style.scss @@ -146,7 +146,7 @@ vn-table { color: $color-font-bg; } &.alert { - background-color: $color-alert-medium; + background-color: lighten($color-alert, 5%); color: $color-font-bg; } &.message { diff --git a/front/core/directives/no-image-dark.png b/front/core/directives/no-image-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f94f961697c229ee77d19e9a23ddc88382db8b43 GIT binary patch literal 6990 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 Date: Thu, 18 Nov 2021 14:07:05 +0100 Subject: [PATCH 097/124] Updated dark image --- front/core/directives/no-image-dark.png | Bin 6990 -> 7038 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/front/core/directives/no-image-dark.png b/front/core/directives/no-image-dark.png index f94f961697c229ee77d19e9a23ddc88382db8b43..2a20d7eb4970509bc5f8e9a2bb2b5d33fee3c260 100644 GIT binary patch literal 7038 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 literal 6990 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 Date: Thu, 18 Nov 2021 14:27:05 +0100 Subject: [PATCH 098/124] feat(ticket): default ticketAction for salesAssistant --- modules/ticket/front/basic-data/step-two/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index ebb93bb3d1..7ffdb8315d 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -23,7 +23,9 @@ class Controller extends Component { } loadDefaultTicketAction() { - let filter = {where: {code: 'changePrice'}}; + const isSalesAssistant = this.aclService.hasAny(['salesAssistant']); + const defaultOption = isSalesAssistant ? 'turnInMana' : 'changePrice'; + const filter = {where: {code: defaultOption}}; this.$http.get(`TicketUpdateActions`, {filter}).then(response => { return this.ticket.option = response.data[0].id; From 3eb7b4cf552d8a648edc3508fd05b3bb445c6bed Mon Sep 17 00:00:00 2001 From: carlosjr Date: Thu, 18 Nov 2021 14:49:05 +0100 Subject: [PATCH 099/124] refactor(item.filter): buildFilter switch refactor --- modules/item/back/methods/item/filter.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/item/back/methods/item/filter.js b/modules/item/back/methods/item/filter.js index 4edb16d3da..29099c7ec2 100644 --- a/modules/item/back/methods/item/filter.js +++ b/modules/item/back/methods/item/filter.js @@ -109,13 +109,13 @@ module.exports = Self => { ? {or: [{'i.id': value}, codeWhere]} : {or: [{'i.name': {like: `%${value}%`}}, codeWhere]}; case 'id': - return {'i.id': value}; case 'isActive': - return {'i.isActive': value}; + case 'typeFk': + case 'isFloramondo': + param = `i.${param}`; + return {[param]: value}; case 'multiplier': return {'i.stemMultiplier': value}; - case 'typeFk': - return {'i.typeFk': value}; case 'categoryFk': return {'ic.id': value}; case 'buyerFk': @@ -126,8 +126,6 @@ module.exports = Self => { return {'intr.description': value}; case 'landed': return {'lb.landed': value}; - case 'isFloramondo': - return {'i.isFloramondo': value}; } }); From 9c5939b66180a68fa595ba403582d347f112fa37 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 18 Nov 2021 16:02:47 +0100 Subject: [PATCH 100/124] Updated styles --- front/core/components/field/style.scss | 4 ++-- front/core/components/smart-table/table.scss | 6 +++--- front/core/components/table/style.scss | 8 ++++---- front/core/styles/variables.scss | 4 +++- front/salix/components/summary/style.scss | 6 +++--- front/salix/styles/misc.scss | 2 +- modules/entry/front/summary/style.scss | 6 +++--- modules/monitor/front/index/orders/style.scss | 2 +- modules/monitor/front/index/style.scss | 2 +- modules/worker/front/calendar/style.scss | 5 ++--- 10 files changed, 23 insertions(+), 22 deletions(-) diff --git a/front/core/components/field/style.scss b/front/core/components/field/style.scss index c611773e35..399122b1d0 100644 --- a/front/core/components/field/style.scss +++ b/front/core/components/field/style.scss @@ -226,7 +226,7 @@ & > .container { & > .infix > .control > * { - color: $color-font; + color: $color-marginal; &::placeholder { color: $color-font-bg; @@ -235,7 +235,7 @@ & > .prepend, & > .append, & > .icons { - color: $color-font-bg-marginal; + color: $color-marginal; } } } diff --git a/front/core/components/smart-table/table.scss b/front/core/components/smart-table/table.scss index 21ac20c811..b38ca7d824 100644 --- a/front/core/components/smart-table/table.scss +++ b/front/core/components/smart-table/table.scss @@ -6,14 +6,14 @@ smart-table table { border-collapse: collapse; & > thead { - border-bottom: 2px solid $color-spacer; + border-bottom: $border; & > * > th { font-weight: normal; } } & > tfoot { - border-top: 2px solid $color-spacer; + border-top: $border; } thead, tbody, tfoot { & > * { @@ -67,7 +67,7 @@ smart-table table { } } tbody > * { - border-bottom: 1px solid $color-spacer-light; + border-bottom: $border-thin; &:last-child { border-bottom: none; diff --git a/front/core/components/table/style.scss b/front/core/components/table/style.scss index b1ff51d6ad..28d5a4f363 100644 --- a/front/core/components/table/style.scss +++ b/front/core/components/table/style.scss @@ -14,7 +14,7 @@ vn-table { & > vn-thead, & > thead { display: table-header-group; - border-bottom: 2px solid $color-spacer; + border-bottom: $border; & > * > th { font-weight: normal; @@ -32,7 +32,7 @@ vn-table { & > vn-tfoot, & > .vn-tfoot, & > tfoot { - border-top: 2px solid $color-spacer; + border-top: $border; display: table-footer-group } & > * > vn-tr, @@ -119,7 +119,7 @@ vn-table { vn-tbody > *, .vn-tbody > *, tbody > * { - border-bottom: 1px solid $color-spacer-light; + border-bottom: $border-thin; &:last-child { border-bottom: none; @@ -197,7 +197,7 @@ vn-table.scrollable > .vn-table, vn-thead vn-th, thead vn-th, thead th { - border-bottom: 2px solid $color-spacer; + border-bottom: $border; background-color: $color-bg-panel; position: sticky; z-index: 9; diff --git a/front/core/styles/variables.scss b/front/core/styles/variables.scss index bd00c9a072..c79a8590fb 100644 --- a/front/core/styles/variables.scss +++ b/front/core/styles/variables.scss @@ -108,6 +108,7 @@ $color-spacer-light: rgba(255, 255, 255, .12); $color-input-underline: rgba(255, 255, 255, .12); $color-input-underline-hover: rgba(255, 255, 255, .6); $color-shadow: rgba(0, 0, 0, .2); +$color-border: rgba(0, 0, 0, .3); $color-hightlight: rgba(255, 255, 255, .15); $color-hover-cd: rgba(255, 255, 255, .1); $color-hover-dc: .7; @@ -129,6 +130,7 @@ $color-alert-light: lighten($color-alert, 35%); // Border -$border-thin: 1px solid $color-spacer; +$border-thin: 1px solid $color-border; $border-thin-light: 1px solid $color-spacer-light; +$border: 2px solid $color-border; $shadow: 0 2px 2px 0 rgba(0, 0, 0, .3); diff --git a/front/salix/components/summary/style.scss b/front/salix/components/summary/style.scss index 2db3d961e0..6f93a61bfe 100644 --- a/front/salix/components/summary/style.scss +++ b/front/salix/components/summary/style.scss @@ -65,10 +65,10 @@ ui-view > .vn-summary { text-transform: uppercase; font-size: 1.25rem; line-height: 1; - padding: 7px; - padding-bottom: 4px; /* Bottom line-height fix */ + padding: 7px 0; + padding-bottom: 5px; /* Bottom line-height fix */ font-weight: lighter; - border-bottom: 1px solid $color-main; + border-bottom: 2px solid $color-main; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; diff --git a/front/salix/styles/misc.scss b/front/salix/styles/misc.scss index 55de5eb0c2..02bfd9f175 100644 --- a/front/salix/styles/misc.scss +++ b/front/salix/styles/misc.scss @@ -60,7 +60,7 @@ vn-bg-title { font-size: 1.25rem; } .totalBox { - border: 1px solid #CCC; + border: $border-thin; text-align: right; justify-content: center; align-items: center; diff --git a/modules/entry/front/summary/style.scss b/modules/entry/front/summary/style.scss index 1e3d3d4824..1d5b22e303 100644 --- a/modules/entry/front/summary/style.scss +++ b/modules/entry/front/summary/style.scss @@ -9,13 +9,13 @@ vn-entry-summary .summary { } tbody tr:nth-child(1) { - border-top: 1px solid $color-spacer; + border-top: $border-thin; } tbody tr:nth-child(1), tbody tr:nth-child(2) { - border-left: 1px solid $color-spacer; - border-right: 1px solid $color-spacer + border-left: $border-thin; + border-right: $border-thin } tbody tr:nth-child(3) { diff --git a/modules/monitor/front/index/orders/style.scss b/modules/monitor/front/index/orders/style.scss index d9d50360e4..64d6497c90 100644 --- a/modules/monitor/front/index/orders/style.scss +++ b/modules/monitor/front/index/orders/style.scss @@ -11,7 +11,7 @@ vn-monitor-sales-orders { color: gray; & > vn-td { - border-bottom: 2px solid $color-spacer; + border-bottom: $border; font-size: 13px; } } diff --git a/modules/monitor/front/index/style.scss b/modules/monitor/front/index/style.scss index 9eda945b56..2b193ac885 100644 --- a/modules/monitor/front/index/style.scss +++ b/modules/monitor/front/index/style.scss @@ -6,7 +6,7 @@ vn-monitor-index { padding: 12px 0 5px 0; color: gray; font-size: 1.2rem; - border-bottom: 2px solid $color-font-secondary; + border-bottom: $border; margin-bottom: 10px; & > vn-none > vn-icon { diff --git a/modules/worker/front/calendar/style.scss b/modules/worker/front/calendar/style.scss index d65c80833a..d92c54806f 100644 --- a/modules/worker/front/calendar/style.scss +++ b/modules/worker/front/calendar/style.scss @@ -11,7 +11,7 @@ vn-worker-calendar { padding: $spacing-md; & > vn-calendar { - border: 1px solid #ddd; + border: $border-thin; margin: $spacing-md; padding: $spacing-xs; max-width: 288px; @@ -38,8 +38,7 @@ vn-worker-calendar { } vn-side-menu div > .input { - border-color: rgba(0, 0, 0, 0.3); - border-bottom: 1px solid rgba(0, 0, 0, 0.3); + border-bottom: $border-thin; } .festive, From 8c5f0d3019a818c838a566ee7405aad852fa2f4e Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 19 Nov 2021 09:24:31 +0100 Subject: [PATCH 101/124] feat(createClaim): disallow claim creation for a ticket delivered more than seven days ago Refs: 3278 --- loopback/locale/es.json | 3 ++- modules/claim/back/methods/claim/createFromSales.js | 6 ++++++ modules/ticket/front/sale/index.html | 3 ++- modules/ticket/front/sale/index.js | 10 ++++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 4a5448d34c..e42c13c72a 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -212,5 +212,6 @@ "You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito", "You can't change the credit set to zero from a manager": "No puedes cambiar el cŕedito establecido a cero por un gerente", "The PDF document does not exists": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'", - "The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos" + "The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos", + "You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días" } \ No newline at end of file diff --git a/modules/claim/back/methods/claim/createFromSales.js b/modules/claim/back/methods/claim/createFromSales.js index f22aabbf36..cdbce865b4 100644 --- a/modules/claim/back/methods/claim/createFromSales.js +++ b/modules/claim/back/methods/claim/createFromSales.js @@ -57,8 +57,14 @@ module.exports = Self => { } }, myOptions); + const landedPlusWeek = new Date(ticket.landed); + landedPlusWeek.setDate(landedPlusWeek.getDate() + 7); + const isClaimable = landedPlusWeek >= new Date(); + if (ticket.isDeleted) throw new UserError(`You can't create a claim for a removed ticket`); + if (!isClaimable) + throw new UserError(`You can't create a claim from a ticket delivered more than seven days ago`); const newClaim = await Self.create({ ticketFk: ticketId, diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index cbb95d9010..0aa41226bb 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -469,7 +469,8 @@ + ng-click="$ctrl.createClaim()" + ng-if="$ctrl.isClaimable"> Add claim = new Date(); + } + return false; + } + getSaleTotal(sale) { if (sale.quantity == null || sale.price == null) return null; From 46d7a6e765b8abd44956fffe72f9dadff0725c7f Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 19 Nov 2021 09:24:49 +0100 Subject: [PATCH 102/124] Added unit tests --- .../claim/specs/createFromSales.spec.js | 64 ++++++++++++++----- modules/ticket/front/sale/index.spec.js | 22 ++++++- 2 files changed, 70 insertions(+), 16 deletions(-) diff --git a/modules/claim/back/methods/claim/specs/createFromSales.spec.js b/modules/claim/back/methods/claim/specs/createFromSales.spec.js index 849ccf8f51..8a48b86131 100644 --- a/modules/claim/back/methods/claim/specs/createFromSales.spec.js +++ b/modules/claim/back/methods/claim/specs/createFromSales.spec.js @@ -1,31 +1,40 @@ -const app = require('vn-loopback/server/server'); +const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('Claim createFromSales()', () => { - const ticketId = 2; + const ticketId = 16; const newSale = [{ id: 3, instance: 0, quantity: 10 }]; - const ctx = { - req: { - accessToken: {userId: 1}, - headers: {origin: 'localhost:5000'}, - __: () => {} - } + const activeCtx = { + accessToken: {userId: 1}, + headers: {origin: 'localhost:5000'}, + __: () => {} }; + const ctx = { + req: activeCtx + }; + + beforeEach(() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + it('should create a new claim', async() => { - const tx = await app.models.Claim.beginTransaction({}); + const tx = await models.Claim.beginTransaction({}); try { const options = {transaction: tx}; - const claim = await app.models.Claim.createFromSales(ctx, ticketId, newSale, options); + const claim = await models.Claim.createFromSales(ctx, ticketId, newSale, options); expect(claim.ticketFk).toEqual(ticketId); - let claimBeginning = await app.models.ClaimBeginning.findOne({where: {claimFk: claim.id}}, options); + let claimBeginning = await models.ClaimBeginning.findOne({where: {claimFk: claim.id}}, options); expect(claimBeginning.saleFk).toEqual(newSale[0].id); expect(claimBeginning.quantity).toEqual(newSale[0].quantity); @@ -37,17 +46,42 @@ describe('Claim createFromSales()', () => { } }); - it('should not be able to create a claim if exists that sale', async() => { - const tx = await app.models.Claim.beginTransaction({}); + it('should not be able to create a claim for a ticket delivered more than seven days ago', async() => { + const tx = await models.Claim.beginTransaction({}); let error; try { const options = {transaction: tx}; - await app.models.Claim.createFromSales(ctx, ticketId, newSale, options); + const todayMinusEightDays = new Date(); + todayMinusEightDays.setDate(todayMinusEightDays.getDate() - 8); - await app.models.Claim.createFromSales(ctx, ticketId, newSale, options); + const ticket = await models.Ticket.findById(ticketId, options); + await ticket.updateAttribute('landed', todayMinusEightDays, options); + + await models.Claim.createFromSales(ctx, ticketId, newSale, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.toString()).toContain(`You can't create a claim from a ticket delivered more than seven days ago`); + }); + + it('should not be able to create a claim if exists that sale', async() => { + const tx = await models.Claim.beginTransaction({}); + + let error; + + try { + const options = {transaction: tx}; + + await models.Claim.createFromSales(ctx, ticketId, newSale, options); + + await models.Claim.createFromSales(ctx, ticketId, newSale, options); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index cee1fe5b40..d543c1b816 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -15,7 +15,8 @@ describe('Ticket', () => { const ticket = { id: 1, clientFk: 1101, - shipped: 1, + shipped: new Date(), + landed: new Date(), created: new Date(), client: {salesPersonFk: 1}, address: {mobile: 111111111} @@ -74,6 +75,25 @@ describe('Ticket', () => { }); }); + describe('isClaimable() getter', () => { + it('should return true for a ticket delivered less than seven days ago', () => { + const result = controller.isClaimable; + + expect(result).toEqual(true); + }); + + it('should return false for a ticket delivered more than seven days ago', () => { + const ticket = controller.ticket; + const landedMinusEightDays = new Date(ticket.landed); + landedMinusEightDays.setDate(landedMinusEightDays.getDate() - 8); + ticket.landed = landedMinusEightDays; + + const result = controller.isClaimable; + + expect(result).toEqual(false); + }); + }); + describe('getSaleTotal()', () => { it('should return the sale total amount', () => { const sale = { From 60c0943044a658fc16a617610385543828fd2e20 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 19 Nov 2021 09:36:27 +0100 Subject: [PATCH 103/124] Dark theme autofill color --- front/core/components/field/style.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/front/core/components/field/style.scss b/front/core/components/field/style.scss index 399122b1d0..91e0c3ec48 100644 --- a/front/core/components/field/style.scss +++ b/front/core/components/field/style.scss @@ -116,6 +116,7 @@ &:active, &:valid { box-shadow: 0 0 0 40px $color-bg-panel inset; + -webkit-text-fill-color: $color-primary-medium } } } From ac9ed90f4a7c8f21470fb903ea6a0e0a2b584770 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 19 Nov 2021 10:02:40 +0100 Subject: [PATCH 104/124] feat(item): modify item_getBalance and do test --- .../10390-constitution/00-item_getBalance.sql | 7 ++-- modules/item/back/methods/item/filter.js | 3 +- .../methods/item/specs/getBalance.spec.js | 32 +++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/db/changes/10390-constitution/00-item_getBalance.sql b/db/changes/10390-constitution/00-item_getBalance.sql index 90e3ee2bb2..54f612eaea 100644 --- a/db/changes/10390-constitution/00-item_getBalance.sql +++ b/db/changes/10390-constitution/00-item_getBalance.sql @@ -2,8 +2,7 @@ DROP PROCEDURE IF EXISTS `vn`.`item_getBalance`; DELIMITER $$ $$ -CREATE - definer = root@`%` procedure `vn`.`item_getBalance`(IN vItemId int, IN vWarehouse int) +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`item_getBalance`(IN vItemId int, IN vWarehouse int) BEGIN DECLARE vDateInventory DATETIME; DECLARE vCurdate DATE DEFAULT CURDATE(); @@ -116,7 +115,7 @@ BEGIN s.id, st.`order`, ct.code, - cl.id + cb.claimFk FROM sale s JOIN ticket t ON t.id = s.ticketFk LEFT JOIN ticketState ts ON ts.ticket = t.id @@ -132,6 +131,7 @@ BEGIN LEFT JOIN state stPrep ON stPrep.`code` = 'PREPARED' LEFT JOIN saleTracking stk ON stk.saleFk = s.id AND stk.stateFk = stPrep.id LEFT JOIN claim cl ON cl.ticketFk = t.id + LEFT JOIN claimBeginning cb ON cl.id = cb.claimFk AND s.id = cb.saleFk WHERE t.shipped >= vDateInventory AND s.itemFk = vItemId AND vWarehouse =t.warehouseFk @@ -141,4 +141,3 @@ BEGIN END; $$ DELIMITER ; - diff --git a/modules/item/back/methods/item/filter.js b/modules/item/back/methods/item/filter.js index 29099c7ec2..810cf4071b 100644 --- a/modules/item/back/methods/item/filter.js +++ b/modules/item/back/methods/item/filter.js @@ -112,8 +112,7 @@ module.exports = Self => { case 'isActive': case 'typeFk': case 'isFloramondo': - param = `i.${param}`; - return {[param]: value}; + return {[`i.${param}`]: value}; case 'multiplier': return {'i.stemMultiplier': value}; case 'categoryFk': diff --git a/modules/item/back/methods/item/specs/getBalance.spec.js b/modules/item/back/methods/item/specs/getBalance.spec.js index 5143a346fd..779516b198 100644 --- a/modules/item/back/methods/item/specs/getBalance.spec.js +++ b/modules/item/back/methods/item/specs/getBalance.spec.js @@ -36,4 +36,36 @@ describe('item getBalance()', () => { throw e; } }); + + it('should show the claimFk only on the claimed item', async() => { + const tx = await models.Item.beginTransaction({}); + const options = {transaction: tx}; + + try { + const firstFilter = { + where: { + itemFk: 1, + warehouseFk: 1 + } + }; + + const secondFilter = { + where: { + itemFk: 2, + warehouseFk: 1 + } + }; + + const firstItemBalance = await models.Item.getBalance(firstFilter, options); + const secondItemBalance = await models.Item.getBalance(secondFilter, options); + + expect(firstItemBalance[9].claimFk).toEqual(null); + expect(secondItemBalance[5].claimFk).toEqual(2); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); From 8f2e29787b2ef3dee96210e283eb6c82bc920e41 Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 19 Nov 2021 10:07:33 +0100 Subject: [PATCH 105/124] fix(payMethod): alter colums name --- db/changes/10390-constitution/00-payMethod.sql | 2 ++ db/dump/fixtures.sql | 2 +- modules/client/back/models/client.js | 2 +- modules/client/back/models/pay-method.json | 4 ++-- modules/client/front/billing-data/index.html | 2 +- modules/supplier/back/models/supplier.js | 2 +- modules/supplier/front/billing-data/index.html | 2 +- 7 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 db/changes/10390-constitution/00-payMethod.sql diff --git a/db/changes/10390-constitution/00-payMethod.sql b/db/changes/10390-constitution/00-payMethod.sql new file mode 100644 index 0000000000..6e196af954 --- /dev/null +++ b/db/changes/10390-constitution/00-payMethod.sql @@ -0,0 +1,2 @@ +ALTER TABLE vn.payMethod CHANGE ibanRequiredForClients isIbanRequiredForClients tinyint(3) DEFAULT 0 NULL; +ALTER TABLE vn.payMethod CHANGE ibanRequiredForSuppliers isIbanRequiredForSuppliers tinyint(3) DEFAULT 0 NULL; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index b460561358..bb48d40b4b 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -217,7 +217,7 @@ UPDATE `vn`.`agencyMode` SET `web` = 1, `reportMail` = 'no-reply@gothamcity.com' UPDATE `vn`.`agencyMode` SET `code` = 'refund' WHERE `id` = 23; -INSERT INTO `vn`.`payMethod`(`id`,`code`, `name`, `graceDays`, `outstandingDebt`, `ibanRequiredForClients`, `ibanRequiredForSuppliers`) +INSERT INTO `vn`.`payMethod`(`id`,`code`, `name`, `graceDays`, `outstandingDebt`, `isIbanRequiredForClients`, `isIbanRequiredForSuppliers`) VALUES (1, NULL, 'PayMethod one', 0, 001, 0, 0), (2, NULL, 'PayMethod two', 10, 001, 0, 0), diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index f3591750da..1a4e9bcb37 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -138,7 +138,7 @@ module.exports = Self => { function hasIban(err, done) { Self.app.models.PayMethod.findById(this.payMethodFk, (_, instance) => { - if (instance && instance.ibanRequiredForClients && !this.iban) + if (instance && instance.isIbanRequiredForClients && !this.iban) err(); done(); }); diff --git a/modules/client/back/models/pay-method.json b/modules/client/back/models/pay-method.json index 0666be7a5b..4080a09538 100644 --- a/modules/client/back/models/pay-method.json +++ b/modules/client/back/models/pay-method.json @@ -25,10 +25,10 @@ "outstandingDebt": { "type": "Number" }, - "ibanRequiredForClients": { + "isIbanRequiredForClients": { "type": "boolean" }, - "ibanRequiredForSuppliers": { + "isIbanRequiredForSuppliers": { "type": "boolean" } } diff --git a/modules/client/front/billing-data/index.html b/modules/client/front/billing-data/index.html index 8c7c6cfe9d..06d7d7d73a 100644 --- a/modules/client/front/billing-data/index.html +++ b/modules/client/front/billing-data/index.html @@ -19,7 +19,7 @@ vn-acl="salesAssistant" ng-model="$ctrl.client.payMethodFk" data="paymethods" - fields="['ibanRequiredForClients']" + fields="['isIbanRequiredForClients']" initial-data="$ctrl.client.payMethod"> { const supplierAccount = await Self.app.models.SupplierAccount.findOne({where: {supplierFk: this.id}}); const hasIban = supplierAccount && supplierAccount.iban; - if (payMethod && payMethod.ibanRequiredForSuppliers && !hasIban) + if (payMethod && payMethod.isIbanRequiredForSuppliers && !hasIban) err(); done(); diff --git a/modules/supplier/front/billing-data/index.html b/modules/supplier/front/billing-data/index.html index c1c57e1357..238760c1a9 100644 --- a/modules/supplier/front/billing-data/index.html +++ b/modules/supplier/front/billing-data/index.html @@ -24,7 +24,7 @@ vn-acl="salesAssistant" ng-model="$ctrl.supplier.payMethodFk" data="paymethods" - fields="['ibanRequiredForSuppliers']" + fields="['isIbanRequiredForSuppliers']" initial-data="$ctrl.supplier.payMethod"> Date: Fri, 19 Nov 2021 10:18:54 +0100 Subject: [PATCH 106/124] Searchbar focus css fix --- front/core/components/field/style.scss | 25 +++++++++++++++++++++++- front/salix/components/layout/style.scss | 9 ++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/front/core/components/field/style.scss b/front/core/components/field/style.scss index 399122b1d0..ceaeda40ab 100644 --- a/front/core/components/field/style.scss +++ b/front/core/components/field/style.scss @@ -116,6 +116,7 @@ &:active, &:valid { box-shadow: 0 0 0 40px $color-bg-panel inset; + -webkit-text-fill-color: $color-primary-medium } } } @@ -198,7 +199,7 @@ } &.standout { border-radius: 1px; - background-color: rgba(255, 255, 255, .1); + background-color: rgba(161, 161, 161, 0.1); padding: 0 12px; transition-property: background-color, color; transition-duration: 200ms; @@ -208,6 +209,17 @@ & > .underline { display: none; } + & > .infix > .control > input { + &:-internal-autofill-selected { + &, + &:hover, + &:active, + &:valid { + box-shadow: 0 0 0 40px #474747 inset; + -webkit-text-fill-color: $color-font-dark + } + } + } & > .infix > .control > * { color: $color-font-dark; @@ -225,6 +237,17 @@ background-color: $color-font-dark; & > .container { + & > .infix > .control > input { + &:-internal-autofill-selected { + &, + &:hover, + &:active, + &:valid { + box-shadow: 0 0 0 40px $color-font-dark inset; + -webkit-text-fill-color: $color-font-bg + } + } + } & > .infix > .control > * { color: $color-marginal; diff --git a/front/salix/components/layout/style.scss b/front/salix/components/layout/style.scss index aa35f8d14e..36522bc3a1 100644 --- a/front/salix/components/layout/style.scss +++ b/front/salix/components/layout/style.scss @@ -23,9 +23,12 @@ vn-layout { padding-right: 16px; overflow: hidden; - & > .logo > img { - height: 32px; - display: block; + & > .logo { + outline: 0; + & > img { + height: 32px; + display: block; + } } & > .main-title { font-size: 1.56rem; From e64e06b9ab090801c560df3f4e1d4b13a8bb802f Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 19 Nov 2021 12:10:53 +0100 Subject: [PATCH 107/124] feat(client): change phone for payMethod in descriptor --- modules/client/front/descriptor/index.html | 4 ++-- modules/client/front/descriptor/locale/es.yml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/client/front/descriptor/index.html b/modules/client/front/descriptor/index.html index d5beca282e..d1a88aee76 100644 --- a/modules/client/front/descriptor/index.html +++ b/modules/client/front/descriptor/index.html @@ -17,8 +17,8 @@

+ label="Pay method" + value="{{$ctrl.client.payMethod.name}}"> Date: Mon, 22 Nov 2021 08:27:14 +0100 Subject: [PATCH 108/124] feat(item and latest-buys: add supplier filter --- .../entry/back/methods/entry/latestBuysFilter.js | 11 ++++++++++- .../entry/front/latest-buys-search-panel/index.html | 11 +++++++++++ modules/item/back/methods/item/filter.js | 11 ++++++++++- modules/item/front/search-panel/index.html | 13 ++++++++++++- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js index 7711bc0f10..3b6da1acde 100644 --- a/modules/entry/back/methods/entry/latestBuysFilter.js +++ b/modules/entry/back/methods/entry/latestBuysFilter.js @@ -39,6 +39,11 @@ module.exports = Self => { type: 'integer', description: 'The buyer of the item', }, + { + arg: 'supplierFk', + type: 'integer', + description: 'The supplier of the item', + }, { arg: 'active', type: 'boolean', @@ -99,6 +104,8 @@ module.exports = Self => { return {'ic.id': value}; case 'salesPersonFk': return {'it.workerFk': value}; + case 'supplierFk': + return {'s.id': value}; case 'code': return {'it.code': value}; case 'active': @@ -172,7 +179,9 @@ module.exports = Self => { LEFT JOIN itemCategory ic ON ic.id = it.categoryFk LEFT JOIN itemType t ON t.id = i.typeFk LEFT JOIN intrastat intr ON intr.id = i.intrastatFk - LEFT JOIN origin ori ON ori.id = i.originFk` + LEFT JOIN origin ori ON ori.id = i.originFk + LEFT JOIN entry e ON e.id = b.entryFk + LEFT JOIN supplier s ON s.id = e.supplierFk` ); if (ctx.args.tags) { diff --git a/modules/entry/front/latest-buys-search-panel/index.html b/modules/entry/front/latest-buys-search-panel/index.html index 4693141f85..7d570f7982 100644 --- a/modules/entry/front/latest-buys-search-panel/index.html +++ b/modules/entry/front/latest-buys-search-panel/index.html @@ -46,6 +46,17 @@ where="{role: {inq: ['logistic', 'buyer']}}" label="Buyer"> + + {{name}}: {{nickname}} + { type: 'integer', description: 'The buyer of the item', }, + { + arg: 'supplierFk', + type: 'integer', + description: 'The supplier of the item', + }, { arg: 'description', type: 'string', @@ -120,6 +125,8 @@ module.exports = Self => { return {'ic.id': value}; case 'buyerFk': return {'it.workerFk': value}; + case 'supplierFk': + return {'s.id': value}; case 'origin': return {'ori.code': value}; case 'intrastat': @@ -170,7 +177,9 @@ module.exports = Self => { LEFT JOIN producer pr ON pr.id = i.producerFk LEFT JOIN origin ori ON ori.id = i.originFk LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = it.warehouseFk - LEFT JOIN vn.buy b ON b.id = lb.buy_id` + LEFT JOIN buy b ON b.id = lb.buy_id + LEFT JOIN entry e ON e.id = b.entryFk + LEFT JOIN supplier s ON s.id = e.supplierFk` ); if (ctx.args.tags) { diff --git a/modules/item/front/search-panel/index.html b/modules/item/front/search-panel/index.html index 57f05bb546..7cbe9c56d2 100644 --- a/modules/item/front/search-panel/index.html +++ b/modules/item/front/search-panel/index.html @@ -43,10 +43,21 @@ ng-model="filter.buyerFk" url="Items/activeBuyers" show-field="nickname" - search-function="{firstName: $search}" + search-function="{nickname: {like: '%'+ $search +'%'}}" value-field="workerFk" label="Buyer"> + + {{name}}: {{nickname}} + From 1e6805a1614ca860a53cdba621c7602ccdbbbbcf Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 22 Nov 2021 08:30:28 +0100 Subject: [PATCH 109/124] remove unnecessary tabulation --- modules/entry/back/methods/entry/latestBuysFilter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js index 3b6da1acde..c877612e1f 100644 --- a/modules/entry/back/methods/entry/latestBuysFilter.js +++ b/modules/entry/back/methods/entry/latestBuysFilter.js @@ -181,7 +181,7 @@ module.exports = Self => { LEFT JOIN intrastat intr ON intr.id = i.intrastatFk LEFT JOIN origin ori ON ori.id = i.originFk LEFT JOIN entry e ON e.id = b.entryFk - LEFT JOIN supplier s ON s.id = e.supplierFk` + LEFT JOIN supplier s ON s.id = e.supplierFk` ); if (ctx.args.tags) { From 97a66754a7518238566d86d961582cb0afbef8c8 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 22 Nov 2021 08:58:54 +0100 Subject: [PATCH 110/124] feat(item and entry): add back test --- .../entry/specs/latestBuysFilter.spec.js | 12 ++++++ .../back/methods/item/specs/filter.spec.js | 40 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js index f386894dde..bdd302adbc 100644 --- a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js +++ b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js @@ -136,5 +136,17 @@ describe('Buy latests buys filter()', () => { expect(results.length).toBe(1); }); + + it('should return results matching "supplierFk"', async() => { + let ctx = { + args: { + supplierFk: 1 + } + }; + + let results = await app.models.Buy.latestBuysFilter(ctx); + + expect(results.length).toBe(2); + }); }); diff --git a/modules/item/back/methods/item/specs/filter.spec.js b/modules/item/back/methods/item/specs/filter.spec.js index 7b1fac9ac0..30bdcec325 100644 --- a/modules/item/back/methods/item/specs/filter.spec.js +++ b/modules/item/back/methods/item/specs/filter.spec.js @@ -79,4 +79,44 @@ describe('item filter()', () => { throw e; } }); + + it('should return 2 result filtering by buyerFk', async() => { + const tx = await models.Item.beginTransaction({}); + const options = {transaction: tx}; + + try { + const filter = {}; + const ctx = {args: {filter: filter, buyerFk: 16}}; + const result = await models.Item.filter(ctx, filter, options); + + expect(result.length).toEqual(2); + expect(result[0].id).toEqual(16); + expect(result[1].id).toEqual(71); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should return 2 result filtering by supplierFk', async() => { + const tx = await models.Item.beginTransaction({}); + const options = {transaction: tx}; + + try { + const filter = {}; + const ctx = {args: {filter: filter, supplierFk: 1}}; + const result = await models.Item.filter(ctx, filter, options); + + expect(result.length).toEqual(2); + expect(result[0].id).toEqual(1); + expect(result[1].id).toEqual(3); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); From fe46dbd34312de5826b0315ab66a8f9b31aeb8bf Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 22 Nov 2021 11:49:30 +0100 Subject: [PATCH 111/124] feat(entry_last-buys): add filter isFloramondo --- db/dump/fixtures.sql | 2 +- .../back/methods/entry/latestBuysFilter.js | 7 ++++++ .../entry/specs/latestBuysFilter.spec.js | 24 +++++++++++++++++++ .../front/latest-buys-search-panel/index.html | 5 ++++ modules/entry/front/latest-buys/locale/es.yml | 2 ++ .../back/methods/item/specs/filter.spec.js | 4 ++-- 6 files changed, 41 insertions(+), 3 deletions(-) diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index b460561358..1fce7ae381 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -806,7 +806,7 @@ INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `d (6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT', 0), (7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT', 0), (8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT', 0), - (9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 0), + (9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 1), (10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT', 0), (11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT', 0), (12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT', 0), diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js index 7711bc0f10..435427448b 100644 --- a/modules/entry/back/methods/entry/latestBuysFilter.js +++ b/modules/entry/back/methods/entry/latestBuysFilter.js @@ -49,6 +49,11 @@ module.exports = Self => { type: 'boolean', description: 'Whether the item is or not visible', }, + { + arg: 'floramondo', + type: 'boolean', + description: 'Whether the item is or not floramondo', + }, { arg: 'typeFk', type: 'integer', @@ -103,6 +108,8 @@ module.exports = Self => { return {'it.code': value}; case 'active': return {'i.isActive': value}; + case 'floramondo': + return {'i.isFloramondo': value}; case 'visible': if (value) return {'v.visible': {gt: 0}}; diff --git a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js index f386894dde..f983b8a4dd 100644 --- a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js +++ b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js @@ -113,6 +113,30 @@ describe('Buy latests buys filter()', () => { expect(results.length).toBe(0); }); + it('should return results matching "floramondo"', async() => { + let ctx = { + args: { + floramondo: true + } + }; + + let results = await app.models.Buy.latestBuysFilter(ctx); + + expect(results.length).toBe(1); + }); + + it('should return results matching "not floramondo"', async() => { + let ctx = { + args: { + floramondo: false + } + }; + + let results = await app.models.Buy.latestBuysFilter(ctx); + + expect(results.length).toBe(5); + }); + it('should return results matching "salesPersonFk"', async() => { let ctx = { args: { diff --git a/modules/entry/front/latest-buys-search-panel/index.html b/modules/entry/front/latest-buys-search-panel/index.html index 4693141f85..8597ab0ea8 100644 --- a/modules/entry/front/latest-buys-search-panel/index.html +++ b/modules/entry/front/latest-buys-search-panel/index.html @@ -58,6 +58,11 @@ ng-model="filter.visible" triple-state="true"> + + diff --git a/modules/entry/front/latest-buys/locale/es.yml b/modules/entry/front/latest-buys/locale/es.yml index 21eae03078..8d70844fa8 100644 --- a/modules/entry/front/latest-buys/locale/es.yml +++ b/modules/entry/front/latest-buys/locale/es.yml @@ -4,6 +4,8 @@ Freight value: Porte Commission value: Comisión Package value: Embalaje Is ignored: Ignorado +Is visible: Visible +Is floramondo: Floramondo Grouping price: Precio grouping Packing price: Precio packing Min price: Precio min diff --git a/modules/item/back/methods/item/specs/filter.spec.js b/modules/item/back/methods/item/specs/filter.spec.js index 7b1fac9ac0..3e798bccaf 100644 --- a/modules/item/back/methods/item/specs/filter.spec.js +++ b/modules/item/back/methods/item/specs/filter.spec.js @@ -70,8 +70,8 @@ describe('item filter()', () => { const ctx = {args: {filter: filter, isFloramondo: true}}; const result = await models.Item.filter(ctx, filter, options); - expect(result.length).toEqual(2); - expect(result[0].id).toEqual(13); + expect(result.length).toEqual(3); + expect(result[0].id).toEqual(9); await tx.rollback(); } catch (e) { From 80f651f37d0757551a7db7f8ca664d16f39f4dee Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 22 Nov 2021 12:34:20 +0100 Subject: [PATCH 112/124] add entries less than a year ago --- modules/entry/back/methods/entry/latestBuysFilter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js index c877612e1f..0c8ce3f999 100644 --- a/modules/entry/back/methods/entry/latestBuysFilter.js +++ b/modules/entry/back/methods/entry/latestBuysFilter.js @@ -180,7 +180,7 @@ module.exports = Self => { LEFT JOIN itemType t ON t.id = i.typeFk LEFT JOIN intrastat intr ON intr.id = i.intrastatFk LEFT JOIN origin ori ON ori.id = i.originFk - LEFT JOIN entry e ON e.id = b.entryFk + LEFT JOIN entry e ON e.id = b.entryFk AND e.created >= DATE_SUB(CURDATE(),INTERVAL 1 YEAR) LEFT JOIN supplier s ON s.id = e.supplierFk` ); From cdf7c20b163132a0942758999cd3ca50f2a7818a Mon Sep 17 00:00:00 2001 From: vicent Date: Mon, 22 Nov 2021 13:34:42 +0100 Subject: [PATCH 113/124] feat(worker_createAbsense): update backTest --- .../methods/worker/specs/createAbsence.spec.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/modules/worker/back/methods/worker/specs/createAbsence.spec.js b/modules/worker/back/methods/worker/specs/createAbsence.spec.js index 03467347a3..0d6ebfc807 100644 --- a/modules/worker/back/methods/worker/specs/createAbsence.spec.js +++ b/modules/worker/back/methods/worker/specs/createAbsence.spec.js @@ -75,7 +75,7 @@ describe('Worker createAbsence()', () => { } }); - it('should return an error trying to create a "Half holiday" absence', async() => { + it(`should throw an error when adding a "Half holiday" absence if there's already one`, async() => { const ctx = { req: {accessToken: {userId: 19}}, args: { @@ -88,22 +88,18 @@ describe('Worker createAbsence()', () => { const tx = await app.models.Calendar.beginTransaction({}); + let error; try { const options = {transaction: tx}; - let error; - await app.models.Worker.createAbsence(ctx, workerId, options).catch(e => { - error = e; - }).finally(() => { - expect(error.message).toEqual(`Cannot add more than one '1/2 day vacation'`); - }); - - expect(error).toBeDefined(); + await app.models.Worker.createAbsence(ctx, workerId, options); await tx.rollback(); } catch (e) { await tx.rollback(); - throw e; + error = e; } + + expect(error.message).toEqual(`Cannot add more than one '1/2 day vacation'`); }); }); From 709a300388e5d02d72bba3fb07e934dd4daa0e03 Mon Sep 17 00:00:00 2001 From: vicent Date: Mon, 22 Nov 2021 13:44:22 +0100 Subject: [PATCH 114/124] fix: extracting logic gates to constants --- modules/client/back/models/client.js | 3 ++- modules/supplier/back/models/supplier.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index 1a4e9bcb37..b4961771d9 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -138,7 +138,8 @@ module.exports = Self => { function hasIban(err, done) { Self.app.models.PayMethod.findById(this.payMethodFk, (_, instance) => { - if (instance && instance.isIbanRequiredForClients && !this.iban) + const isMissingIban = instance && instance.isIbanRequiredForClients && !this.iban; + if (isMissingIban) err(); done(); }); diff --git a/modules/supplier/back/models/supplier.js b/modules/supplier/back/models/supplier.js index bab7259035..1ac6e3bd28 100644 --- a/modules/supplier/back/models/supplier.js +++ b/modules/supplier/back/models/supplier.js @@ -79,8 +79,9 @@ module.exports = Self => { const payMethod = await Self.app.models.PayMethod.findById(this.payMethodFk); const supplierAccount = await Self.app.models.SupplierAccount.findOne({where: {supplierFk: this.id}}); const hasIban = supplierAccount && supplierAccount.iban; + const isMissingIban = payMethod && payMethod.isIbanRequiredForSuppliers && !hasIban; - if (payMethod && payMethod.isIbanRequiredForSuppliers && !hasIban) + if (isMissingIban) err(); done(); From a940d14256e4f516b1ad6547fbf1bd5a4aa17b2d Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 22 Nov 2021 14:40:03 +0100 Subject: [PATCH 115/124] fix(filterValue): fixed sql injection vulnerability Refs: 3369 --- front/core/components/field/style.scss | 2 +- .../entry/front/latest-buys-search-panel/index.html | 13 ++++++++----- .../entry/front/latest-buys-search-panel/index.js | 12 ------------ modules/item/back/methods/tag/filterValue.js | 11 ++++++++--- modules/item/front/search-panel/index.html | 12 +++++++----- modules/item/front/search-panel/index.js | 12 ------------ 6 files changed, 24 insertions(+), 38 deletions(-) diff --git a/front/core/components/field/style.scss b/front/core/components/field/style.scss index ceaeda40ab..9012b8c4c4 100644 --- a/front/core/components/field/style.scss +++ b/front/core/components/field/style.scss @@ -71,7 +71,7 @@ color: $color-font; &::placeholder { - color: $color-font-bg; + color: $color-font-bg-marginal; } &[type=time], &[type=date], diff --git a/modules/entry/front/latest-buys-search-panel/index.html b/modules/entry/front/latest-buys-search-panel/index.html index 4693141f85..c4f9a4a72f 100644 --- a/modules/entry/front/latest-buys-search-panel/index.html +++ b/modules/entry/front/latest-buys-search-panel/index.html @@ -81,18 +81,21 @@ on-change="itemTag.value = null"> - + show-field="value" + value-field="value" + rule> { const where = filter.where; if (where && where.value) { stmt.merge(conn.makeWhere({value: {like: `%${where.value}%`}})); - stmt.merge(` - ORDER BY value LIKE '${where.value}' DESC, - value LIKE '${where.value}%' DESC`); + + const newStmt = new ParameterizedSQL( + `ORDER BY value LIKE ? DESC, + value LIKE ? DESC`, [ + where.value, + `${where.value}%` + ]); + ParameterizedSQL.append(newStmt, stmt); } stmt.merge(conn.makeLimit(filter)); diff --git a/modules/item/front/search-panel/index.html b/modules/item/front/search-panel/index.html index 57f05bb546..42e68c71ce 100644 --- a/modules/item/front/search-panel/index.html +++ b/modules/item/front/search-panel/index.html @@ -72,19 +72,21 @@ - + show-field="value" + value-field="value" + rule> Date: Mon, 22 Nov 2021 15:49:32 +0100 Subject: [PATCH 116/124] Updated unit tests --- .../front/latest-buys-search-panel/index.js | 2 +- .../latest-buys-search-panel/index.spec.js | 53 ++++++++++++------- modules/item/front/search-panel/index.js | 2 +- modules/item/front/search-panel/index.spec.js | 53 ++++++++++++------- 4 files changed, 70 insertions(+), 40 deletions(-) diff --git a/modules/entry/front/latest-buys-search-panel/index.js b/modules/entry/front/latest-buys-search-panel/index.js index ce9eddcca6..83dc88724e 100644 --- a/modules/entry/front/latest-buys-search-panel/index.js +++ b/modules/entry/front/latest-buys-search-panel/index.js @@ -57,7 +57,7 @@ class Controller extends SearchPanel { removeField(index, field) { this.fieldFilters.splice(index, 1); - this.$.filter[field] = undefined; + delete this.$.filter[field]; } } diff --git a/modules/entry/front/latest-buys-search-panel/index.spec.js b/modules/entry/front/latest-buys-search-panel/index.spec.js index 6d403b9fbd..9e187a25a4 100644 --- a/modules/entry/front/latest-buys-search-panel/index.spec.js +++ b/modules/entry/front/latest-buys-search-panel/index.spec.js @@ -12,33 +12,48 @@ describe('Entry', () => { controller = $componentController('vnLatestBuysSearchPanel', {$element}); })); - describe('getSourceTable()', () => { - it(`should return null if there's no selection`, () => { - let selection = null; - let result = controller.getSourceTable(selection); + describe('filter() setter', () => { + it(`should set the tags property to the scope filter with an empty array`, () => { + const expectedFilter = { + tags: [{}] + }; + controller.filter = null; - expect(result).toBeNull(); + expect(controller.filter).toEqual(expectedFilter); }); - it(`should return null if there's a selection but its isFree property is truthy`, () => { - let selection = {isFree: true}; - let result = controller.getSourceTable(selection); + it(`should set the tags property to the scope filter with an array of tags`, () => { + const expectedFilter = { + description: 'My item', + tags: [{}] + }; + const expectedFieldFilter = [{ + info: { + label: 'description', + name: 'description', + type: null + }, + name: 'description', + value: 'My item' + }]; + controller.filter = { + description: 'My item' + }; - expect(result).toBeNull(); + expect(controller.filter).toEqual(expectedFilter); + expect(controller.fieldFilters).toEqual(expectedFieldFilter); }); + }); - it(`should return the formated sourceTable concatenated to a path`, () => { - let selection = {sourceTable: 'hello guy'}; - let result = controller.getSourceTable(selection); + describe('removeField()', () => { + it(`should remove the description property from the fieldFilters and from the scope filter`, () => { + const expectedFilter = {tags: [{}]}; + controller.filter = {description: 'My item'}; - expect(result).toEqual('Hello guys'); - }); + controller.removeField(0, 'description'); - it(`should return a path if there's no sourceTable and the selection has an id`, () => { - let selection = {id: 99}; - let result = controller.getSourceTable(selection); - - expect(result).toEqual(`ItemTags/filterItemTags/${selection.id}`); + expect(controller.filter).toEqual(expectedFilter); + expect(controller.fieldFilters).toEqual([]); }); }); }); diff --git a/modules/item/front/search-panel/index.js b/modules/item/front/search-panel/index.js index 6a0f358ebd..2448728be0 100644 --- a/modules/item/front/search-panel/index.js +++ b/modules/item/front/search-panel/index.js @@ -57,7 +57,7 @@ class Controller extends SearchPanel { removeField(index, field) { this.fieldFilters.splice(index, 1); - this.$.filter[field] = undefined; + delete this.$.filter[field]; } } diff --git a/modules/item/front/search-panel/index.spec.js b/modules/item/front/search-panel/index.spec.js index 0e2b7f848d..39b5b7aa5b 100644 --- a/modules/item/front/search-panel/index.spec.js +++ b/modules/item/front/search-panel/index.spec.js @@ -12,33 +12,48 @@ describe('Item', () => { controller = $componentController('vnItemSearchPanel', {$element}); })); - describe('getSourceTable()', () => { - it(`should return null if there's no selection`, () => { - let selection = null; - let result = controller.getSourceTable(selection); + describe('filter() setter', () => { + it(`should set the tags property to the scope filter with an empty array`, () => { + const expectedFilter = { + tags: [{}] + }; + controller.filter = null; - expect(result).toBeNull(); + expect(controller.filter).toEqual(expectedFilter); }); - it(`should return null if there's a selection but its isFree property is truthy`, () => { - let selection = {isFree: true}; - let result = controller.getSourceTable(selection); + it(`should set the tags property to the scope filter with an array of tags`, () => { + const expectedFilter = { + description: 'My item', + tags: [{}] + }; + const expectedFieldFilter = [{ + info: { + label: 'description', + name: 'description', + type: null + }, + name: 'description', + value: 'My item' + }]; + controller.filter = { + description: 'My item' + }; - expect(result).toBeNull(); + expect(controller.filter).toEqual(expectedFilter); + expect(controller.fieldFilters).toEqual(expectedFieldFilter); }); + }); - it(`should return the formated sourceTable concatenated to a path`, () => { - let selection = {sourceTable: 'hello guy'}; - let result = controller.getSourceTable(selection); + describe('removeField()', () => { + it(`should remove the description property from the fieldFilters and from the scope filter`, () => { + const expectedFilter = {tags: [{}]}; + controller.filter = {description: 'My item'}; - expect(result).toEqual('Hello guys'); - }); + controller.removeField(0, 'description'); - it(`should return a path if there's no sourceTable and the selection has an id`, () => { - let selection = {id: 99}; - let result = controller.getSourceTable(selection); - - expect(result).toEqual(`ItemTags/filterItemTags/${selection.id}`); + expect(controller.filter).toEqual(expectedFilter); + expect(controller.fieldFilters).toEqual([]); }); }); }); From 4ebad6b372d989e579d67d62cd338e3eac5aa415 Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 22 Nov 2021 15:54:01 +0100 Subject: [PATCH 117/124] filter order was not properly being applied --- modules/item/back/methods/tag/filterValue.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/item/back/methods/tag/filterValue.js b/modules/item/back/methods/tag/filterValue.js index 6344a5299d..3f39519fc2 100644 --- a/modules/item/back/methods/tag/filterValue.js +++ b/modules/item/back/methods/tag/filterValue.js @@ -48,13 +48,13 @@ module.exports = Self => { if (where && where.value) { stmt.merge(conn.makeWhere({value: {like: `%${where.value}%`}})); - const newStmt = new ParameterizedSQL( + const orderStmt = new ParameterizedSQL( `ORDER BY value LIKE ? DESC, value LIKE ? DESC`, [ where.value, `${where.value}%` ]); - ParameterizedSQL.append(newStmt, stmt); + ParameterizedSQL.append(stmt, orderStmt); } stmt.merge(conn.makeLimit(filter)); From b460579834ebbe0a546e703dd25404ec39a05c90 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 23 Nov 2021 09:00:46 +0100 Subject: [PATCH 118/124] feat(entry_latest-buys): add from and to in search-panel --- .../00-defaultViewConfig.sql | 7 +++++++ .../back/methods/entry/latestBuysFilter.js | 17 ++++++++++++++++- .../entry/specs/latestBuysFilter.spec.js | 19 +++++++++++++++++++ .../front/latest-buys-search-panel/index.html | 12 ++++++++++++ modules/entry/front/latest-buys/index.html | 4 ++++ modules/entry/front/latest-buys/index.js | 5 ++++- 6 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 db/changes/10390-constitution/00-defaultViewConfig.sql diff --git a/db/changes/10390-constitution/00-defaultViewConfig.sql b/db/changes/10390-constitution/00-defaultViewConfig.sql new file mode 100644 index 0000000000..75788f581b --- /dev/null +++ b/db/changes/10390-constitution/00-defaultViewConfig.sql @@ -0,0 +1,7 @@ +UPDATE `salix`.`defaultViewConfig` + SET `columns` = '{"intrastat":false,"description":false,"density":false,"isActive":false, + "freightValue":false,"packageValue":false,"isIgnored":false,"price2":false,"minPrice":true, + "ektFk":false,"weight":false,"id":true,"packing":true,"grouping":true,"quantity":true, + "size":false,"name":true,"code":true,"origin":true,"family":true,"entryFk":true,"buyingValue":true, + "comissionValue":false,"price3":true,"packageFk":true,"packingOut":true,"landing":false}' + WHERE tableCode = 'latestBuys' \ No newline at end of file diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js index 8bae27ab2c..04570533c2 100644 --- a/modules/entry/back/methods/entry/latestBuysFilter.js +++ b/modules/entry/back/methods/entry/latestBuysFilter.js @@ -73,6 +73,16 @@ module.exports = Self => { arg: 'packingOut', type: 'integer', description: 'the packingOut', + }, + { + arg: 'from', + type: 'date', + description: `The from date filter` + }, + { + arg: 'to', + type: 'date', + description: `The to date filter` } ], returns: { @@ -117,6 +127,10 @@ module.exports = Self => { return {'i.isActive': value}; case 'floramondo': return {'i.isFloramondo': value}; + case 'from': + return {'lb.landing': {gte: value}}; + case 'to': + return {'lb.landing': {lte: value}}; case 'visible': if (value) return {'v.visible': {gt: 0}}; @@ -176,7 +190,8 @@ module.exports = Self => { b.price3, b.ektFk, b.weight, - b.packageFk + b.packageFk, + lb.landing FROM cache.last_buy lb LEFT JOIN cache.visible v ON v.item_id = lb.item_id AND v.calc_id = @calc_id diff --git a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js index f4a404fa4e..2a9e860607 100644 --- a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js +++ b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js @@ -172,5 +172,24 @@ describe('Buy latests buys filter()', () => { expect(results.length).toBe(2); }); + + it('should return results matching "from" and "to"', async() => { + const from = new Date(); + from.setHours(0, 0, 0, 0); + + const to = new Date(); + to.setHours(23, 59, 59, 999); + + let ctx = { + args: { + from: from, + to: to, + } + }; + + let results = await app.models.Buy.latestBuysFilter(ctx); + + expect(results.length).toBe(2); + }); }); diff --git a/modules/entry/front/latest-buys-search-panel/index.html b/modules/entry/front/latest-buys-search-panel/index.html index c829a25bab..3ef688f588 100644 --- a/modules/entry/front/latest-buys-search-panel/index.html +++ b/modules/entry/front/latest-buys-search-panel/index.html @@ -58,6 +58,18 @@ {{name}}: {{nickname}} + + + + + + Package out + + Landing + @@ -207,6 +210,7 @@ {{::buy.weight}} {{::buy.packageFk}} {{::buy.packingOut}} + {{::buy.landing | date: 'dd/MM/yyyy'}} diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js index e899c50fad..ed66292628 100644 --- a/modules/entry/front/latest-buys/index.js +++ b/modules/entry/front/latest-buys/index.js @@ -76,7 +76,8 @@ export default class Controller extends Section { {field: 'description', displayName: this.$t('Description')}, {field: 'size', displayName: this.$t('Size')}, {field: 'density', displayName: this.$t('Density')}, - {field: 'packingOut', displayName: this.$t('PackingOut')} + {field: 'packingOut', displayName: this.$t('PackingOut')}, + {field: 'landing', displayName: this.$t('Landing')} ]; return this._columns; @@ -112,6 +113,8 @@ export default class Controller extends Section { return {'intr.description': value}; case 'origin': return {'ori.code': value}; + case 'landing': + return {[`lb.${param}`]: value}; case 'packing': case 'grouping': case 'quantity': From 854ed9936d50c084cf68275cfffa165e632b0cf8 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 23 Nov 2021 09:05:42 +0100 Subject: [PATCH 119/124] deleted unnecessary comma --- modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js index 2a9e860607..2a26dfa555 100644 --- a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js +++ b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js @@ -183,7 +183,7 @@ describe('Buy latests buys filter()', () => { let ctx = { args: { from: from, - to: to, + to: to } }; From 07dcdab1ef47234c1153092e5c558f72b09537a8 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 23 Nov 2021 09:57:19 +0100 Subject: [PATCH 120/124] fix(sale): disabled clear icons --- front/core/components/input-number/index.html | 1 + front/core/components/input-number/index.js | 3 ++- modules/ticket/front/sale/index.html | 9 +++++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/front/core/components/input-number/index.html b/front/core/components/input-number/index.html index 4d0227333a..3bf1e7ebdf 100644 --- a/front/core/components/input-number/index.html +++ b/front/core/components/input-number/index.html @@ -15,6 +15,7 @@
diff --git a/front/core/components/input-number/index.js b/front/core/components/input-number/index.js index 6f9fefcd89..8b1341e443 100644 --- a/front/core/components/input-number/index.js +++ b/front/core/components/input-number/index.js @@ -85,6 +85,7 @@ ngModule.vnComponent('vnInputNumber', { min: ' + on-change="$ctrl.changeQuantity(sale)" + clear-disabled="true"> @@ -177,7 +178,8 @@ + on-change="$ctrl.updateConcept(sale)" + clear-disabled="true"> @@ -251,6 +253,7 @@ ng-model="$ctrl.edit.price" step="0.01" on-change="$ctrl.updatePrice()" + clear-disabled="true" suffix="€">
@@ -283,6 +286,7 @@ label="Discount" ng-model="$ctrl.edit.discount" on-change="$ctrl.changeDiscount()" + clear-disabled="true" suffix="%">
@@ -311,6 +315,7 @@ label="Discount" ng-model="$ctrl.edit.discount" on-change="$ctrl.changeMultipleDiscount()" + clear-disabled="true" suffix="%">
From abb33c8514d90e54e8b4539fb020443412be2328 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 23 Nov 2021 11:39:31 +0100 Subject: [PATCH 121/124] feat(client): consumption.decription sortable --- modules/client/front/consumption/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/client/front/consumption/index.html b/modules/client/front/consumption/index.html index 5109604574..17e1e8c8b8 100644 --- a/modules/client/front/consumption/index.html +++ b/modules/client/front/consumption/index.html @@ -5,7 +5,7 @@ limit="20" user-params="::$ctrl.filterParams" data="sales" - order="itemTypeFk, itemName, itemSize"> + order="itemTypeFk, itemName, itemSize, description"> Item Ticket Fecha - Description + Description Quantity From 372d5ade17b1cf73798c46b14c78949439592e28 Mon Sep 17 00:00:00 2001 From: carlosjr Date: Tue, 23 Nov 2021 13:58:12 +0100 Subject: [PATCH 122/124] refactor(smartTable): removeProp updated and tests --- front/core/components/contextmenu/index.js | 23 +-- front/core/components/smart-table/index.js | 28 ++-- .../core/components/smart-table/index.spec.js | 150 ++++++++++++++++-- 3 files changed, 173 insertions(+), 28 deletions(-) diff --git a/front/core/components/contextmenu/index.js b/front/core/components/contextmenu/index.js index fa1db6887f..a7980b4352 100755 --- a/front/core/components/contextmenu/index.js +++ b/front/core/components/contextmenu/index.js @@ -223,26 +223,29 @@ export default class Contextmenu { delete userFilter.where; } - function removeProp(instance, findProp, prop) { - if (prop == findProp) - delete instance[prop]; + function removeProp(obj, targetProp, prop) { + if (prop == targetProp) + delete obj[prop]; if (prop === 'and' || prop === 'or') { - const instanceCopy = instance[prop].slice(); - for (let param of instanceCopy) { + const arrayCopy = obj[prop].slice(); + for (let param of arrayCopy) { const [key] = Object.keys(param); - const index = instance[prop].findIndex(param => { + const index = obj[prop].findIndex(param => { return Object.keys(param)[0] == key; }); - if (key == findProp) - instance[prop].splice(index, 1); + if (key == targetProp) + obj[prop].splice(index, 1); if (param[key] instanceof Array) removeProp(param, filterKey, key); + + if (Object.keys(param).length == 0) + obj[prop].splice(index, 1); } - if (instance[prop].length == 0) - delete instance[prop]; + if (obj[prop].length == 0) + delete obj[prop]; } } diff --git a/front/core/components/smart-table/index.js b/front/core/components/smart-table/index.js index cc359e41fc..93d5f93947 100644 --- a/front/core/components/smart-table/index.js +++ b/front/core/components/smart-table/index.js @@ -365,23 +365,33 @@ export default class SmartTable extends Component { for (let key of whereKeys) { removeProp(where, field, key); - if (!Object.keys(where)) + if (Object.keys(where).length == 0) delete userFilter.where; } - function removeProp(instance, findProp, prop) { - if (prop == findProp) - delete instance[prop]; + function removeProp(obj, targetProp, prop) { + if (prop == targetProp) + delete obj[prop]; - if (prop === 'and') { - for (let [index, param] of instance[prop].entries()) { + if (prop === 'and' || prop === 'or') { + const arrayCopy = obj[prop].slice(); + for (let param of arrayCopy) { const [key] = Object.keys(param); - if (key == findProp) - instance[prop].splice(index, 1); + const index = obj[prop].findIndex(param => { + return Object.keys(param)[0] == key; + }); + if (key == targetProp) + obj[prop].splice(index, 1); if (param[key] instanceof Array) removeProp(param, field, key); + + if (Object.keys(param).length == 0) + obj[prop].splice(index, 1); } + + if (obj[prop].length == 0) + delete obj[prop]; } } @@ -415,7 +425,7 @@ export default class SmartTable extends Component { if (!model.isChanged) return this.vnApp.showError(this.$t('No changes to save')); - this.model.save() + return this.model.save() .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); } } diff --git a/front/core/components/smart-table/index.spec.js b/front/core/components/smart-table/index.spec.js index d0ff2f53fd..9b8cc1d09e 100644 --- a/front/core/components/smart-table/index.spec.js +++ b/front/core/components/smart-table/index.spec.js @@ -80,18 +80,150 @@ describe('Component smartTable', () => { }); }); - describe('applyViewConfig()', () => { - it('should ', () => { - controller.$.userViewModel = { - viewConfig: {'test1': true, 'test2': false} + describe('addFilter()', () => { + it('should call the model addFilter() with a basic where filter if exprBuilder() was not received', () => { + controller.model = {addFilter: jest.fn()}; + + controller.addFilter('myField', 'myValue'); + + const expectedFilter = { + where: { + myField: 'myValue' + } }; - controller._columns = [ - {field: 'test1'}, - {field: 'test2'} - ]; + expect(controller.model.addFilter).toHaveBeenCalledWith(expectedFilter); + }); - controller.applyViewConfig(); + it('should call the model addFilter() with a built where filter resultant of exprBuilder()', () => { + controller.exprBuilder = jest.fn().mockReturnValue({builtField: 'builtValue'}); + controller.model = {addFilter: jest.fn()}; + + controller.addFilter('myField', 'myValue'); + + const expectedFilter = { + where: { + builtField: 'builtValue' + } + }; + + expect(controller.model.addFilter).toHaveBeenCalledWith(expectedFilter); + }); + }); + + describe('applySort()', () => { + it('should call the model refresh() without making changes on the model order', () => { + controller.model = {refresh: jest.fn()}; + + controller.applySort(); + + expect(controller.model.order).toBeUndefined(); + expect(controller.model.refresh).toHaveBeenCalled(); + }); + + it('should call the model.refresh() after setting model order according to the controller sortCriteria', () => { + controller.model = {refresh: jest.fn()}; + const orderBy = {field: 'myField', sortType: 'ASC'}; + controller.sortCriteria = [orderBy]; + + controller.applySort(); + + expect(controller.model.order).toEqual(`${orderBy.field} ${orderBy.sortType}`); + expect(controller.model.refresh).toHaveBeenCalled(); + }); + }); + + describe('filterSanitizer()', () => { + it('should remove the where filter after leaving no fields in it', () => { + controller.model = { + userFilter: { + where: {fieldToRemove: 'valueToRemove'} + }, + userParams: {} + }; + + const result = controller.filterSanitizer('fieldToRemove'); + + const exectedObject = {userFilter: {}, userParams: {}}; + + expect(result).toEqual(exectedObject); + }); + + it('should remove the where filter after leaving no fields and "empty ands/ors" in it', () => { + controller.model = { + userFilter: { + where: { + and: [ + {aFieldToRemove: 'aValueToRemove'}, + {aFieldToRemove: 'aValueToRemove'}, + { + or: [ + {aFieldToRemove: 'aValueToRemove'}, + {aFieldToRemove: 'aValueToRemove'}, + ] + } + ] + } + }, + userParams: {} + }; + + const result = controller.filterSanitizer('aFieldToRemove'); + + const exectedObject = {userFilter: {}, userParams: {}}; + + expect(result).toEqual(exectedObject); + }); + + it('should not remove the where filter after leaving no empty "ands/ors" in it', () => { + controller.model = { + userFilter: { + where: { + and: [ + {aFieldToRemove: 'aValueToRemove'}, + {aFieldToRemove: 'aValueToRemove'}, + { + or: [ + {aFieldToRemove: 'aValueToRemove'}, + {aFieldToRemove: 'aValueToRemove'}, + ] + } + ], + or: [{dontKillMe: 'thanks'}] + } + }, + userParams: {} + }; + + const result = controller.filterSanitizer('aFieldToRemove'); + + const exectedObject = {userFilter: {where: {or: [{dontKillMe: 'thanks'}]}}, userParams: {}}; + + expect(result).toEqual(exectedObject); + }); + }); + + describe('saveAll()', () => { + it('should throw an error if there are no changes to save in the model', () => { + jest.spyOn(controller.vnApp, 'showError'); + controller.model = {isChanged: false}; + controller.saveAll(); + + expect(controller.vnApp.showError).toHaveBeenCalledWith('No changes to save'); + }); + + it('should call the showSuccess() if there are changes to save in the model', done => { + jest.spyOn(controller.vnApp, 'showSuccess'); + + controller.model = { + save: jest.fn().mockReturnValue(Promise.resolve()), + isChanged: true + }; + + controller.saveAll().then(() => { + expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!'); + done(); + }).catch(done.fail); }); }); }); From 8ede14ab4051ba3b857ef94512892e4dd7afe23e Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 24 Nov 2021 09:25:24 +0100 Subject: [PATCH 123/124] fix(sales): update price on any change affecting the ticket total Refs: 3363 --- modules/ticket/back/methods/sale/updatePrice.js | 4 ++-- modules/ticket/back/methods/ticket/addSale.js | 8 +++++++- modules/ticket/back/methods/ticket/updateDiscount.js | 8 +++++--- modules/ticket/front/sale/index.js | 2 ++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/modules/ticket/back/methods/sale/updatePrice.js b/modules/ticket/back/methods/sale/updatePrice.js index fa1705e55c..bbd9d154db 100644 --- a/modules/ticket/back/methods/sale/updatePrice.js +++ b/modules/ticket/back/methods/sale/updatePrice.js @@ -102,8 +102,8 @@ module.exports = Self => { } await sale.updateAttributes({price: newPrice}, myOptions); - query = `CALL vn.manaSpellersRequery(?)`; - await Self.rawSql(query, [userId], myOptions); + await Self.rawSql('CALL vn.manaSpellersRequery(?)', [userId], myOptions); + await Self.rawSql('CALL vn.ticket_recalc(?)', [sale.ticketFk], myOptions); const salesPerson = sale.ticket().client().salesPersonUser(); if (salesPerson) { diff --git a/modules/ticket/back/methods/ticket/addSale.js b/modules/ticket/back/methods/ticket/addSale.js index 527b861a16..37d97b2c79 100644 --- a/modules/ticket/back/methods/ticket/addSale.js +++ b/modules/ticket/back/methods/ticket/addSale.js @@ -66,7 +66,12 @@ module.exports = Self => { } }, myOptions); - const itemInfo = await models.Item.getVisibleAvailable(itemId, ticket.warehouseFk, ticket.shipped, myOptions); + const itemInfo = await models.Item.getVisibleAvailable( + itemId, + ticket.warehouseFk, + ticket.shipped, + myOptions + ); const isPackaging = item.family == 'EMB'; if (!isPackaging && itemInfo.available < quantity) @@ -80,6 +85,7 @@ module.exports = Self => { }, myOptions); await Self.rawSql('CALL vn.sale_calculateComponent(?, NULL)', [newSale.id], myOptions); + await Self.rawSql('CALL vn.ticket_recalc(?)', [id], myOptions); const sale = await models.Sale.findById(newSale.id, { include: { diff --git a/modules/ticket/back/methods/ticket/updateDiscount.js b/modules/ticket/back/methods/ticket/updateDiscount.js index cd6a5fabcc..cf217348ad 100644 --- a/modules/ticket/back/methods/ticket/updateDiscount.js +++ b/modules/ticket/back/methods/ticket/updateDiscount.js @@ -117,13 +117,15 @@ module.exports = Self => { const updatedSale = sale.updateAttribute('discount', newDiscount, myOptions); promises.push(newComponent, updatedSale); - changesMade += `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity}) ${oldDiscount}% ➔ *${newDiscount}%*`; + + const change = `${oldDiscount}% ➔ *${newDiscount}%*`; + changesMade += `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity}) ${change}`; } await Promise.all(promises); - const query = `call vn.manaSpellersRequery(?)`; - await Self.rawSql(query, [userId], myOptions); + await Self.rawSql('CALL vn.manaSpellersRequery(?)', [userId], myOptions); + await Self.rawSql('CALL vn.ticket_recalc(?)', [id], myOptions); const ticket = await models.Ticket.findById(id, { include: { diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index a1787e3ea5..2ebe9a1748 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -127,6 +127,8 @@ class Controller extends Section { resetChanges() { if (this.newInstances().length === 0) this.$.watcher.updateOriginalData(); + + this.card.reload(); } changeState(value) { From 00072a7dd137357d310dee126808bf25ec3af47d Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 24 Nov 2021 10:02:52 +0100 Subject: [PATCH 124/124] landing searchable false --- db/changes/10390-constitution/00-defaultViewConfig.sql | 6 ++---- modules/entry/front/latest-buys/index.js | 4 ++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/db/changes/10390-constitution/00-defaultViewConfig.sql b/db/changes/10390-constitution/00-defaultViewConfig.sql index 75788f581b..c67b6fed02 100644 --- a/db/changes/10390-constitution/00-defaultViewConfig.sql +++ b/db/changes/10390-constitution/00-defaultViewConfig.sql @@ -1,7 +1,5 @@ UPDATE `salix`.`defaultViewConfig` SET `columns` = '{"intrastat":false,"description":false,"density":false,"isActive":false, - "freightValue":false,"packageValue":false,"isIgnored":false,"price2":false,"minPrice":true, - "ektFk":false,"weight":false,"id":true,"packing":true,"grouping":true,"quantity":true, - "size":false,"name":true,"code":true,"origin":true,"family":true,"entryFk":true,"buyingValue":true, - "comissionValue":false,"price3":true,"packageFk":true,"packingOut":true,"landing":false}' + "freightValue":false,"packageValue":false,"isIgnored":false,"price2":false,"ektFk":false,"weight":false, + "size":false,"comissionValue":false,"landing":false}' WHERE tableCode = 'latestBuys' \ No newline at end of file diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js index ed66292628..385e7e4b65 100644 --- a/modules/entry/front/latest-buys/index.js +++ b/modules/entry/front/latest-buys/index.js @@ -61,6 +61,10 @@ export default class Controller extends Section { field: 'isIgnored', searchable: false }, + { + field: 'landing', + searchable: false + } ] }; }