From 6f2de903bcdf44dc78a186408e1801e7efbf2466 Mon Sep 17 00:00:00 2001 From: alexandre Date: Mon, 27 Mar 2023 14:29:22 +0200 Subject: [PATCH 1/5] refs #5184 working on search panel --- db/changes/231201/.gitkeep | 0 db/changes/231201/00-invoiceInSerial.sql | 4 ++ db/dump/fixtures.sql | 4 +- .../back/methods/invoice-in/getSerial.js | 34 +++++++++++++++ .../back/models/invoice-in-config.json | 3 ++ modules/invoiceIn/back/models/invoice-in.js | 1 + modules/invoiceIn/front/index.js | 2 + modules/invoiceIn/front/locale/es.yml | 1 + modules/invoiceIn/front/routes.json | 15 ++++++- .../front/serial-search-panel/index.html | 26 ++++++++++++ .../front/serial-search-panel/index.js | 41 ++++++++++++++++++ .../front/serial-search-panel/style.scss | 24 +++++++++++ modules/invoiceIn/front/serial/index.html | 42 +++++++++++++++++++ modules/invoiceIn/front/serial/index.js | 35 ++++++++++++++++ modules/invoiceIn/front/serial/locale/es.yml | 3 ++ 15 files changed, 232 insertions(+), 3 deletions(-) delete mode 100644 db/changes/231201/.gitkeep create mode 100644 db/changes/231201/00-invoiceInSerial.sql create mode 100644 modules/invoiceIn/back/methods/invoice-in/getSerial.js create mode 100644 modules/invoiceIn/front/serial-search-panel/index.html create mode 100644 modules/invoiceIn/front/serial-search-panel/index.js create mode 100644 modules/invoiceIn/front/serial-search-panel/style.scss create mode 100644 modules/invoiceIn/front/serial/index.html create mode 100644 modules/invoiceIn/front/serial/index.js create mode 100644 modules/invoiceIn/front/serial/locale/es.yml diff --git a/db/changes/231201/.gitkeep b/db/changes/231201/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/db/changes/231201/00-invoiceInSerial.sql b/db/changes/231201/00-invoiceInSerial.sql new file mode 100644 index 000000000..de476027c --- /dev/null +++ b/db/changes/231201/00-invoiceInSerial.sql @@ -0,0 +1,4 @@ +ALTER TABLE `vn`.`invoiceInConfig` ADD daysAgo INT UNSIGNED DEFAULT 45 COMMENT 'Días en el pasado para mostrar facturas en invoiceIn series en salix'; +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('InvoiceIn', 'getSerial', 'READ', 'ALLOW', 'ROLE', 'administrative'); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index e9c70878f..61b7cba9e 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2490,9 +2490,9 @@ REPLACE INTO `vn`.`invoiceIn`(`id`, `serialNumber`,`serial`, `supplierFk`, `issu (9, 1009, 'R', 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1242, 1, 442, 1), (10, 1010, 'R', 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1243, 1, 442, 1); -INSERT INTO `vn`.`invoiceInConfig` (`id`, `retentionRate`, `retentionName`, `sageWithholdingFk`) +INSERT INTO `vn`.`invoiceInConfig` (`id`, `retentionRate`, `retentionName`, `sageWithholdingFk`, `daysAgo`) VALUES - (1, -2, '2% retention', 2); + (1, -2, '2% retention', 2, 45); INSERT INTO `vn`.`invoiceInDueDay`(`invoiceInFk`, `dueDated`, `bankFk`, `amount`) VALUES diff --git a/modules/invoiceIn/back/methods/invoice-in/getSerial.js b/modules/invoiceIn/back/methods/invoice-in/getSerial.js new file mode 100644 index 000000000..8635a0be7 --- /dev/null +++ b/modules/invoiceIn/back/methods/invoice-in/getSerial.js @@ -0,0 +1,34 @@ +module.exports = Self => { + Self.remoteMethod('getSerial', { + description: 'Return invoiceIn serial', + accessType: 'READ', + accepts: { + arg: 'issued', + type: 'date', + required: true + }, + returns: { + type: 'object', + root: true + }, + http: { + path: '/getSerial', + verb: 'GET' + } + }); + + Self.getSerial = async(issued, options) => { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const result = await Self.rawSql(` + SELECT i.serial, SUM(IF(i.isBooked, 0,1)) pending, COUNT(*) total + FROM vn.invoiceIn i + WHERE i.issued >= ? + GROUP BY i.serial`, [issued]); + + return result; + }; +}; diff --git a/modules/invoiceIn/back/models/invoice-in-config.json b/modules/invoiceIn/back/models/invoice-in-config.json index 5cf0ed64c..c0236e654 100644 --- a/modules/invoiceIn/back/models/invoice-in-config.json +++ b/modules/invoiceIn/back/models/invoice-in-config.json @@ -17,6 +17,9 @@ }, "retentionName": { "type": "string" + }, + "daysAgo": { + "type": "number" } }, "relations": { diff --git a/modules/invoiceIn/back/models/invoice-in.js b/modules/invoiceIn/back/models/invoice-in.js index 95ccc7b20..51905ccb8 100644 --- a/modules/invoiceIn/back/models/invoice-in.js +++ b/modules/invoiceIn/back/models/invoice-in.js @@ -6,4 +6,5 @@ module.exports = Self => { require('../methods/invoice-in/getTotals')(Self); require('../methods/invoice-in/invoiceInPdf')(Self); require('../methods/invoice-in/invoiceInEmail')(Self); + require('../methods/invoice-in/getSerial')(Self); }; diff --git a/modules/invoiceIn/front/index.js b/modules/invoiceIn/front/index.js index 7b6d6a77c..e257cfee3 100644 --- a/modules/invoiceIn/front/index.js +++ b/modules/invoiceIn/front/index.js @@ -13,3 +13,5 @@ import './dueDay'; import './intrastat'; import './create'; import './log'; +import './serial'; +import './serial-search-panel'; diff --git a/modules/invoiceIn/front/locale/es.yml b/modules/invoiceIn/front/locale/es.yml index 35b43f9f6..f2f77b690 100644 --- a/modules/invoiceIn/front/locale/es.yml +++ b/modules/invoiceIn/front/locale/es.yml @@ -7,6 +7,7 @@ Foreign value: Divisa InvoiceIn: Facturas recibidas InvoiceIn cloned: Factura clonada InvoiceIn deleted: Factura eliminada +InvoiceIn Serial: Facturas por series Invoice list: Listado de facturas recibidas InvoiceIn booked: Factura contabilizada Net: Neto diff --git a/modules/invoiceIn/front/routes.json b/modules/invoiceIn/front/routes.json index 4867b7db9..90c4f8472 100644 --- a/modules/invoiceIn/front/routes.json +++ b/modules/invoiceIn/front/routes.json @@ -12,6 +12,10 @@ { "state": "invoiceIn.index", "icon": "icon-invoice-in" + }, + { + "state": "invoiceIn.serial", + "icon": "icon-invoice-in" } ], "card": [ @@ -54,6 +58,15 @@ "administrative" ] }, + { + "url": "/serial", + "state": "invoiceIn.serial", + "component": "vn-invoice-in-serial", + "description": "InvoiceIn Serial", + "acl": [ + "administrative" + ] + }, { "url": "/:id", "state": "invoiceIn.card", @@ -133,4 +146,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/modules/invoiceIn/front/serial-search-panel/index.html b/modules/invoiceIn/front/serial-search-panel/index.html new file mode 100644 index 000000000..467f7439c --- /dev/null +++ b/modules/invoiceIn/front/serial-search-panel/index.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+ + Id/Name: {{$ctrl.filter.search}} + +
+
diff --git a/modules/invoiceIn/front/serial-search-panel/index.js b/modules/invoiceIn/front/serial-search-panel/index.js new file mode 100644 index 000000000..334e4cf01 --- /dev/null +++ b/modules/invoiceIn/front/serial-search-panel/index.js @@ -0,0 +1,41 @@ +import ngModule from '../module'; +import SearchPanel from 'core/components/searchbar/search-panel'; +import './style.scss'; + +class Controller extends SearchPanel { + constructor($element, $) { + super($element, $); + const filter = { + fields: ['daysAgo'] + }; + this.$http.get('InvoiceInConfigs', {filter}); + } + + $onInit() { + this.filter = { + tags: [] + }; + } + + removeItemFilter(param) { + this.filter[param] = null; + this.addFilters(); + } + + onKeyPress($event) { + if ($event.key === 'Enter') + this.addFilters(); + } + + addFilters() { + return this.model.addFilter({}, this.filter); + } +} + +ngModule.component('vnInvoiceInSerialSearchPanel', { + template: require('./index.html'), + controller: Controller, + bindings: { + model: '<' + } +}); diff --git a/modules/invoiceIn/front/serial-search-panel/style.scss b/modules/invoiceIn/front/serial-search-panel/style.scss new file mode 100644 index 000000000..4abfcbfa2 --- /dev/null +++ b/modules/invoiceIn/front/serial-search-panel/style.scss @@ -0,0 +1,24 @@ +@import "variables"; + +vn-invoice-in-serial-search-panel vn-side-menu div { + & > .input { + padding-left: $spacing-md; + padding-right: $spacing-md; + border-color: $color-spacer; + border-bottom: $border-thin; + } + & > .horizontal { + grid-auto-flow: column; + grid-column-gap: $spacing-sm; + 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; + } +} diff --git a/modules/invoiceIn/front/serial/index.html b/modules/invoiceIn/front/serial/index.html new file mode 100644 index 000000000..f8ca4bbbb --- /dev/null +++ b/modules/invoiceIn/front/serial/index.html @@ -0,0 +1,42 @@ + + + + + + + + + + + + Serial + Pending + Total + + + + + + {{::invoiceIn.serial}} + {{::invoiceIn.pending}} + {{::invoiceIn.total}} + + + + + + + + + diff --git a/modules/invoiceIn/front/serial/index.js b/modules/invoiceIn/front/serial/index.js new file mode 100644 index 000000000..622087748 --- /dev/null +++ b/modules/invoiceIn/front/serial/index.js @@ -0,0 +1,35 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +export default class Controller extends Section { + constructor($element, $) { + super($element, $); + } + + exprBuilder(param, value) { + switch (param) { + case 'issued': + return {'ii.issued': { + between: this.dateRange(value)} + }; + case 'serial': + return {[`ii.${param}`]: value}; + } + } + + dateRange(value) { + const minHour = new Date(value); + minHour.setHours(0, 0, 0, 0); + const maxHour = new Date(value); + maxHour.setHours(23, 59, 59, 59); + + return [minHour, maxHour]; + } +} + +Controller.$inject = ['$element', '$scope']; + +ngModule.vnComponent('vnInvoiceInSerial', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/invoiceIn/front/serial/locale/es.yml b/modules/invoiceIn/front/serial/locale/es.yml new file mode 100644 index 000000000..92a49cc82 --- /dev/null +++ b/modules/invoiceIn/front/serial/locale/es.yml @@ -0,0 +1,3 @@ +Serial: Serie +Pending: Pendientes +Go to InvoiceIn: Ir al listado de facturas recibidas From 695444f6ae4d7a65d909b1189a4880c327a26511 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 28 Mar 2023 11:34:14 +0200 Subject: [PATCH 2/5] refs #5184 back and front tests added --- .../back/methods/invoice-in/getSerial.js | 35 ++++++++++----- .../invoice-in/specs/getSerial.spec.js | 21 +++++++++ modules/invoiceIn/front/locale/es.yml | 1 + .../front/serial-search-panel/index.html | 18 ++++---- .../front/serial-search-panel/index.js | 17 +++++--- .../front/serial-search-panel/index.spec.js | 43 +++++++++++++++++++ modules/invoiceIn/front/serial/index.html | 6 +-- modules/invoiceIn/front/serial/index.js | 22 ++-------- 8 files changed, 115 insertions(+), 48 deletions(-) create mode 100644 modules/invoiceIn/back/methods/invoice-in/specs/getSerial.spec.js create mode 100644 modules/invoiceIn/front/serial-search-panel/index.spec.js diff --git a/modules/invoiceIn/back/methods/invoice-in/getSerial.js b/modules/invoiceIn/back/methods/invoice-in/getSerial.js index 8635a0be7..a6c5ad00e 100644 --- a/modules/invoiceIn/back/methods/invoice-in/getSerial.js +++ b/modules/invoiceIn/back/methods/invoice-in/getSerial.js @@ -1,12 +1,17 @@ +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; + module.exports = Self => { Self.remoteMethod('getSerial', { description: 'Return invoiceIn serial', accessType: 'READ', - accepts: { - arg: 'issued', - type: 'date', + accepts: [{ + arg: 'daysAgo', + type: 'number', required: true - }, + }, { + arg: 'serial', + type: 'string' + }], returns: { type: 'object', root: true @@ -17,17 +22,25 @@ module.exports = Self => { } }); - Self.getSerial = async(issued, options) => { - const myOptions = {}; + Self.getSerial = async(daysAgo, serial) => { + const conn = Self.dataSource.connector; + const stmt = []; - if (typeof options == 'object') - Object.assign(myOptions, options); + const issued = Date.vnNew(); + issued.setDate(issued.getDate() - daysAgo); - const result = await Self.rawSql(` + stmt.push(new ParameterizedSQL(` SELECT i.serial, SUM(IF(i.isBooked, 0,1)) pending, COUNT(*) total FROM vn.invoiceIn i - WHERE i.issued >= ? - GROUP BY i.serial`, [issued]); + WHERE i.issued >= ? `, [issued])); + + if (serial) + stmt.push(new ParameterizedSQL(`AND i.serial LIKE ? `, [serial])); + + stmt.push(`GROUP BY i.serial`); + + const sql = ParameterizedSQL.join(stmt); + const result = await conn.executeStmt(sql); return result; }; diff --git a/modules/invoiceIn/back/methods/invoice-in/specs/getSerial.spec.js b/modules/invoiceIn/back/methods/invoice-in/specs/getSerial.spec.js new file mode 100644 index 000000000..d07fef196 --- /dev/null +++ b/modules/invoiceIn/back/methods/invoice-in/specs/getSerial.spec.js @@ -0,0 +1,21 @@ +const models = require('vn-loopback/server/server').models; + +describe('invoiceIn getSerial()', () => { + it('should check that returns without serial param', async() => { + const result = await models.InvoiceIn.getSerial(45); + + expect(result.length).toBeGreaterThan(0); + }); + + it('should check that returns with serial param', async() => { + const result = await models.InvoiceIn.getSerial(45, 'R'); + + expect(result.length).toBeGreaterThan(0); + }); + + it('should check that returns with non exist serial param', async() => { + const result = await models.InvoiceIn.getSerial(45, 'Mock serial'); + + expect(result.length).toEqual(0); + }); +}); diff --git a/modules/invoiceIn/front/locale/es.yml b/modules/invoiceIn/front/locale/es.yml index f2f77b690..a2d658519 100644 --- a/modules/invoiceIn/front/locale/es.yml +++ b/modules/invoiceIn/front/locale/es.yml @@ -23,3 +23,4 @@ Total stems: Total tallos Show agricultural receipt as PDF: Ver recibo agrícola como PDF Send agricultural receipt as PDF: Enviar recibo agrícola como PDF New InvoiceIn: Nueva Factura +Days ago: Últimos días diff --git a/modules/invoiceIn/front/serial-search-panel/index.html b/modules/invoiceIn/front/serial-search-panel/index.html index 467f7439c..c412e783c 100644 --- a/modules/invoiceIn/front/serial-search-panel/index.html +++ b/modules/invoiceIn/front/serial-search-panel/index.html @@ -1,26 +1,28 @@ - - + ng-keydown="$ctrl.onKeyPress($event)" + required="true" + min="0"> +
- Id/Name: {{$ctrl.filter.search}} + {{$ctrl.$t('Serial')}}: {{$ctrl.filter.serial}}
diff --git a/modules/invoiceIn/front/serial-search-panel/index.js b/modules/invoiceIn/front/serial-search-panel/index.js index 334e4cf01..b11911ee3 100644 --- a/modules/invoiceIn/front/serial-search-panel/index.js +++ b/modules/invoiceIn/front/serial-search-panel/index.js @@ -5,16 +5,16 @@ import './style.scss'; class Controller extends SearchPanel { constructor($element, $) { super($element, $); + this.filter = {}; const filter = { fields: ['daysAgo'] }; - this.$http.get('InvoiceInConfigs', {filter}); - } - - $onInit() { - this.filter = { - tags: [] - }; + this.$http.get('InvoiceInConfigs', {filter}).then(res => { + if (res.data) { + this.invoiceInConfig = res.data[0]; + this.addFilters(); + } + }); } removeItemFilter(param) { @@ -28,6 +28,9 @@ class Controller extends SearchPanel { } addFilters() { + if (!this.filter.daysAgo) + this.filter.daysAgo = this.invoiceInConfig.daysAgo; + return this.model.addFilter({}, this.filter); } } diff --git a/modules/invoiceIn/front/serial-search-panel/index.spec.js b/modules/invoiceIn/front/serial-search-panel/index.spec.js new file mode 100644 index 000000000..b5228e126 --- /dev/null +++ b/modules/invoiceIn/front/serial-search-panel/index.spec.js @@ -0,0 +1,43 @@ +import './index.js'; + +describe('InvoiceIn', () => { + describe('Component serial-search-panel', () => { + let controller; + let $scope; + + beforeEach(ngModule('invoiceIn')); + + beforeEach(inject(($componentController, $rootScope) => { + $scope = $rootScope.$new(); + const $element = angular.element(''); + controller = $componentController('vnInvoiceInSerialSearchPanel', {$element, $scope}); + controller.model = { + addFilter: jest.fn(), + }; + controller.invoiceInConfig = { + daysAgo: 45, + }; + })); + + describe('addFilters()', () => { + it('should add default daysAgo if it is not already set', () => { + controller.filter = { + serial: 'R', + }; + controller.addFilters(); + + expect(controller.filter.daysAgo).toEqual(controller.invoiceInConfig.daysAgo); + }); + + it('should not add default daysAgo if it is already set', () => { + controller.filter = { + daysAgo: 1, + serial: 'R', + }; + controller.addFilters(); + + expect(controller.filter.daysAgo).toEqual(1); + }); + }); + }); +}); diff --git a/modules/invoiceIn/front/serial/index.html b/modules/invoiceIn/front/serial/index.html index f8ca4bbbb..e381e7293 100644 --- a/modules/invoiceIn/front/serial/index.html +++ b/modules/invoiceIn/front/serial/index.html @@ -1,9 +1,7 @@ + limit="20"> @@ -30,7 +28,7 @@ {{::invoiceIn.total}} diff --git a/modules/invoiceIn/front/serial/index.js b/modules/invoiceIn/front/serial/index.js index 622087748..9d27e4e8f 100644 --- a/modules/invoiceIn/front/serial/index.js +++ b/modules/invoiceIn/front/serial/index.js @@ -6,24 +6,10 @@ export default class Controller extends Section { super($element, $); } - exprBuilder(param, value) { - switch (param) { - case 'issued': - return {'ii.issued': { - between: this.dateRange(value)} - }; - case 'serial': - return {[`ii.${param}`]: value}; - } - } - - dateRange(value) { - const minHour = new Date(value); - minHour.setHours(0, 0, 0, 0); - const maxHour = new Date(value); - maxHour.setHours(23, 59, 59, 59); - - return [minHour, maxHour]; + goToIndex(daysAgo) { + const issued = Date.vnNew(); + issued.setDate(issued.getDate() - daysAgo); + this.$state.go('invoiceIn.index', {q: `{"isBooked": true, "from": ${issued.getTime()}}`}); } } From 69be91b96442f6d6bae52d8405c8bda60923b3c1 Mon Sep 17 00:00:00 2001 From: alexandre Date: Tue, 28 Mar 2023 13:45:26 +0200 Subject: [PATCH 3/5] refs #5184 fix back test, added e2e --- e2e/helpers/selectors.js | 9 ++++ e2e/paths/09-invoice-in/05_serial.spec.js | 48 +++++++++++++++++ .../back/methods/invoice-in/getSerial.js | 52 +++++++++++++------ .../invoice-in/specs/getSerial.spec.js | 9 ++-- .../front/serial-search-panel/index.html | 1 - modules/invoiceIn/front/serial/index.html | 2 +- modules/invoiceIn/front/serial/index.js | 5 +- 7 files changed, 104 insertions(+), 22 deletions(-) create mode 100644 e2e/paths/09-invoice-in/05_serial.spec.js diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index f4c67f002..97693e71e 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -1127,6 +1127,15 @@ export default { saveButton: 'vn-invoice-in-tax vn-submit', }, + invoiceInIndex: { + topbarSearchParams: 'vn-searchbar div.search-params > span', + }, + invoiceInSerial: { + daysAgo: 'vn-invoice-in-serial-search-panel vn-input-number[ng-model="$ctrl.filter.daysAgo"]', + serial: 'vn-invoice-in-serial-search-panel vn-textfield[ng-model="$ctrl.filter.serial"]', + chip: 'vn-chip > vn-icon', + goToIndex: 'vn-invoice-in-serial vn-icon-button[icon="icon-invoice-in"]', + }, travelIndex: { anySearchResult: 'vn-travel-index vn-tbody > a', firstSearchResult: 'vn-travel-index vn-tbody > a:nth-child(1)', diff --git a/e2e/paths/09-invoice-in/05_serial.spec.js b/e2e/paths/09-invoice-in/05_serial.spec.js new file mode 100644 index 000000000..3aa94f48c --- /dev/null +++ b/e2e/paths/09-invoice-in/05_serial.spec.js @@ -0,0 +1,48 @@ +import selectors from '../../helpers/selectors.js'; +import getBrowser from '../../helpers/puppeteer'; + +describe('InvoiceIn serial path', () => { + let browser; + let page; + let httpRequest; + + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + await page.loginAndModule('administrative', 'invoiceIn'); + await page.accessToSection('invoiceIn.serial'); + page.on('request', req => { + if (req.url().includes(`InvoiceIns/getSerial`)) + httpRequest = req.url(); + }); + }); + + afterAll(async() => { + await browser.close(); + }); + + it('should check that passes the correct params to back', async() => { + await page.overwrite(selectors.invoiceInSerial.daysAgo, '30'); + await page.keyboard.press('Enter'); + + expect(httpRequest).toContain('daysAgo=30'); + + await page.overwrite(selectors.invoiceInSerial.serial, 'R'); + await page.keyboard.press('Enter'); + + expect(httpRequest).toContain('serial=R'); + await page.click(selectors.invoiceInSerial.chip); + }); + + it('should go to index and check if the search-panel has the correct params', async() => { + await page.click(selectors.invoiceInSerial.goToIndex); + const params = await page.$$(selectors.invoiceInIndex.topbarSearchParams); + const serial = await params[0].getProperty('title'); + const isBooked = await params[1].getProperty('title'); + const from = await params[2].getProperty('title'); + + expect(await serial.jsonValue()).toContain('serial'); + expect(await isBooked.jsonValue()).toContain('not isBooked'); + expect(await from.jsonValue()).toContain('from'); + }); +}); diff --git a/modules/invoiceIn/back/methods/invoice-in/getSerial.js b/modules/invoiceIn/back/methods/invoice-in/getSerial.js index a6c5ad00e..ebafd6fc4 100644 --- a/modules/invoiceIn/back/methods/invoice-in/getSerial.js +++ b/modules/invoiceIn/back/methods/invoice-in/getSerial.js @@ -1,10 +1,15 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; +const buildFilter = require('vn-loopback/util/filter').buildFilter; +const mergeFilters = require('vn-loopback/util/filter').mergeFilters; module.exports = Self => { - Self.remoteMethod('getSerial', { + Self.remoteMethodCtx('getSerial', { description: 'Return invoiceIn serial', accessType: 'READ', accepts: [{ + arg: 'filter', + type: 'object' + }, { arg: 'daysAgo', type: 'number', required: true @@ -22,26 +27,43 @@ module.exports = Self => { } }); - Self.getSerial = async(daysAgo, serial) => { + Self.getSerial = async(ctx, options) => { const conn = Self.dataSource.connector; - const stmt = []; + const args = ctx.args; + const myOptions = {}; + if (typeof options == 'object') + Object.assign(myOptions, options); + + const where = buildFilter(args, (param, value) => { + switch (param) { + case 'serial': + return {'f.serial': {like: `%${value}%`}}; + } + }); + + filter = mergeFilters(args.filter, {where}); const issued = Date.vnNew(); - issued.setDate(issued.getDate() - daysAgo); + issued.setDate(issued.getDate() - args.daysAgo); - stmt.push(new ParameterizedSQL(` - SELECT i.serial, SUM(IF(i.isBooked, 0,1)) pending, COUNT(*) total - FROM vn.invoiceIn i - WHERE i.issued >= ? `, [issued])); + const stmts = []; + const stmt = new ParameterizedSQL( + `SELECT * + FROM ( + SELECT i.serial, SUM(IF(i.isBooked, 0,1)) pending, COUNT(*) total + FROM vn.invoiceIn i + WHERE i.issued >= ? + GROUP BY i.serial) f` + , [issued]); - if (serial) - stmt.push(new ParameterizedSQL(`AND i.serial LIKE ? `, [serial])); + stmt.merge(conn.makeWhere(filter.where)); + stmt.merge(conn.makeOrderBy(filter.order)); + stmt.merge(conn.makeLimit(filter)); - stmt.push(`GROUP BY i.serial`); + const invoiceInIndex = stmts.push(stmt) - 1; + const sql = ParameterizedSQL.join(stmts, ';'); + const result = await conn.executeStmt(sql, myOptions); - const sql = ParameterizedSQL.join(stmt); - const result = await conn.executeStmt(sql); - - return result; + return invoiceInIndex === 0 ? result : result[invoiceInIndex]; }; }; diff --git a/modules/invoiceIn/back/methods/invoice-in/specs/getSerial.spec.js b/modules/invoiceIn/back/methods/invoice-in/specs/getSerial.spec.js index d07fef196..6224ce9ac 100644 --- a/modules/invoiceIn/back/methods/invoice-in/specs/getSerial.spec.js +++ b/modules/invoiceIn/back/methods/invoice-in/specs/getSerial.spec.js @@ -2,19 +2,22 @@ const models = require('vn-loopback/server/server').models; describe('invoiceIn getSerial()', () => { it('should check that returns without serial param', async() => { - const result = await models.InvoiceIn.getSerial(45); + const ctx = {args: {daysAgo: 45}}; + const result = await models.InvoiceIn.getSerial(ctx); expect(result.length).toBeGreaterThan(0); }); it('should check that returns with serial param', async() => { - const result = await models.InvoiceIn.getSerial(45, 'R'); + const ctx = {args: {daysAgo: 45, serial: 'R'}}; + const result = await models.InvoiceIn.getSerial(ctx); expect(result.length).toBeGreaterThan(0); }); it('should check that returns with non exist serial param', async() => { - const result = await models.InvoiceIn.getSerial(45, 'Mock serial'); + const ctx = {args: {daysAgo: 45, serial: 'Mock serial'}}; + const result = await models.InvoiceIn.getSerial(ctx); expect(result.length).toEqual(0); }); diff --git a/modules/invoiceIn/front/serial-search-panel/index.html b/modules/invoiceIn/front/serial-search-panel/index.html index c412e783c..0dda54852 100644 --- a/modules/invoiceIn/front/serial-search-panel/index.html +++ b/modules/invoiceIn/front/serial-search-panel/index.html @@ -5,7 +5,6 @@ ng-model="$ctrl.filter.daysAgo" vn-focus ng-keydown="$ctrl.onKeyPress($event)" - required="true" min="0"> diff --git a/modules/invoiceIn/front/serial/index.html b/modules/invoiceIn/front/serial/index.html index e381e7293..1649ec7d7 100644 --- a/modules/invoiceIn/front/serial/index.html +++ b/modules/invoiceIn/front/serial/index.html @@ -28,7 +28,7 @@ {{::invoiceIn.total}} diff --git a/modules/invoiceIn/front/serial/index.js b/modules/invoiceIn/front/serial/index.js index 9d27e4e8f..193a57492 100644 --- a/modules/invoiceIn/front/serial/index.js +++ b/modules/invoiceIn/front/serial/index.js @@ -6,10 +6,11 @@ export default class Controller extends Section { super($element, $); } - goToIndex(daysAgo) { + goToIndex(daysAgo, serial) { const issued = Date.vnNew(); issued.setDate(issued.getDate() - daysAgo); - this.$state.go('invoiceIn.index', {q: `{"isBooked": true, "from": ${issued.getTime()}}`}); + this.$state.go('invoiceIn.index', + {q: `{"serial": "${serial}", "isBooked": false, "from": ${issued.getTime()}}`}); } } From 3ad85c0de3cc06ec1ccb570c403848bc1a3db504 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 29 Mar 2023 08:44:35 +0200 Subject: [PATCH 4/5] refs #5184 subselect deleted --- .../back/methods/invoice-in/getSerial.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/modules/invoiceIn/back/methods/invoice-in/getSerial.js b/modules/invoiceIn/back/methods/invoice-in/getSerial.js index ebafd6fc4..3ef37d401 100644 --- a/modules/invoiceIn/back/methods/invoice-in/getSerial.js +++ b/modules/invoiceIn/back/methods/invoice-in/getSerial.js @@ -35,28 +35,27 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); + const issued = Date.vnNew(); const where = buildFilter(args, (param, value) => { switch (param) { + case 'daysAgo': + issued.setDate(issued.getDate() - value); + return {'i.issued': {gte: issued}}; case 'serial': - return {'f.serial': {like: `%${value}%`}}; + return {'i.serial': {like: `%${value}%`}}; } }); filter = mergeFilters(args.filter, {where}); - const issued = Date.vnNew(); - issued.setDate(issued.getDate() - args.daysAgo); const stmts = []; const stmt = new ParameterizedSQL( - `SELECT * - FROM ( - SELECT i.serial, SUM(IF(i.isBooked, 0,1)) pending, COUNT(*) total - FROM vn.invoiceIn i - WHERE i.issued >= ? - GROUP BY i.serial) f` - , [issued]); + `SELECT i.serial, SUM(IF(i.isBooked, 0,1)) pending, COUNT(*) total + FROM vn.invoiceIn i` + ); stmt.merge(conn.makeWhere(filter.where)); + stmt.merge(`GROUP BY i.serial`); stmt.merge(conn.makeOrderBy(filter.order)); stmt.merge(conn.makeLimit(filter)); From 9a713d2753d80451da3637d6f1a78346bfc31e90 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 29 Mar 2023 08:48:54 +0200 Subject: [PATCH 5/5] refs #5184 stmts removed --- modules/invoiceIn/back/methods/invoice-in/getSerial.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/modules/invoiceIn/back/methods/invoice-in/getSerial.js b/modules/invoiceIn/back/methods/invoice-in/getSerial.js index 3ef37d401..dcc1fbc3c 100644 --- a/modules/invoiceIn/back/methods/invoice-in/getSerial.js +++ b/modules/invoiceIn/back/methods/invoice-in/getSerial.js @@ -48,7 +48,6 @@ module.exports = Self => { filter = mergeFilters(args.filter, {where}); - const stmts = []; const stmt = new ParameterizedSQL( `SELECT i.serial, SUM(IF(i.isBooked, 0,1)) pending, COUNT(*) total FROM vn.invoiceIn i` @@ -59,10 +58,8 @@ module.exports = Self => { stmt.merge(conn.makeOrderBy(filter.order)); stmt.merge(conn.makeLimit(filter)); - const invoiceInIndex = stmts.push(stmt) - 1; - const sql = ParameterizedSQL.join(stmts, ';'); - const result = await conn.executeStmt(sql, myOptions); + const result = await conn.executeStmt(stmt, myOptions); - return invoiceInIndex === 0 ? result : result[invoiceInIndex]; + return result; }; };