From f36b54f97b305446b3a1e9bca451215fe70ee53d Mon Sep 17 00:00:00 2001 From: carlosjr Date: Mon, 14 Jun 2021 11:38:57 +0200 Subject: [PATCH] invoiceOut summary tickets pagination + refactor --- modules/entry/back/methods/entry/getBuys.js | 18 ++++-- modules/entry/front/summary/index.html | 13 ++++- modules/entry/front/summary/index.js | 10 +--- modules/entry/front/summary/index.spec.js | 16 ------ .../back/methods/invoiceOut/getTickets.js | 55 ++++++++++++++++++ .../invoiceOut/specs/getTickets.spec.js | 10 ++++ .../methods/invoiceOut/specs/summary.spec.js | 8 --- .../back/methods/invoiceOut/summary.js | 41 +------------ modules/invoiceOut/back/models/invoiceOut.js | 1 + modules/invoiceOut/front/summary/index.html | 15 ++++- modules/ticket/back/methods/ticket/filter.js | 57 ++++++++++++------- 11 files changed, 146 insertions(+), 98 deletions(-) create mode 100644 modules/invoiceOut/back/methods/invoiceOut/getTickets.js create mode 100644 modules/invoiceOut/back/methods/invoiceOut/specs/getTickets.spec.js diff --git a/modules/entry/back/methods/entry/getBuys.js b/modules/entry/back/methods/entry/getBuys.js index 5bd8cd47e..0f09f06d5 100644 --- a/modules/entry/back/methods/entry/getBuys.js +++ b/modules/entry/back/methods/entry/getBuys.js @@ -1,14 +1,22 @@ +const mergeFilters = require('vn-loopback/util/filter').mergeFilters; + module.exports = Self => { Self.remoteMethod('getBuys', { description: 'Returns buys for one entry', accessType: 'READ', - accepts: { + accepts: [{ arg: 'id', type: 'number', required: true, description: 'The entry id', http: {source: 'path'} }, + { + arg: 'filter', + type: 'object', + description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string' + } + ], returns: { type: ['Object'], root: true @@ -19,14 +27,14 @@ module.exports = Self => { } }); - Self.getBuys = async(id, options) => { + Self.getBuys = async(id, filter, options) => { const models = Self.app.models; let myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const filter = { + let defaultFilter = { where: {entryFk: id}, fields: [ 'id', @@ -74,6 +82,8 @@ module.exports = Self => { } }; - return models.Buy.find(filter, myOptions); + defaultFilter = mergeFilters(defaultFilter, filter); + + return models.Buy.find(defaultFilter, myOptions); }; }; diff --git a/modules/entry/front/summary/index.html b/modules/entry/front/summary/index.html index e4ad6ba31..3f91ddc26 100644 --- a/modules/entry/front/summary/index.html +++ b/modules/entry/front/summary/index.html @@ -1,3 +1,10 @@ + +
Packing price - + {{::line.quantity}} {{::line.stickers | dashIfEmpty}} @@ -156,6 +163,10 @@ + + diff --git a/modules/entry/front/summary/index.js b/modules/entry/front/summary/index.js index 93c985a67..c949dba64 100644 --- a/modules/entry/front/summary/index.js +++ b/modules/entry/front/summary/index.js @@ -10,10 +10,8 @@ class Controller extends Summary { set entry(value) { this._entry = value; - if (value && value.id) { + if (value && value.id) this.getEntryData(); - this.getBuys(); - } } getEntryData() { @@ -21,12 +19,6 @@ class Controller extends Summary { this.entryData = response.data; }); } - - getBuys() { - return this.$http.get(`Entries/${this.entry.id}/getBuys`).then(response => { - this.buys = response.data; - }); - } } ngModule.vnComponent('vnEntrySummary', { diff --git a/modules/entry/front/summary/index.spec.js b/modules/entry/front/summary/index.spec.js index 396e92b01..baeb43ac8 100644 --- a/modules/entry/front/summary/index.spec.js +++ b/modules/entry/front/summary/index.spec.js @@ -46,20 +46,4 @@ describe('component vnEntrySummary', () => { expect(controller.entryData).toEqual('I am the entryData'); }); }); - - describe('getBuys()', () => { - it('should perform a get asking for the buys of an entry', () => { - controller._entry = {id: 999}; - - const thatQuery = `Entries/${controller._entry.id}/getEntry`; - const query = `Entries/${controller._entry.id}/getBuys`; - - $httpBackend.whenGET(thatQuery).respond('My Entries'); - $httpBackend.expectGET(query).respond('Some buys'); - controller.getBuys(); - $httpBackend.flush(); - - expect(controller.buys).toEqual('Some buys'); - }); - }); }); diff --git a/modules/invoiceOut/back/methods/invoiceOut/getTickets.js b/modules/invoiceOut/back/methods/invoiceOut/getTickets.js new file mode 100644 index 000000000..dc3296aba --- /dev/null +++ b/modules/invoiceOut/back/methods/invoiceOut/getTickets.js @@ -0,0 +1,55 @@ +const mergeFilters = require('vn-loopback/util/filter').mergeFilters; + +module.exports = Self => { + Self.remoteMethod('getTickets', { + description: 'Returns tickets for one invoiceOut', + accessType: 'READ', + accepts: [{ + arg: 'id', + type: 'number', + required: true, + description: 'The invoiceOut id', + http: {source: 'path'} + }, + { + arg: 'filter', + type: 'object', + description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string' + } + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/:id/getTickets`, + verb: 'GET' + } + }); + + Self.getTickets = async(id, filter, options) => { + const models = Self.app.models; + let myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const invoiceOut = await models.InvoiceOut.findById(id, {fields: 'ref'}, myOptions); + + let defaultFilter = { + where: {refFk: invoiceOut.ref}, + fields: [ + 'id', + 'nickname', + 'shipped', + 'totalWithVat', + 'clientFk' + ] + + }; + + defaultFilter = mergeFilters(defaultFilter, filter); + + return models.Ticket.find(defaultFilter, myOptions); + }; +}; diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/getTickets.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/getTickets.spec.js new file mode 100644 index 000000000..0872ff85f --- /dev/null +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/getTickets.spec.js @@ -0,0 +1,10 @@ +const app = require('vn-loopback/server/server'); + +describe('entry getTickets()', () => { + const invoiceOutId = 4; + it('should get the ticket of an invoiceOut', async() => { + const result = await app.models.InvoiceOut.getTickets(invoiceOutId); + + expect(result.length).toEqual(1); + }); +}); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/summary.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/summary.spec.js index 1b1b84d15..115597717 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/summary.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/summary.spec.js @@ -7,14 +7,6 @@ describe('invoiceOut summary()', () => { expect(result.invoiceOut.id).toEqual(1); }); - it(`should return a summary object containing data from it's tickets`, async() => { - const summary = await app.models.InvoiceOut.summary(1); - const tickets = summary.invoiceOut.tickets(); - - expect(summary.invoiceOut.ref).toEqual('T1111111'); - expect(tickets.length).toEqual(2); - }); - it(`should return a summary object containing it's supplier country`, async() => { const summary = await app.models.InvoiceOut.summary(1); const supplier = summary.invoiceOut.supplier(); diff --git a/modules/invoiceOut/back/methods/invoiceOut/summary.js b/modules/invoiceOut/back/methods/invoiceOut/summary.js index caa2a1c06..0dd82fd0d 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/summary.js +++ b/modules/invoiceOut/back/methods/invoiceOut/summary.js @@ -1,5 +1,3 @@ -const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; - module.exports = Self => { Self.remoteMethod('summary', { description: 'The invoiceOut summary', @@ -22,7 +20,6 @@ module.exports = Self => { }); Self.summary = async id => { - const conn = Self.dataSource.connector; let summary = {}; const filter = { @@ -57,54 +54,20 @@ module.exports = Self => { scope: { fields: ['id', 'socialName'] } - }, - { - relation: 'tickets' } ] }; summary.invoiceOut = await Self.app.models.InvoiceOut.findOne(filter); - let stmts = []; - - stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticket'); - - stmt = new ParameterizedSQL(` - CREATE TEMPORARY TABLE tmp.ticket - (INDEX (ticketFk)) ENGINE = MEMORY - SELECT id ticketFk FROM vn.ticket WHERE refFk=?`, [summary.invoiceOut.ref]); - stmts.push(stmt); - - stmts.push('CALL ticketGetTotal()'); - - let ticketTotalsIndex = stmts.push('SELECT * FROM tmp.ticketTotal') - 1; - - stmt = new ParameterizedSQL(` + const invoiceOutTaxes = await Self.rawSql(` SELECT iot.* , pgc.*, IF(pe.equFk IS NULL, taxableBase, 0) AS Base, pgc.rate / 100 as vatPercent FROM vn.invoiceOutTax iot JOIN vn.pgc ON pgc.code = iot.pgcFk LEFT JOIN vn.pgcEqu pe ON pe.equFk = pgc.code WHERE invoiceOutFk = ?`, [summary.invoiceOut.id]); - let invoiceOutTaxesIndex = stmts.push(stmt) - 1; - stmts.push( - `DROP TEMPORARY TABLE - tmp.ticket, - tmp.ticketTotal`); - - let sql = ParameterizedSQL.join(stmts, ';'); - let result = await conn.executeStmt(sql); - - totalMap = {}; - for (ticketTotal of result[ticketTotalsIndex]) - totalMap[ticketTotal.ticketFk] = ticketTotal.total; - - summary.invoiceOut.tickets().forEach(ticket => { - ticket.total = totalMap[ticket.id]; - }); - - summary.invoiceOut.taxesBreakdown = result[invoiceOutTaxesIndex]; + summary.invoiceOut.taxesBreakdown = invoiceOutTaxes; return summary; }; diff --git a/modules/invoiceOut/back/models/invoiceOut.js b/modules/invoiceOut/back/models/invoiceOut.js index e84a0495e..7c6503d8e 100644 --- a/modules/invoiceOut/back/models/invoiceOut.js +++ b/modules/invoiceOut/back/models/invoiceOut.js @@ -1,6 +1,7 @@ module.exports = Self => { require('../methods/invoiceOut/filter')(Self); require('../methods/invoiceOut/summary')(Self); + require('../methods/invoiceOut/getTickets')(Self); require('../methods/invoiceOut/download')(Self); require('../methods/invoiceOut/delete')(Self); require('../methods/invoiceOut/book')(Self); diff --git a/modules/invoiceOut/front/summary/index.html b/modules/invoiceOut/front/summary/index.html index 452ec23db..0dd9bfe0b 100644 --- a/modules/invoiceOut/front/summary/index.html +++ b/modules/invoiceOut/front/summary/index.html @@ -1,3 +1,10 @@ + +
- + {{ticket.shipped | date: 'dd/MM/yyyy' | dashIfEmpty}} - {{ticket.total | currency: 'EUR': 2}} + {{ticket.totalWithVat | currency: 'EUR': 2}} + + diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js index 5d7c014f7..31834112e 100644 --- a/modules/ticket/back/methods/ticket/filter.js +++ b/modules/ticket/back/methods/ticket/filter.js @@ -12,79 +12,98 @@ module.exports = Self => { arg: 'ctx', type: 'object', http: {source: 'context'} - }, { + }, + { arg: 'filter', type: 'object', description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string` - }, { + }, + { arg: 'search', type: 'string', description: `If it's and number searchs by id, otherwise it searchs by nickname` - }, { + }, + { arg: 'from', type: 'date', description: `The from date filter` - }, { + }, + { arg: 'to', type: 'date', description: `The to date filter` - }, { + }, + { arg: 'nickname', type: 'string', description: `The nickname filter` - }, { + }, + { arg: 'id', type: 'number', description: `The ticket id filter` - }, { + }, + { arg: 'clientFk', type: 'number', description: `The client id filter` - }, { + }, + { arg: 'agencyModeFk', type: 'number', description: `The agency mode id filter` - }, { + }, + { arg: 'warehouseFk', type: 'number', description: `The warehouse id filter` - }, { + }, + { arg: 'salesPersonFk', type: 'number', description: `The salesperson id filter` - }, { + }, + { arg: 'provinceFk', type: 'number', description: `The province id filter` - }, { + }, + { arg: 'stateFk', type: 'number', description: `The state id filter` - }, { + }, + { arg: 'myTeam', type: 'boolean', description: `Whether to show only tickets for the current logged user team (For now it shows only the current user tickets)` - }, { + }, + { arg: 'problems', type: 'boolean', description: `Whether to show only tickets with problems` - }, { + }, + { arg: 'pending', type: 'boolean', description: `Whether to show only tickets with state 'Pending'` - }, { + }, + { arg: 'mine', type: 'boolean', description: `Whether to show only tickets for the current logged user` - }, { + }, + { arg: 'orderFk', type: 'number', description: `The order id filter` - }, { + }, + { arg: 'refFk', type: 'string', description: `The invoice reference filter` - }, { + }, + { arg: 'alertLevel', type: 'number', description: `The alert level of the tickets`