From 955e55a7f42c3b486f45e5bffd8d72c9e573f4d9 Mon Sep 17 00:00:00 2001 From: carlossa Date: Tue, 7 Mar 2023 15:43:48 +0100 Subject: [PATCH 01/30] refs #5284 new onCreateClaimAccepted y createClaim --- db/changes/230801/00-ticketConfig.sql | 1 + modules/ticket/back/models/ticket-config.json | 9 ++++++++ modules/ticket/front/sale/index.html | 8 +++++++ modules/ticket/front/sale/index.js | 21 ++++++++++++++++++- modules/ticket/front/sale/locale/es.yml | 2 ++ 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 db/changes/230801/00-ticketConfig.sql diff --git a/db/changes/230801/00-ticketConfig.sql b/db/changes/230801/00-ticketConfig.sql new file mode 100644 index 000000000..ca63dbf63 --- /dev/null +++ b/db/changes/230801/00-ticketConfig.sql @@ -0,0 +1 @@ +ALTER TABLE `vn`.`ticketConfig` ADD daysForWarningClaim INT DEFAULT 2 NOT NULL COMMENT 'dias restantes hasta que salte el aviso de reclamación fuerade plazo'; diff --git a/modules/ticket/back/models/ticket-config.json b/modules/ticket/back/models/ticket-config.json index a1c96e7f6..d757fbd1a 100644 --- a/modules/ticket/back/models/ticket-config.json +++ b/modules/ticket/back/models/ticket-config.json @@ -14,6 +14,15 @@ }, "scopeDays": { "type": "number" + }, + "pickingDelay": { + "type": "number" + }, + "packagingInvoicingDated": { + "type": "date" + }, + "daysForWarningClaim": { + "type": "number" } } } diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index 8764417a8..fc5865cfd 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -480,6 +480,13 @@ on-accept="$ctrl.transferSales($ctrl.transfer.ticketId)"> + + + Add claim + { + this.ticketConfig = res.data; + }); + } get isClaimable() { if (this.ticket) { @@ -184,13 +194,22 @@ class Controller extends Section { } createClaim() { + const timeDifference = new Date().getTime() - new Date(this.ticket.shipped).getTime(); + const pastDays = Math.floor(timeDifference / 86400000); + + if (pastDays >= this.ticketConfig[0].daysForWarningClaim) + this.$.claimConfirm.show(); + else + this.onCreateClaimAccepted(); + } + + onCreateClaimAccepted() { const sales = this.selectedValidSales(); const params = {ticketId: this.ticket.id, sales: sales}; this.resetChanges(); this.$http.post(`Claims/createFromSales`, params) .then(res => this.$state.go('claim.card.basicData', {id: res.data.id})); } - showTransferPopover(event) { this.setTransferParams(); this.$.transfer.show(event); diff --git a/modules/ticket/front/sale/locale/es.yml b/modules/ticket/front/sale/locale/es.yml index 2668b7811..762fcf6eb 100644 --- a/modules/ticket/front/sale/locale/es.yml +++ b/modules/ticket/front/sale/locale/es.yml @@ -40,3 +40,5 @@ Refund: Abono Promotion mana: Maná promoción Claim mana: Maná reclamación History: Historial +Do you want to continue?: ¿Desea continuar? +Claim out of time: Reclamación fuera de plazo \ No newline at end of file From 0c8fe855acf8c10369900371bea3e4d9529848be Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 27 Mar 2023 09:11:29 +0200 Subject: [PATCH 02/30] refs #5418 lateral search panel added, missing e2e --- front/core/styles/variables.scss | 1 + front/salix/components/layout/style.scss | 6 +- .../front/fixed-price-search-panel/index.html | 351 +++++++++++------- .../front/fixed-price-search-panel/index.js | 53 ++- .../fixed-price-search-panel/index.spec.js | 56 +++ .../front/fixed-price-search-panel/style.scss | 71 ++++ modules/item/front/fixed-price/index.html | 10 +- 7 files changed, 396 insertions(+), 152 deletions(-) create mode 100644 modules/item/front/fixed-price-search-panel/index.spec.js create mode 100644 modules/item/front/fixed-price-search-panel/style.scss diff --git a/front/core/styles/variables.scss b/front/core/styles/variables.scss index bcc9fab66..0a00e2e1f 100644 --- a/front/core/styles/variables.scss +++ b/front/core/styles/variables.scss @@ -2,6 +2,7 @@ $font-size: 11pt; $menu-width: 256px; +$right-menu-width: 315px; $topbar-height: 56px; $mobile-width: 800px; $float-spacing: 20px; diff --git a/front/salix/components/layout/style.scss b/front/salix/components/layout/style.scss index 612366228..6697bb1b0 100644 --- a/front/salix/components/layout/style.scss +++ b/front/salix/components/layout/style.scss @@ -88,13 +88,13 @@ vn-layout { } &.right-menu { & > vn-topbar > .end { - width: 80px + $menu-width; + width: 80px + $right-menu-width; } & > .main-view { - padding-right: $menu-width; + padding-right: $right-menu-width; } [fixed-bottom-right] { - right: $menu-width; + right: $right-menu-width; } } & > .main-view { diff --git a/modules/item/front/fixed-price-search-panel/index.html b/modules/item/front/fixed-price-search-panel/index.html index 5c8a58674..ebe210277 100644 --- a/modules/item/front/fixed-price-search-panel/index.html +++ b/modules/item/front/fixed-price-search-panel/index.html @@ -1,136 +1,215 @@ - - -
-
- - - - - - - - - -
{{name}}
-
- {{category.name}} -
-
-
-
- - - - - - - - - - - - - - - - - - - - - Tags - - - - - - - - - - - - - - - - - -
-
+ + + + + + + + + + + + + + + + + + +
{{name}}
+
+ {{category.name}} +
+
+
+
+ + + + + + + + + + + + + + + + + + + + Tags + + + + + + + + + + + + + +
+ + Id/{{$ctrl.$t('Name')}}: {{$ctrl.filter.search}} + + + {{$ctrl.$t('Category')}}: {{category.selection.name}} + + + {{$ctrl.$t('Type')}}: {{type.selection.name}} + + + {{$ctrl.$t('Buyer')}}: {{buyer.selection.nickname}} + + + {{$ctrl.$t('Warehouse')}}: {{warehouse.selection.name}} + + + {{$ctrl.$t('Started')}}: {{$ctrl.filter.started | date:'dd/MM/yyyy'}} + + + {{$ctrl.$t('Ended')}}: {{$ctrl.filter.ended | date:'dd/MM/yyyy'}} + + + {{$ctrl.$t('For me')}}: {{$ctrl.filter.mine ? '✓' : '✗'}} + + + {{$ctrl.$t('Minimum price')}}: {{$ctrl.filter.hasMinPrice ? '✓' : '✗'}} + + + {{$ctrl.showTagInfo(chipTag)}} + +
+
diff --git a/modules/item/front/fixed-price-search-panel/index.js b/modules/item/front/fixed-price-search-panel/index.js index ec13765fd..0882eb5ac 100644 --- a/modules/item/front/fixed-price-search-panel/index.js +++ b/modules/item/front/fixed-price-search-panel/index.js @@ -1,19 +1,60 @@ import ngModule from '../module'; import SearchPanel from 'core/components/searchbar/search-panel'; +import './style.scss'; class Controller extends SearchPanel { - get filter() { - return this.$.filter; + constructor($element, $) { + super($element, $); } - set filter(value = {}) { - if (!value.tags) value.tags = [{}]; + $onInit() { + this.filter = { + tags: [] + }; + } - this.$.filter = value; + changeCategory(id) { + if (this.filter.categoryFk != id) { + this.filter.categoryFk = id; + this.addFilters(); + } + } + + removeItemFilter(param) { + this.filter[param] = null; + if (param == 'categoryFk') this.filter['typeFk'] = null; + this.addFilters(); + } + + removeTag(tag) { + const index = this.filter.tags.indexOf(tag); + if (index > -1) this.filter.tags.splice(index, 1); + this.addFilters(); + } + + onKeyPress($event) { + if ($event.key === 'Enter') + this.addFilters(); + } + + addFilters() { + for (let i = 0; i < this.filter.tags.length; i++) { + if (!this.filter.tags[i].value) + this.filter.tags.splice(i, 1); + } + return this.model.addFilter({}, this.filter); + } + + showTagInfo(itemTag) { + if (!itemTag.tagFk) return itemTag.value; + return `${this.tags.find(tag => tag.id == itemTag.tagFk).name}: ${itemTag.value}`; } } ngModule.vnComponent('vnFixedPriceSearchPanel', { template: require('./index.html'), - controller: Controller + controller: Controller, + bindings: { + model: '<' + } }); diff --git a/modules/item/front/fixed-price-search-panel/index.spec.js b/modules/item/front/fixed-price-search-panel/index.spec.js new file mode 100644 index 000000000..597bc108e --- /dev/null +++ b/modules/item/front/fixed-price-search-panel/index.spec.js @@ -0,0 +1,56 @@ +import './index.js'; + +describe('Item', () => { + describe('Component vnFixedPriceSearchPanel', () => { + let $element; + let controller; + + beforeEach(ngModule('item')); + + beforeEach(angular.mock.inject($componentController => { + $element = angular.element(``); + controller = $componentController('vnFixedPriceSearchPanel', {$element}); + controller.model = {addFilter: () => {}}; + })); + + describe('removeItemFilter()', () => { + it(`should remove param from filter`, () => { + controller.filter = {tags: [], categoryFk: 1, typeFk: 1}; + const expectFilter = {tags: [], categoryFk: null, typeFk: null}; + + controller.removeItemFilter('categoryFk'); + + expect(controller.filter).toEqual(expectFilter); + }); + }); + + describe('removeTag()', () => { + it(`should remove tag from filter`, () => { + const tag = {tagFk: 1, value: 'Value'}; + controller.filter = {tags: [tag]}; + const expectFilter = {tags: []}; + + controller.removeTag(tag); + + expect(controller.filter).toEqual(expectFilter); + }); + }); + + describe('showTagInfo()', () => { + it(`should show tag value`, () => { + const tag = {value: 'Value'}; + const result = controller.showTagInfo(tag); + + expect(result).toEqual('Value'); + }); + + it(`should show tag name and value`, () => { + const tag = {tagFk: 1, value: 'Value'}; + controller.tags = [{id: 1, name: 'tagName'}]; + const result = controller.showTagInfo(tag); + + expect(result).toEqual('tagName: Value'); + }); + }); + }); +}); diff --git a/modules/item/front/fixed-price-search-panel/style.scss b/modules/item/front/fixed-price-search-panel/style.scss new file mode 100644 index 000000000..a63f84f3b --- /dev/null +++ b/modules/item/front/fixed-price-search-panel/style.scss @@ -0,0 +1,71 @@ +@import "variables"; + +vn-fixed-price-search-panel vn-side-menu { + .menu { + min-width: $right-menu-width; + } + & > div { + .input { + padding-left: $spacing-md; + padding-right: $spacing-md; + border-color: $color-spacer; + border-bottom: $border-thin; + } + .horizontal { + padding-left: $spacing-md; + padding-right: $spacing-md; + grid-auto-flow: column; + grid-column-gap: $spacing-sm; + align-items: center; + } + .tags { + padding: $spacing-md; + padding-bottom: 0%; + padding-top: 0%; + align-items: center; + } + .chips { + display: flex; + flex-wrap: wrap; + padding: $spacing-md; + overflow: hidden; + max-width: 100%; + border-color: $color-spacer; + border-top: $border-thin; + } + .item-category { + padding: $spacing-sm; + justify-content: flex-start; + align-items: flex-start; + flex-wrap: wrap; + + vn-autocomplete[vn-id="category"] { + display: none; + } + + & > vn-one { + padding: $spacing-sm; + min-width: 33.33%; + text-align: center; + box-sizing: border-box; + + & > vn-icon { + padding: $spacing-sm; + background-color: $color-font-secondary; + border-radius: 50%; + cursor: pointer; + + &.active { + background-color: $color-main; + color: #fff; + } + & > i:before { + font-size: 2.6rem; + width: 16px; + height: 16px; + } + } + } + } + } +} diff --git a/modules/item/front/fixed-price/index.html b/modules/item/front/fixed-price/index.html index ce7cefe7a..be5acf368 100644 --- a/modules/item/front/fixed-price/index.html +++ b/modules/item/front/fixed-price/index.html @@ -13,14 +13,10 @@ order="name">
- - + +
Date: Mon, 27 Mar 2023 12:12:42 +0200 Subject: [PATCH 03/30] refs #5418 e2e implemented and fixed --- e2e/helpers/selectors.js | 15 ++++- ..._smartTable_searchBar_integrations.spec.js | 9 +-- e2e/paths/04-item/13_fixedPrice.spec.js | 58 +++++++++++++++++-- 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index f4c67f002..2cbbd31c0 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -414,7 +414,7 @@ export default { saveFieldsButton: '.vn-popover.shown vn-button[label="Save"] > button' }, itemFixedPrice: { - add: 'vn-fixed-price vn-icon-button[icon="add_circle"]', + add: 'vn-fixed-price vn-icon-button[vn-tooltip="Add fixed price"]', firstItemID: 'vn-fixed-price tr:nth-child(2) vn-autocomplete[ng-model="price.itemFk"]', fourthFixedPrice: 'vn-fixed-price tr:nth-child(5)', fourthItemID: 'vn-fixed-price tr:nth-child(5) vn-autocomplete[ng-model="price.itemFk"]', @@ -426,7 +426,18 @@ export default { fourthStarted: 'vn-fixed-price tr:nth-child(5) vn-date-picker[ng-model="price.started"]', fourthEnded: 'vn-fixed-price tr:nth-child(5) vn-date-picker[ng-model="price.ended"]', fourthDeleteIcon: 'vn-fixed-price tr:nth-child(5) > td:nth-child(9) > vn-icon-button[icon="delete"]', - orderColumnId: 'vn-fixed-price th[field="itemFk"]' + orderColumnId: 'vn-fixed-price th[field="itemFk"]', + generalSearchFilter: 'vn-fixed-price-search-panel vn-textfield[ng-model="$ctrl.filter.search"]', + reignFilter: 'vn-fixed-price-search-panel vn-horizontal.item-category vn-one', + typeFilter: 'vn-fixed-price-search-panel vn-autocomplete[ng-model="$ctrl.filter.typeFk"]', + buyerFilter: 'vn-fixed-price-search-panel vn-autocomplete[ng-model="$ctrl.filter.buyerFk"]', + warehouseFilter: 'vn-fixed-price-search-panel vn-autocomplete[ng-model="$ctrl.filter.warehouseFk"]', + mineFilter: 'vn-fixed-price-search-panel vn-check[ng-model="$ctrl.filter.mine"]', + hasMinPriceFilter: 'vn-fixed-price-search-panel vn-check[ng-model="$ctrl.filter.hasMinPrice"]', + addTag: 'vn-fixed-price-search-panel vn-icon-button[icon="add_circle"]', + tagFilter: 'vn-fixed-price-search-panel vn-autocomplete[ng-model="itemTag.tagFk"]', + tagValueFilter: 'vn-fixed-price-search-panel vn-autocomplete[ng-model="itemTag.value"]', + chip: 'vn-fixed-price-search-panel vn-chip > vn-icon', }, itemCreateView: { temporalName: 'vn-item-create vn-textfield[ng-model="$ctrl.item.provisionalName"]', diff --git a/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js b/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js index ad558ace2..1c8fe0840 100644 --- a/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js +++ b/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js @@ -79,21 +79,14 @@ describe('SmartTable SearchBar integration', () => { it('should order by first id', async() => { await page.loginAndModule('developer', 'item'); await page.accessToSection('item.fixedPrice'); - await page.doSearch(); const result = await page.waitToGetProperty(selectors.itemFixedPrice.firstItemID, 'value'); expect(result).toEqual('1'); }); - it('should order by last id', async() => { + it('should order by last id, reload page and have same order', async() => { await page.waitToClick(selectors.itemFixedPrice.orderColumnId); - const result = await page.waitToGetProperty(selectors.itemFixedPrice.firstItemID, 'value'); - - expect(result).toEqual('13'); - }); - - it('should reload page and have same order', async() => { await page.reload({ waitUntil: 'networkidle2' }); diff --git a/e2e/paths/04-item/13_fixedPrice.spec.js b/e2e/paths/04-item/13_fixedPrice.spec.js index 1b0f82d83..df3b4f7a3 100644 --- a/e2e/paths/04-item/13_fixedPrice.spec.js +++ b/e2e/paths/04-item/13_fixedPrice.spec.js @@ -4,19 +4,69 @@ import getBrowser from '../../helpers/puppeteer'; describe('Item fixed prices path', () => { let browser; let page; + let httpRequest; + beforeAll(async() => { browser = await getBrowser(); page = browser.page; await page.loginAndModule('buyer', 'item'); await page.accessToSection('item.fixedPrice'); + page.on('request', req => { + if (req.url().includes(`FixedPrices/filter`)) + httpRequest = req.url(); + }); }); afterAll(async() => { await browser.close(); }); - it('should click on the add new foxed price button', async() => { - await page.doSearch(); + it('should filter using all the fields', async() => { + await page.write(selectors.itemFixedPrice.generalSearchFilter, 'item'); + await page.keyboard.press('Enter'); + + expect(httpRequest).toContain('search=item'); + + await page.click(selectors.itemFixedPrice.chip); + await page.click(selectors.itemFixedPrice.reignFilter); + + expect(httpRequest).toContain('categoryFk'); + + await page.autocompleteSearch(selectors.itemFixedPrice.typeFilter, 'Alstroemeria'); + + expect(httpRequest).toContain('typeFk'); + + await page.click(selectors.itemFixedPrice.chip); + await page.autocompleteSearch(selectors.itemFixedPrice.buyerFilter, 'buyerNick'); + + expect(httpRequest).toContain('buyerFk'); + + await page.click(selectors.itemFixedPrice.chip); + await page.autocompleteSearch(selectors.itemFixedPrice.warehouseFilter, 'Algemesi'); + + expect(httpRequest).toContain('warehouseFk'); + + await page.click(selectors.itemFixedPrice.chip); + await page.click(selectors.itemFixedPrice.mineFilter); + + expect(httpRequest).toContain('mine=true'); + + await page.click(selectors.itemFixedPrice.chip); + await page.click(selectors.itemFixedPrice.hasMinPriceFilter); + + expect(httpRequest).toContain('hasMinPrice=true'); + + await page.click(selectors.itemFixedPrice.chip); + await page.click(selectors.itemFixedPrice.addTag); + await page.autocompleteSearch(selectors.itemFixedPrice.tagFilter, 'Color'); + await page.autocompleteSearch(selectors.itemFixedPrice.tagValueFilter, 'Brown'); + + expect(httpRequest).toContain('tags'); + + await page.click(selectors.itemFixedPrice.chip); + }); + + it('should click on the add new fixed price button', async() => { await page.waitToClick(selectors.itemFixedPrice.add); await page.waitForSelector(selectors.itemFixedPrice.fourthFixedPrice); }); @@ -35,9 +85,7 @@ describe('Item fixed prices path', () => { }); it('should reload the section and check the created price has the expected ID', async() => { - await page.accessToSection('item.index'); - await page.accessToSection('item.fixedPrice'); - await page.doSearch(); + await page.goto(`http://localhost:5000/#!/item/fixed-price`); const result = await page.waitToGetProperty(selectors.itemFixedPrice.fourthItemID, 'value'); From ecbfdad1025af31ed536fde8f69e6b284fe2fbcf Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 4 Apr 2023 09:51:07 +0200 Subject: [PATCH 04/30] refs #5418 changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5ee05fe4..dc16a87d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - (Facturas recibidas -> Bases negativas) Nueva sección ### Changed -- +- (Artículo -> Precio fijado) Modificado el buscador superior por uno lateral ### Fixed - From 0bfa4c54aac1e41c3590d1c19ed5f7cb8d3debe4 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 4 Apr 2023 09:52:46 +0200 Subject: [PATCH 05/30] fix: inserta en workerTimeControlMail --- modules/worker/back/methods/worker-time-control/sendMail.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/worker/back/methods/worker-time-control/sendMail.js b/modules/worker/back/methods/worker-time-control/sendMail.js index 579a83112..4962e96f8 100644 --- a/modules/worker/back/methods/worker-time-control/sendMail.js +++ b/modules/worker/back/methods/worker-time-control/sendMail.js @@ -332,6 +332,12 @@ module.exports = Self => { const lastDay = days[index][days[index].length - 1]; if (day.workerFk != previousWorkerFk || day == lastDay) { + await models.WorkerTimeControlMail.create({ + workerFk: previousWorkerFk, + year: args.year, + week: args.week + }, myOptions); + const salix = await models.Url.findOne({ where: { appName: 'salix', From 0372d44415a7015d0a9bed40b8cc37146db3a6ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Andr=C3=A9s?= Date: Tue, 4 Apr 2023 15:00:28 +0200 Subject: [PATCH 06/30] fixes #5529 Fixes: missing awaits, buffer-to-file --- .../back/methods/invoiceOut/createPdf.js | 4 +- .../front/global-invoicing/index.js | 23 ++++--- .../front/global-invoicing/locale/es.yml | 3 +- modules/ticket/back/methods/ticket/closure.js | 2 +- print/core/cluster.js | 60 +++++++++---------- print/core/report.js | 39 ++++++------ print/core/storage.js | 16 +---- 7 files changed, 72 insertions(+), 75 deletions(-) diff --git a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js index e56516237..23b6c9e04 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/createPdf.js +++ b/modules/invoiceOut/back/methods/invoiceOut/createPdf.js @@ -56,7 +56,7 @@ module.exports = Self => { reference: invoiceOut.ref, recipientId: invoiceOut.clientFk }); - const stream = await invoiceReport.toPdfStream(); + const buffer = await invoiceReport.toPdfStream(); const issued = invoiceOut.issued; const year = issued.getFullYear().toString(); @@ -66,7 +66,7 @@ module.exports = Self => { const fileName = `${year}${invoiceOut.ref}.pdf`; // Store invoice - print.storage.write(stream, { + await print.storage.write(buffer, { type: 'invoice', path: `${year}/${month}/${day}`, fileName: fileName diff --git a/modules/invoiceOut/front/global-invoicing/index.js b/modules/invoiceOut/front/global-invoicing/index.js index 0ac0223b4..0aa6a4a24 100644 --- a/modules/invoiceOut/front/global-invoicing/index.js +++ b/modules/invoiceOut/front/global-invoicing/index.js @@ -100,16 +100,23 @@ class Controller extends Section { }; this.$http.post(`InvoiceOuts/invoiceClient`, params) + .then(() => this.invoiceNext()) .catch(res => { - this.errors.unshift({ - address, - message: res.data.error.message - }); + const message = res.data?.error?.message || res.message; + if (res.status >= 400 && res.status < 500) { + this.errors.unshift({address, message}); + this.invoiceNext(); + } else { + this.invoicing = false; + this.status = 'done'; + throw new UserError(`Critical invoicing error, proccess stopped`); + } }) - .finally(() => { - this.addressIndex++; - this.invoiceOut(); - }); + } + + invoiceNext() { + this.addressIndex++; + this.invoiceOut(); } get nAddresses() { diff --git a/modules/invoiceOut/front/global-invoicing/locale/es.yml b/modules/invoiceOut/front/global-invoicing/locale/es.yml index 242b5a93f..5b1f7e883 100644 --- a/modules/invoiceOut/front/global-invoicing/locale/es.yml +++ b/modules/invoiceOut/front/global-invoicing/locale/es.yml @@ -17,4 +17,5 @@ Ended process: Proceso finalizado Invoice out: Facturar One client: Un solo cliente Choose a valid client: Selecciona un cliente válido -Stop: Parar \ No newline at end of file +Stop: Parar +Critical invoicing error, proccess stopped: Error crítico al facturar, proceso detenido \ No newline at end of file diff --git a/modules/ticket/back/methods/ticket/closure.js b/modules/ticket/back/methods/ticket/closure.js index d5fa58e7b..9b3355d6c 100644 --- a/modules/ticket/back/methods/ticket/closure.js +++ b/modules/ticket/back/methods/ticket/closure.js @@ -46,7 +46,7 @@ module.exports = async function(Self, tickets, reqArgs = {}) { const fileName = `${year}${invoiceOut.ref}.pdf`; // Store invoice - storage.write(stream, { + await storage.write(stream, { type: 'invoice', path: `${year}/${month}/${day}`, fileName: fileName diff --git a/print/core/cluster.js b/print/core/cluster.js index 23b3d88e9..d54044fa2 100644 --- a/print/core/cluster.js +++ b/print/core/cluster.js @@ -4,40 +4,38 @@ const {cpus} = require('os'); module.exports = { init() { - if (!this.pool) { - Cluster.launch({ - concurrency: Cluster.CONCURRENCY_CONTEXT, - maxConcurrency: cpus().length, - puppeteerOptions: { - headless: true, - args: [ - '--no-sandbox', - '--disable-setuid-sandbox', - '--no-zygote' - ] - } - }) - .then(cluster => { - this.pool = cluster; + if (this.pool) return; + Cluster.launch({ + concurrency: Cluster.CONCURRENCY_CONTEXT, + maxConcurrency: cpus().length, + puppeteerOptions: { + headless: true, + args: [ + '--no-sandbox', + '--disable-setuid-sandbox', + '--no-zygote' + ] + } + }).then(cluster => { + this.pool = cluster; - log4js.configure({ - appenders: { - out: {type: 'stdout'} - }, - categories: {default: {appenders: ['out'], level: 'info'}}, - }); + log4js.configure({ + appenders: { + out: {type: 'stdout'} + }, + categories: {default: {appenders: ['out'], level: 'info'}}, + }); - const logger = log4js.getLogger(); + const logger = log4js.getLogger(); - cluster.on('taskerror', (err, data, willRetry) => { - if (willRetry) - logger.warn(`[Print] => ${err.message}\nThis job will be retried`); - else - logger.error(`[Print] => ${err.message}`); - }); + cluster.on('taskerror', (err, data, willRetry) => { + if (willRetry) + logger.warn(`[Print] => ${err.message}\nThis job will be retried`); + else + logger.error(`[Print] => ${err.message}`); + }); - cluster.on('queue', () => logger.info('Printing task initialized by pool')); - }); - } + cluster.on('queue', () => logger.info('Printing task initialized by pool')); + }); } }; diff --git a/print/core/report.js b/print/core/report.js index c5182d1a8..23cffac2c 100644 --- a/print/core/report.js +++ b/print/core/report.js @@ -32,28 +32,31 @@ class Report extends Component { if (fs.existsSync(fullPath)) options = require(optionsPath); - return new Promise(resolve => { + return new Promise((resolve, reject) => { Cluster.pool.queue({}, async({page}) => { - await page.emulateMediaType('screen'); - await page.setContent(template); + try { + await page.emulateMediaType('screen'); + await page.setContent(template); - const element = await page.$('#pageFooter'); + const element = await page.$('#pageFooter'); - let footer = '\n'; - if (element) { - footer = await page.evaluate(el => { - const html = el.innerHTML; - el.remove(); - return html; - }, element); + let footer = '\n'; + if (element) { + footer = await page.evaluate(el => { + const html = el.innerHTML; + el.remove(); + return html; + }, element); + } + + options.headerTemplate = '\n'; + options.footerTemplate = footer; + + const buffer = await page.pdf(options); + resolve(buffer); + } catch (err) { + reject(err); } - - options.headerTemplate = '\n'; - options.footerTemplate = footer; - - const stream = await page.pdf(options); - - resolve(stream); }); }); } diff --git a/print/core/storage.js b/print/core/storage.js index 063a2fbec..66f7ce98a 100644 --- a/print/core/storage.js +++ b/print/core/storage.js @@ -3,26 +3,14 @@ const path = require('path'); const fs = require('fs-extra'); module.exports = { - async write(stream, options) { + async write(buffer, options) { const storage = config.storage[options.type]; - if (!storage) return; const src = path.join(storage.root, options.path); const fileSrc = path.join(src, options.fileName); await fs.mkdir(src, {recursive: true}); - - const writeStream = fs.createWriteStream(fileSrc); - writeStream.on('open', () => writeStream.write(stream)); - writeStream.on('finish', () => writeStream.end()); - - return new Promise(resolve => { - writeStream.on('close', () => resolve()); - }); - }, - - load(type, data) { - + await fs.writeFile(fileSrc, buffer); } }; From 6fc2867551376775dad65635ce3d1a4d39e345c8 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 6 Apr 2023 08:05:37 +0200 Subject: [PATCH 07/30] permite decimales --- .../supplier/front/agency-term/create/index.html | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/modules/supplier/front/agency-term/create/index.html b/modules/supplier/front/agency-term/create/index.html index 29d7b9b6a..728e98146 100644 --- a/modules/supplier/front/agency-term/create/index.html +++ b/modules/supplier/front/agency-term/create/index.html @@ -22,7 +22,7 @@ value-field="id" rule> - - - - - - - \ No newline at end of file + From abaeeddc21c4ede37b2c0fb431effd9350e3185e Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 11 Apr 2023 10:54:58 +0200 Subject: [PATCH 08/30] refs #5418 fix e2e --- e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js b/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js index 70fa121fd..1c8fe0840 100644 --- a/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js +++ b/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js @@ -92,7 +92,7 @@ describe('SmartTable SearchBar integration', () => { }); const result = await page.waitToGetProperty(selectors.itemFixedPrice.firstItemID, 'value'); - expect(result).toEqual('3'); + expect(result).toEqual('13'); }); }); }); From d5d18d537633716f6c09cc2005d89c4f0dd4f0a5 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 11 Apr 2023 11:02:08 +0200 Subject: [PATCH 09/30] hotfix apply SQL delivery.sql --- db/changes/231202/00-delivery.sql | 74 +++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 db/changes/231202/00-delivery.sql diff --git a/db/changes/231202/00-delivery.sql b/db/changes/231202/00-delivery.sql new file mode 100644 index 000000000..3a9269183 --- /dev/null +++ b/db/changes/231202/00-delivery.sql @@ -0,0 +1,74 @@ +DROP TABLE `vn`.`dmsRecover`; + +ALTER TABLE `vn`.`delivery` DROP FOREIGN KEY delivery_FK; +ALTER TABLE `vn`.`delivery` DROP COLUMN addressFk; +ALTER TABLE `vn`.`delivery` ADD ticketFk INT NOT NULL; +ALTER TABLE `vn`.`delivery` ADD CONSTRAINT delivery_ticketFk_FK FOREIGN KEY (`ticketFk`) REFERENCES `vn`.`ticket`(`id`); + +DELETE FROM `salix`.`ACL` WHERE `property` = 'saveSign'; +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalId`) + VALUES + ('Ticket','saveSign','WRITE','ALLOW','employee'); + +DROP PROCEDURE IF EXISTS vn.route_getTickets; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`route_getTickets`(vRouteFk INT) +BEGIN +/** + * Pasado un RouteFk devuelve la información + * de sus tickets. + * + * @param vRouteFk + * + * @select Información de los tickets + */ + + SELECT + t.id Id, + t.clientFk Client, + a.id Address, + t.packages Packages, + a.street AddressName, + a.postalCode PostalCode, + a.city City, + sub2.itemPackingTypeFk PackingType, + c.phone ClientPhone, + c.mobile ClientMobile, + a.phone AddressPhone, + a.mobile AddressMobile, + d.longitude Longitude, + d.latitude Latitude, + wm.mediaValue SalePersonPhone, + tob.Note Note, + t.isSigned Signed + FROM ticket t + JOIN client c ON t.clientFk = c.id + JOIN address a ON t.addressFk = a.id + LEFT JOIN delivery d ON t.id = d.ticketFk + LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk + LEFT JOIN + (SELECT tob.description Note, t.id + FROM ticketObservation tob + JOIN ticket t ON tob.ticketFk = t.id + JOIN observationType ot ON ot.id = tob.observationTypeFk + WHERE t.routeFk = vRouteFk + AND ot.code = 'delivery' + )tob ON tob.id = t.id + LEFT JOIN + (SELECT sub.ticketFk, + CONCAT('(', GROUP_CONCAT(DISTINCT sub.itemPackingTypeFk ORDER BY sub.items DESC SEPARATOR ','), ') ') itemPackingTypeFk + FROM (SELECT s.ticketFk , i.itemPackingTypeFk, COUNT(*) items + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + WHERE t.routeFk = vRouteFk + GROUP BY t.id,i.itemPackingTypeFk)sub + GROUP BY sub.ticketFk + ) sub2 ON sub2.ticketFk = t.id + WHERE t.routeFk = vRouteFk + GROUP BY t.id + ORDER BY t.priority; +END$$ +DELIMITER ; From c6db5f1a4bba2389eff12fb54ced6f1bcbfc055e Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 11 Apr 2023 12:29:09 +0200 Subject: [PATCH 10/30] hotfix apply changes procedure --- db/changes/231202/00-delivery.sql | 68 ------------------------------- db/changes/231202/01-delivery.sql | 67 ++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 68 deletions(-) create mode 100644 db/changes/231202/01-delivery.sql diff --git a/db/changes/231202/00-delivery.sql b/db/changes/231202/00-delivery.sql index 3a9269183..87e5119e3 100644 --- a/db/changes/231202/00-delivery.sql +++ b/db/changes/231202/00-delivery.sql @@ -4,71 +4,3 @@ ALTER TABLE `vn`.`delivery` DROP FOREIGN KEY delivery_FK; ALTER TABLE `vn`.`delivery` DROP COLUMN addressFk; ALTER TABLE `vn`.`delivery` ADD ticketFk INT NOT NULL; ALTER TABLE `vn`.`delivery` ADD CONSTRAINT delivery_ticketFk_FK FOREIGN KEY (`ticketFk`) REFERENCES `vn`.`ticket`(`id`); - -DELETE FROM `salix`.`ACL` WHERE `property` = 'saveSign'; -INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalId`) - VALUES - ('Ticket','saveSign','WRITE','ALLOW','employee'); - -DROP PROCEDURE IF EXISTS vn.route_getTickets; - -DELIMITER $$ -$$ -CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`route_getTickets`(vRouteFk INT) -BEGIN -/** - * Pasado un RouteFk devuelve la información - * de sus tickets. - * - * @param vRouteFk - * - * @select Información de los tickets - */ - - SELECT - t.id Id, - t.clientFk Client, - a.id Address, - t.packages Packages, - a.street AddressName, - a.postalCode PostalCode, - a.city City, - sub2.itemPackingTypeFk PackingType, - c.phone ClientPhone, - c.mobile ClientMobile, - a.phone AddressPhone, - a.mobile AddressMobile, - d.longitude Longitude, - d.latitude Latitude, - wm.mediaValue SalePersonPhone, - tob.Note Note, - t.isSigned Signed - FROM ticket t - JOIN client c ON t.clientFk = c.id - JOIN address a ON t.addressFk = a.id - LEFT JOIN delivery d ON t.id = d.ticketFk - LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk - LEFT JOIN - (SELECT tob.description Note, t.id - FROM ticketObservation tob - JOIN ticket t ON tob.ticketFk = t.id - JOIN observationType ot ON ot.id = tob.observationTypeFk - WHERE t.routeFk = vRouteFk - AND ot.code = 'delivery' - )tob ON tob.id = t.id - LEFT JOIN - (SELECT sub.ticketFk, - CONCAT('(', GROUP_CONCAT(DISTINCT sub.itemPackingTypeFk ORDER BY sub.items DESC SEPARATOR ','), ') ') itemPackingTypeFk - FROM (SELECT s.ticketFk , i.itemPackingTypeFk, COUNT(*) items - FROM ticket t - JOIN sale s ON s.ticketFk = t.id - JOIN item i ON i.id = s.itemFk - WHERE t.routeFk = vRouteFk - GROUP BY t.id,i.itemPackingTypeFk)sub - GROUP BY sub.ticketFk - ) sub2 ON sub2.ticketFk = t.id - WHERE t.routeFk = vRouteFk - GROUP BY t.id - ORDER BY t.priority; -END$$ -DELIMITER ; diff --git a/db/changes/231202/01-delivery.sql b/db/changes/231202/01-delivery.sql new file mode 100644 index 000000000..0815ec421 --- /dev/null +++ b/db/changes/231202/01-delivery.sql @@ -0,0 +1,67 @@ +DELETE FROM `salix`.`ACL` WHERE `property` = 'saveSign'; +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalId`) + VALUES + ('Ticket','saveSign','WRITE','ALLOW','employee'); + +DROP PROCEDURE IF EXISTS vn.route_getTickets; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`route_getTickets`(vRouteFk INT) +BEGIN +/** + * Pasado un RouteFk devuelve la información + * de sus tickets. + * + * @param vRouteFk + * + * @select Información de los tickets + */ + + SELECT + t.id Id, + t.clientFk Client, + a.id Address, + t.packages Packages, + a.street AddressName, + a.postalCode PostalCode, + a.city City, + sub2.itemPackingTypeFk PackingType, + c.phone ClientPhone, + c.mobile ClientMobile, + a.phone AddressPhone, + a.mobile AddressMobile, + d.longitude Longitude, + d.latitude Latitude, + wm.mediaValue SalePersonPhone, + tob.Note Note, + t.isSigned Signed + FROM ticket t + JOIN client c ON t.clientFk = c.id + JOIN address a ON t.addressFk = a.id + LEFT JOIN delivery d ON t.id = d.ticketFk + LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk + LEFT JOIN + (SELECT tob.description Note, t.id + FROM ticketObservation tob + JOIN ticket t ON tob.ticketFk = t.id + JOIN observationType ot ON ot.id = tob.observationTypeFk + WHERE t.routeFk = vRouteFk + AND ot.code = 'delivery' + )tob ON tob.id = t.id + LEFT JOIN + (SELECT sub.ticketFk, + CONCAT('(', GROUP_CONCAT(DISTINCT sub.itemPackingTypeFk ORDER BY sub.items DESC SEPARATOR ','), ') ') itemPackingTypeFk + FROM (SELECT s.ticketFk , i.itemPackingTypeFk, COUNT(*) items + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + WHERE t.routeFk = vRouteFk + GROUP BY t.id,i.itemPackingTypeFk)sub + GROUP BY sub.ticketFk + ) sub2 ON sub2.ticketFk = t.id + WHERE t.routeFk = vRouteFk + GROUP BY t.id + ORDER BY t.priority; +END$$ +DELIMITER ; From 3ee08e030026ff93b8950daca874a9ad48f98352 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 11 Apr 2023 12:34:26 +0200 Subject: [PATCH 11/30] changed folder --- db/changes/231202/00-delivery.sql | 68 +++++++++++++++++++ .../00-delivery.sql} | 0 2 files changed, 68 insertions(+) rename db/changes/{231202/01-delivery.sql => 231203/00-delivery.sql} (100%) diff --git a/db/changes/231202/00-delivery.sql b/db/changes/231202/00-delivery.sql index 87e5119e3..3a9269183 100644 --- a/db/changes/231202/00-delivery.sql +++ b/db/changes/231202/00-delivery.sql @@ -4,3 +4,71 @@ ALTER TABLE `vn`.`delivery` DROP FOREIGN KEY delivery_FK; ALTER TABLE `vn`.`delivery` DROP COLUMN addressFk; ALTER TABLE `vn`.`delivery` ADD ticketFk INT NOT NULL; ALTER TABLE `vn`.`delivery` ADD CONSTRAINT delivery_ticketFk_FK FOREIGN KEY (`ticketFk`) REFERENCES `vn`.`ticket`(`id`); + +DELETE FROM `salix`.`ACL` WHERE `property` = 'saveSign'; +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalId`) + VALUES + ('Ticket','saveSign','WRITE','ALLOW','employee'); + +DROP PROCEDURE IF EXISTS vn.route_getTickets; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`route_getTickets`(vRouteFk INT) +BEGIN +/** + * Pasado un RouteFk devuelve la información + * de sus tickets. + * + * @param vRouteFk + * + * @select Información de los tickets + */ + + SELECT + t.id Id, + t.clientFk Client, + a.id Address, + t.packages Packages, + a.street AddressName, + a.postalCode PostalCode, + a.city City, + sub2.itemPackingTypeFk PackingType, + c.phone ClientPhone, + c.mobile ClientMobile, + a.phone AddressPhone, + a.mobile AddressMobile, + d.longitude Longitude, + d.latitude Latitude, + wm.mediaValue SalePersonPhone, + tob.Note Note, + t.isSigned Signed + FROM ticket t + JOIN client c ON t.clientFk = c.id + JOIN address a ON t.addressFk = a.id + LEFT JOIN delivery d ON t.id = d.ticketFk + LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk + LEFT JOIN + (SELECT tob.description Note, t.id + FROM ticketObservation tob + JOIN ticket t ON tob.ticketFk = t.id + JOIN observationType ot ON ot.id = tob.observationTypeFk + WHERE t.routeFk = vRouteFk + AND ot.code = 'delivery' + )tob ON tob.id = t.id + LEFT JOIN + (SELECT sub.ticketFk, + CONCAT('(', GROUP_CONCAT(DISTINCT sub.itemPackingTypeFk ORDER BY sub.items DESC SEPARATOR ','), ') ') itemPackingTypeFk + FROM (SELECT s.ticketFk , i.itemPackingTypeFk, COUNT(*) items + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + WHERE t.routeFk = vRouteFk + GROUP BY t.id,i.itemPackingTypeFk)sub + GROUP BY sub.ticketFk + ) sub2 ON sub2.ticketFk = t.id + WHERE t.routeFk = vRouteFk + GROUP BY t.id + ORDER BY t.priority; +END$$ +DELIMITER ; diff --git a/db/changes/231202/01-delivery.sql b/db/changes/231203/00-delivery.sql similarity index 100% rename from db/changes/231202/01-delivery.sql rename to db/changes/231203/00-delivery.sql From 245b0e70f47f3399681e2921c5d4ed9d7ccdef07 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 11 Apr 2023 14:51:39 +0200 Subject: [PATCH 12/30] hotfix rollback delivery.sql --- db/changes/231204/00-rollbackDelivery.sql | 83 +++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 db/changes/231204/00-rollbackDelivery.sql diff --git a/db/changes/231204/00-rollbackDelivery.sql b/db/changes/231204/00-rollbackDelivery.sql new file mode 100644 index 000000000..d7fa6b587 --- /dev/null +++ b/db/changes/231204/00-rollbackDelivery.sql @@ -0,0 +1,83 @@ +CREATE TABLE `vn`.`dmsRecover` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ticketFk` int(11) DEFAULT NULL, + `sign` text DEFAULT NULL, + `created` timestamp NULL DEFAULT current_timestamp(), + PRIMARY KEY (`id`), + KEY `ticketFk_idx` (`ticketFk`), + CONSTRAINT `ticketFk` FOREIGN KEY (`ticketFk`) REFERENCES `ticket` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=31917 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +ALTER TABLE `vn`.`delivery` ADD addressFk INT; + +DROP PROCEDURE IF EXISTS `vn`.`route_getTickets`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`route_getTickets`(vRouteFk INT) +BEGIN +/** + * Pasado un RouteFk devuelve la información + * de sus tickets. + * + * @param vRouteFk + * @select Información de los tickets + */ +SELECT * + FROM ( + SELECT t.id Id, + t.clientFk Client, + a.id Address, + a.nickname ClientName, + t.packages Packages, + a.street AddressName, + a.postalCode PostalCode, + a.city City, + sub2.itemPackingTypeFk PackingType, + c.phone ClientPhone, + c.mobile ClientMobile, + a.phone AddressPhone, + a.mobile AddressMobile, + d.longitude Longitude, + d.latitude Latitude, + wm.mediaValue SalePersonPhone, + tob.description Note, + t.isSigned Signed, + t.priority + FROM ticket t + JOIN client c ON t.clientFk = c.id + JOIN address a ON t.addressFk = a.id + LEFT JOIN delivery d ON d.addressFk = a.id + LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk + LEFT JOIN( + SELECT tob.description, t.id + FROM ticketObservation tob + JOIN ticket t ON tob.ticketFk = t.id + JOIN observationType ot ON ot.id = tob.observationTypeFk + WHERE t.routeFk = vRouteFk + AND ot.code = 'delivery' + )tob ON tob.id = t.id + LEFT JOIN( + SELECT sub.ticketFk, + CONCAT('(', + GROUP_CONCAT(DISTINCT sub.itemPackingTypeFk + ORDER BY sub.items DESC SEPARATOR ','), + ') ') itemPackingTypeFk + FROM ( + SELECT s.ticketFk, i.itemPackingTypeFk, COUNT(*) items + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + WHERE t.routeFk = vRouteFk + GROUP BY t.id, i.itemPackingTypeFk + )sub + GROUP BY sub.ticketFk + )sub2 ON sub2.ticketFk = t.id + WHERE t.routeFk = vRouteFk + ORDER BY d.id DESC + LIMIT 10000000000000000000 + )sub3 + GROUP BY sub3.id + ORDER BY sub3.priority; +END$$ +DELIMITER ; From 0666163ca068e1a910a5b219f2e0f1a5acc64de1 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 12 Apr 2023 12:33:14 +0200 Subject: [PATCH 13/30] refs #5546 deleted log property, fixed back tests --- .../methods/vn-model/specs/crud.spec.js | 14 + .../vn-model/specs/rewriteDbError.spec.js | 15 + loopback/server/connectors/vn-mysql.js | 264 ++---------------- .../methods/claim/specs/updateClaim.spec.js | 14 + .../claim/specs/updateClaimAction.spec.js | 14 + .../claim/back/models/claim-beginning.json | 5 - .../claim/back/models/claim-development.json | 4 - modules/claim/back/models/claim-dms.json | 10 +- modules/claim/back/models/claim-end.json | 4 - .../claim/back/models/claim-observation.json | 6 +- modules/claim/back/models/claim-state.json | 5 - modules/claim/back/models/claim.json | 4 - modules/client/back/models/address.json | 7 +- .../client/back/models/client-contact.json | 7 +- modules/client/back/models/client-dms.json | 5 - .../back/models/client-observation.json | 4 - modules/client/back/models/client-sample.json | 5 - modules/client/back/models/client.json | 6 +- modules/client/back/models/greuge.json | 7 +- modules/client/back/models/recovery.json | 6 +- modules/entry/back/models/buy.json | 5 - .../entry/back/models/entry-observation.json | 4 - modules/entry/back/models/entry.json | 4 - .../methods/invoice-in/specs/clone.spec.js | 15 + .../invoiceIn/back/models/invoice-in-tax.json | 6 +- modules/invoiceIn/back/models/invoice-in.json | 3 - .../methods/item/specs/updateTaxes.spec.js | 15 + .../back/methods/tag/specs/onSubmit.spec.js | 15 + modules/item/back/models/item-barcode.json | 7 +- modules/item/back/models/item-botanical.json | 6 +- modules/item/back/models/item-tag.json | 5 - .../item/back/models/item-tax-country.json | 7 +- modules/item/back/models/item.json | 5 - .../agency-term/specs/createInvoiceIn.spec.js | 14 + modules/route/back/models/route.json | 4 - modules/shelving/back/models/shelving.json | 4 - .../back/models/supplier-account.json | 6 +- .../back/models/supplier-address.json | 7 +- .../back/models/supplier-contact.json | 6 +- modules/supplier/back/models/supplier.json | 3 - .../specs/deleteExpeditions.spec.js | 15 + .../expedition/specs/moveExpeditions.spec.js | 15 + .../ticket-request/specs/confirm.spec.js | 14 + .../methods/ticket-request/specs/deny.spec.js | 15 + .../ticket/specs/componentUpdate.spec.js | 14 +- modules/ticket/back/models/expedition.json | 5 - modules/ticket/back/models/sale.json | 6 - .../models/specs/ticket-packaging.spec.js | 14 + modules/ticket/back/models/ticket-dms.json | 6 +- .../back/models/ticket-observation.json | 4 - .../ticket/back/models/ticket-packaging.json | 4 - modules/ticket/back/models/ticket-refund.json | 4 - .../ticket/back/models/ticket-request.json | 6 +- .../ticket/back/models/ticket-service.json | 7 +- .../ticket/back/models/ticket-tracking.json | 16 +- modules/ticket/back/models/ticket-weekly.json | 7 +- modules/ticket/back/models/ticket.json | 5 - .../travel/specs/createThermograph.spec.js | 14 + .../back/models/travel-thermograph.json | 7 +- modules/travel/back/models/travel.json | 5 - modules/worker/back/models/worker-dms.json | 5 - modules/worker/back/models/worker.json | 4 - .../back/methods/zone/specs/clone.spec.js | 15 + .../methods/zone/specs/exclusionGeo.spec.js | 14 + .../zone/specs/toggleIsIncluded.spec.js | 15 + modules/zone/back/models/zone-event.json | 6 +- modules/zone/back/models/zone-exclusion.json | 6 +- modules/zone/back/models/zone-included.json | 7 +- modules/zone/back/models/zone-warehouse.json | 6 +- modules/zone/back/models/zone.json | 8 +- 70 files changed, 314 insertions(+), 502 deletions(-) diff --git a/loopback/common/methods/vn-model/specs/crud.spec.js b/loopback/common/methods/vn-model/specs/crud.spec.js index 4aa35c14d..56af72bd9 100644 --- a/loopback/common/methods/vn-model/specs/crud.spec.js +++ b/loopback/common/methods/vn-model/specs/crud.spec.js @@ -1,6 +1,20 @@ const app = require('vn-loopback/server/server'); +const LoopBackContext = require('loopback-context'); describe('Model crud()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); let insertId; const barcodeModel = app.models.ItemBarcode; diff --git a/loopback/common/methods/vn-model/specs/rewriteDbError.spec.js b/loopback/common/methods/vn-model/specs/rewriteDbError.spec.js index 1c4d53266..a3dba14d7 100644 --- a/loopback/common/methods/vn-model/specs/rewriteDbError.spec.js +++ b/loopback/common/methods/vn-model/specs/rewriteDbError.spec.js @@ -1,6 +1,21 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('Model rewriteDbError()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + it('should extend rewriteDbError properties to any model passed', () => { const exampleModel = models.ItemTag; diff --git a/loopback/server/connectors/vn-mysql.js b/loopback/server/connectors/vn-mysql.js index 728454d86..234fa3500 100644 --- a/loopback/server/connectors/vn-mysql.js +++ b/loopback/server/connectors/vn-mysql.js @@ -1,41 +1,9 @@ const mysql = require('mysql'); const MySQL = require('loopback-connector-mysql').MySQL; const EnumFactory = require('loopback-connector-mysql').EnumFactory; -const { Transaction, SQLConnector, ParameterizedSQL } = require('loopback-connector'); +const {Transaction, SQLConnector, ParameterizedSQL} = require('loopback-connector'); const fs = require('fs'); -const limitSet = new Set([ - 'save', - 'updateOrCreate', - 'replaceOrCreate', - 'replaceById', - 'update' -]); - -const opOpts = { - update: [ - 'update', - 'replaceById', - // |insert - 'save', - 'updateOrCreate', - 'replaceOrCreate' - ], - delete: [ - 'destroy', - 'destroyAll' - ], - insert: [ - 'create' - ] -}; - -const opMap = new Map(); -for (const op in opOpts) { - for (const met of opOpts[op]) - opMap.set(met, op); -} - class VnMySQL extends MySQL { /** * Promisified version of execute(). @@ -253,49 +221,49 @@ class VnMySQL extends MySQL { } create(model, data, opts, cb) { - const ctx = { data }; + const ctx = {data}; this.invokeMethod('create', arguments, model, ctx, opts, cb); } createAll(model, data, opts, cb) { - const ctx = { data }; + const ctx = {data}; this.invokeMethod('createAll', arguments, model, ctx, opts, cb); } save(model, data, opts, cb) { - const ctx = { data }; + const ctx = {data}; this.invokeMethod('save', arguments, model, ctx, opts, cb); } updateOrCreate(model, data, opts, cb) { - const ctx = { data }; + const ctx = {data}; this.invokeMethod('updateOrCreate', arguments, model, ctx, opts, cb); } replaceOrCreate(model, data, opts, cb) { - const ctx = { data }; + const ctx = {data}; this.invokeMethod('replaceOrCreate', arguments, model, ctx, opts, cb); } destroyAll(model, where, opts, cb) { - const ctx = { where }; + const ctx = {where}; this.invokeMethod('destroyAll', arguments, model, ctx, opts, cb); } update(model, where, data, opts, cb) { - const ctx = { where, data }; + const ctx = {where, data}; this.invokeMethod('update', arguments, model, ctx, opts, cb); } replaceById(model, id, data, opts, cb) { - const ctx = { id, data }; + const ctx = {id, data}; this.invokeMethod('replaceById', arguments, model, ctx, opts, cb); } @@ -316,47 +284,16 @@ class VnMySQL extends MySQL { async invokeMethodP(method, args, model, ctx, opts) { const Model = this.getModelDefinition(model).model; - const settings = Model.definition.settings; let tx; if (!opts.transaction) { tx = await Transaction.begin(this, {}); - opts = Object.assign({ transaction: tx, httpCtx: opts.httpCtx }, opts); + opts = Object.assign({transaction: tx, httpCtx: opts.httpCtx}, opts); } try { - // Fetch old values (update|delete) or login - let where, id, data, idName, limit, op, oldInstances, newInstances; - const hasGrabUser = settings.log && settings.log.grabUser; - if (hasGrabUser) { - const userId = opts.httpCtx && opts.httpCtx.active.accessToken.userId; - const user = await Model.app.models.Account.findById(userId, { fields: ['name'] }, opts); - await this.executeP(`CALL account.myUser_loginWithName(?)`, [user.name], opts); - } - else { - where = ctx.where; - id = ctx.id; - data = ctx.data; - idName = this.idName(model); - - limit = limitSet.has(method); - - op = opMap.get(method); - - if (!where) { - if (id) where = { [idName]: id }; - else where = { [idName]: data[idName] }; - } - - // Fetch old values - switch (op) { - case 'update': - case 'delete': - // Single entity operation - const stmt = this.buildSelectStmt(op, data, idName, model, where, limit); - stmt.merge(`FOR UPDATE`); - oldInstances = await this.executeStmt(stmt, opts); - } - } + const userId = opts.httpCtx && opts.httpCtx.active.accessToken.userId; + const user = await Model.app.models.Account.findById(userId, {fields: ['name']}, opts); + await this.executeP(`CALL account.myUser_loginWithName(?)`, [user.name], opts); const res = await new Promise(resolve => { const fnArgs = args.slice(0, -2); @@ -364,38 +301,7 @@ class VnMySQL extends MySQL { super[method].apply(this, fnArgs); }); - if (hasGrabUser) - await this.executeP(`CALL account.myUser_logout()`, null, opts); - else { - // Fetch new values - const ids = []; - - switch (op) { - case 'insert': - case 'update': { - switch (method) { - case 'createAll': - for (const row of res[1]) - ids.push(row[idName]); - break; - case 'create': - ids.push(res[1]); - break; - case 'update': - if (data[idName] != null) - ids.push(data[idName]); - break; - } - - const newWhere = ids.length ? { [idName]: ids } : where; - - const stmt = this.buildSelectStmt(op, data, idName, model, newWhere, limit); - newInstances = await this.executeStmt(stmt, opts); - } - } - - await this.createLogRecord(oldInstances, newInstances, model, opts); - } + await this.executeP(`CALL account.myUser_logout()`, null, opts); if (tx) await tx.commit(); return res; } catch (err) { @@ -403,125 +309,6 @@ class VnMySQL extends MySQL { throw err; } } - - buildSelectStmt(op, data, idName, model, where, limit) { - const Model = this.getModelDefinition(model).model; - const properties = Object.keys(Model.definition.properties); - - const fields = data ? Object.keys(data) : []; - if (op == 'delete') - properties.forEach(property => fields.push(property)); - else { - const log = Model.definition.settings.log; - fields.push(idName); - if (log.relation) fields.push(Model.relations[log.relation].keyFrom); - if (log.showField) fields.push(log.showField); - else { - const showFieldNames = ['name', 'description', 'code', 'nickname']; - for (const field of showFieldNames) { - if (properties.includes(field)) { - log.showField = field; - fields.push(field); - break; - } - } - } - } - - const stmt = new ParameterizedSQL( - 'SELECT ' + - this.buildColumnNames(model, { fields }) + - ' FROM ' + - this.tableEscaped(model) - ); - stmt.merge(this.buildWhere(model, where)); - if (limit) stmt.merge(`LIMIT 1`); - - return stmt; - } - - async createLogRecord(oldInstances, newInstances, model, opts) { - function setActionType() { - if (oldInstances && newInstances) - return 'update'; - else if (!oldInstances && newInstances) - return 'insert'; - return 'delete'; - } - - const action = setActionType(); - if (!newInstances && action != 'delete') return; - - const Model = this.getModelDefinition(model).model; - const models = Model.app.models; - const definition = Model.definition; - const log = definition.settings.log; - - const primaryKey = this.idName(model); - const originRelation = log.relation; - const originFkField = originRelation - ? Model.relations[originRelation].keyFrom - : primaryKey; - - // Prevent adding logs when deleting a principal entity (Client, Zone...) - if (action == 'delete' && !originRelation) return; - - function map(instances) { - const map = new Map(); - if (!instances) return; - for (const instance of instances) - map.set(instance[primaryKey], instance); - return map; - } - - const changedModel = definition.name; - const userFk = opts.httpCtx && opts.httpCtx.active.accessToken.userId; - const oldMap = map(oldInstances); - const newMap = map(newInstances); - const ids = (oldMap || newMap).keys(); - - const logEntries = []; - - function insertValuesLogEntry(logEntry, instance) { - logEntry.originFk = instance[originFkField]; - logEntry.changedModelId = instance[primaryKey]; - if (log.showField) logEntry.changedModelValue = instance[log.showField]; - } - - for (const id of ids) { - const oldI = oldMap && oldMap.get(id); - const newI = newMap && newMap.get(id); - - const logEntry = { - action, - userFk, - changedModel, - }; - - if (newI) { - insertValuesLogEntry(logEntry, newI); - // Delete unchanged properties - if (oldI) { - Object.keys(oldI).forEach(prop => { - const hasChanges = oldI[prop] instanceof Date ? - oldI[prop]?.getTime() != newI[prop]?.getTime() : - oldI[prop] != newI[prop]; - - if (!hasChanges) { - delete oldI[prop]; - delete newI[prop]; - } - }); - } - } else - insertValuesLogEntry(logEntry, oldI); - - logEntry.oldInstance = oldI; - logEntry.newInstance = newI; - logEntries.push(logEntry); - } - await models[log.model].create(logEntries, opts); - } } exports.VnMySQL = VnMySQL; @@ -542,7 +329,7 @@ exports.initialize = function initialize(dataSource, callback) { if (callback) { if (dataSource.settings.lazyConnect) { - process.nextTick(function () { + process.nextTick(function() { callback(); }); } else @@ -550,13 +337,13 @@ exports.initialize = function initialize(dataSource, callback) { } }; -MySQL.prototype.connect = function (callback) { +MySQL.prototype.connect = function(callback) { const self = this; const options = generateOptions(this.settings); if (this.client) { if (callback) { - process.nextTick(function () { + process.nextTick(function() { callback(null, self.client); }); } @@ -565,7 +352,7 @@ MySQL.prototype.connect = function (callback) { function connectionHandler(options, callback) { const client = mysql.createPool(options); - client.getConnection(function (err, connection) { + client.getConnection(function(err, connection) { const conn = connection; if (!err) { if (self.debug) @@ -645,30 +432,27 @@ function generateOptions(settings) { return options; } - SQLConnector.prototype.all = function find(model, filter, options, cb) { const self = this; // Order by id if no order is specified filter = filter || {}; const stmt = this.buildSelect(model, filter, options); - this.execute(stmt.sql, stmt.params, options, function (err, data) { - if (err) { + this.execute(stmt.sql, stmt.params, options, function(err, data) { + if (err) return cb(err, []); - } try { - const objs = data.map(function (obj) { + const objs = data.map(function(obj) { return self.fromRow(model, obj); }); if (filter && filter.include) { self.getModelDefinition(model).model.include( objs, filter.include, options, cb, ); - } else { + } else cb(null, objs); - } } catch (error) { - cb(error, []) + cb(error, []); } }); -}; \ No newline at end of file +}; diff --git a/modules/claim/back/methods/claim/specs/updateClaim.spec.js b/modules/claim/back/methods/claim/specs/updateClaim.spec.js index 113df35c9..d367fb89f 100644 --- a/modules/claim/back/methods/claim/specs/updateClaim.spec.js +++ b/modules/claim/back/methods/claim/specs/updateClaim.spec.js @@ -1,6 +1,20 @@ const app = require('vn-loopback/server/server'); +const LoopBackContext = require('loopback-context'); describe('Update Claim', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); const newDate = Date.vnNew(); const originalData = { ticketFk: 3, diff --git a/modules/claim/back/methods/claim/specs/updateClaimAction.spec.js b/modules/claim/back/methods/claim/specs/updateClaimAction.spec.js index 12ab45fac..2f16d002c 100644 --- a/modules/claim/back/methods/claim/specs/updateClaimAction.spec.js +++ b/modules/claim/back/methods/claim/specs/updateClaimAction.spec.js @@ -1,6 +1,20 @@ const app = require('vn-loopback/server/server'); +const LoopBackContext = require('loopback-context'); describe('Update Claim', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); const newDate = Date.vnNew(); const original = { ticketFk: 3, diff --git a/modules/claim/back/models/claim-beginning.json b/modules/claim/back/models/claim-beginning.json index afa21f817..d355881e8 100644 --- a/modules/claim/back/models/claim-beginning.json +++ b/modules/claim/back/models/claim-beginning.json @@ -1,11 +1,6 @@ { "name": "ClaimBeginning", "base": "Loggable", - "log": { - "model": "ClaimLog", - "relation": "claim", - "showField": "quantity" - }, "options": { "mysql": { "table": "claimBeginning" diff --git a/modules/claim/back/models/claim-development.json b/modules/claim/back/models/claim-development.json index 02061fab7..b0f352f50 100644 --- a/modules/claim/back/models/claim-development.json +++ b/modules/claim/back/models/claim-development.json @@ -1,10 +1,6 @@ { "name": "ClaimDevelopment", "base": "Loggable", - "log": { - "model": "ClaimLog", - "relation": "claim" - }, "options": { "mysql": { "table": "claimDevelopment" diff --git a/modules/claim/back/models/claim-dms.json b/modules/claim/back/models/claim-dms.json index a215b6bb7..26c90fd69 100644 --- a/modules/claim/back/models/claim-dms.json +++ b/modules/claim/back/models/claim-dms.json @@ -1,18 +1,14 @@ { "name": "ClaimDms", "base": "Loggable", - "log": { - "model": "ClaimLog", - "relation": "claim" - }, "options": { "mysql": { "table": "claimDms" } }, "allowedContentTypes": [ - "image/png", - "image/jpeg", + "image/png", + "image/jpeg", "image/jpg" ], "properties": { @@ -34,4 +30,4 @@ "foreignKey": "dmsFk" } } -} \ No newline at end of file +} diff --git a/modules/claim/back/models/claim-end.json b/modules/claim/back/models/claim-end.json index 12d79f71b..9f12ff93a 100644 --- a/modules/claim/back/models/claim-end.json +++ b/modules/claim/back/models/claim-end.json @@ -1,10 +1,6 @@ { "name": "ClaimEnd", "base": "Loggable", - "log": { - "model": "ClaimLog", - "relation": "claim" - }, "options": { "mysql": { "table": "claimEnd" diff --git a/modules/claim/back/models/claim-observation.json b/modules/claim/back/models/claim-observation.json index e882ad09d..2d418b76e 100644 --- a/modules/claim/back/models/claim-observation.json +++ b/modules/claim/back/models/claim-observation.json @@ -1,10 +1,6 @@ { "name": "ClaimObservation", "base": "Loggable", - "log": { - "model": "ClaimLog", - "relation": "claim" - }, "options": { "mysql": { "table": "claimObservation" @@ -40,4 +36,4 @@ "foreignKey": "claimFk" } } -} \ No newline at end of file +} diff --git a/modules/claim/back/models/claim-state.json b/modules/claim/back/models/claim-state.json index 2fd6d4845..f5bde4168 100644 --- a/modules/claim/back/models/claim-state.json +++ b/modules/claim/back/models/claim-state.json @@ -1,11 +1,6 @@ { "name": "ClaimState", "base": "Loggable", - "log": { - "model": "ClaimLog", - "relation": "claim", - "showField": "description" - }, "options": { "mysql": { "table": "claimState" diff --git a/modules/claim/back/models/claim.json b/modules/claim/back/models/claim.json index 4b26720e5..a7db1f3e1 100644 --- a/modules/claim/back/models/claim.json +++ b/modules/claim/back/models/claim.json @@ -1,10 +1,6 @@ { "name": "Claim", "base": "Loggable", - "log": { - "model": "ClaimLog", - "showField": "id" - }, "options": { "mysql": { "table": "claim" diff --git a/modules/client/back/models/address.json b/modules/client/back/models/address.json index 0dcbbf7fe..5f962677d 100644 --- a/modules/client/back/models/address.json +++ b/modules/client/back/models/address.json @@ -2,11 +2,6 @@ "name": "Address", "description": "Client addresses", "base": "Loggable", - "log": { - "model": "ClientLog", - "relation": "client", - "showField": "nickname" - }, "options": { "mysql": { "table": "address" @@ -88,4 +83,4 @@ "foreignKey": "customsAgentFk" } } -} \ No newline at end of file +} diff --git a/modules/client/back/models/client-contact.json b/modules/client/back/models/client-contact.json index 514ebbf5e..3f71ab79e 100644 --- a/modules/client/back/models/client-contact.json +++ b/modules/client/back/models/client-contact.json @@ -2,11 +2,6 @@ "name": "ClientContact", "description": "Client phone contacts", "base": "Loggable", - "log": { - "model": "ClientLog", - "relation": "client", - "showField": "name" - }, "options": { "mysql": { "table": "clientContact" @@ -33,4 +28,4 @@ "foreignKey": "clientFk" } } -} \ No newline at end of file +} diff --git a/modules/client/back/models/client-dms.json b/modules/client/back/models/client-dms.json index 88b4349df..14b19498e 100644 --- a/modules/client/back/models/client-dms.json +++ b/modules/client/back/models/client-dms.json @@ -1,11 +1,6 @@ { "name": "ClientDms", "base": "Loggable", - "log": { - "model":"ClientLog", - "relation": "client", - "showField": "dmsFk" - }, "options": { "mysql": { "table": "clientDms" diff --git a/modules/client/back/models/client-observation.json b/modules/client/back/models/client-observation.json index d3059377d..b8852b186 100644 --- a/modules/client/back/models/client-observation.json +++ b/modules/client/back/models/client-observation.json @@ -2,10 +2,6 @@ "name": "ClientObservation", "description": "Client notes", "base": "Loggable", - "log": { - "model": "ClientLog", - "relation": "client" - }, "options": { "mysql": { "table": "clientObservation" diff --git a/modules/client/back/models/client-sample.json b/modules/client/back/models/client-sample.json index fc64cd949..6430b66ae 100644 --- a/modules/client/back/models/client-sample.json +++ b/modules/client/back/models/client-sample.json @@ -1,11 +1,6 @@ { "name": "ClientSample", "base": "Loggable", - "log": { - "model": "ClientLog", - "relation": "client", - "showField": "type" - }, "options": { "mysql": { "table": "clientSample" diff --git a/modules/client/back/models/client.json b/modules/client/back/models/client.json index 21db28eaf..6b40aff8e 100644 --- a/modules/client/back/models/client.json +++ b/modules/client/back/models/client.json @@ -1,10 +1,6 @@ { "name": "Client", "base": "Loggable", - "log": { - "model":"ClientLog", - "showField": "id" - }, "options": { "mysql": { "table": "client" @@ -260,4 +256,4 @@ } } } -} \ No newline at end of file +} diff --git a/modules/client/back/models/greuge.json b/modules/client/back/models/greuge.json index 625bf4e28..9cc056260 100644 --- a/modules/client/back/models/greuge.json +++ b/modules/client/back/models/greuge.json @@ -1,11 +1,6 @@ { "name": "Greuge", "base": "Loggable", - "log": { - "model": "ClientLog", - "relation": "client", - "showField": "description" - }, "options": { "mysql": { "table": "greuge" @@ -58,4 +53,4 @@ "foreignKey": "userFk" } } -} \ No newline at end of file +} diff --git a/modules/client/back/models/recovery.json b/modules/client/back/models/recovery.json index de4183924..5ea89197d 100644 --- a/modules/client/back/models/recovery.json +++ b/modules/client/back/models/recovery.json @@ -1,10 +1,6 @@ { "name": "Recovery", "base": "Loggable", - "log": { - "model": "ClientLog", - "relation": "client" - }, "options": { "mysql": { "table": "recovery" @@ -38,4 +34,4 @@ "foreignKey": "clientFk" } } -} \ No newline at end of file +} diff --git a/modules/entry/back/models/buy.json b/modules/entry/back/models/buy.json index de2ddffd6..379e55427 100644 --- a/modules/entry/back/models/buy.json +++ b/modules/entry/back/models/buy.json @@ -1,11 +1,6 @@ { "name": "Buy", "base": "Loggable", - "log": { - "model": "EntryLog", - "relation": "entry", - "grabUser": true - }, "options": { "mysql": { "table": "buy" diff --git a/modules/entry/back/models/entry-observation.json b/modules/entry/back/models/entry-observation.json index 0c63dd663..cdf0c5e6e 100644 --- a/modules/entry/back/models/entry-observation.json +++ b/modules/entry/back/models/entry-observation.json @@ -1,10 +1,6 @@ { "name": "EntryObservation", "base": "Loggable", - "log": { - "model": "EntryLog", - "relation": "entry" - }, "options": { "mysql": { "table": "entryObservation" diff --git a/modules/entry/back/models/entry.json b/modules/entry/back/models/entry.json index 5aa175758..3933f6a34 100644 --- a/modules/entry/back/models/entry.json +++ b/modules/entry/back/models/entry.json @@ -1,10 +1,6 @@ { "name": "Entry", "base": "Loggable", - "log": { - "model":"EntryLog", - "grabUser": true - }, "options": { "mysql": { "table": "entry" diff --git a/modules/invoiceIn/back/methods/invoice-in/specs/clone.spec.js b/modules/invoiceIn/back/methods/invoice-in/specs/clone.spec.js index e0f191962..42ebe52b3 100644 --- a/modules/invoiceIn/back/methods/invoice-in/specs/clone.spec.js +++ b/modules/invoiceIn/back/methods/invoice-in/specs/clone.spec.js @@ -1,6 +1,21 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('invoiceIn clone()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + it('should return the cloned invoiceIn and also clone invoiceInDueDays and invoiceInTaxes if there are any referencing the invoiceIn', async() => { const userId = 1; const ctx = { diff --git a/modules/invoiceIn/back/models/invoice-in-tax.json b/modules/invoiceIn/back/models/invoice-in-tax.json index 789020161..1f68476c3 100644 --- a/modules/invoiceIn/back/models/invoice-in-tax.json +++ b/modules/invoiceIn/back/models/invoice-in-tax.json @@ -1,10 +1,6 @@ { "name": "InvoiceInTax", "base": "Loggable", - "log": { - "model": "InvoiceInLog", - "relation": "invoiceIn" - }, "options": { "mysql": { "table": "invoiceInTax" @@ -55,4 +51,4 @@ "foreignKey": "transactionTypeSageFk" } } -} \ No newline at end of file +} diff --git a/modules/invoiceIn/back/models/invoice-in.json b/modules/invoiceIn/back/models/invoice-in.json index c6a736b06..754899866 100644 --- a/modules/invoiceIn/back/models/invoice-in.json +++ b/modules/invoiceIn/back/models/invoice-in.json @@ -1,9 +1,6 @@ { "name": "InvoiceIn", "base": "Loggable", - "log": { - "model": "InvoiceInLog" - }, "options": { "mysql": { "table": "invoiceIn" diff --git a/modules/item/back/methods/item/specs/updateTaxes.spec.js b/modules/item/back/methods/item/specs/updateTaxes.spec.js index 66d2ce81c..793e43de8 100644 --- a/modules/item/back/methods/item/specs/updateTaxes.spec.js +++ b/modules/item/back/methods/item/specs/updateTaxes.spec.js @@ -1,6 +1,21 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('item updateTaxes()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + it('should throw an error if the taxClassFk is blank', async() => { const tx = await models.Item.beginTransaction({}); const options = {transaction: tx}; diff --git a/modules/item/back/methods/tag/specs/onSubmit.spec.js b/modules/item/back/methods/tag/specs/onSubmit.spec.js index f24aad7e4..1e96d9e81 100644 --- a/modules/item/back/methods/tag/specs/onSubmit.spec.js +++ b/modules/item/back/methods/tag/specs/onSubmit.spec.js @@ -1,6 +1,21 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('tag onSubmit()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + it('should delete a tag', async() => { const tx = await models.Item.beginTransaction({}); const options = {transaction: tx}; diff --git a/modules/item/back/models/item-barcode.json b/modules/item/back/models/item-barcode.json index e2ce347cb..12068a65f 100644 --- a/modules/item/back/models/item-barcode.json +++ b/modules/item/back/models/item-barcode.json @@ -1,11 +1,6 @@ { "name": "ItemBarcode", "base": "Loggable", - "log": { - "model": "ItemLog", - "relation": "item", - "showField": "code" - }, "options": { "mysql": { "table": "itemBarcode" @@ -27,6 +22,6 @@ "type": "belongsTo", "model": "Item", "foreignKey": "itemFk" - } + } } } diff --git a/modules/item/back/models/item-botanical.json b/modules/item/back/models/item-botanical.json index 8d8fd389f..8a8bba870 100644 --- a/modules/item/back/models/item-botanical.json +++ b/modules/item/back/models/item-botanical.json @@ -1,10 +1,6 @@ { "name": "ItemBotanical", "base": "Loggable", - "log": { - "model": "ItemLog", - "relation": "item" - }, "options": { "mysql": { "table": "itemBotanical" @@ -34,4 +30,4 @@ "foreignKey": "specieFk" } } -} \ No newline at end of file +} diff --git a/modules/item/back/models/item-tag.json b/modules/item/back/models/item-tag.json index 5660b3628..0742f8d3f 100644 --- a/modules/item/back/models/item-tag.json +++ b/modules/item/back/models/item-tag.json @@ -1,11 +1,6 @@ { "name": "ItemTag", "base": "Loggable", - "log": { - "model": "ItemLog", - "relation": "item", - "showField": "value" - }, "options": { "mysql": { "table": "itemTag" diff --git a/modules/item/back/models/item-tax-country.json b/modules/item/back/models/item-tax-country.json index f10a9eb72..002be97d8 100644 --- a/modules/item/back/models/item-tax-country.json +++ b/modules/item/back/models/item-tax-country.json @@ -1,11 +1,6 @@ { "name": "ItemTaxCountry", "base": "Loggable", - "log": { - "model": "ItemLog", - "relation": "item", - "showField": "countryFk" - }, "options": { "mysql": { "table": "itemTaxCountry" @@ -47,4 +42,4 @@ "foreignKey": "taxClassFk" } } -} \ No newline at end of file +} diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json index d6b3c27ad..4a7e04002 100644 --- a/modules/item/back/models/item.json +++ b/modules/item/back/models/item.json @@ -1,11 +1,6 @@ { "name": "Item", "base": "Loggable", - "log": { - "model": "ItemLog", - "showField": "id", - "grabUser": true - }, "options": { "mysql": { "table": "item" diff --git a/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js b/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js index 2a8ebdba3..628c5fb9a 100644 --- a/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js +++ b/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js @@ -1,6 +1,20 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('AgencyTerm createInvoiceIn()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); const rows = [ { routeFk: 2, diff --git a/modules/route/back/models/route.json b/modules/route/back/models/route.json index 3b12f4ee6..cdb64dd71 100644 --- a/modules/route/back/models/route.json +++ b/modules/route/back/models/route.json @@ -1,10 +1,6 @@ { "name": "Route", "base": "Loggable", - "log": { - "model":"RouteLog", - "grabUser": true - }, "options": { "mysql": { "table": "route" diff --git a/modules/shelving/back/models/shelving.json b/modules/shelving/back/models/shelving.json index 508ac428f..5f60318a5 100644 --- a/modules/shelving/back/models/shelving.json +++ b/modules/shelving/back/models/shelving.json @@ -1,10 +1,6 @@ { "name": "Shelving", "base": "Loggable", - "log": { - "model": "ShelvingLog", - "showField": "id" - }, "options": { "mysql": { "table": "shelving" diff --git a/modules/supplier/back/models/supplier-account.json b/modules/supplier/back/models/supplier-account.json index 2ee83338b..bc9cf0e24 100644 --- a/modules/supplier/back/models/supplier-account.json +++ b/modules/supplier/back/models/supplier-account.json @@ -1,10 +1,6 @@ { "name": "SupplierAccount", "base": "Loggable", - "log": { - "model":"SupplierLog", - "relation": "supplier" - }, "options": { "mysql": { "table": "supplierAccount" @@ -35,4 +31,4 @@ "foreignKey": "bankEntityFk" } } -} \ No newline at end of file +} diff --git a/modules/supplier/back/models/supplier-address.json b/modules/supplier/back/models/supplier-address.json index 302f15e4b..001b3a31f 100644 --- a/modules/supplier/back/models/supplier-address.json +++ b/modules/supplier/back/models/supplier-address.json @@ -2,11 +2,6 @@ "name": "SupplierAddress", "description": "Supplier addresses", "base": "Loggable", - "log": { - "model": "SupplierLog", - "relation": "supplier", - "showField": "name" - }, "options": { "mysql": { "table": "supplierAddress" @@ -52,4 +47,4 @@ "foreignKey": "supplierFk" } } -} \ No newline at end of file +} diff --git a/modules/supplier/back/models/supplier-contact.json b/modules/supplier/back/models/supplier-contact.json index 9e13c33a8..f928cd204 100644 --- a/modules/supplier/back/models/supplier-contact.json +++ b/modules/supplier/back/models/supplier-contact.json @@ -1,10 +1,6 @@ { "name": "SupplierContact", "base": "Loggable", - "log": { - "model":"SupplierLog", - "relation": "supplier" - }, "options": { "mysql": { "table": "supplierContact" @@ -50,4 +46,4 @@ "permission": "ALLOW" } ] -} \ No newline at end of file +} diff --git a/modules/supplier/back/models/supplier.json b/modules/supplier/back/models/supplier.json index ee2c4fbbd..b6245ef32 100644 --- a/modules/supplier/back/models/supplier.json +++ b/modules/supplier/back/models/supplier.json @@ -1,9 +1,6 @@ { "name": "Supplier", "base": "Loggable", - "log": { - "model":"SupplierLog" - }, "options": { "mysql": { "table": "supplier" diff --git a/modules/ticket/back/methods/expedition/specs/deleteExpeditions.spec.js b/modules/ticket/back/methods/expedition/specs/deleteExpeditions.spec.js index 14bdf7aea..61937989e 100644 --- a/modules/ticket/back/methods/expedition/specs/deleteExpeditions.spec.js +++ b/modules/ticket/back/methods/expedition/specs/deleteExpeditions.spec.js @@ -1,6 +1,21 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('ticket deleteExpeditions()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + it('should delete the selected expeditions', async() => { const tx = await models.Expedition.beginTransaction({}); diff --git a/modules/ticket/back/methods/expedition/specs/moveExpeditions.spec.js b/modules/ticket/back/methods/expedition/specs/moveExpeditions.spec.js index ac397d38e..5f211543e 100644 --- a/modules/ticket/back/methods/expedition/specs/moveExpeditions.spec.js +++ b/modules/ticket/back/methods/expedition/specs/moveExpeditions.spec.js @@ -1,6 +1,21 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('ticket moveExpeditions()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + it('should move the selected expeditions to new ticket', async() => { const tx = await models.Expedition.beginTransaction({}); const ctx = { diff --git a/modules/ticket/back/methods/ticket-request/specs/confirm.spec.js b/modules/ticket/back/methods/ticket-request/specs/confirm.spec.js index 49413cf44..de2817d87 100644 --- a/modules/ticket/back/methods/ticket-request/specs/confirm.spec.js +++ b/modules/ticket/back/methods/ticket-request/specs/confirm.spec.js @@ -1,6 +1,20 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('ticket-request confirm()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); let ctx = { req: { accessToken: {userId: 9}, 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 95fd0e84d..875a75921 100644 --- a/modules/ticket/back/methods/ticket-request/specs/deny.spec.js +++ b/modules/ticket/back/methods/ticket-request/specs/deny.spec.js @@ -1,6 +1,21 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('ticket-request deny()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + it('should return the denied ticket request', async() => { const tx = await models.TicketRequest.beginTransaction({}); diff --git a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js index d65c87654..ef6422be2 100644 --- a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js +++ b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js @@ -17,6 +17,17 @@ describe('ticket componentUpdate()', () => { let componentValue; beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); const deliveryComponenet = await models.Component.findOne({where: {code: 'delivery'}}); deliveryComponentId = deliveryComponenet.id; componentOfSaleSeven = `SELECT value @@ -180,9 +191,6 @@ describe('ticket componentUpdate()', () => { } }; - spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ - active: ctx.req - }); const oldTicket = await models.Ticket.findById(ticketID, null, options); await models.Ticket.componentUpdate(ctx, options); diff --git a/modules/ticket/back/models/expedition.json b/modules/ticket/back/models/expedition.json index d74c56d2c..e32a3b23d 100644 --- a/modules/ticket/back/models/expedition.json +++ b/modules/ticket/back/models/expedition.json @@ -1,10 +1,6 @@ { "name": "Expedition", "base": "Loggable", - "log": { - "model": "TicketLog", - "relation": "ticket" - }, "options": { "mysql": { "table": "expedition" @@ -59,4 +55,3 @@ } } } - \ No newline at end of file diff --git a/modules/ticket/back/models/sale.json b/modules/ticket/back/models/sale.json index 7b8cf501b..72ca1f5e0 100644 --- a/modules/ticket/back/models/sale.json +++ b/modules/ticket/back/models/sale.json @@ -1,12 +1,6 @@ { "name": "Sale", "base": "Loggable", - "log": { - "model": "TicketLog", - "relation": "ticket", - "showField": "concept", - "grabUser": true - }, "options": { "mysql": { "table": "sale" diff --git a/modules/ticket/back/models/specs/ticket-packaging.spec.js b/modules/ticket/back/models/specs/ticket-packaging.spec.js index f2834643d..6d59456a3 100644 --- a/modules/ticket/back/models/specs/ticket-packaging.spec.js +++ b/modules/ticket/back/models/specs/ticket-packaging.spec.js @@ -1,6 +1,20 @@ const app = require('vn-loopback/server/server'); +const LoopBackContext = require('loopback-context'); describe('ticket model TicketTracking', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); let ticketTrackingId; afterAll(async() => { diff --git a/modules/ticket/back/models/ticket-dms.json b/modules/ticket/back/models/ticket-dms.json index 8bcff254c..071999be7 100644 --- a/modules/ticket/back/models/ticket-dms.json +++ b/modules/ticket/back/models/ticket-dms.json @@ -1,10 +1,6 @@ { "name": "TicketDms", "base": "Loggable", - "log": { - "model": "TicketLog", - "relation": "ticket" - }, "options": { "mysql": { "table": "ticketDms" @@ -29,4 +25,4 @@ "foreignKey": "dmsFk" } } -} \ No newline at end of file +} diff --git a/modules/ticket/back/models/ticket-observation.json b/modules/ticket/back/models/ticket-observation.json index 9035e4440..64e49b217 100644 --- a/modules/ticket/back/models/ticket-observation.json +++ b/modules/ticket/back/models/ticket-observation.json @@ -1,10 +1,6 @@ { "name": "TicketObservation", "base": "Loggable", - "log": { - "model": "TicketLog", - "relation": "ticket" - }, "options": { "mysql": { "table": "ticketObservation" diff --git a/modules/ticket/back/models/ticket-packaging.json b/modules/ticket/back/models/ticket-packaging.json index 533f4064c..6c94c810e 100644 --- a/modules/ticket/back/models/ticket-packaging.json +++ b/modules/ticket/back/models/ticket-packaging.json @@ -1,10 +1,6 @@ { "name": "TicketPackaging", "base": "Loggable", - "log": { - "model": "TicketLog", - "relation": "ticket" - }, "options": { "mysql": { "table": "ticketPackaging" diff --git a/modules/ticket/back/models/ticket-refund.json b/modules/ticket/back/models/ticket-refund.json index 8fd0e2306..d344a3f1c 100644 --- a/modules/ticket/back/models/ticket-refund.json +++ b/modules/ticket/back/models/ticket-refund.json @@ -6,10 +6,6 @@ "table": "ticketRefund" } }, - "log": { - "model": "TicketLog", - "relation": "originalTicket" - }, "properties": { "id": { "id": true, diff --git a/modules/ticket/back/models/ticket-request.json b/modules/ticket/back/models/ticket-request.json index 01601c7f6..f8407792e 100644 --- a/modules/ticket/back/models/ticket-request.json +++ b/modules/ticket/back/models/ticket-request.json @@ -1,10 +1,6 @@ { "name": "TicketRequest", "base": "Loggable", - "log": { - "model": "TicketLog", - "relation": "ticket" - }, "options": { "mysql": { "table": "ticketRequest" @@ -64,4 +60,4 @@ "foreignKey": "itemFk" } } -} \ No newline at end of file +} diff --git a/modules/ticket/back/models/ticket-service.json b/modules/ticket/back/models/ticket-service.json index 347b6b976..f1dbede13 100644 --- a/modules/ticket/back/models/ticket-service.json +++ b/modules/ticket/back/models/ticket-service.json @@ -1,11 +1,6 @@ { "name": "TicketService", "base": "Loggable", - "log": { - "model": "TicketLog", - "relation": "ticket", - "showField": "description" - }, "options": { "mysql": { "table": "ticketService" @@ -59,4 +54,4 @@ "foreignKey": "ticketServiceTypeFk" } } -} \ No newline at end of file +} diff --git a/modules/ticket/back/models/ticket-tracking.json b/modules/ticket/back/models/ticket-tracking.json index e80e2f8f4..8b5ce0b64 100644 --- a/modules/ticket/back/models/ticket-tracking.json +++ b/modules/ticket/back/models/ticket-tracking.json @@ -1,16 +1,11 @@ { "name": "TicketTracking", "base": "Loggable", - "log": { - "model": "TicketLog", - "relation": "ticket", - "showField": "stateFk" - }, - "options": { - "mysql": { - "table": "ticketTracking" - } - }, + "options": { + "mysql": { + "table": "ticketTracking" + } + }, "properties": { "id": { "id": true, @@ -48,4 +43,3 @@ } } } - \ No newline at end of file diff --git a/modules/ticket/back/models/ticket-weekly.json b/modules/ticket/back/models/ticket-weekly.json index d81baf4ad..c5e485aa2 100644 --- a/modules/ticket/back/models/ticket-weekly.json +++ b/modules/ticket/back/models/ticket-weekly.json @@ -1,11 +1,6 @@ { "name": "TicketWeekly", "base": "Loggable", - "log": { - "model": "TicketLog", - "relation": "ticket", - "showField": "ticketFk" - }, "options": { "mysql": { "table": "ticketWeekly" @@ -32,4 +27,4 @@ "foreignKey": "agencyModeFk" } } -} \ No newline at end of file +} diff --git a/modules/ticket/back/models/ticket.json b/modules/ticket/back/models/ticket.json index dabda838a..b2e87362f 100644 --- a/modules/ticket/back/models/ticket.json +++ b/modules/ticket/back/models/ticket.json @@ -1,11 +1,6 @@ { "name": "Ticket", "base": "Loggable", - "log": { - "model":"TicketLog", - "showField": "id", - "grabUser": true - }, "options": { "mysql": { "table": "ticket" diff --git a/modules/travel/back/methods/travel/specs/createThermograph.spec.js b/modules/travel/back/methods/travel/specs/createThermograph.spec.js index 742e2dc18..e812eae70 100644 --- a/modules/travel/back/methods/travel/specs/createThermograph.spec.js +++ b/modules/travel/back/methods/travel/specs/createThermograph.spec.js @@ -1,6 +1,20 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('Travel createThermograph()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); const travelId = 3; const currentUserId = 1102; const thermographId = '138350-0'; diff --git a/modules/travel/back/models/travel-thermograph.json b/modules/travel/back/models/travel-thermograph.json index 754df1c3e..08eec2847 100644 --- a/modules/travel/back/models/travel-thermograph.json +++ b/modules/travel/back/models/travel-thermograph.json @@ -1,14 +1,9 @@ { "name": "TravelThermograph", "base": "Loggable", - "log": { - "model":"TravelLog", - "relation": "travel", - "showField": "ref" - }, "options": { "mysql": { - "table": "travelThermograph" + "table": "travelThermograph" } }, "properties": { diff --git a/modules/travel/back/models/travel.json b/modules/travel/back/models/travel.json index 7dd9f5bba..95d458121 100644 --- a/modules/travel/back/models/travel.json +++ b/modules/travel/back/models/travel.json @@ -1,11 +1,6 @@ { "name": "Travel", "base": "Loggable", - "log": { - "model":"TravelLog", - "showField": "ref", - "grabUser": true - }, "options": { "mysql": { "table": "travel" diff --git a/modules/worker/back/models/worker-dms.json b/modules/worker/back/models/worker-dms.json index 575cfbc24..e9a9f1773 100644 --- a/modules/worker/back/models/worker-dms.json +++ b/modules/worker/back/models/worker-dms.json @@ -1,11 +1,6 @@ { "name": "WorkerDms", "base": "Loggable", - "log": { - "model":"ClientLog", - "relation": "worker", - "showField": "dmsFk" - }, "options": { "mysql": { "table": "workerDocument" diff --git a/modules/worker/back/models/worker.json b/modules/worker/back/models/worker.json index d21094f26..1a9b6ba69 100644 --- a/modules/worker/back/models/worker.json +++ b/modules/worker/back/models/worker.json @@ -2,10 +2,6 @@ "name": "Worker", "description": "Company employees", "base": "Loggable", - "log": { - "model":"WorkerLog", - "showField": "firstName" - }, "options": { "mysql": { "table": "worker" diff --git a/modules/zone/back/methods/zone/specs/clone.spec.js b/modules/zone/back/methods/zone/specs/clone.spec.js index 92392d789..1b7393912 100644 --- a/modules/zone/back/methods/zone/specs/clone.spec.js +++ b/modules/zone/back/methods/zone/specs/clone.spec.js @@ -1,6 +1,21 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('agency clone()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + it('should clone a zone', async() => { const tx = await models.Zone.beginTransaction({}); diff --git a/modules/zone/back/methods/zone/specs/exclusionGeo.spec.js b/modules/zone/back/methods/zone/specs/exclusionGeo.spec.js index a34132be4..fbe96fc5f 100644 --- a/modules/zone/back/methods/zone/specs/exclusionGeo.spec.js +++ b/modules/zone/back/methods/zone/specs/exclusionGeo.spec.js @@ -1,6 +1,20 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('zone exclusionGeo()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); const zoneId = 1; const today = Date.vnNew(); diff --git a/modules/zone/back/methods/zone/specs/toggleIsIncluded.spec.js b/modules/zone/back/methods/zone/specs/toggleIsIncluded.spec.js index 562e62f5f..746a2d0bd 100644 --- a/modules/zone/back/methods/zone/specs/toggleIsIncluded.spec.js +++ b/modules/zone/back/methods/zone/specs/toggleIsIncluded.spec.js @@ -1,6 +1,21 @@ const models = require('vn-loopback/server/server').models; +const LoopBackContext = require('loopback-context'); describe('zone toggleIsIncluded()', () => { + beforeAll(async() => { + const activeCtx = { + accessToken: {userId: 9}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + it('should return the created location with isIncluded true', async() => { const tx = await models.Zone.beginTransaction({}); diff --git a/modules/zone/back/models/zone-event.json b/modules/zone/back/models/zone-event.json index 7cf4b8301..e477dad6a 100644 --- a/modules/zone/back/models/zone-event.json +++ b/modules/zone/back/models/zone-event.json @@ -1,10 +1,6 @@ { "name": "ZoneEvent", "base": "Loggable", - "log": { - "model":"ZoneLog", - "relation": "zone" - }, "options": { "mysql": { "table": "zoneEvent" @@ -57,4 +53,4 @@ "foreignKey": "zoneFk" } } -} \ No newline at end of file +} diff --git a/modules/zone/back/models/zone-exclusion.json b/modules/zone/back/models/zone-exclusion.json index e8088cd44..00c9145cd 100644 --- a/modules/zone/back/models/zone-exclusion.json +++ b/modules/zone/back/models/zone-exclusion.json @@ -1,10 +1,6 @@ { "name": "ZoneExclusion", "base": "Loggable", - "log": { - "model":"ZoneLog", - "relation": "zone" - }, "options": { "mysql": { "table": "zoneExclusion" @@ -27,4 +23,4 @@ "foreignKey": "zoneFk" } } -} \ No newline at end of file +} diff --git a/modules/zone/back/models/zone-included.json b/modules/zone/back/models/zone-included.json index 595f47a78..61633a3c7 100644 --- a/modules/zone/back/models/zone-included.json +++ b/modules/zone/back/models/zone-included.json @@ -1,11 +1,6 @@ { "name": "ZoneIncluded", "base": "Loggable", - "log": { - "model": "ZoneLog", - "relation": "zone", - "showField": "isIncluded" - }, "options": { "mysql": { "table": "zoneIncluded" @@ -32,4 +27,4 @@ "foreignKey": "geoFk" } } -} \ No newline at end of file +} diff --git a/modules/zone/back/models/zone-warehouse.json b/modules/zone/back/models/zone-warehouse.json index 003e4e3c2..b222e95e7 100644 --- a/modules/zone/back/models/zone-warehouse.json +++ b/modules/zone/back/models/zone-warehouse.json @@ -1,10 +1,6 @@ { "name": "ZoneWarehouse", "base": "Loggable", - "log": { - "model":"ZoneLog", - "relation": "zone" - }, "options": { "mysql": { "table": "zoneWarehouse" @@ -32,4 +28,4 @@ "foreignKey": "warehouseFk" } } -} \ No newline at end of file +} diff --git a/modules/zone/back/models/zone.json b/modules/zone/back/models/zone.json index 06ea5ca2b..c86da3d3e 100644 --- a/modules/zone/back/models/zone.json +++ b/modules/zone/back/models/zone.json @@ -1,10 +1,6 @@ { "name": "Zone", "base": "Loggable", - "log": { - "model":"ZoneLog", - "showField": "name" - }, "options": { "mysql": { "table": "zone" @@ -59,7 +55,7 @@ "exclusions": { "type": "hasMany", "model": "ZoneExclusion", - "foreignKey": "zoneFk" + "foreignKey": "zoneFk" }, "warehouses": { "type": "hasMany", @@ -72,4 +68,4 @@ "foreignKey": "zoneFk" } } -} \ No newline at end of file +} From ef6e85532eefc1a1b434428fbbc9e8b9c2d883dc Mon Sep 17 00:00:00 2001 From: carlossa Date: Wed, 12 Apr 2023 14:20:05 +0200 Subject: [PATCH 14/30] refs #5213 cambios e2e, descriptor --- e2e/helpers/selectors.js | 6 +++--- e2e/paths/03-worker/08_add_notes.spec.js | 2 +- loopback/locale/en.json | 5 +++-- modules/client/front/locale/es.yml | 1 + modules/client/front/postcode/locale/es.yml | 3 ++- modules/supplier/front/consumption/index.html | 12 +++++++++--- 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index b504244ea..7689892f0 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -989,9 +989,9 @@ export default { saveButton: 'vn-worker-basic-data button[type=submit]' }, workerNotes: { - addNoteFloatButton: 'vn-float-button', - note: 'vn-textarea[ng-model="$ctrl.note.text"]', - saveButton: 'button[type=submit]', + addNoteFloatButton: 'vn-worker-note vn-icon[icon="add"]', + note: 'vn-note-worker-create vn-textarea[ng-model="$ctrl.note.text"]', + saveButton: 'vn-note-worker-create button[type=submit]', firstNoteText: 'vn-worker-note .text' }, workerPbx: { diff --git a/e2e/paths/03-worker/08_add_notes.spec.js b/e2e/paths/03-worker/08_add_notes.spec.js index eb2e4c041..bdc475c90 100644 --- a/e2e/paths/03-worker/08_add_notes.spec.js +++ b/e2e/paths/03-worker/08_add_notes.spec.js @@ -7,7 +7,7 @@ describe('Worker Add notes path', () => { beforeAll(async() => { browser = await getBrowser(); page = browser.page; - await page.loginAndModule('employee', 'worker'); + await page.loginAndModule('hr', 'worker'); await page.accessToSearchResult('Bruce Banner'); await page.accessToSection('worker.card.note.index'); }); diff --git a/loopback/locale/en.json b/loopback/locale/en.json index e9fd67209..c3c8d234d 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -154,5 +154,6 @@ "Valid priorities: 1,2,3": "Valid priorities: 1,2,3", "Warehouse inventory not set": "Almacén inventario no está establecido", "Component cost not set": "Componente coste no está estabecido", - "Tickets with associated refunds can't be deleted. This ticket is associated with refund Nº 2": "Tickets with associated refunds can't be deleted. This ticket is associated with refund Nº 2" -} + "Tickets with associated refunds can't be deleted. This ticket is associated with refund Nº 2": "Tickets with associated refunds can't be deleted. This ticket is associated with refund Nº 2", + "Description cannot be blank": "Description cannot be blank" +} \ No newline at end of file diff --git a/modules/client/front/locale/es.yml b/modules/client/front/locale/es.yml index adbca8dbf..45ae33914 100644 --- a/modules/client/front/locale/es.yml +++ b/modules/client/front/locale/es.yml @@ -64,3 +64,4 @@ Compensation Account: Cuenta para compensar Amount to return: Cantidad a devolver Delivered amount: Cantidad entregada Unpaid: Impagado +There is no zona: No hay zona \ No newline at end of file diff --git a/modules/client/front/postcode/locale/es.yml b/modules/client/front/postcode/locale/es.yml index 782690e88..29d0d7af9 100644 --- a/modules/client/front/postcode/locale/es.yml +++ b/modules/client/front/postcode/locale/es.yml @@ -8,4 +8,5 @@ The province can't be empty: La provincia no puede quedar vacía The country can't be empty: El país no puede quedar vacío The postcode has been created. You can save the data now: Se ha creado el código postal. Ahora puedes guardar los datos The city has been created: Se ha creado la ciudad -The province has been created: Se ha creado la provincia \ No newline at end of file +The province has been created: Se ha creado la provincia +Autonomy: Autonomia \ No newline at end of file diff --git a/modules/supplier/front/consumption/index.html b/modules/supplier/front/consumption/index.html index 9e3bdac17..e6c86abe3 100644 --- a/modules/supplier/front/consumption/index.html +++ b/modules/supplier/front/consumption/index.html @@ -47,9 +47,11 @@ - - {{::buy.itemName}} - + + {{::buy.itemName}} +
@@ -89,3 +91,7 @@ message="The consumption report will be sent" on-accept="$ctrl.sendEmail()"> + + From eed57c9b4e76b0ccba17ee648bee2ceeb3d6f60f Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 12 Apr 2023 14:47:07 +0200 Subject: [PATCH 15/30] refs #5546 removed log tests --- e2e/paths/02-client/13_log.spec.js | 18 ------------- e2e/paths/04-item/10_item_log.spec.js | 19 -------------- .../05-ticket/02_expeditions_and_log.spec.js | 16 ------------ e2e/paths/05-ticket/17_log.spec.js | 26 ------------------- e2e/paths/11-zone/02_descriptor.spec.js | 10 ------- e2e/paths/13-supplier/02_basic_data.spec.js | 10 ------- loopback/server/connectors/vn-mysql.js | 8 +++--- 7 files changed, 5 insertions(+), 102 deletions(-) diff --git a/e2e/paths/02-client/13_log.spec.js b/e2e/paths/02-client/13_log.spec.js index 8f186d842..5292b1a65 100644 --- a/e2e/paths/02-client/13_log.spec.js +++ b/e2e/paths/02-client/13_log.spec.js @@ -28,22 +28,4 @@ describe('Client log path', () => { it('should navigate to the log section', async() => { await page.accessToSection('client.card.log'); }); - - it('should check the previous value of the last logged change', async() => { - let lastModificationPreviousValue = await page - .waitToGetProperty(selectors.clientLog.lastModificationPreviousValue, 'innerText'); - - expect(lastModificationPreviousValue).toContain('DavidCharlesHaller'); - }); - - it('should check the current value of the last logged change', async() => { - let lastModificationPreviousValue = await page - .waitToGetProperty(selectors.clientLog.lastModificationPreviousValue, 'innerText'); - - let lastModificationCurrentValue = await page. - waitToGetProperty(selectors.clientLog.lastModificationCurrentValue, 'innerText'); - - expect(lastModificationPreviousValue).toEqual('DavidCharlesHaller'); - expect(lastModificationCurrentValue).toEqual('this is a test'); - }); }); diff --git a/e2e/paths/04-item/10_item_log.spec.js b/e2e/paths/04-item/10_item_log.spec.js index 6a7bd7ae2..dc467044d 100644 --- a/e2e/paths/04-item/10_item_log.spec.js +++ b/e2e/paths/04-item/10_item_log.spec.js @@ -42,23 +42,4 @@ describe('Item log path', () => { await page.waitForSelector(selectors.itemsIndex.createItemButton); await page.waitForState('item.index'); }); - - it(`should search for the created item and navigate to it's log section`, async() => { - await page.accessToSearchResult('Knowledge artifact'); - await page.accessToSection('item.card.log'); - }); - - it(`should confirm the log is showing 4 entries`, async() => { - await page.waitForSelector(selectors.itemLog.anyLineCreated); - const anyLineCreatedCount = await page.countElement(selectors.itemLog.anyLineCreated); - - expect(anyLineCreatedCount).toEqual(4); - }); - - xit(`should confirm the log is showing the intrastat for the created item`, async() => { - const fifthLineCreatedProperty = await page - .waitToGetProperty(selectors.itemLog.fifthLineCreatedProperty, 'innerText'); - - expect(fifthLineCreatedProperty).toEqual('05080000'); - }); }); diff --git a/e2e/paths/05-ticket/02_expeditions_and_log.spec.js b/e2e/paths/05-ticket/02_expeditions_and_log.spec.js index ae5e2fb0c..edccd5561 100644 --- a/e2e/paths/05-ticket/02_expeditions_and_log.spec.js +++ b/e2e/paths/05-ticket/02_expeditions_and_log.spec.js @@ -29,20 +29,4 @@ describe('Ticket expeditions and log path', () => { expect(result).toEqual(3); }); - - it(`should confirm the expedition deleted is shown now in the ticket log`, async() => { - await page.accessToSection('ticket.card.log'); - const user = await page - .waitToGetProperty(selectors.ticketLog.user, 'innerText'); - - const action = await page - .waitToGetProperty(selectors.ticketLog.action, 'innerText'); - - const id = await page - .waitToGetProperty(selectors.ticketLog.id, 'innerText'); - - expect(user).toContain('production'); - expect(action).toContain('Deletes'); - expect(id).toEqual('2'); - }); }); diff --git a/e2e/paths/05-ticket/17_log.spec.js b/e2e/paths/05-ticket/17_log.spec.js index 32829ee74..e1da2df44 100644 --- a/e2e/paths/05-ticket/17_log.spec.js +++ b/e2e/paths/05-ticket/17_log.spec.js @@ -31,30 +31,4 @@ describe('Ticket log path', () => { expect(message.text).toContain('Data saved!'); }); - - it('should navigate to the log section', async() => { - await page.accessToSection('ticket.card.log'); - }); - - it('should set the viewport width to 1920 to see the table full width', async() => { - await page.setViewport({ - width: 1920, - height: 0, - }); - - const result = await page.waitToGetProperty(selectors.ticketLog.firstTD, 'innerText'); - - expect(result.length).not.toBeGreaterThan('20'); - }); - - it('should set the viewport width to 800 to see the table shrink and move data to the 1st column', async() => { - await page.setViewport({ - width: 800, - height: 0, - }); - - const result = await page.waitToGetProperty(selectors.ticketLog.firstTD, 'innerText'); - - expect(result.length).toBeGreaterThan('15'); - }); }); diff --git a/e2e/paths/11-zone/02_descriptor.spec.js b/e2e/paths/11-zone/02_descriptor.spec.js index 12a1c8f68..f3c0e7740 100644 --- a/e2e/paths/11-zone/02_descriptor.spec.js +++ b/e2e/paths/11-zone/02_descriptor.spec.js @@ -29,14 +29,4 @@ describe('Zone descriptor path', () => { expect(count).toEqual(0); }); - - it('should check the ticket whom lost the zone and see evidence on the logs', async() => { - await page.waitToClick(selectors.globalItems.homeButton); - await page.selectModule('ticket'); - await page.accessToSearchResult('20'); - await page.accessToSection('ticket.card.log'); - const lastChanges = await page.waitToGetProperty(selectors.ticketLog.changes, 'innerText'); - - expect(lastChanges).toContain('1'); - }); }); diff --git a/e2e/paths/13-supplier/02_basic_data.spec.js b/e2e/paths/13-supplier/02_basic_data.spec.js index 9d86e11d4..72ea6d890 100644 --- a/e2e/paths/13-supplier/02_basic_data.spec.js +++ b/e2e/paths/13-supplier/02_basic_data.spec.js @@ -64,14 +64,4 @@ describe('Supplier basic data path', () => { expect(result).toEqual('Some notes'); }); - - it('should navigate to the log section', async() => { - await page.accessToSection('supplier.card.log'); - }); - - it('should check the changes have been recorded', async() => { - const result = await page.waitToGetProperty('vn-tr table tr:nth-child(3) td.after', 'innerText'); - - expect(result).toEqual('Some notes'); - }); }); diff --git a/loopback/server/connectors/vn-mysql.js b/loopback/server/connectors/vn-mysql.js index 234fa3500..fc62ae8ed 100644 --- a/loopback/server/connectors/vn-mysql.js +++ b/loopback/server/connectors/vn-mysql.js @@ -292,8 +292,10 @@ class VnMySQL extends MySQL { try { const userId = opts.httpCtx && opts.httpCtx.active.accessToken.userId; - const user = await Model.app.models.Account.findById(userId, {fields: ['name']}, opts); - await this.executeP(`CALL account.myUser_loginWithName(?)`, [user.name], opts); + if (userId) { + const user = await Model.app.models.Account.findById(userId, {fields: ['name']}, opts); + await this.executeP(`CALL account.myUser_loginWithName(?)`, [user.name], opts); + } const res = await new Promise(resolve => { const fnArgs = args.slice(0, -2); @@ -301,7 +303,7 @@ class VnMySQL extends MySQL { super[method].apply(this, fnArgs); }); - await this.executeP(`CALL account.myUser_logout()`, null, opts); + if (userId) await this.executeP(`CALL account.myUser_logout()`, null, opts); if (tx) await tx.commit(); return res; } catch (err) { From 41f9ec63ff95d28a99fdfa5a009667b6798bc400 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 13 Apr 2023 13:35:11 +0200 Subject: [PATCH 16/30] refs #5418 changelog --- CHANGELOG.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 222f547e4..bf7887b9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2316.01] - 2023-05-04 + +### Added +- + +### Changed +- (Artículo -> Precio fijado) Modificado el buscador superior por uno lateral + +### Fixed +- + + ## [2314.01] - 2023-04-20 ### Added @@ -13,7 +25,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - (Facturas recibidas -> Bases negativas) Nueva sección ### Changed -- (Artículo -> Precio fijado) Modificado el buscador superior por uno lateral ### Fixed - (Clientes -> Morosos) Ahora se mantienen los elementos seleccionados al hacer sroll. From 05ceba65d6257a929572d65132653c61f90a4a93 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 13 Apr 2023 13:35:54 +0200 Subject: [PATCH 17/30] refs #5418 changelog --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf7887b9a..e89f394b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,8 +24,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - (Monitor tickets) Muestra un icono al lado de la zona, si el ticket es frágil y se envía por agencia - (Facturas recibidas -> Bases negativas) Nueva sección -### Changed - ### Fixed - (Clientes -> Morosos) Ahora se mantienen los elementos seleccionados al hacer sroll. From 90268a79b0b267af5e63a593d116f851b377d2d3 Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 13 Apr 2023 13:41:10 +0200 Subject: [PATCH 18/30] refs #5284 test createClaim --- modules/ticket/front/sale/index.spec.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index 8585503cc..68973a9e5 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -45,6 +45,7 @@ describe('Ticket', () => { $scope.model = crudModel; $scope.editDiscount = {relocate: () => {}, hide: () => {}}; $scope.editPricePopover = {relocate: () => {}}; + $scope.claimConfirm = {show: () => {}}; $httpBackend = _$httpBackend_; Object.defineProperties($state.params, { id: { @@ -61,6 +62,10 @@ describe('Ticket', () => { controller.card = {reload: () => {}}; controller._ticket = ticket; controller._sales = sales; + controller.ticketConfig = [ + {daysForWarningClaim: 2} + ]; + $httpBackend.expect('GET', 'TicketConfigs').respond(200); })); describe('ticket() setter', () => { @@ -113,7 +118,6 @@ describe('Ticket', () => { it('should make an HTTP GET query and return the worker mana', () => { controller.edit = {}; const expectedAmount = 250; - $httpBackend.expect('GET', 'Tickets/1/getSalesPersonMana').respond(200, expectedAmount); $httpBackend.expect('GET', 'Sales/usesMana').respond(200); $httpBackend.expect('GET', 'WorkerManas/getCurrentWorkerMana').respond(200, expectedAmount); @@ -279,6 +283,17 @@ describe('Ticket', () => { }); describe('createClaim()', () => { + it('should perform a query and call windows open', () => { + jest.spyOn(controller.$.claimConfirm, 'show').mockReturnThis(); + + controller.createClaim(); + $httpBackend.flush(); + + expect(controller.$.claimConfirm); + }); + }); + + describe('onCreateClaimAccepted()', () => { it('should perform a query and call windows open', () => { jest.spyOn(controller, 'resetChanges').mockReturnThis(); jest.spyOn(controller.$state, 'go').mockReturnThis(); From ac4772e44ee6a27e019dcff3e2d40b2022a0b688 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 13 Apr 2023 13:46:29 +0200 Subject: [PATCH 19/30] refs #5418 mistake doing git pull origin dev --- .../231401/00-claimBeginningAfterInsert.sql | 1 + db/dump/fixtures.sql | 10 +++++----- loopback/locale/es.json | 3 ++- loopback/server/connectors/vn-mysql.js | 20 ++++++++++--------- .../claim/specs/createFromSales.spec.js | 4 ++-- modules/claim/back/models/claim-beginning.js | 12 +++++++++-- .../fixed-price/specs/editFixedPrice.spec.js | 2 +- modules/item/back/models/item-shelving.json | 3 +++ package.json | 2 +- .../expedition-pallet-label/sql/labelData.sql | 4 ++-- 10 files changed, 38 insertions(+), 23 deletions(-) create mode 100644 db/changes/231401/00-claimBeginningAfterInsert.sql diff --git a/db/changes/231401/00-claimBeginningAfterInsert.sql b/db/changes/231401/00-claimBeginningAfterInsert.sql new file mode 100644 index 000000000..230b6defb --- /dev/null +++ b/db/changes/231401/00-claimBeginningAfterInsert.sql @@ -0,0 +1 @@ +DROP TRIGGER IF EXISTS `vn`.`claimBeginning_afterInsert`; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 9006c6676..59d0a5eaa 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1774,12 +1774,12 @@ INSERT INTO `vn`.`claimState`(`id`, `code`, `description`, `roleFk`, `priority`, ( 6, 'mana', 'Mana', 72, 4, 0), ( 7, 'lack', 'Faltas', 72, 2, 0); -INSERT INTO `vn`.`claim`(`id`, `ticketCreated`, `claimStateFk`, `clientFk`, `workerFk`, `responsibility`, `isChargedToMana`, `created`, `packages`, `rma`) +INSERT INTO `vn`.`claim`(`id`, `ticketCreated`, `claimStateFk`, `clientFk`, `workerFk`, `responsibility`, `isChargedToMana`, `created`, `packages`, `rma`, `ticketFk`) VALUES - (1, util.VN_CURDATE(), 1, 1101, 18, 3, 0, util.VN_CURDATE(), 0, '02676A049183'), - (2, util.VN_CURDATE(), 2, 1101, 18, 3, 0, util.VN_CURDATE(), 1, NULL), - (3, util.VN_CURDATE(), 3, 1101, 18, 1, 1, util.VN_CURDATE(), 5, NULL), - (4, util.VN_CURDATE(), 3, 1104, 18, 5, 0, util.VN_CURDATE(), 10, NULL); + (1, util.VN_CURDATE(), 1, 1101, 18, 3, 0, util.VN_CURDATE(), 0, '02676A049183', 11), + (2, util.VN_CURDATE(), 2, 1101, 18, 3, 0, util.VN_CURDATE(), 1, NULL, 16), + (3, util.VN_CURDATE(), 3, 1101, 18, 1, 1, util.VN_CURDATE(), 5, NULL, 7), + (4, util.VN_CURDATE(), 3, 1104, 18, 5, 0, util.VN_CURDATE(), 10, NULL, 8); INSERT INTO `vn`.`claimObservation` (`claimFk`, `workerFk`, `text`, `created`) VALUES diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 42276efe7..33741d395 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -274,5 +274,6 @@ "This ticket cannot be signed because it has not been boxed": "Este ticket no puede firmarse porque no ha sido encajado", "Insert a date range": "Inserte un rango de fechas", "Added observation": "{{user}} añadió esta observacion: {{text}}", - "Comment added to client": "Observación añadida al cliente {{clientFk}}" + "Comment added to client": "Observación añadida al cliente {{clientFk}}", + "Cannot create a new claimBeginning from a different ticket": "No se puede crear una línea de reclamación de un ticket diferente al origen" } diff --git a/loopback/server/connectors/vn-mysql.js b/loopback/server/connectors/vn-mysql.js index 728454d86..a6fd3351a 100644 --- a/loopback/server/connectors/vn-mysql.js +++ b/loopback/server/connectors/vn-mysql.js @@ -311,7 +311,7 @@ class VnMySQL extends MySQL { return super[method].apply(this, args); this.invokeMethodP(method, [...args], model, ctx, opts) - .then(res => cb(...res), cb); + .then(res => cb(...[null].concat(res)), cb); } async invokeMethodP(method, args, model, ctx, opts) { @@ -331,8 +331,7 @@ class VnMySQL extends MySQL { const userId = opts.httpCtx && opts.httpCtx.active.accessToken.userId; const user = await Model.app.models.Account.findById(userId, { fields: ['name'] }, opts); await this.executeP(`CALL account.myUser_loginWithName(?)`, [user.name], opts); - } - else { + } else { where = ctx.where; id = ctx.id; data = ctx.data; @@ -358,9 +357,12 @@ class VnMySQL extends MySQL { } } - const res = await new Promise(resolve => { + const res = await new Promise((resolve, reject) => { const fnArgs = args.slice(0, -2); - fnArgs.push(opts, (...args) => resolve(args)); + fnArgs.push(opts, (err, ...args) => { + if (err) return reject(err); + resolve(args); + }); super[method].apply(this, fnArgs); }); @@ -375,11 +377,11 @@ class VnMySQL extends MySQL { case 'update': { switch (method) { case 'createAll': - for (const row of res[1]) + for (const row of res[0]) ids.push(row[idName]); break; case 'create': - ids.push(res[1]); + ids.push(res[0]); break; case 'update': if (data[idName] != null) @@ -387,7 +389,7 @@ class VnMySQL extends MySQL { break; } - const newWhere = ids.length ? { [idName]: ids } : where; + const newWhere = ids.length ? {[idName]: {inq: ids}} : where; const stmt = this.buildSelectStmt(op, data, idName, model, newWhere, limit); newInstances = await this.executeStmt(stmt, opts); @@ -671,4 +673,4 @@ SQLConnector.prototype.all = function find(model, filter, options, cb) { cb(error, []) } }); -}; \ No newline at end of file +}; diff --git a/modules/claim/back/methods/claim/specs/createFromSales.spec.js b/modules/claim/back/methods/claim/specs/createFromSales.spec.js index 7cf663caf..fe009c1c3 100644 --- a/modules/claim/back/methods/claim/specs/createFromSales.spec.js +++ b/modules/claim/back/methods/claim/specs/createFromSales.spec.js @@ -2,9 +2,9 @@ const models = require('vn-loopback/server/server').models; const LoopBackContext = require('loopback-context'); describe('Claim createFromSales()', () => { - const ticketId = 16; + const ticketId = 23; const newSale = [{ - id: 3, + id: 31, instance: 0, quantity: 10 }]; diff --git a/modules/claim/back/models/claim-beginning.js b/modules/claim/back/models/claim-beginning.js index 4c4b59737..4b870e5ea 100644 --- a/modules/claim/back/models/claim-beginning.js +++ b/modules/claim/back/models/claim-beginning.js @@ -10,8 +10,16 @@ module.exports = Self => { }); Self.observe('before save', async ctx => { - if (ctx.isNewInstance) return; - //await claimIsEditable(ctx); + if (ctx.isNewInstance) { + const models = Self.app.models; + const options = ctx.options; + const instance = ctx.instance; + const ticket = await models.Sale.findById(instance.saleFk, {fields: ['ticketFk']}, options); + const claim = await models.Claim.findById(instance.claimFk, {fields: ['ticketFk']}, options); + if (ticket.ticketFk != claim.ticketFk) + throw new UserError(`Cannot create a new claimBeginning from a different ticket`); + } + // await claimIsEditable(ctx); }); Self.observe('before delete', async ctx => { diff --git a/modules/item/back/methods/fixed-price/specs/editFixedPrice.spec.js b/modules/item/back/methods/fixed-price/specs/editFixedPrice.spec.js index a5e6cd35a..9c265f28a 100644 --- a/modules/item/back/methods/fixed-price/specs/editFixedPrice.spec.js +++ b/modules/item/back/methods/fixed-price/specs/editFixedPrice.spec.js @@ -50,7 +50,7 @@ describe('Item editFixedPrice()', () => { await models.FixedPrice.editFixedPrice(ctx, field, newValue, null, filter, options); - const [result] = await models.FixedPrice.filter(ctx, null, options); + const [result] = await models.FixedPrice.filter(ctx, filter, options); expect(result[field]).toEqual(newValue); diff --git a/modules/item/back/models/item-shelving.json b/modules/item/back/models/item-shelving.json index 0890350da..b24edfc53 100644 --- a/modules/item/back/models/item-shelving.json +++ b/modules/item/back/models/item-shelving.json @@ -20,6 +20,9 @@ }, "created": { "type": "date" + }, + "isChecked": { + "type": "boolean" } }, "relations": { diff --git a/package.json b/package.json index 8fa177646..607367e7b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.14.01", + "version": "23.16.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0", diff --git a/print/templates/reports/expedition-pallet-label/sql/labelData.sql b/print/templates/reports/expedition-pallet-label/sql/labelData.sql index 0661dbe0f..b2a805251 100644 --- a/print/templates/reports/expedition-pallet-label/sql/labelData.sql +++ b/print/templates/reports/expedition-pallet-label/sql/labelData.sql @@ -12,8 +12,8 @@ SELECT ep.id palletFk, JOIN vn.expedition e ON e.id = es.expeditionFk JOIN vn.ticket t ON t.id = e.ticketFk JOIN vn.route r ON r.id = t.routeFk - LEFT JOIN vn2008.Rutas_monitor rm ON rm.Id_Ruta = r.id + LEFT JOIN vn.routesMonitor rm ON rm.routeFk = r.id LEFT JOIN vn.expeditionTruck et2 ON et2.id = rm.expeditionTruckFk WHERE ep.id = ? GROUP BY ep.id, t.routeFk - ORDER BY t.routeFk \ No newline at end of file + ORDER BY t.routeFk From 025c158b279d246b432f8b5f32a2537af095d963 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 13 Apr 2023 13:52:11 +0200 Subject: [PATCH 20/30] refs #5418 minor fixes --- .../03_smartTable_searchBar_integrations.spec.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js b/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js index 1c8fe0840..a3d747f1c 100644 --- a/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js +++ b/e2e/paths/01-salix/03_smartTable_searchBar_integrations.spec.js @@ -79,20 +79,27 @@ describe('SmartTable SearchBar integration', () => { it('should order by first id', async() => { await page.loginAndModule('developer', 'item'); await page.accessToSection('item.fixedPrice'); + await page.doSearch(); const result = await page.waitToGetProperty(selectors.itemFixedPrice.firstItemID, 'value'); expect(result).toEqual('1'); }); - it('should order by last id, reload page and have same order', async() => { + it('should order by last id', async() => { await page.waitToClick(selectors.itemFixedPrice.orderColumnId); + const result = await page.waitToGetProperty(selectors.itemFixedPrice.firstItemID, 'value'); + + expect(result).toEqual('3'); + }); + + it('should reload page and have same order', async() => { await page.reload({ waitUntil: 'networkidle2' }); const result = await page.waitToGetProperty(selectors.itemFixedPrice.firstItemID, 'value'); - expect(result).toEqual('13'); + expect(result).toEqual('3'); }); }); }); From a2ddbd8a660958cab8abf00a8de4f4b7af0a1f8f Mon Sep 17 00:00:00 2001 From: carlossa Date: Thu, 13 Apr 2023 14:04:10 +0200 Subject: [PATCH 21/30] refs #5284 test update --- modules/ticket/front/sale/index.js | 1 + modules/ticket/front/sale/index.spec.js | 11 +++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index 4daba70c8..20739b619 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -210,6 +210,7 @@ class Controller extends Section { this.$http.post(`Claims/createFromSales`, params) .then(res => this.$state.go('claim.card.basicData', {id: res.data.id})); } + showTransferPopover(event) { this.setTransferParams(); this.$.transfer.show(event); diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index 68973a9e5..c35ed3d9a 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -63,7 +63,7 @@ describe('Ticket', () => { controller._ticket = ticket; controller._sales = sales; controller.ticketConfig = [ - {daysForWarningClaim: 2} + {daysForWarningClaim: 1} ]; $httpBackend.expect('GET', 'TicketConfigs').respond(200); })); @@ -283,18 +283,17 @@ describe('Ticket', () => { }); describe('createClaim()', () => { - it('should perform a query and call windows open', () => { + it('should call to the claimConfirm show() method', () => { jest.spyOn(controller.$.claimConfirm, 'show').mockReturnThis(); controller.createClaim(); - $httpBackend.flush(); - expect(controller.$.claimConfirm); + expect(controller.$.claimConfirm.show).toHaveBeenCalledWith(); }); }); describe('onCreateClaimAccepted()', () => { - it('should perform a query and call windows open', () => { + it('should perform a query and call window open', () => { jest.spyOn(controller, 'resetChanges').mockReturnThis(); jest.spyOn(controller.$state, 'go').mockReturnThis(); @@ -305,7 +304,7 @@ describe('Ticket', () => { const expectedParams = {ticketId: 1, sales: [firstSale]}; $httpBackend.expect('POST', `Claims/createFromSales`, expectedParams).respond(200, {id: 1}); - controller.createClaim(); + controller.onCreateClaimAccepted(); $httpBackend.flush(); expect(controller.resetChanges).toHaveBeenCalledWith(); From 8ade60256390200f2e768ff1c052b0f11439a867 Mon Sep 17 00:00:00 2001 From: alexandre Date: Thu, 13 Apr 2023 14:18:01 +0200 Subject: [PATCH 22/30] hotfix one sign for every ticket --- db/changes/231401/00-hotfixDelivery.sql | 70 +++++++++++++++++++ .../ticket/back/methods/ticket/saveSign.js | 15 ++-- 2 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 db/changes/231401/00-hotfixDelivery.sql diff --git a/db/changes/231401/00-hotfixDelivery.sql b/db/changes/231401/00-hotfixDelivery.sql new file mode 100644 index 000000000..4628cc1db --- /dev/null +++ b/db/changes/231401/00-hotfixDelivery.sql @@ -0,0 +1,70 @@ +DROP TABLE IF EXISTS `vn`.`dmsRecover`; + +ALTER TABLE `vn`.`delivery` DROP COLUMN addressFk; +ALTER TABLE `vn`.`delivery` DROP CONSTRAINT delivery_ticketFk_FK; +ALTER TABLE `vn`.`delivery` DROP COLUMN ticketFk; +ALTER TABLE `vn`.`delivery` ADD ticketFk INT DEFAULT NULL; +ALTER TABLE `vn`.`delivery` ADD CONSTRAINT delivery_ticketFk_FK FOREIGN KEY (`ticketFk`) REFERENCES `vn`.`ticket`(`id`); + +DROP PROCEDURE IF EXISTS vn.route_getTickets; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`route_getTickets`(vRouteFk INT) +BEGIN +/** + * Pasado un RouteFk devuelve la información + * de sus tickets. + * + * @param vRouteFk + * + * @select Información de los tickets + */ + + SELECT + t.id Id, + t.clientFk Client, + a.id Address, + t.packages Packages, + a.street AddressName, + a.postalCode PostalCode, + a.city City, + sub2.itemPackingTypeFk PackingType, + c.phone ClientPhone, + c.mobile ClientMobile, + a.phone AddressPhone, + a.mobile AddressMobile, + d.longitude Longitude, + d.latitude Latitude, + wm.mediaValue SalePersonPhone, + tob.Note Note, + t.isSigned Signed + FROM ticket t + JOIN client c ON t.clientFk = c.id + JOIN address a ON t.addressFk = a.id + LEFT JOIN delivery d ON t.id = d.ticketFk + LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk + LEFT JOIN + (SELECT tob.description Note, t.id + FROM ticketObservation tob + JOIN ticket t ON tob.ticketFk = t.id + JOIN observationType ot ON ot.id = tob.observationTypeFk + WHERE t.routeFk = vRouteFk + AND ot.code = 'delivery' + )tob ON tob.id = t.id + LEFT JOIN + (SELECT sub.ticketFk, + CONCAT('(', GROUP_CONCAT(DISTINCT sub.itemPackingTypeFk ORDER BY sub.items DESC SEPARATOR ','), ') ') itemPackingTypeFk + FROM (SELECT s.ticketFk , i.itemPackingTypeFk, COUNT(*) items + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + WHERE t.routeFk = vRouteFk + GROUP BY t.id,i.itemPackingTypeFk)sub + GROUP BY sub.ticketFk + ) sub2 ON sub2.ticketFk = t.id + WHERE t.routeFk = vRouteFk + GROUP BY t.id + ORDER BY t.priority; +END$$ +DELIMITER ; diff --git a/modules/ticket/back/methods/ticket/saveSign.js b/modules/ticket/back/methods/ticket/saveSign.js index ab1c32d1b..39347f418 100644 --- a/modules/ticket/back/methods/ticket/saveSign.js +++ b/modules/ticket/back/methods/ticket/saveSign.js @@ -34,6 +34,8 @@ module.exports = Self => { const models = Self.app.models; const myOptions = {}; let tx; + let dms; + let gestDocCreated = false; if (typeof options == 'object') Object.assign(myOptions, options); @@ -96,11 +98,12 @@ module.exports = Self => { warehouseId: ticket.warehouseFk, companyId: ticket.companyFk, dmsTypeId: dmsType.id, - reference: id, - description: `Ticket ${id} Cliente ${ticket.client().name} Ruta ${ticket.route().id}`, + reference: '', + description: `Firma del cliente - Ruta ${ticket.route().id}`, hasFile: true }; - await models.Ticket.uploadFile(ctxUploadFile, id, myOptions); + dms = await models.Dms.uploadFile(ctxUploadFile, myOptions); + gestDocCreated = true; } try { @@ -118,12 +121,16 @@ module.exports = Self => { throw new UserError('This ticket cannot be signed because it has not been boxed'); else if (!await gestDocExists(args.tickets[i])) { if (args.location) setLocation(args.tickets[i]); - await createGestDoc(args.tickets[i]); + if (!gestDocCreated) await createGestDoc(args.tickets[i]); + await models.TicketDms.create({ticketFk: args.tickets[i], dmsFk: dms[0].id}, myOptions); + const ticket = await models.Ticket.findById(args.tickets[i], null, myOptions); + await ticket.updateAttribute('isSigned', true, myOptions); await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [args.tickets[i], 'DELIVERED'], myOptions); } } if (tx) await tx.commit(); + return; } catch (e) { if (tx) await tx.rollback(); throw e; From 35f94c58b71f3ecc4377a3741cf14fdfdca634fd Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 14 Apr 2023 13:04:40 +0200 Subject: [PATCH 23/30] reafactor(image): upload image using gm library --- back/methods/image/upload.js | 24 +- back/models/image.js | 193 ++++------ front/salix/components/upload-photo/index.js | 6 - .../back/methods/item-image-queue/download.js | 121 +----- package-lock.json | 364 +----------------- package.json | 1 - 6 files changed, 108 insertions(+), 601 deletions(-) diff --git a/back/methods/image/upload.js b/back/methods/image/upload.js index 143da275e..1de0064f6 100644 --- a/back/methods/image/upload.js +++ b/back/methods/image/upload.js @@ -1,7 +1,6 @@ const UserError = require('vn-loopback/util/user-error'); -const fs = require('fs-extra'); +const fs = require('fs/promises'); const path = require('path'); -const uuid = require('uuid'); module.exports = Self => { Self.remoteMethodCtx('upload', { @@ -36,7 +35,7 @@ module.exports = Self => { const fileOptions = {}; const args = ctx.args; - let srcFile; + let tempFilePath; try { const hasWriteRole = await models.ImageCollection.hasWriteRole(ctx, args.collection); if (!hasWriteRole) @@ -53,15 +52,20 @@ module.exports = Self => { }); const file = await TempContainer.getFile(tempContainer.name, uploadedFile.name); - srcFile = path.join(file.client.root, file.container, file.name); + tempFilePath = path.join(file.client.root, file.container, file.name); - const fileName = `${uuid.v4()}.png`; - await models.Image.registerImage(args.collection, srcFile, fileName, args.id); - } catch (e) { - if (fs.existsSync(srcFile)) - await fs.unlink(srcFile); + const fileName = `${args.id}.png`; - throw e; + await models.Image.resize({ + collectionName: args.collection, + srcFile: tempFilePath, + fileName: fileName, + entityId: args.id + }); + } finally { + try { + await fs.unlink(tempFilePath); + } catch (error) { } } }; }; diff --git a/back/models/image.js b/back/models/image.js index 3d3b03879..1f777f51c 100644 --- a/back/models/image.js +++ b/back/models/image.js @@ -1,161 +1,108 @@ const fs = require('fs-extra'); -const sharp = require('sharp'); const path = require('path'); -const readChunk = require('read-chunk'); -const imageType = require('image-type'); -const bmp = require('bmp-js'); +const gm = require('gm'); module.exports = Self => { require('../methods/image/download')(Self); require('../methods/image/upload')(Self); - // Function extracted from jimp package (utils) - function scan(image, x, y, w, h, f) { - // round input - x = Math.round(x); - y = Math.round(y); - w = Math.round(w); - h = Math.round(h); - - for (let _y = y; _y < y + h; _y++) { - for (let _x = x; _x < x + w; _x++) { - const idx = (image.bitmap.width * _y + _x) << 2; - f.call(image, _x, _y, idx); - } - } - - return image; - } - - // Function extracted from jimp package (type-bmp) - function fromAGBR(bitmap) { - return scan({bitmap}, 0, 0, bitmap.width, bitmap.height, function( - x, - y, - index - ) { - const alpha = this.bitmap.data[index + 0]; - const blue = this.bitmap.data[index + 1]; - const green = this.bitmap.data[index + 2]; - const red = this.bitmap.data[index + 3]; - - this.bitmap.data[index + 0] = red; - this.bitmap.data[index + 1] = green; - this.bitmap.data[index + 2] = blue; - this.bitmap.data[index + 3] = bitmap.is_with_alpha ? alpha : 0xff; - }).bitmap; - } - - Self.registerImage = async(collectionName, srcFilePath, fileName, entityId) => { + Self.resize = async function({collectionName, srcFile, fileName, entityId}) { const models = Self.app.models; - const tx = await Self.beginTransaction({}); - const myOptions = {transaction: tx}; - try { - const collection = await models.ImageCollection.findOne({ + const collection = await models.ImageCollection.findOne( + { fields: [ 'id', - 'name', 'maxWidth', 'maxHeight', 'model', - 'property' + 'property', ], where: {name: collectionName}, include: { relation: 'sizes', scope: { - fields: ['width', 'height', 'crop'] - } - } - }, myOptions); + fields: ['width', 'height', 'crop'], + }, + }, + } + ); - const data = { + // Insert image row + await models.Image.upsertWithWhere( + { name: fileName, collectionFk: collectionName - }; - const newImage = await Self.upsertWithWhere(data, { + }, + { name: fileName, collectionFk: collectionName, - updated: Date.vnNow() - }, myOptions); - - // Resizes and saves the image - const container = await models.ImageContainer.container(collectionName); - const rootPath = container.client.root; - const collectionDir = path.join(rootPath, collectionName); - const dstDir = path.join(collectionDir, 'full'); - const dstFile = path.join(dstDir, fileName); - - const buffer = readChunk.sync(srcFilePath, 0, 12); - const type = imageType(buffer); - - let sharpOptions; - let imgSrc = srcFilePath; - if (type.mime == 'image/bmp') { - const bmpBuffer = fs.readFileSync(srcFilePath); - const bmpData = fromAGBR(bmp.decode(bmpBuffer)); - imgSrc = bmpData.data; - sharpOptions = { - raw: { - width: bmpData.width, - height: bmpData.height, - channels: 4 - }, - failOn: 'none' - }; + updated: Date.vnNow() / 1000, } + ); - const resizeOpts = { - withoutEnlargement: true, - fit: 'inside' - }; + // Update entity image file name + const model = models[collection.model]; + if (!model) throw new Error('No matching model found'); - await fs.mkdir(dstDir, {recursive: true}); - await sharp(imgSrc, sharpOptions) - .resize(collection.maxWidth, collection.maxHeight, resizeOpts) - .png() - .toFile(dstFile); + const entity = await model.findById(entityId); + if (entity) { + await entity.updateAttribute( + collection.property, + fileName + ); + } - const sizes = collection.sizes(); - for (let size of sizes) { - const dstDir = path.join(collectionDir, `${size.width}x${size.height}`); - const dstFile = path.join(dstDir, fileName); - const resizeOpts = { - withoutEnlargement: true, - fit: size.crop ? 'cover' : 'inside' - }; + // Resize + const container = await models.ImageContainer.container( + collectionName + ); + const rootPath = container.client.root; + const collectionDir = path.join(rootPath, collectionName); - await fs.mkdir(dstDir, {recursive: true}); - await sharp(imgSrc, sharpOptions) - .resize(size.width, size.height, resizeOpts) - .png() - .toFile(dstFile); - } + // To max size + const {maxWidth, maxHeight} = collection; + const fullSizePath = path.join(collectionDir, 'full'); + const toFullSizePath = `${fullSizePath}/${fileName}`; - const model = models[collection.model]; + await fs.mkdir(fullSizePath, {recursive: true}); + await new Promise((resolve, reject) => { + gm(srcFile) + .resize(maxWidth, maxHeight, '>') + .setFormat('png') + .write(toFullSizePath, function(err) { + if (err) reject(err); + if (!err) resolve(); + }); + }); - if (!model) - throw new Error('Matching model not found'); + // To collection sizes + for (const size of collection.sizes()) { + const {width, height} = size; - const item = await model.findById(entityId, null, myOptions); - if (item) { - await item.updateAttribute( - collection.property, - fileName, - myOptions - ); - } + const sizePath = path.join(collectionDir, `${width}x${height}`); + const toSizePath = `${sizePath}/${fileName}`; - if (fs.existsSync(srcFilePath)) - await fs.unlink(srcFilePath); + await fs.mkdir(sizePath, {recursive: true}); + await new Promise((resolve, reject) => { + const gmInstance = gm(srcFile); - await tx.commit(); + if (size.crop) { + gmInstance + .resize(width, height, '^') + .gravity('Center') + .crop(width, height); + } - return newImage; - } catch (e) { - await tx.rollback(); - throw e; + if (!size.crop) gmInstance.resize(width, height, '>'); + + gmInstance + .setFormat('png') + .write(toSizePath, function(err) { + if (err) reject(err); + if (!err) resolve(); + }); + }); } }; }; diff --git a/front/salix/components/upload-photo/index.js b/front/salix/components/upload-photo/index.js index da1fda923..c9774d037 100644 --- a/front/salix/components/upload-photo/index.js +++ b/front/salix/components/upload-photo/index.js @@ -162,14 +162,8 @@ export default class UploadPhoto extends Component { if (!this.newPhoto.files) throw new Error(`Select an image`); - const viewportType = this.viewportSelection; - const output = viewportType.output; const options = { type: 'blob', - size: { - width: output.width, - height: output.height - } }; return this.editor.result(options) .then(blob => this.newPhoto.blob = blob) diff --git a/modules/item/back/methods/item-image-queue/download.js b/modules/item/back/methods/item-image-queue/download.js index cdc0fe049..eb952daa4 100644 --- a/modules/item/back/methods/item-image-queue/download.js +++ b/modules/item/back/methods/item-image-queue/download.js @@ -1,9 +1,7 @@ const axios = require('axios'); -const uuid = require('uuid'); const fs = require('fs/promises'); -const { createWriteStream } = require('fs'); +const {createWriteStream} = require('fs'); const path = require('path'); -const gm = require('gm'); module.exports = Self => { Self.remoteMethod('download', { @@ -15,7 +13,7 @@ module.exports = Self => { }, }); - Self.download = async () => { + Self.download = async() => { const models = Self.app.models; const tempContainer = await models.TempContainer.container( 'salix-image' @@ -27,75 +25,27 @@ module.exports = Self => { const maxAttempts = 3; const collectionName = 'catalog'; - const tx = await Self.beginTransaction({}); - let tempFilePath; let queueRow; try { - const myOptions = { transaction: tx }; - queueRow = await Self.findOne( { fields: ['id', 'itemFk', 'url', 'attempts'], where: { - url: { neq: null }, + url: {neq: null}, attempts: { lt: maxAttempts, }, }, order: 'priority, attempts, updated', - }, - myOptions + } ); if (!queueRow) return; - const collection = await models.ImageCollection.findOne( - { - fields: [ - 'id', - 'maxWidth', - 'maxHeight', - 'model', - 'property', - ], - where: { name: collectionName }, - include: { - relation: 'sizes', - scope: { - fields: ['width', 'height', 'crop'], - }, - }, - }, - myOptions - ); - - const fileName = `${uuid.v4()}.png`; + const fileName = `${queueRow.itemFk}.png`; tempFilePath = path.join(tempPath, fileName); - // Insert image row - await models.Image.create( - { - name: fileName, - collectionFk: collectionName, - updated: Date.vnNow(), - }, - myOptions - ); - - // Update item - const model = models[collection.model]; - if (!model) throw new Error('No matching model found'); - - const item = await model.findById(queueRow.itemFk, null, myOptions); - if (item) { - await item.updateAttribute( - collection.property, - fileName, - myOptions - ); - } - // Download remote image const response = await axios.get(queueRow.url, { responseType: 'stream', @@ -108,71 +58,22 @@ module.exports = Self => { writeStream.on('error', error => reject(error)); }); - // Resize - const container = await models.ImageContainer.container( - collectionName - ); - const rootPath = container.client.root; - const collectionDir = path.join(rootPath, collectionName); - - // To max size - const { maxWidth, maxHeight } = collection; - const fullSizePath = path.join(collectionDir, 'full'); - const toFullSizePath = `${fullSizePath}/${fileName}`; - - await fs.mkdir(fullSizePath, { recursive: true }); - await new Promise((resolve, reject) => { - gm(tempFilePath) - .resize(maxWidth, maxHeight, '>') - .setFormat('png') - .write(toFullSizePath, function (err) { - if (err) reject(err); - if (!err) resolve(); - }); + await models.Image.resize({ + collectionName: collectionName, + srcFile: tempFilePath, + fileName: fileName, + entityId: queueRow.itemFk }); - // To collection sizes - for (const size of collection.sizes()) { - const { width, height } = size; - - const sizePath = path.join(collectionDir, `${width}x${height}`); - const toSizePath = `${sizePath}/${fileName}`; - - await fs.mkdir(sizePath, { recursive: true }); - await new Promise((resolve, reject) => { - const gmInstance = gm(tempFilePath); - - if (size.crop) { - gmInstance - .resize(width, height, '^') - .gravity('Center') - .crop(width, height); - } - - if (!size.crop) gmInstance.resize(width, height, '>'); - - gmInstance - .setFormat('png') - .write(toSizePath, function (err) { - if (err) reject(err); - if (!err) resolve(); - }); - }); - } - try { await fs.unlink(tempFilePath); } catch (error) { } - await queueRow.destroy(myOptions); + await queueRow.destroy(); // Restart queue Self.download(); - - await tx.commit(); } catch (error) { - await tx.rollback(); - if (queueRow.attempts < maxAttempts) { await queueRow.updateAttributes({ error: error, diff --git a/package-lock.json b/package-lock.json index 7e86dbba9..e59a073c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "salix-back", - "version": "23.08.01", + "version": "23.12.01", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "salix-back", - "version": "23.08.01", + "version": "23.12.01", "license": "GPL-3.0", "dependencies": { "axios": "^1.2.2", @@ -41,7 +41,6 @@ "puppeteer": "^18.0.5", "read-chunk": "^3.2.0", "require-yaml": "0.0.1", - "sharp": "^0.31.3", "smbhash": "0.0.1", "strong-error-handler": "^2.3.2", "uuid": "^3.3.3", @@ -5444,17 +5443,6 @@ "node": ">=0.10.0" } }, - "node_modules/color": { - "version": "4.2.3", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "license": "MIT", @@ -5469,14 +5457,6 @@ "version": "1.1.4", "license": "MIT" }, - "node_modules/color-string": { - "version": "1.9.1", - "license": "MIT", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, "node_modules/color-support": { "version": "1.1.3", "license": "ISC", @@ -6149,6 +6129,7 @@ }, "node_modules/deep-extend": { "version": "0.6.0", + "dev": true, "license": "MIT", "engines": { "node": ">=4.0.0" @@ -7630,13 +7611,6 @@ "node": ">=0.10.0" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, "node_modules/expand-tilde": { "version": "2.0.2", "dev": true, @@ -8891,10 +8865,6 @@ "assert-plus": "^1.0.0" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "license": "MIT" - }, "node_modules/glob": { "version": "7.2.0", "license": "ISC", @@ -11516,6 +11486,7 @@ }, "node_modules/ini": { "version": "1.3.8", + "dev": true, "license": "ISC" }, "node_modules/internal-ip": { @@ -11645,10 +11616,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "license": "MIT" - }, "node_modules/is-bigint": { "version": "1.0.4", "dev": true, @@ -15610,10 +15577,6 @@ "node": ">=0.10.0" } }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "license": "MIT" - }, "node_modules/natural-compare": { "version": "1.4.0", "dev": true, @@ -15655,43 +15618,6 @@ "node": ">=4.0.0" } }, - "node_modules/node-abi": { - "version": "3.28.0", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/lru-cache": { - "version": "6.0.0", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.3.8", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/yallist": { - "version": "4.0.0", - "license": "ISC" - }, "node_modules/node-addon-api": { "version": "5.0.0", "license": "MIT" @@ -17539,30 +17465,6 @@ "node": ">=0.10.0" } }, - "node_modules/prebuild-install": { - "version": "7.1.1", - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/precond": { "version": "0.2.3", "engines": { @@ -18057,6 +17959,7 @@ }, "node_modules/rc": { "version": "1.2.8", + "dev": true, "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", @@ -19786,55 +19689,6 @@ "node": ">=8" } }, - "node_modules/sharp": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz", - "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==", - "hasInstallScript": true, - "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.1", - "node-addon-api": "^5.0.0", - "prebuild-install": "^7.1.1", - "semver": "^7.3.8", - "simple-get": "^4.0.1", - "tar-fs": "^2.1.1", - "tunnel-agent": "^0.6.0" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/sharp/node_modules/lru-cache": { - "version": "6.0.0", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sharp/node_modules/semver": { - "version": "7.3.8", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sharp/node_modules/yallist": { - "version": "4.0.0", - "license": "ISC" - }, "node_modules/shebang-command": { "version": "2.0.0", "license": "MIT", @@ -19893,77 +19747,6 @@ "version": "3.0.7", "license": "ISC" }, - "node_modules/simple-concat": { - "version": "1.0.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-get": { - "version": "4.0.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-get/node_modules/decompress-response": { - "version": "6.0.0", - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/simple-get/node_modules/mimic-response": { - "version": "3.1.0", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, "node_modules/simple-update-notifier": { "version": "1.0.7", "dev": true, @@ -20864,6 +20647,7 @@ }, "node_modules/strip-json-comments": { "version": "2.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -30018,13 +29802,6 @@ "object-visit": "^1.0.0" } }, - "color": { - "version": "4.2.3", - "requires": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - } - }, "color-convert": { "version": "2.0.1", "requires": { @@ -30034,13 +29811,6 @@ "color-name": { "version": "1.1.4" }, - "color-string": { - "version": "1.9.1", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, "color-support": { "version": "1.1.3" }, @@ -30487,7 +30257,8 @@ } }, "deep-extend": { - "version": "0.6.0" + "version": "0.6.0", + "dev": true }, "deep-is": { "version": "0.1.4" @@ -31501,9 +31272,6 @@ } } }, - "expand-template": { - "version": "2.0.3" - }, "expand-tilde": { "version": "2.0.2", "dev": true, @@ -32389,9 +32157,6 @@ "assert-plus": "^1.0.0" } }, - "github-from-package": { - "version": "0.0.0" - }, "glob": { "version": "7.2.0", "requires": { @@ -34296,7 +34061,8 @@ "version": "2.0.4" }, "ini": { - "version": "1.3.8" + "version": "1.3.8", + "dev": true }, "internal-ip": { "version": "4.3.0", @@ -34372,9 +34138,6 @@ "has-tostringtag": "^1.0.0" } }, - "is-arrayish": { - "version": "0.3.2" - }, "is-bigint": { "version": "1.0.4", "dev": true, @@ -37151,9 +36914,6 @@ "to-regex": "^3.0.1" } }, - "napi-build-utils": { - "version": "1.0.2" - }, "natural-compare": { "version": "1.4.0", "dev": true @@ -37182,29 +36942,6 @@ "nocache": { "version": "2.1.0" }, - "node-abi": { - "version": "3.28.0", - "requires": { - "semver": "^7.3.5" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.3.8", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0" - } - } - }, "node-addon-api": { "version": "5.0.0" }, @@ -38439,23 +38176,6 @@ "version": "3.3.1", "dev": true }, - "prebuild-install": { - "version": "7.1.1", - "requires": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - } - }, "precond": { "version": "0.2.3" }, @@ -38789,6 +38509,7 @@ }, "rc": { "version": "1.2.8", + "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -40001,38 +39722,6 @@ "kind-of": "^6.0.2" } }, - "sharp": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz", - "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==", - "requires": { - "color": "^4.2.3", - "detect-libc": "^2.0.1", - "node-addon-api": "^5.0.0", - "prebuild-install": "^7.1.1", - "semver": "^7.3.8", - "simple-get": "^4.0.1", - "tar-fs": "^2.1.1", - "tunnel-agent": "^0.6.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.3.8", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0" - } - } - }, "shebang-command": { "version": "2.0.0", "requires": { @@ -40073,34 +39762,6 @@ "signal-exit": { "version": "3.0.7" }, - "simple-concat": { - "version": "1.0.1" - }, - "simple-get": { - "version": "4.0.1", - "requires": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - }, - "dependencies": { - "decompress-response": { - "version": "6.0.0", - "requires": { - "mimic-response": "^3.1.0" - } - }, - "mimic-response": { - "version": "3.1.0" - } - } - }, - "simple-swizzle": { - "version": "0.2.2", - "requires": { - "is-arrayish": "^0.3.1" - } - }, "simple-update-notifier": { "version": "1.0.7", "dev": true, @@ -40746,7 +40407,8 @@ } }, "strip-json-comments": { - "version": "2.0.1" + "version": "2.0.1", + "dev": true }, "strong-error-handler": { "version": "2.3.2", diff --git a/package.json b/package.json index 3d0fc4aed..9af083934 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,6 @@ "puppeteer": "^18.0.5", "read-chunk": "^3.2.0", "require-yaml": "0.0.1", - "sharp": "^0.31.3", "smbhash": "0.0.1", "strong-error-handler": "^2.3.2", "uuid": "^3.3.3", From 6e7b452792c5a0f182167aa4b1c4bd61e67a78dd Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 14 Apr 2023 13:19:17 +0200 Subject: [PATCH 24/30] Max quality --- back/models/image.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/back/models/image.js b/back/models/image.js index 1f777f51c..61c6199b8 100644 --- a/back/models/image.js +++ b/back/models/image.js @@ -70,6 +70,7 @@ module.exports = Self => { gm(srcFile) .resize(maxWidth, maxHeight, '>') .setFormat('png') + .quality(100) .write(toFullSizePath, function(err) { if (err) reject(err); if (!err) resolve(); @@ -98,6 +99,7 @@ module.exports = Self => { gmInstance .setFormat('png') + .quality(100) .write(toSizePath, function(err) { if (err) reject(err); if (!err) resolve(); From ad3836552e3647640544091ecc7345d8becdaad7 Mon Sep 17 00:00:00 2001 From: alexandre Date: Fri, 14 Apr 2023 14:16:29 +0200 Subject: [PATCH 25/30] refs #5518 sections added --- back/model-config.json | 3 ++ back/models/role-log.json | 58 +++++++++++++++++++++++ back/models/user-log.json | 6 +-- db/changes/231601/00-userRoleLog.sql | 44 +++++++++++++++++ modules/account/front/index.js | 2 + modules/account/front/locale/es.yml | 3 +- modules/account/front/role-log/index.html | 1 + modules/account/front/role-log/index.js | 7 +++ modules/account/front/routes.json | 18 ++++++- modules/account/front/user-log/index.html | 1 + modules/account/front/user-log/index.js | 7 +++ 11 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 back/models/role-log.json create mode 100644 db/changes/231601/00-userRoleLog.sql create mode 100644 modules/account/front/role-log/index.html create mode 100644 modules/account/front/role-log/index.js create mode 100644 modules/account/front/user-log/index.html create mode 100644 modules/account/front/user-log/index.js diff --git a/back/model-config.json b/back/model-config.json index 29676e979..0410d45a7 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -128,6 +128,9 @@ "UserLog": { "dataSource": "vn" }, + "RoleLog": { + "dataSource": "vn" + }, "Warehouse": { "dataSource": "vn" }, diff --git a/back/models/role-log.json b/back/models/role-log.json new file mode 100644 index 000000000..b4fc3daf9 --- /dev/null +++ b/back/models/role-log.json @@ -0,0 +1,58 @@ +{ + "name": "RoleLog", + "base": "VnModel", + "options": { + "mysql": { + "table": "account.roleLog" + } + }, + "properties": { + "id": { + "id": true, + "type": "number", + "forceId": false + }, + "originFk": { + "type": "number", + "required": true + }, + "userFk": { + "type": "number" + }, + "action": { + "type": "string", + "required": true + }, + "changedModel": { + "type": "string" + }, + "oldInstance": { + "type": "object" + }, + "newInstance": { + "type": "object" + }, + "creationDate": { + "type": "date" + }, + "changedModelId": { + "type": "number" + }, + "changedModelValue": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "relations": { + "user": { + "type": "belongsTo", + "model": "Account", + "foreignKey": "userFk" + } + }, + "scope": { + "order": ["creationDate DESC", "id DESC"] + } +} diff --git a/back/models/user-log.json b/back/models/user-log.json index 43ccbfa43..5169d99b0 100644 --- a/back/models/user-log.json +++ b/back/models/user-log.json @@ -3,7 +3,7 @@ "base": "VnModel", "options": { "mysql": { - "table": "userLog" + "table": "account.userLog" } }, "properties": { @@ -16,7 +16,7 @@ "type": "number", "required": true }, - "userFk": { + "userFk": { "type": "number" }, "action": { @@ -50,7 +50,7 @@ "type": "belongsTo", "model": "Account", "foreignKey": "userFk" - } + } }, "scope": { "order": ["creationDate DESC", "id DESC"] diff --git a/db/changes/231601/00-userRoleLog.sql b/db/changes/231601/00-userRoleLog.sql new file mode 100644 index 000000000..12000993a --- /dev/null +++ b/db/changes/231601/00-userRoleLog.sql @@ -0,0 +1,44 @@ +DROP TABLE IF EXISTS `vn`.`userLog`; + +CREATE TABLE `account`.`userLog` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `originFk` int(10) unsigned DEFAULT NULL, + `userFk` int(10) unsigned DEFAULT NULL, + `action` set('insert','update','delete') COLLATE utf8mb4_unicode_ci NOT NULL, + `creationDate` timestamp NULL DEFAULT current_timestamp(), + `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `changedModel` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `oldInstance` text COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `newInstance` text COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `changedModelId` int(11) DEFAULT NULL, + `changedModelValue` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `originFk` (`originFk`), + KEY `userFk` (`userFk`), + CONSTRAINT `userLog_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `userLog_ibfk_2` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `account`.`roleLog` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `originFk` int(10) unsigned DEFAULT NULL, + `userFk` int(10) unsigned DEFAULT NULL, + `action` set('insert','update','delete') COLLATE utf8mb3_unicode_ci NOT NULL, + `creationDate` timestamp NULL DEFAULT current_timestamp(), + `description` text CHARACTER SET utf8mb3 DEFAULT NULL, + `changedModel` varchar(45) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `oldInstance` text COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `newInstance` text COLLATE utf8mb3_unicode_ci DEFAULT NULL, + `changedModelId` int(11) DEFAULT NULL, + `changedModelValue` varchar(45) COLLATE utf8mb3_unicode_ci DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `originFk` (`originFk`), + KEY `userFk` (`userFk`), + CONSTRAINT `roleLog_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `roleLog_ibfk_2` FOREIGN KEY (`userFk`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('UserLog', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), + ('RoleLog', '*', 'READ', 'ALLOW', 'ROLE', 'employee'); diff --git a/modules/account/front/index.js b/modules/account/front/index.js index 0cd0c4955..695f36967 100644 --- a/modules/account/front/index.js +++ b/modules/account/front/index.js @@ -19,3 +19,5 @@ import './ldap'; import './samba'; import './accounts'; import './privileges'; +import './user-log'; +import './role-log'; diff --git a/modules/account/front/locale/es.yml b/modules/account/front/locale/es.yml index 18e2c06a1..7988cbda6 100644 --- a/modules/account/front/locale/es.yml +++ b/modules/account/front/locale/es.yml @@ -8,4 +8,5 @@ Role: Rol Mail aliases: Alias de correo Account not enabled: Cuenta no habilitada Inherited roles: Roles heredados -Go to the user: Ir al usuario \ No newline at end of file +Go to the user: Ir al usuario +Log: Histórico diff --git a/modules/account/front/role-log/index.html b/modules/account/front/role-log/index.html new file mode 100644 index 000000000..9e2b151b5 --- /dev/null +++ b/modules/account/front/role-log/index.html @@ -0,0 +1 @@ + diff --git a/modules/account/front/role-log/index.js b/modules/account/front/role-log/index.js new file mode 100644 index 000000000..02448ccaa --- /dev/null +++ b/modules/account/front/role-log/index.js @@ -0,0 +1,7 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +ngModule.vnComponent('vnRoleLog', { + template: require('./index.html'), + controller: Section, +}); diff --git a/modules/account/front/routes.json b/modules/account/front/routes.json index a6f2f5d3f..cc66df103 100644 --- a/modules/account/front/routes.json +++ b/modules/account/front/routes.json @@ -20,12 +20,14 @@ {"state": "account.card.roles", "icon": "group"}, {"state": "account.card.mailForwarding", "icon": "forward"}, {"state": "account.card.aliases", "icon": "email"}, - {"state": "account.card.privileges", "icon": "badge"} + {"state": "account.card.privileges", "icon": "badge"}, + {"state": "account.card.log", "icon": "history"} ], "role": [ {"state": "account.role.card.basicData", "icon": "settings"}, {"state": "account.role.card.subroles", "icon": "groups"}, - {"state": "account.role.card.inherited", "icon": "account_tree"} + {"state": "account.role.card.inherited", "icon": "account_tree"}, + {"state": "account.role.card.log", "icon": "history"} ], "alias": [ {"state": "account.alias.card.basicData", "icon": "settings"}, @@ -80,6 +82,18 @@ "description": "Basic data", "acl": ["hr"] }, + { + "url" : "/log", + "state": "account.card.log", + "component": "vn-user-log", + "description": "Log" + }, + { + "url" : "/log", + "state": "account.role.card.log", + "component": "vn-role-log", + "description": "Log" + }, { "url": "/roles", "state": "account.card.roles", diff --git a/modules/account/front/user-log/index.html b/modules/account/front/user-log/index.html new file mode 100644 index 000000000..5a77ed7b9 --- /dev/null +++ b/modules/account/front/user-log/index.html @@ -0,0 +1 @@ + diff --git a/modules/account/front/user-log/index.js b/modules/account/front/user-log/index.js new file mode 100644 index 000000000..7cd0bb378 --- /dev/null +++ b/modules/account/front/user-log/index.js @@ -0,0 +1,7 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +ngModule.vnComponent('vnUserLog', { + template: require('./index.html'), + controller: Section, +}); From f97d169cbf68d70ff1eade93d05d4056cd640c6c Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 17 Apr 2023 11:52:31 +0200 Subject: [PATCH 26/30] observationEmail --- db/changes/231601/00-observationEmailACL.sql | 2 ++ e2e/helpers/selectors.js | 2 +- e2e/paths/02-client/21_defaulter.spec.js | 2 +- e2e/paths/03-worker/08_add_notes.spec.js | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 db/changes/231601/00-observationEmailACL.sql diff --git a/db/changes/231601/00-observationEmailACL.sql b/db/changes/231601/00-observationEmailACL.sql new file mode 100644 index 000000000..6c0c5a51c --- /dev/null +++ b/db/changes/231601/00-observationEmailACL.sql @@ -0,0 +1,2 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES ('Defaulter', 'observationEmail', 'WRITE', 'ALLOW', 'ROLE', 'employee'); diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index b504244ea..1eb01de7e 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -989,7 +989,7 @@ export default { saveButton: 'vn-worker-basic-data button[type=submit]' }, workerNotes: { - addNoteFloatButton: 'vn-float-button', + addNoteFloatButton: 'a vn-float-button', note: 'vn-textarea[ng-model="$ctrl.note.text"]', saveButton: 'button[type=submit]', firstNoteText: 'vn-worker-note .text' diff --git a/e2e/paths/02-client/21_defaulter.spec.js b/e2e/paths/02-client/21_defaulter.spec.js index 0eb16441f..97e62abef 100644 --- a/e2e/paths/02-client/21_defaulter.spec.js +++ b/e2e/paths/02-client/21_defaulter.spec.js @@ -50,7 +50,7 @@ describe('Client defaulter path', () => { expect(message.text).toContain(`The message can't be empty`); }); - it('shoul checked all defaulters', async() => { + it('should checked all defaulters', async() => { await page.loginAndModule('insurance', 'client'); await page.accessToSection('client.defaulter'); diff --git a/e2e/paths/03-worker/08_add_notes.spec.js b/e2e/paths/03-worker/08_add_notes.spec.js index eb2e4c041..bdc475c90 100644 --- a/e2e/paths/03-worker/08_add_notes.spec.js +++ b/e2e/paths/03-worker/08_add_notes.spec.js @@ -7,7 +7,7 @@ describe('Worker Add notes path', () => { beforeAll(async() => { browser = await getBrowser(); page = browser.page; - await page.loginAndModule('employee', 'worker'); + await page.loginAndModule('hr', 'worker'); await page.accessToSearchResult('Bruce Banner'); await page.accessToSection('worker.card.note.index'); }); From 2675c02d13cef9cfbafc8a5b40650fcca8489545 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 17 Apr 2023 11:52:52 +0200 Subject: [PATCH 27/30] refs #5518 moved models to account --- back/model-config.json | 6 --- db/changes/231601/00-userRoleLog.sql | 40 ------------------- modules/account/back/model-config.json | 8 +++- .../account/back}/models/role-log.json | 0 .../account/back}/models/user-log.json | 0 5 files changed, 7 insertions(+), 47 deletions(-) rename {back => modules/account/back}/models/role-log.json (100%) rename {back => modules/account/back}/models/user-log.json (100%) diff --git a/back/model-config.json b/back/model-config.json index 0410d45a7..5a5c6d3ac 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -125,12 +125,6 @@ "UserConfigView": { "dataSource": "vn" }, - "UserLog": { - "dataSource": "vn" - }, - "RoleLog": { - "dataSource": "vn" - }, "Warehouse": { "dataSource": "vn" }, diff --git a/db/changes/231601/00-userRoleLog.sql b/db/changes/231601/00-userRoleLog.sql index 12000993a..ae5da13cb 100644 --- a/db/changes/231601/00-userRoleLog.sql +++ b/db/changes/231601/00-userRoleLog.sql @@ -1,43 +1,3 @@ -DROP TABLE IF EXISTS `vn`.`userLog`; - -CREATE TABLE `account`.`userLog` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `originFk` int(10) unsigned DEFAULT NULL, - `userFk` int(10) unsigned DEFAULT NULL, - `action` set('insert','update','delete') COLLATE utf8mb4_unicode_ci NOT NULL, - `creationDate` timestamp NULL DEFAULT current_timestamp(), - `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `changedModel` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `oldInstance` text COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `newInstance` text COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `changedModelId` int(11) DEFAULT NULL, - `changedModelValue` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `originFk` (`originFk`), - KEY `userFk` (`userFk`), - CONSTRAINT `userLog_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `userLog_ibfk_2` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - -CREATE TABLE `account`.`roleLog` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `originFk` int(10) unsigned DEFAULT NULL, - `userFk` int(10) unsigned DEFAULT NULL, - `action` set('insert','update','delete') COLLATE utf8mb3_unicode_ci NOT NULL, - `creationDate` timestamp NULL DEFAULT current_timestamp(), - `description` text CHARACTER SET utf8mb3 DEFAULT NULL, - `changedModel` varchar(45) COLLATE utf8mb3_unicode_ci DEFAULT NULL, - `oldInstance` text COLLATE utf8mb3_unicode_ci DEFAULT NULL, - `newInstance` text COLLATE utf8mb3_unicode_ci DEFAULT NULL, - `changedModelId` int(11) DEFAULT NULL, - `changedModelValue` varchar(45) COLLATE utf8mb3_unicode_ci DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `originFk` (`originFk`), - KEY `userFk` (`userFk`), - CONSTRAINT `roleLog_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `roleLog_ibfk_2` FOREIGN KEY (`userFk`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; - INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('UserLog', '*', 'READ', 'ALLOW', 'ROLE', 'employee'), diff --git a/modules/account/back/model-config.json b/modules/account/back/model-config.json index c697bd3b9..057a487dd 100644 --- a/modules/account/back/model-config.json +++ b/modules/account/back/model-config.json @@ -23,6 +23,9 @@ "RoleConfig": { "dataSource": "vn" }, + "RoleLog": { + "dataSource": "vn" + }, "RoleInherit": { "dataSource": "vn" }, @@ -41,10 +44,13 @@ "UserAccount": { "dataSource": "vn" }, + "UserLog": { + "dataSource": "vn" + }, "UserPassword": { "dataSource": "vn" }, "UserSync": { "dataSource": "vn" } -} \ No newline at end of file +} diff --git a/back/models/role-log.json b/modules/account/back/models/role-log.json similarity index 100% rename from back/models/role-log.json rename to modules/account/back/models/role-log.json diff --git a/back/models/user-log.json b/modules/account/back/models/user-log.json similarity index 100% rename from back/models/user-log.json rename to modules/account/back/models/user-log.json From 6144c24a448dd571ec66633f03b5da401082f0fb Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 17 Apr 2023 12:44:58 +0200 Subject: [PATCH 28/30] fix(ticket_edit): fix e2e --- e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js index f9b520981..323646d29 100644 --- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js @@ -249,6 +249,7 @@ describe('Ticket Edit sale path', () => { await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox); await page.waitToClick(selectors.ticketSales.moreMenu); await page.waitToClick(selectors.ticketSales.moreMenuCreateClaim); + await page.waitToClick(selectors.globalItems.acceptButton); await page.waitForState('claim.card.basicData'); }); From b5434c5e4e859334e6d9b68091b4e0e7dd5dc6e0 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 17 Apr 2023 12:58:55 +0200 Subject: [PATCH 29/30] tab --- db/changes/231601/00-observationEmailACL.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/changes/231601/00-observationEmailACL.sql b/db/changes/231601/00-observationEmailACL.sql index 6c0c5a51c..1a5d475e8 100644 --- a/db/changes/231601/00-observationEmailACL.sql +++ b/db/changes/231601/00-observationEmailACL.sql @@ -1,2 +1,3 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) - VALUES ('Defaulter', 'observationEmail', 'WRITE', 'ALLOW', 'ROLE', 'employee'); + VALUES + ('Defaulter', 'observationEmail', 'WRITE', 'ALLOW', 'ROLE', 'employee'); From 6a0a08be953ef1a70f7538f9c44f2660a5ccc5a8 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 17 Apr 2023 13:03:09 +0200 Subject: [PATCH 30/30] typo --- e2e/helpers/selectors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 1eb01de7e..84db638e3 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -989,7 +989,7 @@ export default { saveButton: 'vn-worker-basic-data button[type=submit]' }, workerNotes: { - addNoteFloatButton: 'a vn-float-button', + addNoteFloatButton: 'vn-worker-note vn-float-button', note: 'vn-textarea[ng-model="$ctrl.note.text"]', saveButton: 'button[type=submit]', firstNoteText: 'vn-worker-note .text'