diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index f4fb25a12..d38bc89d8 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2252,3 +2252,8 @@ INSERT INTO `vn`.`duaInvoiceIn`(`id`, `duaFk`, `invoiceInFk`) (8, 8, 8), (9, 9, 9), (10, 10, 10); + +INSERT INTO `vn`.`ticketRecalc`(`ticketFk`) + SELECT `id` FROM `vn`.`ticket`; + +CALL `vn`.`ticket_doRecalc`(); diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js index 5d0c513df..4c3536b8d 100644 --- a/modules/entry/back/methods/entry/latestBuysFilter.js +++ b/modules/entry/back/methods/entry/latestBuysFilter.js @@ -37,11 +37,11 @@ module.exports = Self => { }, { arg: 'active', type: 'Boolean', - description: 'Whether the the item is or not active', + description: 'Whether the item is or not active', }, { arg: 'visible', type: 'Boolean', - description: 'Whether the the item is or not visible', + description: 'Whether the item is or not visible', }, { arg: 'typeFk', type: 'Integer', diff --git a/modules/ticket/back/methods/ticket/canBeInvoiced.js b/modules/ticket/back/methods/ticket/canBeInvoiced.js index 3b588c32e..8300ae110 100644 --- a/modules/ticket/back/methods/ticket/canBeInvoiced.js +++ b/modules/ticket/back/methods/ticket/canBeInvoiced.js @@ -1,13 +1,13 @@ module.exports = function(Self) { Self.remoteMethodCtx('canBeInvoiced', { - description: 'Change property isEqualizated in all client addresses', + description: 'Whether the ticket can or not be invoiced', accessType: 'READ', accepts: [ { arg: 'id', - type: 'string', + type: 'number', required: true, - description: 'Client id', + description: 'The ticket id', http: {source: 'path'} } ], @@ -23,8 +23,9 @@ module.exports = function(Self) { }); Self.canBeInvoiced = async id => { - let ticket = await Self.app.models.Ticket.findById(id, {fields: ['id', 'refFk', 'shipped']}); - let ticketTotal = await Self.app.models.Ticket.getTotal(id); + let ticket = await Self.app.models.Ticket.findById(id, { + fields: ['id', 'refFk', 'shipped', 'totalWithVat'] + }); let query = `SELECT vn.hasSomeNegativeBase(?) AS hasSomeNegativeBase`; let [result] = await Self.rawSql(query, [id]); @@ -33,7 +34,7 @@ module.exports = function(Self) { let today = new Date(); let shipped = new Date(ticket.shipped); - if (ticket.refFk || ticketTotal == 0 || shipped.getTime() > today.getTime() || hasSomeNegativeBase) + if (ticket.refFk || ticket.totalWithVat == 0 || shipped.getTime() > today.getTime() || hasSomeNegativeBase) return false; return true; diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js index 5c941ef84..caed359d0 100644 --- a/modules/ticket/back/methods/ticket/filter.js +++ b/modules/ticket/back/methods/ticket/filter.js @@ -203,6 +203,8 @@ module.exports = Self => { t.routeFk, t.warehouseFk, t.clientFk, + t.totalWithoutVat, + t.totalWithVat, io.id AS invoiceOutId, a.provinceFk, p.name AS province, @@ -246,6 +248,7 @@ module.exports = Self => { stmts.push(stmt); stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticketGetProblems'); + stmts.push(` CREATE TEMPORARY TABLE tmp.ticketGetProblems (INDEX (ticketFk)) @@ -255,23 +258,15 @@ module.exports = Self => { LEFT JOIN alertLevel al ON al.alertLevel = f.alertLevel WHERE (al.code = 'FREE' OR f.alertLevel IS NULL) AND f.shipped >= CURDATE()`); - stmts.push('CALL ticketGetProblems()'); - stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticket'); - stmts.push(` - CREATE TEMPORARY TABLE tmp.ticket - (INDEX (ticketFk)) ENGINE = MEMORY - SELECT id ticketFk FROM tmp.filter`); - stmts.push('CALL ticketGetTotal()'); + stmts.push('CALL ticketGetProblems()'); stmt = new ParameterizedSQL(` SELECT f.*, - tt.total, tp.* FROM tmp.filter f - LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id - LEFT JOIN tmp.ticketTotal tt ON tt.ticketFk = f.id`); + LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id`); if (args.problems != undefined && (!args.from && !args.to)) throw new UserError('Choose a date range or days forward'); diff --git a/modules/ticket/back/methods/ticket/getTaxes.js b/modules/ticket/back/methods/ticket/getTaxes.js deleted file mode 100644 index 151866eff..000000000 --- a/modules/ticket/back/methods/ticket/getTaxes.js +++ /dev/null @@ -1,28 +0,0 @@ -module.exports = Self => { - Self.remoteMethod('getTaxes', { - description: 'Returns ticket taxes', - accessType: 'READ', - accepts: [{ - arg: 'id', - type: 'number', - required: true, - description: 'ticket id', - http: {source: 'path'} - }], - returns: { - type: 'number', - root: true - }, - http: { - path: `/:id/getTaxes`, - verb: 'GET' - } - }); - - Self.getTaxes = async ticketFk => { - let query = `CALL vn.ticketGetTaxAdd(?)`; - let [taxes] = await Self.rawSql(query, [ticketFk]); - - return taxes; - }; -}; diff --git a/modules/ticket/back/methods/ticket/getTotal.js b/modules/ticket/back/methods/ticket/getTotal.js deleted file mode 100644 index 8e342cf5d..000000000 --- a/modules/ticket/back/methods/ticket/getTotal.js +++ /dev/null @@ -1,28 +0,0 @@ -module.exports = Self => { - Self.remoteMethod('getTotal', { - description: 'Returns the total of a ticket', - accessType: 'READ', - accepts: [{ - arg: 'id', - type: 'number', - required: true, - description: 'ticket id', - http: {source: 'path'} - }], - returns: { - type: 'number', - root: true - }, - http: { - path: `/:id/getTotal`, - verb: 'GET' - } - }); - - Self.getTotal = async ticketFk => { - let query = `SELECT vn.ticketGetTotal(?) AS amount`; - let [total] = await Self.rawSql(query, [ticketFk]); - - return total.amount ? total.amount : 0.00; - }; -}; diff --git a/modules/ticket/back/methods/ticket/getVAT.js b/modules/ticket/back/methods/ticket/getVAT.js deleted file mode 100644 index 087697b0c..000000000 --- a/modules/ticket/back/methods/ticket/getVAT.js +++ /dev/null @@ -1,32 +0,0 @@ -module.exports = Self => { - Self.remoteMethod('getVAT', { - description: 'Returns ticket total VAT', - accessType: 'READ', - accepts: [{ - arg: 'id', - type: 'number', - required: true, - description: 'ticket id', - http: {source: 'path'} - }], - returns: { - type: 'number', - root: true - }, - http: { - path: `/:id/getVAT`, - verb: 'GET' - } - }); - - Self.getVAT = async ticketFk => { - let totalTax = 0.00; - let taxes = await Self.app.models.Ticket.getTaxes(ticketFk); - - taxes.forEach(tax => { - totalTax += tax.tax; - }); - - return Math.round(totalTax * 100) / 100; - }; -}; diff --git a/modules/ticket/back/methods/ticket/specs/getTaxes.spec.js b/modules/ticket/back/methods/ticket/specs/getTaxes.spec.js deleted file mode 100644 index 68010479c..000000000 --- a/modules/ticket/back/methods/ticket/specs/getTaxes.spec.js +++ /dev/null @@ -1,9 +0,0 @@ -const app = require('vn-loopback/server/server'); - -describe('ticket getTaxes()', () => { - it('should return the tax of a given ticket', async() => { - let result = await app.models.Ticket.getTaxes(1); - - expect(result[0].tax).toEqual(7.1); - }); -}); diff --git a/modules/ticket/back/methods/ticket/specs/getTotal.spec.js b/modules/ticket/back/methods/ticket/specs/getTotal.spec.js deleted file mode 100644 index d0191e55a..000000000 --- a/modules/ticket/back/methods/ticket/specs/getTotal.spec.js +++ /dev/null @@ -1,15 +0,0 @@ -const app = require('vn-loopback/server/server'); - -describe('ticket getTotal()', () => { - it('should return the total of a ticket', async() => { - let result = await app.models.Ticket.getTotal(1); - - expect(result).toEqual(891.87); - }); - - it(`should return zero if the ticket doesn't have lines`, async() => { - let result = await app.models.Ticket.getTotal(21); - - expect(result).toEqual(0); - }); -}); diff --git a/modules/ticket/back/methods/ticket/specs/getVAT.spec.js b/modules/ticket/back/methods/ticket/specs/getVAT.spec.js deleted file mode 100644 index 8ba2a3285..000000000 --- a/modules/ticket/back/methods/ticket/specs/getVAT.spec.js +++ /dev/null @@ -1,10 +0,0 @@ -const app = require('vn-loopback/server/server'); - -describe('ticket getVAT()', () => { - it('should return the ticket VAT', async() => { - await app.models.Ticket.getVAT(1) - .then(response => { - expect(response).toEqual(84.64); - }); - }); -}); diff --git a/modules/ticket/back/methods/ticket/specs/subtotal.spec.js b/modules/ticket/back/methods/ticket/specs/subtotal.spec.js deleted file mode 100644 index bd706b6b5..000000000 --- a/modules/ticket/back/methods/ticket/specs/subtotal.spec.js +++ /dev/null @@ -1,15 +0,0 @@ -const app = require('vn-loopback/server/server'); - -describe('ticket subtotal()', () => { - it('should return the subtotal of a ticket', async() => { - let result = await app.models.Ticket.subtotal(1); - - expect(result).toEqual(809.23); - }); - - it(`should return 0 if the ticket doesn't have lines`, async() => { - let result = await app.models.Ticket.subtotal(21); - - expect(result).toEqual(0.00); - }); -}); diff --git a/modules/ticket/back/methods/ticket/specs/summary.spec.js b/modules/ticket/back/methods/ticket/specs/summary.spec.js index c67db0520..0402c0a56 100644 --- a/modules/ticket/back/methods/ticket/specs/summary.spec.js +++ b/modules/ticket/back/methods/ticket/specs/summary.spec.js @@ -14,23 +14,15 @@ describe('ticket summary()', () => { expect(result.sales.length).toEqual(4); }); - it('should return a summary object containing subtotal for 1 ticket', async() => { + it('should return a summary object containing totalWithoutVat for 1 ticket', async() => { let result = await app.models.Ticket.summary(1); - expect(Math.round(result.subtotal * 100) / 100).toEqual(809.23); - }); - - it('should return a summary object containing VAT for 1 ticket', async() => { - let result = await app.models.Ticket.summary(1); - - expect(Math.round(result.vat * 100) / 100).toEqual(84.64); + expect(result.totalWithoutVat).toEqual(807.23); }); it('should return a summary object containing total for 1 ticket', async() => { let result = await app.models.Ticket.summary(1); - let total = result.subtotal + result.vat; - let expectedTotal = Math.round(total * 100) / 100; - expect(result.total).toEqual(expectedTotal); + expect(result.totalWithVat).toEqual(891.87); }); }); diff --git a/modules/ticket/back/methods/ticket/subtotal.js b/modules/ticket/back/methods/ticket/subtotal.js deleted file mode 100644 index 0fd16fbdd..000000000 --- a/modules/ticket/back/methods/ticket/subtotal.js +++ /dev/null @@ -1,39 +0,0 @@ -module.exports = Self => { - Self.remoteMethod('subtotal', { - description: 'Returns the total of a ticket', - accessType: 'READ', - accepts: [{ - arg: 'id', - type: 'number', - required: true, - description: 'ticket id', - http: {source: 'path'} - }], - returns: { - type: 'number', - root: true - }, - http: { - path: `/:id/subtotal`, - verb: 'GET' - } - }); - - Self.subtotal = async ticketFk => { - const sale = Self.app.models.Sale; - const ticketSales = await sale.find({where: {ticketFk}}); - const ticketService = Self.app.models.TicketService; - const ticketServices = await ticketService.find({where: {ticketFk}}); - - let subtotal = 0.00; - ticketSales.forEach(sale => { - subtotal += sale.price * sale.quantity * ((100 - sale.discount) / 100); - }); - - ticketServices.forEach(service => { - subtotal += service.price * service.quantity; - }); - - return Math.round(subtotal * 100) / 100; - }; -}; diff --git a/modules/ticket/back/methods/ticket/summary.js b/modules/ticket/back/methods/ticket/summary.js index 24009ed0a..08de35482 100644 --- a/modules/ticket/back/methods/ticket/summary.js +++ b/modules/ticket/back/methods/ticket/summary.js @@ -23,9 +23,6 @@ module.exports = Self => { let models = Self.app.models; let summaryObj = await getTicketData(Self, ticketFk); summaryObj.sales = await getSales(models.Sale, ticketFk); - summaryObj.subtotal = await models.Ticket.subtotal(ticketFk); - summaryObj.vat = await models.Ticket.getVAT(ticketFk); - summaryObj.total = summaryObj.subtotal + summaryObj.vat; summaryObj.packagings = await models.TicketPackaging.find({ where: {ticketFk: ticketFk}, include: [{relation: 'packaging', diff --git a/modules/ticket/back/models/ticket.js b/modules/ticket/back/models/ticket.js index c47f33081..8159d254d 100644 --- a/modules/ticket/back/models/ticket.js +++ b/modules/ticket/back/models/ticket.js @@ -6,16 +6,12 @@ module.exports = Self => { require('../methods/ticket/getVolume')(Self); require('../methods/ticket/getTotalVolume')(Self); require('../methods/ticket/summary')(Self); - require('../methods/ticket/getTotal')(Self); - require('../methods/ticket/getTaxes')(Self); - require('../methods/ticket/subtotal')(Self); require('../methods/ticket/priceDifference')(Self); require('../methods/ticket/componentUpdate')(Self); require('../methods/ticket/new')(Self); require('../methods/ticket/isEditable')(Self); require('../methods/ticket/setDeleted')(Self); require('../methods/ticket/restore')(Self); - require('../methods/ticket/getVAT')(Self); require('../methods/ticket/getSales')(Self); require('../methods/ticket/getSalesPersonMana')(Self); require('../methods/ticket/filter')(Self); diff --git a/modules/ticket/back/models/ticket.json b/modules/ticket/back/models/ticket.json index 2bb86312d..8f91ee689 100644 --- a/modules/ticket/back/models/ticket.json +++ b/modules/ticket/back/models/ticket.json @@ -12,30 +12,30 @@ "properties": { "id": { "id": true, - "type": "Number", + "type": "number", "description": "Identifier" }, "shipped": { - "type": "Date", + "type": "date", "required": true }, "landed": { - "type": "Date" + "type": "date" }, "nickname": { - "type": "String" + "type": "string" }, "location": { - "type": "String" + "type": "string" }, "solution": { - "type": "String" + "type": "string" }, "packages": { - "type": "Number" + "type": "number" }, "updated": { - "type": "Date", + "type": "date", "mysql": { "columnName": "created" } @@ -44,16 +44,22 @@ "type": "boolean" }, "priority": { - "type": "Number" + "type": "number" }, "zoneFk": { - "type": "Number" + "type": "number" }, "zonePrice": { - "type": "Number" + "type": "number" }, "zoneBonus": { - "type": "Number" + "type": "number" + }, + "totalWithVat": { + "type": "number" + }, + "totalWithoutVat": { + "type": "number" } }, "relations": { diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index b47ff86c0..13e2944e5 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -121,7 +121,7 @@ {{::ticket.warehouse}} - {{::ticket.total | currency: 'EUR': 2}} + {{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}} diff --git a/modules/ticket/front/index/index.js b/modules/ticket/front/index/index.js index 8b1ca2dfd..8fe39184a 100644 --- a/modules/ticket/front/index/index.js +++ b/modules/ticket/front/index/index.js @@ -49,7 +49,7 @@ export default class Controller extends Section { throw new UserError('You cannot make a payment on account from multiple clients'); for (let ticket of checkedTickets) { - this.$.balanceCreateDialog.amountPaid += ticket.total; + this.$.balanceCreateDialog.amountPaid += ticket.totalWithVat; this.$.balanceCreateDialog.clientFk = ticket.clientFk; description.push(`${ticket.id}`); } @@ -109,7 +109,7 @@ export default class Controller extends Section { } totalPriceColor(ticket) { - const total = parseInt(ticket.total); + const total = parseInt(ticket.totalWithVat); if (total > 0 && total < 50) return 'warning'; } diff --git a/modules/ticket/front/index/index.spec.js b/modules/ticket/front/index/index.spec.js index 27940c63d..b966ca8c4 100644 --- a/modules/ticket/front/index/index.spec.js +++ b/modules/ticket/front/index/index.spec.js @@ -6,18 +6,18 @@ describe('Component vnTicketIndex', () => { let tickets = [{ id: 1, clientFk: 1, - total: 10.5, - checked: false + checked: false, + totalWithVat: 10.5 }, { id: 2, clientFk: 1, - total: 20.5, - checked: true + checked: true, + totalWithVat: 20.5 }, { id: 3, clientFk: 1, - total: 30, - checked: true + checked: true, + totalWithVat: 30 }]; beforeEach(ngModule('ticket')); @@ -76,7 +76,6 @@ describe('Component vnTicketIndex', () => { jest.spyOn(controller.$.balanceCreateDialog, 'show').mockReturnThis(); controller.$.model = {data: tickets}; - controller.$.balanceCreateDialog.amountPaid = 0; controller.openBalanceDialog(); let description = controller.$.balanceCreateDialog.description; diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index f5772b6e5..806c5f99e 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -39,8 +39,8 @@ class Controller extends Section { getSubTotal() { if (!this.$params.id || !this.sales) return; - this.$http.get(`Tickets/${this.$params.id}/subtotal`).then(res => { - this.subtotal = res.data || 0.0; + this.$http.get(`Tickets/${this.$params.id}`).then(res => { + this.subtotal = res.data.totalWithoutVat || 0.0; }); } @@ -62,8 +62,8 @@ class Controller extends Section { getVat() { this.VAT = 0.0; if (!this.$params.id || !this.sales) return; - this.$http.get(`Tickets/${this.$params.id}/getVAT`).then(res => { - this.VAT = res.data || 0.0; + this.$http.get(`Tickets/${this.$params.id}`).then(res => { + this.VAT = res.data.totalWithVat - res.data.totalWithoutVat || 0.0; }); } diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index 28b3ce3dd..c8692f4e9 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -84,13 +84,13 @@ describe('Ticket', () => { describe('getSubTotal()', () => { it('should make an HTTP GET query and then set the subtotal property', () => { - const expectedAmount = 128; + const expectedResponse = {totalWithoutVat: 128}; - $httpBackend.expect('GET', 'Tickets/1/subtotal').respond(200, expectedAmount); + $httpBackend.expect('GET', 'Tickets/1').respond(200, expectedResponse); controller.getSubTotal(); $httpBackend.flush(); - expect(controller.subtotal).toEqual(expectedAmount); + expect(controller.subtotal).toEqual(expectedResponse.totalWithoutVat); }); }); @@ -125,13 +125,15 @@ describe('Ticket', () => { describe('getVat()', () => { it('should make an HTTP GET query and return the ticket VAT', () => { controller.edit = {}; - const expectedAmount = 67; + const expectedResponse = {totalWithVat: 1000, totalWithoutVat: 999}; - $httpBackend.expect('GET', 'Tickets/1/getVAT').respond(200, expectedAmount); + const expectedVAT = expectedResponse.totalWithVat - expectedResponse.totalWithoutVat; + + $httpBackend.expect('GET', 'Tickets/1').respond(200, expectedResponse); controller.getVat(); $httpBackend.flush(); - expect(controller.VAT).toEqual(expectedAmount); + expect(controller.VAT).toEqual(expectedVAT); }); }); diff --git a/modules/ticket/front/summary/index.html b/modules/ticket/front/summary/index.html index c29735a1b..bc75c2cc7 100644 --- a/modules/ticket/front/summary/index.html +++ b/modules/ticket/front/summary/index.html @@ -99,9 +99,9 @@ -

Subtotal {{$ctrl.summary.subtotal | currency: 'EUR':2}}

-

VAT {{$ctrl.summary.vat | currency: 'EUR':2}}

-

Total {{$ctrl.summary.total | currency: 'EUR':2}}

+

Subtotal {{$ctrl.summary.totalWithoutVat | currency: 'EUR':2}}

+

VAT {{$ctrl.summary.totalWithVat - $ctrl.summary.totalWithoutVat | currency: 'EUR':2}}

+

Total {{$ctrl.summary.totalWithVat | currency: 'EUR':2}}