From 19887bdd16108e8d89d5b6a8340429224f757833 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 24 Feb 2022 14:52:32 +0100 Subject: [PATCH 01/23] feat: add section autonomous --- .../10420-valentines/00-aclAgencyTerm.sql | 2 + db/dump/fixtures.sql | 23 +++ .../route/back/methods/agency-term/filter.js | 143 +++++++++++++++++ modules/route/back/model-config.json | 3 + modules/route/back/models/agency-term.js | 3 + modules/route/back/models/agency-term.json | 37 +++++ modules/route/front/agency-term/index.html | 149 ++++++++++++++++++ modules/route/front/agency-term/index.js | 121 ++++++++++++++ modules/route/front/agency-term/index.spec.js | 30 ++++ modules/route/front/agency-term/locale/es.yml | 5 + modules/route/front/agency-term/preview.svg | 11 ++ modules/route/front/agency-term/style.scss | 32 ++++ modules/route/front/index.js | 1 + modules/route/front/routes.json | 9 +- 14 files changed, 568 insertions(+), 1 deletion(-) create mode 100644 db/changes/10420-valentines/00-aclAgencyTerm.sql create mode 100644 modules/route/back/methods/agency-term/filter.js create mode 100644 modules/route/back/models/agency-term.js create mode 100644 modules/route/back/models/agency-term.json create mode 100644 modules/route/front/agency-term/index.html create mode 100644 modules/route/front/agency-term/index.js create mode 100644 modules/route/front/agency-term/index.spec.js create mode 100644 modules/route/front/agency-term/locale/es.yml create mode 100644 modules/route/front/agency-term/preview.svg create mode 100644 modules/route/front/agency-term/style.scss diff --git a/db/changes/10420-valentines/00-aclAgencyTerm.sql b/db/changes/10420-valentines/00-aclAgencyTerm.sql new file mode 100644 index 000000000..d3e11e53e --- /dev/null +++ b/db/changes/10420-valentines/00-aclAgencyTerm.sql @@ -0,0 +1,2 @@ +INSERT INTO salix.ACL (model,property,accessType,principalId) + VALUES ('AgencyTerm','*','*','administrative'); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 07eaf23fd..35013b35b 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2443,3 +2443,26 @@ INSERT INTO `bs`.`defaulter` (`clientFk`, `amount`, `created`, `defaulterSinced` (1103, 500, CURDATE(), CURDATE()), (1107, 500, CURDATE(), CURDATE()), (1109, 500, CURDATE(), CURDATE()); + +INSERT INTO `vn`.`agencyTerm` (`agencyFk`, `minimumPackages`, `kmPrice`, `packagePrice`, `routePrice`, `minimumKm`, `minimumM3`, `m3Price`) + VALUES + (1, 0, 0.00, 0.00, NULL, 0, 0.00, 0), + (3, 0, 0.00, 3.05, NULL, 0, 0.00, 0), + (2, 60, 0.00, 0.00, NULL, 0, 5.00, 33); + +UPDATE `vn`.`agency` +SET `supplierFk`=1 +WHERE `id`=1; +UPDATE `vn`.`agency` +SET `supplierFk`=1 +WHERE `id`=2; +UPDATE `vn`.`agency` +SET `supplierFk`=2 +WHERE `id`=3; + +UPDATE `vn`.`route` +SET `invoiceInFk`=1 +WHERE `id`=1; +UPDATE `vn`.`route` +SET `invoiceInFk`=2 +WHERE `id`=2; \ No newline at end of file diff --git a/modules/route/back/methods/agency-term/filter.js b/modules/route/back/methods/agency-term/filter.js new file mode 100644 index 000000000..94ed7fc91 --- /dev/null +++ b/modules/route/back/methods/agency-term/filter.js @@ -0,0 +1,143 @@ + +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.remoteMethodCtx('filter', { + description: 'Find all instances of the model matched by filter from the data source.', + accessType: 'READ', + accepts: [ + { + arg: 'filter', + type: 'object', + description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', + http: {source: 'query'} + }, + { + arg: 'search', + type: 'string', + description: 'Searchs the route by id', + http: {source: 'query'} + }, + { + arg: 'agencyModeFk', + type: 'integer', + description: 'The agencyMode id', + http: {source: 'query'} + }, + { + arg: 'to', + type: 'date', + description: 'The to date filter', + http: {source: 'query'} + }, + { + arg: 'from', + type: 'date', + description: 'The to date filter', + http: {source: 'query'} + }, + { + arg: 'vehicleFk', + type: 'integer', + description: 'The vehicle id', + http: {source: 'query'} + }, + { + arg: 'm3', + type: 'number', + description: 'The m3 filter', + http: {source: 'query'} + }, + { + arg: 'warehouseFk', + type: 'number', + description: 'The warehouse filter', + http: {source: 'query'} + }, + { + arg: 'description', + type: 'string', + description: 'The description filter', + http: {source: 'query'} + } + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/filter`, + verb: 'GET' + } + }); + + Self.filter = async(ctx, filter) => { + let conn = Self.dataSource.connector; + + let where = buildFilter(ctx.args, (param, value) => { + switch (param) { + case 'search': + return {'r.id': value}; + case 'from': + return {'r.created': {gte: value}}; + case 'to': + return {'r.created': {lte: value}}; + case 'm3': + return {'r.m3': value}; + case 'description': + return {'r.description': {like: `%${value}%`}}; + case 'warehouseFk': + param = `v.${param}`; + return {[param]: value}; + case 'vehicleFk': + case 'agencyModeFk': + param = `r.${param}`; + return {[param]: value}; + } + }); + + filter = mergeFilters(ctx.args.filter, {where}); + + let stmts = []; + let stmt; + + stmt = new ParameterizedSQL( + `SELECT + r.id routeFk, + r.created, + r.agencyModeFk, + am.name agencyModeName, + am.agencyFk, + a.name agencyAgreement, + SUM(t.packages) packages, + r.m3, + r.kmEnd - r.kmStart kmTotal, + CAST(IFNULL(ate.routePrice, + (ate.kmPrice * (GREATEST(r.kmEnd - r.kmStart , ate.minimumKm)) + + GREATEST(r.m3 , ate.minimumM3) * ate.m3Price) + + ate.packagePrice * SUM(t.packages) ) + AS DECIMAL(10,2)) price, + r.invoiceInFk, + a.supplierFk, + s.name supplierName + FROM vn.route r + LEFT JOIN vn.agencyMode am ON r.agencyModeFk = am.id + LEFT JOIN vn.agency a ON am.agencyFk = a.id + LEFT JOIN vn.ticket t ON t.routeFk = r.id + LEFT JOIN vn.agencyTerm ate ON ate.agencyFk = a.id + LEFT JOIN vn.supplier s ON s.id = a.supplierFk + WHERE r.created > DATE_ADD(CURDATE(), INTERVAL -2 MONTH) AND a.supplierFk IS NOT NULL + GROUP BY r.id;` + ); + + stmt.merge(conn.makeSuffix(filter)); + let agencyTerm = stmts.push(stmt) - 1; + + let sql = ParameterizedSQL.join(stmts, ';'); + let result = await conn.executeStmt(sql); + return agencyTerm === 0 ? result : result[agencyTerm]; + }; +}; + diff --git a/modules/route/back/model-config.json b/modules/route/back/model-config.json index 0dfe1d02a..5d5c5cc18 100644 --- a/modules/route/back/model-config.json +++ b/modules/route/back/model-config.json @@ -1,4 +1,7 @@ { + "AgencyTerm": { + "dataSource": "vn" + }, "Route": { "dataSource": "vn" }, diff --git a/modules/route/back/models/agency-term.js b/modules/route/back/models/agency-term.js new file mode 100644 index 000000000..14fe76d28 --- /dev/null +++ b/modules/route/back/models/agency-term.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/agency-term/filter')(Self); +}; diff --git a/modules/route/back/models/agency-term.json b/modules/route/back/models/agency-term.json new file mode 100644 index 000000000..29f70951b --- /dev/null +++ b/modules/route/back/models/agency-term.json @@ -0,0 +1,37 @@ +{ + "name": "AgencyTerm", + "base": "VnModel", + "options": { + "mysql": { + "table": "agencyTerm" + } + }, + "properties": { + "agencyFk": { + "type": "Number", + "id": true, + "description": "Identifier" + }, + "minimumPackages": { + "type": "Number" + }, + "kmPrice": { + "type": "Number" + }, + "packagePrice": { + "type": "Number" + }, + "routePrice": { + "type": "Number" + }, + "minimumKm": { + "type": "Number" + }, + "minimumM3": { + "type": "Number" + }, + "m3Price": { + "type": "Number" + } + } +} diff --git a/modules/route/front/agency-term/index.html b/modules/route/front/agency-term/index.html new file mode 100644 index 000000000..6ccd0cb56 --- /dev/null +++ b/modules/route/front/agency-term/index.html @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Id + + Date + + Agency route + + Agency Agreement + + Packages + + M3 + + Km + + Price + + Received + + Autonomous +
+ + + + + {{::agencyTerm.routeFk}} + + {{::agencyTerm.created | date:'dd/MM/yyyy'}}{{::agencyTerm.agencyModeName | dashIfEmpty}}{{::agencyTerm.agencyAgreement | dashIfEmpty}}{{::agencyTerm.packages | dashIfEmpty}}{{::agencyTerm.m3 | dashIfEmpty}}{{::agencyTerm.kmTotal | dashIfEmpty}}{{::agencyTerm.price | dashIfEmpty}} + + {{::agencyTerm.invoiceInFk}} + + + + {{::agencyTerm.supplierName}} + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + Filter by selection + + + Exclude selection + + + Remove filter + + + Remove all filters + + + \ No newline at end of file diff --git a/modules/route/front/agency-term/index.js b/modules/route/front/agency-term/index.js new file mode 100644 index 000000000..4f80ffc60 --- /dev/null +++ b/modules/route/front/agency-term/index.js @@ -0,0 +1,121 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; +import './style.scss'; + +class Controller extends Section { + constructor($element, $) { + super($element, $); + + this.smartTableOptions = { + activeButtons: { + search: false, + shownColumns: false, + }, + columns: [ + { + field: 'agencyFk', + autocomplete: { + url: 'ItemCategories', + valueField: 'name', + } + }, + { + field: 'origin', + autocomplete: { + url: 'Origins', + showField: 'code', + valueField: 'code' + } + }, + { + field: 'typeFk', + autocomplete: { + url: 'ItemTypes', + } + }, + { + field: 'intrastat', + autocomplete: { + url: 'Intrastats', + showField: 'description', + valueField: 'description' + } + }, + { + field: 'buyerFk', + autocomplete: { + url: 'Workers/activeWithRole', + where: `{role: {inq: ['logistic', 'buyer']}}`, + searchFunction: '{firstName: $search}', + showField: 'nickname', + valueField: 'id', + } + }, + { + field: 'active', + searchable: false + }, + { + field: 'landed', + searchable: false + }, + ] + }; + } + + exprBuilder(param, value) { + switch (param) { + case 'category': + return {'ic.name': value}; + case 'buyerFk': + return {'it.workerFk': value}; + case 'grouping': + return {'b.grouping': value}; + case 'packing': + return {'b.packing': value}; + case 'origin': + return {'ori.code': value}; + case 'typeFk': + return {'i.typeFk': value}; + case 'intrastat': + return {'intr.description': value}; + case 'name': + return {'i.name': {like: `%${value}%`}}; + case 'producer': + return {'pr.name': {like: `%${value}%`}}; + case 'id': + case 'size': + case 'subname': + case 'isActive': + case 'density': + case 'stemMultiplier': + case 'stems': + return {[`i.${param}`]: value}; + } + } + + get checked() { + const routes = this.$.model.data || []; + const checkedRoutes = []; + for (let route of routes) { + if (route.checked) + checkedRoutes.push(route); + } + + return checkedRoutes; + } + + get totalChecked() { + return this.checked.length; + } + + preview(route) { + this.routeSelected = route; + this.$.summary.show(); + } +} + +ngModule.vnComponent('vnAgencyTerm', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/route/front/agency-term/index.spec.js b/modules/route/front/agency-term/index.spec.js new file mode 100644 index 000000000..18abde581 --- /dev/null +++ b/modules/route/front/agency-term/index.spec.js @@ -0,0 +1,30 @@ +import './index.js'; + +describe('Item', () => { + describe('Component vnItemIndex', () => { + let controller; + let $httpBackend; + let $scope; + + beforeEach(ngModule('item')); + + beforeEach(inject(($componentController, _$httpBackend_, $rootScope) => { + $httpBackend = _$httpBackend_; + $scope = $rootScope.$new(); + const $element = angular.element(''); + controller = $componentController('vnItemIndex', {$element, $scope}); + })); + + describe('onCloneAccept()', () => { + it('should perform a post query and then call go() then update itemSelected in the controller', () => { + jest.spyOn(controller.$state, 'go'); + + $httpBackend.expectRoute('POST', `Items/:id/clone`).respond({id: 99}); + controller.onCloneAccept(1); + $httpBackend.flush(); + + expect(controller.$state.go).toHaveBeenCalledWith('item.card.tags', {id: 99}); + }); + }); + }); +}); diff --git a/modules/route/front/agency-term/locale/es.yml b/modules/route/front/agency-term/locale/es.yml new file mode 100644 index 000000000..0e766f5aa --- /dev/null +++ b/modules/route/front/agency-term/locale/es.yml @@ -0,0 +1,5 @@ +picture: Foto +Buy requests: Peticiones de compra +Agency route: Agencia ruta +Agency Agreement: Agencia acuerdo +Autonomous: Autónomo \ No newline at end of file diff --git a/modules/route/front/agency-term/preview.svg b/modules/route/front/agency-term/preview.svg new file mode 100644 index 000000000..5d56b5f34 --- /dev/null +++ b/modules/route/front/agency-term/preview.svg @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/modules/route/front/agency-term/style.scss b/modules/route/front/agency-term/style.scss new file mode 100644 index 000000000..eaa1a16ed --- /dev/null +++ b/modules/route/front/agency-term/style.scss @@ -0,0 +1,32 @@ +@import "variables"; + +vn-item-product { + display: block; + + .id { + background-color: $color-main; + color: $color-font-dark; + margin-bottom: 0; + } + .image { + height: 112px; + width: 112px; + + & > img { + max-height: 100%; + max-width: 100%; + border-radius: 3px; + } + } + vn-label-value:first-of-type section{ + margin-top: 9px; + } +} + +table { + img { + border-radius: 50%; + width: 50px; + height: 50px; + } +} \ No newline at end of file diff --git a/modules/route/front/index.js b/modules/route/front/index.js index 7c2a17483..206c97953 100644 --- a/modules/route/front/index.js +++ b/modules/route/front/index.js @@ -11,3 +11,4 @@ import './create'; import './basic-data'; import './log'; import './tickets'; +import './agency-term'; diff --git a/modules/route/front/routes.json b/modules/route/front/routes.json index beb444abc..307d0e941 100644 --- a/modules/route/front/routes.json +++ b/modules/route/front/routes.json @@ -6,7 +6,8 @@ "dependencies": ["client", "worker", "ticket"], "menus": { "main": [ - {"state": "route.index", "icon": "icon-delivery"} + {"state": "route.index", "icon": "icon-delivery"}, + {"state": "route.agencyTerm", "icon": "icon-delivery"} ], "card": [ {"state": "route.card.basicData", "icon": "settings"}, @@ -37,6 +38,12 @@ "state": "route.card", "abstract": true, "component": "vn-route-card" + }, { + "url" : "/agency-term?q", + "state": "route.agencyTerm", + "component": "vn-agency-term", + "description": "Autonomous", + "acl": ["administrative"] }, { "url": "/summary", "state": "route.card.summary", From ade34c1e0ab7ecb354140287263a3b92f20bd8d6 Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 2 Mar 2022 14:59:30 +0100 Subject: [PATCH 02/23] add section Autonomous --- db/changes/10420-valentines/00-aclAgency.sql | 2 + db/changes/10420-valentines/00-agencyTerm.sql | 10 ++ db/dump/fixtures.sql | 12 +- .../methods/agency-term/createInvoiceIn.js | 85 +++++++++++ .../route/back/methods/agency-term/filter.js | 141 +++++------------- modules/route/back/models/agency-term.js | 1 + .../agency-term/createInvoiceIn/index.html | 108 ++++++++++++++ .../agency-term/createInvoiceIn/index.js | 123 +++++++++++++++ .../agency-term/createInvoiceIn/index.spec.js | 74 +++++++++ .../agency-term/createInvoiceIn/style.scss | 7 + modules/route/front/agency-term/index.js | 121 --------------- .../front/agency-term/{ => index}/index.html | 54 +++---- .../route/front/agency-term/index/index.js | 127 ++++++++++++++++ .../agency-term/{ => index}/index.spec.js | 0 .../front/agency-term/{ => index}/style.scss | 0 modules/route/front/agency-term/preview.svg | 11 -- modules/route/front/index.js | 3 +- modules/route/front/routes.json | 22 ++- 18 files changed, 625 insertions(+), 276 deletions(-) create mode 100644 db/changes/10420-valentines/00-aclAgency.sql create mode 100644 db/changes/10420-valentines/00-agencyTerm.sql create mode 100644 modules/route/back/methods/agency-term/createInvoiceIn.js create mode 100644 modules/route/front/agency-term/createInvoiceIn/index.html create mode 100644 modules/route/front/agency-term/createInvoiceIn/index.js create mode 100644 modules/route/front/agency-term/createInvoiceIn/index.spec.js create mode 100644 modules/route/front/agency-term/createInvoiceIn/style.scss delete mode 100644 modules/route/front/agency-term/index.js rename modules/route/front/agency-term/{ => index}/index.html (81%) create mode 100644 modules/route/front/agency-term/index/index.js rename modules/route/front/agency-term/{ => index}/index.spec.js (100%) rename modules/route/front/agency-term/{ => index}/style.scss (100%) delete mode 100644 modules/route/front/agency-term/preview.svg diff --git a/db/changes/10420-valentines/00-aclAgency.sql b/db/changes/10420-valentines/00-aclAgency.sql new file mode 100644 index 000000000..2134285cb --- /dev/null +++ b/db/changes/10420-valentines/00-aclAgency.sql @@ -0,0 +1,2 @@ +INSERT INTO salix.ACL (id, model, property, accessType, permission, principalType, principalId) +VALUES(301, 'Agency', '*', 'READ', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/changes/10420-valentines/00-agencyTerm.sql b/db/changes/10420-valentines/00-agencyTerm.sql new file mode 100644 index 000000000..9822b160b --- /dev/null +++ b/db/changes/10420-valentines/00-agencyTerm.sql @@ -0,0 +1,10 @@ +CREATE TABLE `vn`.`agencyTermConfig` ( + `expenceFk` varchar(10) DEFAULT NULL, + `vatAccountSupported` varchar(15) DEFAULT NULL, + `vatPercentage` decimal(28,10) DEFAULT NULL, + `transaction` varchar(50) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `vn`.`agencyTermConfig` +(`expenceFk`, `vatAccountSupported`, `vatPercentage`, `transaction`) +VALUES('6240000000', '4721000015', 21.0000000000, 'Adquisiciones intracomunitarias de servicios'); \ No newline at end of file diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 35013b35b..52d267e00 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -167,9 +167,11 @@ INSERT INTO `vn`.`accountingType`(`id`, `description`, `receiptDescription`,`cod INSERT INTO `vn`.`bank`(`id`, `bank`, `account`, `cash`, `entityFk`, `isActive`, `currencyFk`) VALUES - (1, 'Pay on receipt', '5720000001', 3, 0, 1, 1), - (2, 'Cash', '5700000001', 2, 0, 1, 1), - (3, 'Compensation', '4000000000', 8, 0, 1, 1); + (1, 'Pay on receipt', '5720000001', 3, 0, 1, 1), + (2, 'Cash', '5700000001', 2, 0, 1, 1), + (3, 'Compensation', '4000000000', 8, 0, 1, 1), + (3117, 'Caixa Rural d''Algemesi', '5720000000', 8, 3117, 1, 1); + INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`) VALUES @@ -522,6 +524,8 @@ INSERT INTO `vn`.`expence`(`id`, `taxTypeFk`, `name`, `isWithheld`) (4751000000, 1, 'Retenciones', 1), (4751000000, 6, 'Retencion', 0), (6210000567, 0, 'Alquiler VNH', 0), + (6240000000, 1, 'Transportes de ventas rutas', 0), + (6240000000, 4, 'Transportes de ventas rutas', 0), (7001000000, 1, 'Mercaderia', 0), (7050000000, 1, 'Prestacion de servicios', 1); @@ -2465,4 +2469,4 @@ SET `invoiceInFk`=1 WHERE `id`=1; UPDATE `vn`.`route` SET `invoiceInFk`=2 -WHERE `id`=2; \ No newline at end of file +WHERE `id`=2; diff --git a/modules/route/back/methods/agency-term/createInvoiceIn.js b/modules/route/back/methods/agency-term/createInvoiceIn.js new file mode 100644 index 000000000..82e4437c0 --- /dev/null +++ b/modules/route/back/methods/agency-term/createInvoiceIn.js @@ -0,0 +1,85 @@ +module.exports = Self => { + Self.remoteMethod('createInvoiceIn', { + description: 'create a invoce in from a agency terms', + accessType: 'WRITE', + accepts: [{ + arg: 'rows', + type: ['object'], + required: true, + description: `the rows from which the invoice in will be created`, + }, + { + arg: 'dms', + type: ['object'], + required: true, + description: 'The dms files' + }], + returns: { + }, + http: { + path: `/createInvoiceIn`, + verb: 'POST' + } + }); + + Self.createInvoiceIn = async(rows, dms, options) => { + const models = Self.app.models; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const [firstRow] = rows; + const [firstDms] = dms; + + const [reference] = await Self.rawSql(`SELECT reference FROM vn.dms WHERE id = ?`, [firstDms.id]); + + const newInvoiceIn = await models.InvoiceIn.create({ + supplierFk: firstRow.supplierFk, + supplierRef: reference.value, + issued: firstRow.created, + booked: firstRow.created, + operated: firstRow.created, + bookEntried: firstRow.created, + gestdoc_id: firstDms.id + }); + + const [expence] = await Self.rawSql(`SELECT expenceFk value FROM vn.agencyTermConfig`); + + const [taxTypeSage] = await Self.rawSql(` + SELECT IFNULL(s.taxTypeSageFk, CodigoIva) value + FROM vn.supplier s + JOIN sage.TiposIva ti ON TRUE + JOIN vn.agencyTermConfig atg + WHERE s.id = ? + AND ti.CuentaIvaSoportado = atg.vatAccountSupported + AND ti.PorcentajeIva = atg.vatPercentage + `, [firstRow.supplierFk]); + + const [transactionTypeSage] = await Self.rawSql(` + SELECT IFNULL(s.transactionTypeSageFk, tt.CodigoTransaccion) value + FROM vn.supplier s + JOIN sage.TiposTransacciones tt ON TRUE + JOIN vn.agencyTermConfig atg + WHERE s.id = ? + AND tt.Transaccion = atg.transaction + `, [firstRow.supplierFk]); + + await models.InvoiceInTax.create({ + invoiceInFk: newInvoiceIn.id, + taxableBase: firstRow.totalPrice, + expenseFk: expence.value, + taxTypeSageFk: taxTypeSage.value, + transactionTypeSageFk: transactionTypeSage.value + }); + + await Self.rawSql(`CALL invoiceInDueDay_calculate(?)`, [newInvoiceIn.id]); + + for (let agencyTerm of rows) { + const route = await models.Route.findById(agencyTerm.routeFk); + await Self.rawSql(` + UPDATE vn.route SET invoiceInFk = ? WHERE id = ? + `, [newInvoiceIn.id, route.id]); + } + }; +}; diff --git a/modules/route/back/methods/agency-term/filter.js b/modules/route/back/methods/agency-term/filter.js index 94ed7fc91..0b6e2635a 100644 --- a/modules/route/back/methods/agency-term/filter.js +++ b/modules/route/back/methods/agency-term/filter.js @@ -1,7 +1,4 @@ - 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.remoteMethodCtx('filter', { @@ -13,54 +10,6 @@ module.exports = Self => { type: 'object', description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', http: {source: 'query'} - }, - { - arg: 'search', - type: 'string', - description: 'Searchs the route by id', - http: {source: 'query'} - }, - { - arg: 'agencyModeFk', - type: 'integer', - description: 'The agencyMode id', - http: {source: 'query'} - }, - { - arg: 'to', - type: 'date', - description: 'The to date filter', - http: {source: 'query'} - }, - { - arg: 'from', - type: 'date', - description: 'The to date filter', - http: {source: 'query'} - }, - { - arg: 'vehicleFk', - type: 'integer', - description: 'The vehicle id', - http: {source: 'query'} - }, - { - arg: 'm3', - type: 'number', - description: 'The m3 filter', - http: {source: 'query'} - }, - { - arg: 'warehouseFk', - type: 'number', - description: 'The warehouse filter', - http: {source: 'query'} - }, - { - arg: 'description', - type: 'string', - description: 'The description filter', - http: {source: 'query'} } ], returns: { @@ -73,70 +22,52 @@ module.exports = Self => { } }); - Self.filter = async(ctx, filter) => { - let conn = Self.dataSource.connector; - - let where = buildFilter(ctx.args, (param, value) => { - switch (param) { - case 'search': - return {'r.id': value}; - case 'from': - return {'r.created': {gte: value}}; - case 'to': - return {'r.created': {lte: value}}; - case 'm3': - return {'r.m3': value}; - case 'description': - return {'r.description': {like: `%${value}%`}}; - case 'warehouseFk': - param = `v.${param}`; - return {[param]: value}; - case 'vehicleFk': - case 'agencyModeFk': - param = `r.${param}`; - return {[param]: value}; - } - }); - - filter = mergeFilters(ctx.args.filter, {where}); + Self.filter = async(ctx, filter, options) => { + const conn = Self.dataSource.connector; let stmts = []; let stmt; - stmt = new ParameterizedSQL( - `SELECT - r.id routeFk, - r.created, - r.agencyModeFk, - am.name agencyModeName, - am.agencyFk, - a.name agencyAgreement, - SUM(t.packages) packages, - r.m3, - r.kmEnd - r.kmStart kmTotal, - CAST(IFNULL(ate.routePrice, - (ate.kmPrice * (GREATEST(r.kmEnd - r.kmStart , ate.minimumKm)) - + GREATEST(r.m3 , ate.minimumM3) * ate.m3Price) - + ate.packagePrice * SUM(t.packages) ) - AS DECIMAL(10,2)) price, - r.invoiceInFk, - a.supplierFk, - s.name supplierName - FROM vn.route r - LEFT JOIN vn.agencyMode am ON r.agencyModeFk = am.id - LEFT JOIN vn.agency a ON am.agencyFk = a.id - LEFT JOIN vn.ticket t ON t.routeFk = r.id - LEFT JOIN vn.agencyTerm ate ON ate.agencyFk = a.id - LEFT JOIN vn.supplier s ON s.id = a.supplierFk - WHERE r.created > DATE_ADD(CURDATE(), INTERVAL -2 MONTH) AND a.supplierFk IS NOT NULL - GROUP BY r.id;` + `SELECT * + FROM ( + SELECT r.id routeFk, + r.created, + r.agencyModeFk, + am.name agencyModeName, + am.agencyFk, + a.name agencyAgreement, + SUM(t.packages) packages, + r.m3, + r.kmEnd - r.kmStart kmTotal, + CAST(IFNULL(ate.routePrice, + (ate.kmPrice * (GREATEST(r.kmEnd - r.kmStart , ate.minimumKm)) + + GREATEST(r.m3 , ate.minimumM3) * ate.m3Price) + + ate.packagePrice * SUM(t.packages) ) + AS DECIMAL(10,2)) price, + r.invoiceInFk, + a.supplierFk, + s.name supplierName + FROM vn.route r + LEFT JOIN vn.agencyMode am ON r.agencyModeFk = am.id + LEFT JOIN vn.agency a ON am.agencyFk = a.id + LEFT JOIN vn.ticket t ON t.routeFk = r.id + LEFT JOIN vn.agencyTerm ate ON ate.agencyFk = a.id + LEFT JOIN vn.supplier s ON s.id = a.supplierFk + WHERE r.created > DATE_ADD(CURDATE(), INTERVAL -2 MONTH) AND a.supplierFk IS NOT NULL + GROUP BY r.id + ) a` ); stmt.merge(conn.makeSuffix(filter)); - let agencyTerm = stmts.push(stmt) - 1; + let agencyTerm = stmts.push(stmt) - 1; let sql = ParameterizedSQL.join(stmts, ';'); let result = await conn.executeStmt(sql); + + const models = Self.app.models; + for (let agencyTerm of result) + agencyTerm.route = await models.Route.findById(agencyTerm.routeFk); + return agencyTerm === 0 ? result : result[agencyTerm]; }; }; diff --git a/modules/route/back/models/agency-term.js b/modules/route/back/models/agency-term.js index 14fe76d28..8a0eea655 100644 --- a/modules/route/back/models/agency-term.js +++ b/modules/route/back/models/agency-term.js @@ -1,3 +1,4 @@ module.exports = Self => { require('../methods/agency-term/filter')(Self); + require('../methods/agency-term/createInvoiceIn')(Self); }; diff --git a/modules/route/front/agency-term/createInvoiceIn/index.html b/modules/route/front/agency-term/createInvoiceIn/index.html new file mode 100644 index 000000000..8f270378f --- /dev/null +++ b/modules/route/front/agency-term/createInvoiceIn/index.html @@ -0,0 +1,108 @@ + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/modules/route/front/agency-term/createInvoiceIn/index.js b/modules/route/front/agency-term/createInvoiceIn/index.js new file mode 100644 index 000000000..3f3703a6c --- /dev/null +++ b/modules/route/front/agency-term/createInvoiceIn/index.js @@ -0,0 +1,123 @@ +import ngModule from '../../module'; +import Section from 'salix/components/section'; +import './style.scss'; + +class Controller extends Section { + constructor($element, $) { + super($element, $); + this.dms = { + files: [], + hasFile: false, + hasFileAttached: false + }; + this.addedDms; + } + + get route() { + return this._route; + } + + set route(value) { + this._route = value; + + this.setDefaultParams(); + this.getAllowedContentTypes(); + } + + $onChanges() { + if (this.$params && this.$params.q) + this.params = JSON.parse(this.$params.q); + } + + getAllowedContentTypes() { + this.$http.get('DmsContainers/allowedContentTypes').then(res => { + const contentTypes = res.data.join(', '); + this.allowedContentTypes = contentTypes; + }); + } + + get contentTypesInfo() { + return this.$t('ContentTypesInfo', { + allowedContentTypes: this.allowedContentTypes + }); + } + + setDefaultParams() { + const params = {filter: { + where: {code: 'invoiceIn'} + }}; + this.$http.get('DmsTypes/findOne', {params}).then(res => { + const dmsType = res.data && res.data; + const companyId = this.vnConfig.companyFk; + const warehouseId = this.vnConfig.warehouseFk; + const defaultParams = { + warehouseId: warehouseId, + companyId: companyId, + dmsTypeId: dmsType.id, + description: this.params.supplierName + }; + + this.dms = Object.assign(this.dms, defaultParams); + }); + } + + onSubmit() { + const query = `dms/uploadFile`; + const options = { + method: 'POST', + url: query, + params: this.dms, + headers: { + 'Content-Type': undefined + }, + transformRequest: files => { + const formData = new FormData(); + + for (let i = 0; i < files.length; i++) + formData.append(files[i].name, files[i]); + + return formData; + }, + data: this.dms.files + }; + this.$http(options).then(res => { + if (res) { + let addedDms = res.data; + this.vnApp.showSuccess(this.$t('Data saved!')); + this.$.watcher.updateOriginalData(); + + const params = { + rows: this.params.rows, + dms: addedDms + }; + + this.$http.post('AgencyTerms/createInvoiceIn', params) + .then(() => { + this.$state.go('route.agencyTerm.index'); + this.vnApp.showSuccess(this.$t('InvoiceIn created')); + }); + } + }); + } + + onFileChange(files) { + let hasFileAttached = false; + + if (files.length > 0) + hasFileAttached = true; + + this.$.$applyAsync(() => { + this.dms.hasFileAttached = hasFileAttached; + }); + } +} + +Controller.$inject = ['$element', '$scope']; + +ngModule.vnComponent('vnAgencyTermCreateInvoiceIn', { + template: require('./index.html'), + controller: Controller, + bindings: { + route: '<' + } +}); diff --git a/modules/route/front/agency-term/createInvoiceIn/index.spec.js b/modules/route/front/agency-term/createInvoiceIn/index.spec.js new file mode 100644 index 000000000..fe302f7d2 --- /dev/null +++ b/modules/route/front/agency-term/createInvoiceIn/index.spec.js @@ -0,0 +1,74 @@ +import './index'; + +describe('Client', () => { + describe('Component vnClientDmsCreate', () => { + let controller; + let $scope; + let $httpBackend; + let $httpParamSerializer; + + beforeEach(ngModule('client')); + + beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => { + $scope = $rootScope.$new(); + $httpBackend = _$httpBackend_; + $httpParamSerializer = _$httpParamSerializer_; + const $element = angular.element(''); + controller = $componentController('vnClientDmsCreate', {$element, $scope}); + controller._client = {id: 1101, name: 'Bruce wayne'}; + })); + + describe('client() setter', () => { + it('should set the client data and then call setDefaultParams() and getAllowedContentTypes()', () => { + jest.spyOn(controller, 'setDefaultParams'); + jest.spyOn(controller, 'getAllowedContentTypes'); + controller.client = { + id: 15, + name: 'Bruce wayne' + }; + + expect(controller.client).toBeDefined(); + expect(controller.setDefaultParams).toHaveBeenCalledWith(); + expect(controller.getAllowedContentTypes).toHaveBeenCalledWith(); + }); + }); + + describe('setDefaultParams()', () => { + it('should perform a GET query and define the dms property on controller', () => { + const params = {filter: { + where: {code: 'paymentsLaw'} + }}; + let serializedParams = $httpParamSerializer(params); + $httpBackend.expect('GET', `DmsTypes/findOne?${serializedParams}`).respond({id: 12, code: 'paymentsLaw'}); + controller.setDefaultParams(); + $httpBackend.flush(); + + expect(controller.dms).toBeDefined(); + expect(controller.dms.reference).toEqual(1101); + expect(controller.dms.dmsTypeId).toEqual(12); + }); + }); + + describe('onFileChange()', () => { + it('should set dms hasFileAttached property to true if has any files', () => { + const files = [{id: 1, name: 'MyFile'}]; + controller.onFileChange(files); + $scope.$apply(); + + expect(controller.dms.hasFileAttached).toBeTruthy(); + }); + }); + + describe('getAllowedContentTypes()', () => { + it('should make an HTTP GET request to get the allowed content types', () => { + const expectedResponse = ['image/png', 'image/jpg']; + $httpBackend.expect('GET', `DmsContainers/allowedContentTypes`).respond(expectedResponse); + controller.getAllowedContentTypes(); + $httpBackend.flush(); + + expect(controller.allowedContentTypes).toBeDefined(); + expect(controller.allowedContentTypes).toEqual('image/png, image/jpg'); + }); + }); + }); +}); diff --git a/modules/route/front/agency-term/createInvoiceIn/style.scss b/modules/route/front/agency-term/createInvoiceIn/style.scss new file mode 100644 index 000000000..73f136fc1 --- /dev/null +++ b/modules/route/front/agency-term/createInvoiceIn/style.scss @@ -0,0 +1,7 @@ +vn-ticket-request { + .vn-textfield { + margin: 0!important; + max-width: 100px; + } +} + diff --git a/modules/route/front/agency-term/index.js b/modules/route/front/agency-term/index.js deleted file mode 100644 index 4f80ffc60..000000000 --- a/modules/route/front/agency-term/index.js +++ /dev/null @@ -1,121 +0,0 @@ -import ngModule from '../module'; -import Section from 'salix/components/section'; -import './style.scss'; - -class Controller extends Section { - constructor($element, $) { - super($element, $); - - this.smartTableOptions = { - activeButtons: { - search: false, - shownColumns: false, - }, - columns: [ - { - field: 'agencyFk', - autocomplete: { - url: 'ItemCategories', - valueField: 'name', - } - }, - { - field: 'origin', - autocomplete: { - url: 'Origins', - showField: 'code', - valueField: 'code' - } - }, - { - field: 'typeFk', - autocomplete: { - url: 'ItemTypes', - } - }, - { - field: 'intrastat', - autocomplete: { - url: 'Intrastats', - showField: 'description', - valueField: 'description' - } - }, - { - field: 'buyerFk', - autocomplete: { - url: 'Workers/activeWithRole', - where: `{role: {inq: ['logistic', 'buyer']}}`, - searchFunction: '{firstName: $search}', - showField: 'nickname', - valueField: 'id', - } - }, - { - field: 'active', - searchable: false - }, - { - field: 'landed', - searchable: false - }, - ] - }; - } - - exprBuilder(param, value) { - switch (param) { - case 'category': - return {'ic.name': value}; - case 'buyerFk': - return {'it.workerFk': value}; - case 'grouping': - return {'b.grouping': value}; - case 'packing': - return {'b.packing': value}; - case 'origin': - return {'ori.code': value}; - case 'typeFk': - return {'i.typeFk': value}; - case 'intrastat': - return {'intr.description': value}; - case 'name': - return {'i.name': {like: `%${value}%`}}; - case 'producer': - return {'pr.name': {like: `%${value}%`}}; - case 'id': - case 'size': - case 'subname': - case 'isActive': - case 'density': - case 'stemMultiplier': - case 'stems': - return {[`i.${param}`]: value}; - } - } - - get checked() { - const routes = this.$.model.data || []; - const checkedRoutes = []; - for (let route of routes) { - if (route.checked) - checkedRoutes.push(route); - } - - return checkedRoutes; - } - - get totalChecked() { - return this.checked.length; - } - - preview(route) { - this.routeSelected = route; - this.$.summary.show(); - } -} - -ngModule.vnComponent('vnAgencyTerm', { - template: require('./index.html'), - controller: Controller -}); diff --git a/modules/route/front/agency-term/index.html b/modules/route/front/agency-term/index/index.html similarity index 81% rename from modules/route/front/agency-term/index.html rename to modules/route/front/agency-term/index/index.html index 6ccd0cb56..bb18af250 100644 --- a/modules/route/front/agency-term/index.html +++ b/modules/route/front/agency-term/index/index.html @@ -10,6 +10,17 @@ model="model" options="$ctrl.smartTableOptions" expr-builder="$ctrl.exprBuilder(param, value)"> + +
+
+
Total
+ + +
+
+
@@ -19,7 +30,7 @@ model="model"> -
+ Id @@ -82,7 +93,6 @@ {{::agencyTerm.invoiceInFk}} - @@ -120,30 +130,14 @@ vn-id="invoiceInDescriptor"> - - - - Filter by selection - - - Exclude selection - - - Remove filter - - - Remove all filters - - - \ No newline at end of file +
+ + + + +
diff --git a/modules/route/front/agency-term/index/index.js b/modules/route/front/agency-term/index/index.js new file mode 100644 index 000000000..c1089e1a7 --- /dev/null +++ b/modules/route/front/agency-term/index/index.js @@ -0,0 +1,127 @@ +import ngModule from '../../module'; +import Section from 'salix/components/section'; +import './style.scss'; + +class Controller extends Section { + constructor($element, $) { + super($element, $); + + this.smartTableOptions = { + activeButtons: { + search: true + }, + columns: [ + { + field: 'agencyFk', + autocomplete: { + url: 'AgencyModes', + showField: 'name', + valueField: 'name' + } + }, + { + field: 'agencyAgreement', + autocomplete: { + url: 'Agencies', + showField: 'name', + valueField: 'name' + } + }, + { + field: 'supplierFk', + autocomplete: { + url: 'Suppliers', + showField: 'name', + valueField: 'name', + } + } + ] + }; + } + + exprBuilder(param, value) { + switch (param) { + case 'routeFk': + return {'a.routeFk': value}; + case 'created': + return {'a.created': value}; + case 'agencyFk': + return {'a.agencyModeName': value}; + case 'agencyAgreement': + return {'a.agencyAgreement': value}; + case 'packages': + return {'a.packages': value}; + case 'm3': + return {'a.m3': value}; + case 'kmTotal': + return {'a.kmTotal': value}; + case 'price': + return {'a.price': value}; + case 'invoiceInFk': + return {'a.invoiceInFk': value}; + case 'supplierFk': + return {'a.supplierName': value}; + } + } + + get checked() { + const agencyTerms = this.$.model.data || []; + const checkedAgencyTerms = []; + for (let agencyTerm of agencyTerms) { + if (agencyTerm.checked) + checkedAgencyTerms.push(agencyTerm); + } + + return checkedAgencyTerms; + } + + get totalChecked() { + return this.checked.length; + } + + get totalPrice() { + let totalPrice = 0; + + if (this.checked.length > 0) { + for (let agencyTerm of this.checked) + totalPrice += agencyTerm.price; + + return totalPrice; + } + + return totalPrice; + } + + preview(route) { + this.routeSelected = route; + this.$.summary.show(); + } + + createInvoiceIn() { + const rowsToCreateInvoiceIn = []; + const supplier = this.checked[0].supplierFk; + + for (let agencyTerm of this.checked) { + if (supplier == agencyTerm.supplierFk) { + rowsToCreateInvoiceIn.push({ + routeFk: agencyTerm.routeFk, + supplierFk: agencyTerm.supplierFk, + created: agencyTerm.created, + totalPrice: this.totalPrice}); + } else { + this.vnApp.showError(this.$t('Two autonomous cannot be counted at the same time')); + return false; + } + } + const params = JSON.stringify({ + supplierName: this.checked[0].supplierName, + rows: rowsToCreateInvoiceIn + }); + this.$state.go('route.agencyTerm.createInvoiceIn', {q: params}); + } +} + +ngModule.vnComponent('vnAgencyTermIndex', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/route/front/agency-term/index.spec.js b/modules/route/front/agency-term/index/index.spec.js similarity index 100% rename from modules/route/front/agency-term/index.spec.js rename to modules/route/front/agency-term/index/index.spec.js diff --git a/modules/route/front/agency-term/style.scss b/modules/route/front/agency-term/index/style.scss similarity index 100% rename from modules/route/front/agency-term/style.scss rename to modules/route/front/agency-term/index/style.scss diff --git a/modules/route/front/agency-term/preview.svg b/modules/route/front/agency-term/preview.svg deleted file mode 100644 index 5d56b5f34..000000000 --- a/modules/route/front/agency-term/preview.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - diff --git a/modules/route/front/index.js b/modules/route/front/index.js index 206c97953..6a6518a43 100644 --- a/modules/route/front/index.js +++ b/modules/route/front/index.js @@ -11,4 +11,5 @@ import './create'; import './basic-data'; import './log'; import './tickets'; -import './agency-term'; +import './agency-term/index'; +import './agency-term/createInvoiceIn'; diff --git a/modules/route/front/routes.json b/modules/route/front/routes.json index 307d0e941..1e7d94765 100644 --- a/modules/route/front/routes.json +++ b/modules/route/front/routes.json @@ -3,11 +3,11 @@ "name": "Routes", "icon": "icon-delivery", "validations" : true, - "dependencies": ["client", "worker", "ticket"], + "dependencies": ["client", "worker", "ticket", "supplier", "invoiceIn"], "menus": { "main": [ {"state": "route.index", "icon": "icon-delivery"}, - {"state": "route.agencyTerm", "icon": "icon-delivery"} + {"state": "route.agencyTerm.index", "icon": "icon-delivery"} ], "card": [ {"state": "route.card.basicData", "icon": "settings"}, @@ -39,11 +39,25 @@ "abstract": true, "component": "vn-route-card" }, { - "url" : "/agency-term?q", + "url": "/agency-term", + "abstract": true, "state": "route.agencyTerm", - "component": "vn-agency-term", + "component": "ui-view" + }, { + "url": "/index", + "state": "route.agencyTerm.index", + "component": "vn-agency-term-index", "description": "Autonomous", "acl": ["administrative"] + },{ + "url": "/createInvoiceIn?q", + "state": "route.agencyTerm.createInvoiceIn", + "component": "vn-agency-term-create-invoice-in", + "description": "Create invoiceIn", + "params": { + "route": "$ctrl.route" + }, + "acl": ["administrative"] }, { "url": "/summary", "state": "route.card.summary", From 2f87ac8c96378e89ae0844268f1dbe6d01962db2 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 3 Mar 2022 14:42:12 +0100 Subject: [PATCH 03/23] add test --- .../methods/agency-term/createInvoiceIn.js | 4 +- .../agency-term/specs/createInvoiceIn.spec.js | 61 ++++++++++ .../methods/agency-term/specs/filter.spec.js | 26 +++++ .../agency-term/createInvoiceIn/index.js | 4 +- .../agency-term/createInvoiceIn/index.spec.js | 109 ++++++++++++------ .../route/front/agency-term/index/index.js | 5 +- .../front/agency-term/index/index.spec.js | 96 ++++++++++++--- modules/route/front/agency-term/locale/es.yml | 3 +- modules/route/front/routes.json | 2 +- 9 files changed, 247 insertions(+), 63 deletions(-) create mode 100644 modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js create mode 100644 modules/route/back/methods/agency-term/specs/filter.spec.js diff --git a/modules/route/back/methods/agency-term/createInvoiceIn.js b/modules/route/back/methods/agency-term/createInvoiceIn.js index 82e4437c0..c686f3ad1 100644 --- a/modules/route/back/methods/agency-term/createInvoiceIn.js +++ b/modules/route/back/methods/agency-term/createInvoiceIn.js @@ -1,6 +1,6 @@ module.exports = Self => { Self.remoteMethod('createInvoiceIn', { - description: 'create a invoce in from a agency terms', + description: 'create a invoce in from one or more agency terms', accessType: 'WRITE', accepts: [{ arg: 'rows', @@ -12,7 +12,7 @@ module.exports = Self => { arg: 'dms', type: ['object'], required: true, - description: 'The dms files' + description: 'the dms file' }], returns: { }, diff --git a/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js b/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js new file mode 100644 index 000000000..40a2e7b07 --- /dev/null +++ b/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js @@ -0,0 +1,61 @@ +const models = require('vn-loopback/server/server').models; + +describe('AgencyTerm createInvoiceIn()', () => { + const rows = [ + { + routeFk: 2, + supplierFk: 1, + created: '2022-03-02T23:00:00.000Z', + totalPrice: 165 + } + ]; + const dms = [ + { + id: 7, + file: '7.pdf', + contentType: 'application/pdf', + reference: '1', + description: 'Plants SL', + hasFile: false, + companyFk: 442, + dmsTypeFk: 1, + warehouseFk: 1, + workerFk: 9 + } + ]; + const userId = 1; + const activeCtx = { + accessToken: {userId: userId}, + }; + const ctx = {req: activeCtx}; + + it('should make a global invoicing', async() => { + const tx = await models.AgencyTerm.beginTransaction({}); + const options = {transaction: tx}; + + try { + const invoiceInId = 10; + const invoiceInDueDayId = 11; + const invoiceInTaxId = 12; + + const oldInvoiceIn = await models.AgencyTerm.findById(invoiceInId, null, options); + const oldInvoiceInDueDay = await models.AgencyTerm.findById(invoiceInDueDayId, null, options); + const oldInvoiceInTax = await models.AgencyTerm.findById(invoiceInTaxId, null, options); + + const [newInvoiceIn] = await models.Ticket.rawSql('SELECT MAX(id) id FROM invoiceIn', null, options); + // const [newInvoiceInDueDay] = await models.AgencyTerm.rawSql('SELECT MAX(id) id FROM invoiceInDueDay', null, options); + // const [newInvoiceInTax] = await models.AgencyTerm.rawSql('SELECT MAX(id) id FROM invoiceInTax', null, options); + + await models.AgencyTerm.createInvoiceIn(rows, dms, options); + + // expect(newInvoiceIn.id).toEqual(oldInvoiceIn.id + 1); + // expect(newInvoiceInDueDay.id).toEqual(oldInvoiceInDueDay.id + 1); + // expect(newInvoiceInTax.id).toEqual(oldInvoiceInTax.id + 1); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/route/back/methods/agency-term/specs/filter.spec.js b/modules/route/back/methods/agency-term/specs/filter.spec.js new file mode 100644 index 000000000..23671cef3 --- /dev/null +++ b/modules/route/back/methods/agency-term/specs/filter.spec.js @@ -0,0 +1,26 @@ +const models = require('vn-loopback/server/server').models; + +xdescribe('AgencyTerm filter()', () => { + const authUserId = 9; + + it('should all return the tickets matching the filter', async() => { + const tx = await models.AgencyTerm.beginTransaction({}); + + try { + const options = {transaction: tx}; + const filter = {}; + const ctx = {req: {accessToken: {userId: authUserId}}, args: {filter: filter}}; + + const agencyTerms = await models.AgencyTerm.filter(ctx, null, options); + const firstAgencyTerm = agencyTerms[0]; + + expect(firstAgencyTerm.routeFk).toEqual(1); + expect(agencyTerms.length).toEqual(3); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/route/front/agency-term/createInvoiceIn/index.js b/modules/route/front/agency-term/createInvoiceIn/index.js index 3f3703a6c..9bfa30d51 100644 --- a/modules/route/front/agency-term/createInvoiceIn/index.js +++ b/modules/route/front/agency-term/createInvoiceIn/index.js @@ -10,7 +10,6 @@ class Controller extends Section { hasFile: false, hasFileAttached: false }; - this.addedDms; } get route() { @@ -83,7 +82,6 @@ class Controller extends Section { this.$http(options).then(res => { if (res) { let addedDms = res.data; - this.vnApp.showSuccess(this.$t('Data saved!')); this.$.watcher.updateOriginalData(); const params = { @@ -94,7 +92,7 @@ class Controller extends Section { this.$http.post('AgencyTerms/createInvoiceIn', params) .then(() => { this.$state.go('route.agencyTerm.index'); - this.vnApp.showSuccess(this.$t('InvoiceIn created')); + this.vnApp.showSuccess(this.$t('Data saved!')); }); } }); diff --git a/modules/route/front/agency-term/createInvoiceIn/index.spec.js b/modules/route/front/agency-term/createInvoiceIn/index.spec.js index fe302f7d2..1c64eee93 100644 --- a/modules/route/front/agency-term/createInvoiceIn/index.spec.js +++ b/modules/route/front/agency-term/createInvoiceIn/index.spec.js @@ -1,64 +1,53 @@ import './index'; +import watcher from 'core/mocks/watcher.js'; -describe('Client', () => { - describe('Component vnClientDmsCreate', () => { +describe('AgencyTerm', () => { + describe('Component vnAgencyTermCreateInvoiceIn', () => { let controller; let $scope; let $httpBackend; let $httpParamSerializer; - beforeEach(ngModule('client')); + beforeEach(ngModule('route')); beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => { $scope = $rootScope.$new(); $httpBackend = _$httpBackend_; $httpParamSerializer = _$httpParamSerializer_; - const $element = angular.element(''); - controller = $componentController('vnClientDmsCreate', {$element, $scope}); - controller._client = {id: 1101, name: 'Bruce wayne'}; + const $element = angular.element(''); + controller = $componentController('vnAgencyTermCreateInvoiceIn', {$element}); + controller._route = { + id: 1 + }; })); - describe('client() setter', () => { - it('should set the client data and then call setDefaultParams() and getAllowedContentTypes()', () => { + describe('$onChanges()', () => { + it('should update the params data when $params.q is defined', () => { + controller.$params = {q: '{"supplierName": "Plants SL","rows": null}'}; + + const params = {q: '{"supplierName": "Plants SL", "rows": null}'}; + const json = JSON.parse(params.q); + + controller.$onChanges(); + + expect(controller.params).toEqual(json); + }); + }); + + describe('route() setter', () => { + it('should set the ticket data and then call setDefaultParams() and getAllowedContentTypes()', () => { jest.spyOn(controller, 'setDefaultParams'); jest.spyOn(controller, 'getAllowedContentTypes'); - controller.client = { - id: 15, - name: 'Bruce wayne' + controller.route = { + id: 1 }; - expect(controller.client).toBeDefined(); + expect(controller.route).toBeDefined(); expect(controller.setDefaultParams).toHaveBeenCalledWith(); expect(controller.getAllowedContentTypes).toHaveBeenCalledWith(); }); }); - describe('setDefaultParams()', () => { - it('should perform a GET query and define the dms property on controller', () => { - const params = {filter: { - where: {code: 'paymentsLaw'} - }}; - let serializedParams = $httpParamSerializer(params); - $httpBackend.expect('GET', `DmsTypes/findOne?${serializedParams}`).respond({id: 12, code: 'paymentsLaw'}); - controller.setDefaultParams(); - $httpBackend.flush(); - - expect(controller.dms).toBeDefined(); - expect(controller.dms.reference).toEqual(1101); - expect(controller.dms.dmsTypeId).toEqual(12); - }); - }); - - describe('onFileChange()', () => { - it('should set dms hasFileAttached property to true if has any files', () => { - const files = [{id: 1, name: 'MyFile'}]; - controller.onFileChange(files); - $scope.$apply(); - - expect(controller.dms.hasFileAttached).toBeTruthy(); - }); - }); - describe('getAllowedContentTypes()', () => { it('should make an HTTP GET request to get the allowed content types', () => { const expectedResponse = ['image/png', 'image/jpg']; @@ -70,5 +59,49 @@ describe('Client', () => { expect(controller.allowedContentTypes).toEqual('image/png, image/jpg'); }); }); + + describe('setDefaultParams()', () => { + it('should perform a GET query and define the dms property on controller', () => { + const params2 = {filter: { + where: {code: 'invoiceIn'} + }}; + let serializedParams = $httpParamSerializer(params2); + $httpBackend.expect('GET', `DmsTypes/findOne?${serializedParams}`).respond({id: 1, code: 'invoiceIn'}); + controller.params = {supplierName: 'Plants SL'}; + controller.setDefaultParams(); + $httpBackend.flush(); + + expect(controller.dms).toBeDefined(); + expect(controller.dms.dmsTypeId).toEqual(1); + }); + }); + + describe('onSubmit()', () => { + it('should make an HTTP POST request to save the form data', () => { + controller.$.watcher = watcher; + + jest.spyOn(controller.$.watcher, 'updateOriginalData'); + const files = [{id: 1, name: 'MyFile'}]; + controller.dms = {files}; + const serializedParams = $httpParamSerializer(controller.dms); + const query = `dms/uploadFile?${serializedParams}`; + controller.params = {rows: null}; + + $httpBackend.expect('POST', query).respond({}); + $httpBackend.expect('POST', 'AgencyTerms/createInvoiceIn').respond({}); + controller.onSubmit(); + $httpBackend.flush(); + }); + }); + + describe('onFileChange()', () => { + it('should set dms hasFileAttached property to true if has any files', () => { + const files = [{id: 1, name: 'MyFile'}]; + controller.onFileChange(files); + $scope.$apply(); + + expect(controller.dms.hasFileAttached).toBeTruthy(); + }); + }); }); }); diff --git a/modules/route/front/agency-term/index/index.js b/modules/route/front/agency-term/index/index.js index c1089e1a7..89d71134b 100644 --- a/modules/route/front/agency-term/index/index.js +++ b/modules/route/front/agency-term/index/index.js @@ -99,10 +99,11 @@ class Controller extends Section { createInvoiceIn() { const rowsToCreateInvoiceIn = []; - const supplier = this.checked[0].supplierFk; + const supplierFk = this.checked[0].supplierFk; for (let agencyTerm of this.checked) { - if (supplier == agencyTerm.supplierFk) { + let hasSameSupplier = supplierFk == agencyTerm.supplierFk; + if (hasSameSupplier) { rowsToCreateInvoiceIn.push({ routeFk: agencyTerm.routeFk, supplierFk: agencyTerm.supplierFk, diff --git a/modules/route/front/agency-term/index/index.spec.js b/modules/route/front/agency-term/index/index.spec.js index 18abde581..18a49284a 100644 --- a/modules/route/front/agency-term/index/index.spec.js +++ b/modules/route/front/agency-term/index/index.spec.js @@ -1,29 +1,93 @@ import './index.js'; +import crudModel from 'core/mocks/crud-model'; -describe('Item', () => { - describe('Component vnItemIndex', () => { +describe('AgencyTerm', () => { + describe('Component vnAgencyTermIndex', () => { let controller; - let $httpBackend; - let $scope; + let $window; - beforeEach(ngModule('item')); + beforeEach(ngModule('route')); - beforeEach(inject(($componentController, _$httpBackend_, $rootScope) => { - $httpBackend = _$httpBackend_; - $scope = $rootScope.$new(); - const $element = angular.element(''); - controller = $componentController('vnItemIndex', {$element, $scope}); + beforeEach(inject(($componentController, _$window_) => { + $window = _$window_; + const $element = angular.element(''); + controller = $componentController('vnAgencyTermIndex', {$element}); + controller.$.model = crudModel; + controller.$.model.data = [ + {supplierFk: 1, totalPrice: null}, + {supplierFk: 1}, + {supplierFk: 2} + ]; })); - describe('onCloneAccept()', () => { - it('should perform a post query and then call go() then update itemSelected in the controller', () => { + describe('checked() getter', () => { + it('should return the checked lines', () => { + const data = controller.$.model.data; + data[0].checked = true; + + const checkedRows = controller.checked; + + const firstCheckedRow = checkedRows[0]; + + expect(firstCheckedRow.supplierFk).toEqual(1); + }); + }); + + describe('totalCheked() getter', () => { + it('should return the total checked lines', () => { + const data = controller.$.model.data; + data[0].checked = true; + + const checkedRows = controller.totalChecked; + + expect(checkedRows).toEqual(1); + }); + }); + + describe('preview()', () => { + it('should show the dialog summary', () => { + controller.$.summary = {show: () => {}}; + jest.spyOn(controller.$.summary, 'show'); + + let event = new MouseEvent('click', { + view: $window, + bubbles: true, + cancelable: true + }); + const route = {id: 1}; + + controller.preview(event, route); + + expect(controller.$.summary.show).toHaveBeenCalledWith(); + }); + }); + + describe('createInvoiceIn()', () => { + it('should throw an error if are checked more than one autonomous', () => { + jest.spyOn(controller.vnApp, 'showError'); + const data = controller.$.model.data; + data[0].checked = true; + data[2].checked = true; + + controller.createInvoiceIn(); + + expect(controller.vnApp.showError).toHaveBeenCalled(); + }); + + it('should call the function go() on $state to go to the file managment', () => { jest.spyOn(controller.$state, 'go'); + const data = controller.$.model.data; + data[0].checked = true; - $httpBackend.expectRoute('POST', `Items/:id/clone`).respond({id: 99}); - controller.onCloneAccept(1); - $httpBackend.flush(); + controller.createInvoiceIn(); - expect(controller.$state.go).toHaveBeenCalledWith('item.card.tags', {id: 99}); + delete data[0].checked; + const params = JSON.stringify({ + supplierName: data[0].supplierName, + rows: [data[0]] + }); + + expect(controller.$state.go).toHaveBeenCalledWith('route.agencyTerm.createInvoiceIn', {q: params}); }); }); }); diff --git a/modules/route/front/agency-term/locale/es.yml b/modules/route/front/agency-term/locale/es.yml index 0e766f5aa..98301ea6e 100644 --- a/modules/route/front/agency-term/locale/es.yml +++ b/modules/route/front/agency-term/locale/es.yml @@ -2,4 +2,5 @@ picture: Foto Buy requests: Peticiones de compra Agency route: Agencia ruta Agency Agreement: Agencia acuerdo -Autonomous: Autónomo \ No newline at end of file +Autonomous: Autónomos +Two autonomous cannot be counted at the same time: Dos autonónomos no pueden ser contabilizados al mismo tiempo \ No newline at end of file diff --git a/modules/route/front/routes.json b/modules/route/front/routes.json index 1e7d94765..7e0273441 100644 --- a/modules/route/front/routes.json +++ b/modules/route/front/routes.json @@ -53,7 +53,7 @@ "url": "/createInvoiceIn?q", "state": "route.agencyTerm.createInvoiceIn", "component": "vn-agency-term-create-invoice-in", - "description": "Create invoiceIn", + "description": "File management", "params": { "route": "$ctrl.route" }, From 02aeb84c0cbd727883d2eb2aa216b31d46d13142 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 3 Mar 2022 14:42:29 +0100 Subject: [PATCH 04/23] jgallego change --- modules/entry/front/basic-data/index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/entry/front/basic-data/index.html b/modules/entry/front/basic-data/index.html index f75834045..a05630dd6 100644 --- a/modules/entry/front/basic-data/index.html +++ b/modules/entry/front/basic-data/index.html @@ -79,7 +79,6 @@ Date: Fri, 4 Mar 2022 11:28:26 +0100 Subject: [PATCH 05/23] feat: check cannot attach more than one pdf --- modules/route/back/methods/agency-term/filter.js | 7 ++++++- modules/route/front/agency-term/createInvoiceIn/index.js | 4 +++- modules/route/front/agency-term/locale/es.yml | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/modules/route/back/methods/agency-term/filter.js b/modules/route/back/methods/agency-term/filter.js index 0b6e2635a..48a85e629 100644 --- a/modules/route/back/methods/agency-term/filter.js +++ b/modules/route/back/methods/agency-term/filter.js @@ -1,4 +1,5 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; +const mergeFilters = require('vn-loopback/util/filter').mergeFilters; module.exports = Self => { Self.remoteMethodCtx('filter', { @@ -24,6 +25,10 @@ module.exports = Self => { Self.filter = async(ctx, filter, options) => { const conn = Self.dataSource.connector; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); let stmts = []; let stmt; @@ -62,7 +67,7 @@ module.exports = Self => { let agencyTerm = stmts.push(stmt) - 1; let sql = ParameterizedSQL.join(stmts, ';'); - let result = await conn.executeStmt(sql); + let result = await conn.executeStmt(sql, myOptions); const models = Self.app.models; for (let agencyTerm of result) diff --git a/modules/route/front/agency-term/createInvoiceIn/index.js b/modules/route/front/agency-term/createInvoiceIn/index.js index 9bfa30d51..7ab8adbfa 100644 --- a/modules/route/front/agency-term/createInvoiceIn/index.js +++ b/modules/route/front/agency-term/createInvoiceIn/index.js @@ -1,6 +1,7 @@ import ngModule from '../../module'; import Section from 'salix/components/section'; import './style.scss'; +import UserError from 'core/lib/user-error'; class Controller extends Section { constructor($element, $) { @@ -81,7 +82,8 @@ class Controller extends Section { }; this.$http(options).then(res => { if (res) { - let addedDms = res.data; + const addedDms = res.data; + if (addedDms.length > 1) throw new UserError('You cannot attach more than one document'); this.$.watcher.updateOriginalData(); const params = { diff --git a/modules/route/front/agency-term/locale/es.yml b/modules/route/front/agency-term/locale/es.yml index 98301ea6e..1ba1d9ef5 100644 --- a/modules/route/front/agency-term/locale/es.yml +++ b/modules/route/front/agency-term/locale/es.yml @@ -3,4 +3,5 @@ Buy requests: Peticiones de compra Agency route: Agencia ruta Agency Agreement: Agencia acuerdo Autonomous: Autónomos -Two autonomous cannot be counted at the same time: Dos autonónomos no pueden ser contabilizados al mismo tiempo \ No newline at end of file +Two autonomous cannot be counted at the same time: Dos autonónomos no pueden ser contabilizados al mismo tiempo +You cannot attach more than one document: No puedes adjuntar más de un documento \ No newline at end of file From d22be6620c3b6f393c83b259fc7a2916e86ddbf2 Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 4 Mar 2022 11:28:45 +0100 Subject: [PATCH 06/23] feat: add backTest --- .../methods/agency-term/createInvoiceIn.js | 72 +++++++++++-------- .../agency-term/specs/createInvoiceIn.spec.js | 36 +++------- .../methods/agency-term/specs/filter.spec.js | 6 +- 3 files changed, 57 insertions(+), 57 deletions(-) diff --git a/modules/route/back/methods/agency-term/createInvoiceIn.js b/modules/route/back/methods/agency-term/createInvoiceIn.js index c686f3ad1..e82e0fb64 100644 --- a/modules/route/back/methods/agency-term/createInvoiceIn.js +++ b/modules/route/back/methods/agency-term/createInvoiceIn.js @@ -24,29 +24,37 @@ module.exports = Self => { Self.createInvoiceIn = async(rows, dms, options) => { const models = Self.app.models; + + let tx; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); - const [firstRow] = rows; - const [firstDms] = dms; + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } - const [reference] = await Self.rawSql(`SELECT reference FROM vn.dms WHERE id = ?`, [firstDms.id]); + try { + const [firstRow] = rows; + const [firstDms] = dms; - const newInvoiceIn = await models.InvoiceIn.create({ - supplierFk: firstRow.supplierFk, - supplierRef: reference.value, - issued: firstRow.created, - booked: firstRow.created, - operated: firstRow.created, - bookEntried: firstRow.created, - gestdoc_id: firstDms.id - }); + const [reference] = await Self.rawSql(`SELECT reference FROM vn.dms WHERE id = ?`, [firstDms.id], myOptions); - const [expence] = await Self.rawSql(`SELECT expenceFk value FROM vn.agencyTermConfig`); + const newInvoiceIn = await models.InvoiceIn.create({ + supplierFk: firstRow.supplierFk, + supplierRef: reference.value, + issued: firstRow.created, + booked: firstRow.created, + operated: firstRow.created, + bookEntried: firstRow.created, + gestdoc_id: firstDms.id + }, myOptions); - const [taxTypeSage] = await Self.rawSql(` + const [expence] = await Self.rawSql(`SELECT expenceFk value FROM vn.agencyTermConfig`, null, myOptions); + + const [taxTypeSage] = await Self.rawSql(` SELECT IFNULL(s.taxTypeSageFk, CodigoIva) value FROM vn.supplier s JOIN sage.TiposIva ti ON TRUE @@ -54,32 +62,38 @@ module.exports = Self => { WHERE s.id = ? AND ti.CuentaIvaSoportado = atg.vatAccountSupported AND ti.PorcentajeIva = atg.vatPercentage - `, [firstRow.supplierFk]); + `, [firstRow.supplierFk], myOptions); - const [transactionTypeSage] = await Self.rawSql(` + const [transactionTypeSage] = await Self.rawSql(` SELECT IFNULL(s.transactionTypeSageFk, tt.CodigoTransaccion) value FROM vn.supplier s JOIN sage.TiposTransacciones tt ON TRUE JOIN vn.agencyTermConfig atg WHERE s.id = ? AND tt.Transaccion = atg.transaction - `, [firstRow.supplierFk]); + `, [firstRow.supplierFk], myOptions); - await models.InvoiceInTax.create({ - invoiceInFk: newInvoiceIn.id, - taxableBase: firstRow.totalPrice, - expenseFk: expence.value, - taxTypeSageFk: taxTypeSage.value, - transactionTypeSageFk: transactionTypeSage.value - }); + await models.InvoiceInTax.create({ + invoiceInFk: newInvoiceIn.id, + taxableBase: firstRow.totalPrice, + expenseFk: expence.value, + taxTypeSageFk: taxTypeSage.value, + transactionTypeSageFk: transactionTypeSage.value + }, myOptions); - await Self.rawSql(`CALL invoiceInDueDay_calculate(?)`, [newInvoiceIn.id]); + await Self.rawSql(`CALL invoiceInDueDay_calculate(?)`, [newInvoiceIn.id], myOptions); - for (let agencyTerm of rows) { - const route = await models.Route.findById(agencyTerm.routeFk); - await Self.rawSql(` + for (let agencyTerm of rows) { + const route = await models.Route.findById(agencyTerm.routeFk, null, myOptions); + await Self.rawSql(` UPDATE vn.route SET invoiceInFk = ? WHERE id = ? - `, [newInvoiceIn.id, route.id]); + `, [newInvoiceIn.id, route.id], myOptions); + } + + if (tx) await tx.commit(); + } catch (e) { + if (tx) await tx.rollback(); + throw e; } }; }; 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 40a2e7b07..3f9c0ba44 100644 --- a/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js +++ b/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js @@ -11,23 +11,9 @@ describe('AgencyTerm createInvoiceIn()', () => { ]; const dms = [ { - id: 7, - file: '7.pdf', - contentType: 'application/pdf', - reference: '1', - description: 'Plants SL', - hasFile: false, - companyFk: 442, - dmsTypeFk: 1, - warehouseFk: 1, - workerFk: 9 + id: 6 } ]; - const userId = 1; - const activeCtx = { - accessToken: {userId: userId}, - }; - const ctx = {req: activeCtx}; it('should make a global invoicing', async() => { const tx = await models.AgencyTerm.beginTransaction({}); @@ -38,19 +24,19 @@ describe('AgencyTerm createInvoiceIn()', () => { const invoiceInDueDayId = 11; const invoiceInTaxId = 12; - const oldInvoiceIn = await models.AgencyTerm.findById(invoiceInId, null, options); - const oldInvoiceInDueDay = await models.AgencyTerm.findById(invoiceInDueDayId, null, options); - const oldInvoiceInTax = await models.AgencyTerm.findById(invoiceInTaxId, null, options); - - const [newInvoiceIn] = await models.Ticket.rawSql('SELECT MAX(id) id FROM invoiceIn', null, options); - // const [newInvoiceInDueDay] = await models.AgencyTerm.rawSql('SELECT MAX(id) id FROM invoiceInDueDay', null, options); - // const [newInvoiceInTax] = await models.AgencyTerm.rawSql('SELECT MAX(id) id FROM invoiceInTax', null, options); + const oldInvoiceIn = await models.InvoiceIn.findById(invoiceInId, null, options); + const oldInvoiceInDueDay = await models.InvoiceInDueDay.findById(invoiceInDueDayId, null, options); + const oldInvoiceInTax = await models.InvoiceInTax.findById(invoiceInTaxId, null, options); await models.AgencyTerm.createInvoiceIn(rows, dms, options); - // expect(newInvoiceIn.id).toEqual(oldInvoiceIn.id + 1); - // expect(newInvoiceInDueDay.id).toEqual(oldInvoiceInDueDay.id + 1); - // expect(newInvoiceInTax.id).toEqual(oldInvoiceInTax.id + 1); + const [newInvoiceIn] = await models.InvoiceIn.rawSql('SELECT MAX(id) id FROM invoiceIn', null, options); + const [newInvoiceInDueDay] = await models.InvoiceInDueDay.rawSql('SELECT MAX(id) id FROM invoiceInDueDay', null, options); + const [newInvoiceInTax] = await models.InvoiceInTax.rawSql('SELECT MAX(id) id FROM invoiceInTax', null, options); + + expect(newInvoiceIn.id).toBeGreaterThan(oldInvoiceIn.id); + expect(newInvoiceInDueDay.id).toBeGreaterThan(oldInvoiceInDueDay.id); + expect(newInvoiceInTax.id).toBeGreaterThan(oldInvoiceInTax.id); await tx.rollback(); } catch (e) { diff --git a/modules/route/back/methods/agency-term/specs/filter.spec.js b/modules/route/back/methods/agency-term/specs/filter.spec.js index 23671cef3..665af0b45 100644 --- a/modules/route/back/methods/agency-term/specs/filter.spec.js +++ b/modules/route/back/methods/agency-term/specs/filter.spec.js @@ -1,6 +1,6 @@ const models = require('vn-loopback/server/server').models; -xdescribe('AgencyTerm filter()', () => { +describe('AgencyTerm filter()', () => { const authUserId = 9; it('should all return the tickets matching the filter', async() => { @@ -9,9 +9,9 @@ xdescribe('AgencyTerm filter()', () => { try { const options = {transaction: tx}; const filter = {}; - const ctx = {req: {accessToken: {userId: authUserId}}, args: {filter: filter}}; + const ctx = {req: {accessToken: {userId: authUserId}}}; - const agencyTerms = await models.AgencyTerm.filter(ctx, null, options); + const agencyTerms = await models.AgencyTerm.filter(ctx, filter, options); const firstAgencyTerm = agencyTerms[0]; expect(firstAgencyTerm.routeFk).toEqual(1); From b58020978ab188106e9ab640153f36e65ff7d998 Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 4 Mar 2022 11:59:45 +0100 Subject: [PATCH 07/23] fix: check cannot attach more than one file --- modules/route/front/agency-term/createInvoiceIn/index.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/modules/route/front/agency-term/createInvoiceIn/index.js b/modules/route/front/agency-term/createInvoiceIn/index.js index 7ab8adbfa..0198ab80f 100644 --- a/modules/route/front/agency-term/createInvoiceIn/index.js +++ b/modules/route/front/agency-term/createInvoiceIn/index.js @@ -62,6 +62,7 @@ class Controller extends Section { } onSubmit() { + if (this.dms.files.length > 1) throw new UserError('You cannot attach more than one document'); const query = `dms/uploadFile`; const options = { method: 'POST', @@ -72,10 +73,7 @@ class Controller extends Section { }, transformRequest: files => { const formData = new FormData(); - - for (let i = 0; i < files.length; i++) - formData.append(files[i].name, files[i]); - + formData.append(files[0].name, files[0]); return formData; }, data: this.dms.files @@ -83,7 +81,6 @@ class Controller extends Section { this.$http(options).then(res => { if (res) { const addedDms = res.data; - if (addedDms.length > 1) throw new UserError('You cannot attach more than one document'); this.$.watcher.updateOriginalData(); const params = { From 10d48f9bb4379a82b2b8517897b372bd05c89e82 Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 4 Mar 2022 12:01:32 +0100 Subject: [PATCH 08/23] refactor uppercase --- back/methods/dms/uploadFile.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/back/methods/dms/uploadFile.js b/back/methods/dms/uploadFile.js index fb4b2e5b8..a4212b804 100644 --- a/back/methods/dms/uploadFile.js +++ b/back/methods/dms/uploadFile.js @@ -9,35 +9,35 @@ module.exports = Self => { accepts: [ { arg: 'warehouseId', - type: 'Number', + type: 'number', description: 'The warehouse id', required: true }, { arg: 'companyId', - type: 'Number', + type: 'number', description: 'The company id', required: true }, { arg: 'dmsTypeId', - type: 'Number', + type: 'number', description: 'The dms type id', required: true }, { arg: 'reference', - type: 'String', + type: 'string', required: true }, { arg: 'description', - type: 'String', + type: 'string', required: true }, { arg: 'hasFile', - type: 'Boolean', + type: 'boolean', description: 'True if has an attached file', required: true }], returns: { - type: 'Object', + type: 'object', root: true }, http: { From f88f60ef271b69156970e9559e76ef32809cd4d2 Mon Sep 17 00:00:00 2001 From: vicent Date: Mon, 7 Mar 2022 12:43:05 +0100 Subject: [PATCH 09/23] refactor code and icons --- modules/entry/front/routes.json | 2 +- .../agency-term/specs/createInvoiceIn.spec.js | 2 +- modules/route/back/models/agency-term.json | 16 ++++++++-------- modules/route/front/routes.json | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/entry/front/routes.json b/modules/entry/front/routes.json index 3b2a8f146..37dda7584 100644 --- a/modules/entry/front/routes.json +++ b/modules/entry/front/routes.json @@ -7,7 +7,7 @@ "menus": { "main": [ {"state": "entry.index", "icon": "icon-entry"}, - {"state": "entry.latestBuys", "icon": "icon-lastBuy"} + {"state": "entry.latestBuys", "icon": "contact_support"} ], "card": [ {"state": "entry.card.basicData", "icon": "settings"}, 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 3f9c0ba44..d141dcadb 100644 --- a/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js +++ b/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js @@ -15,7 +15,7 @@ describe('AgencyTerm createInvoiceIn()', () => { } ]; - it('should make a global invoicing', async() => { + it('should make a invoice in', async() => { const tx = await models.AgencyTerm.beginTransaction({}); const options = {transaction: tx}; diff --git a/modules/route/back/models/agency-term.json b/modules/route/back/models/agency-term.json index 29f70951b..4e13c2a18 100644 --- a/modules/route/back/models/agency-term.json +++ b/modules/route/back/models/agency-term.json @@ -8,30 +8,30 @@ }, "properties": { "agencyFk": { - "type": "Number", + "type": "number", "id": true, "description": "Identifier" }, "minimumPackages": { - "type": "Number" + "type": "number" }, "kmPrice": { - "type": "Number" + "type": "number" }, "packagePrice": { - "type": "Number" + "type": "number" }, "routePrice": { - "type": "Number" + "type": "number" }, "minimumKm": { - "type": "Number" + "type": "number" }, "minimumM3": { - "type": "Number" + "type": "number" }, "m3Price": { - "type": "Number" + "type": "number" } } } diff --git a/modules/route/front/routes.json b/modules/route/front/routes.json index 7e0273441..0d66a5697 100644 --- a/modules/route/front/routes.json +++ b/modules/route/front/routes.json @@ -7,7 +7,7 @@ "menus": { "main": [ {"state": "route.index", "icon": "icon-delivery"}, - {"state": "route.agencyTerm.index", "icon": "icon-delivery"} + {"state": "route.agencyTerm.index", "icon": "contact_support"} ], "card": [ {"state": "route.card.basicData", "icon": "settings"}, From 03c8ceffb2418547acddb0043bf4734889f81716 Mon Sep 17 00:00:00 2001 From: vicent Date: Mon, 7 Mar 2022 13:54:18 +0100 Subject: [PATCH 10/23] refactor code --- loopback/locale/es.json | 3 ++- .../methods/agency-term/createInvoiceIn.js | 10 ++++---- .../agency-term/specs/createInvoiceIn.spec.js | 6 +++-- modules/route/back/model-config.json | 3 +++ .../route/back/models/agency-term-config.json | 24 +++++++++++++++++++ 5 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 modules/route/back/models/agency-term-config.json diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 856ee57d8..e929876d4 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -219,5 +219,6 @@ "You can not modify is pay method checked": "No se puede modificar el campo método de pago validado", "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", "You don't have privileges to create pay back": "No tienes permisos para crear un abono", - "The item is required": "El artículo es requerido" + "The item is required": "El artículo es requerido", + "reference duplicated": "reference duplicated" } \ No newline at end of file diff --git a/modules/route/back/methods/agency-term/createInvoiceIn.js b/modules/route/back/methods/agency-term/createInvoiceIn.js index e82e0fb64..2a0d24509 100644 --- a/modules/route/back/methods/agency-term/createInvoiceIn.js +++ b/modules/route/back/methods/agency-term/createInvoiceIn.js @@ -40,11 +40,11 @@ module.exports = Self => { const [firstRow] = rows; const [firstDms] = dms; - const [reference] = await Self.rawSql(`SELECT reference FROM vn.dms WHERE id = ?`, [firstDms.id], myOptions); + const reference = await models.Dms.findById([firstDms.id], null, myOptions); const newInvoiceIn = await models.InvoiceIn.create({ supplierFk: firstRow.supplierFk, - supplierRef: reference.value, + supplierRef: reference.reference, issued: firstRow.created, booked: firstRow.created, operated: firstRow.created, @@ -52,7 +52,7 @@ module.exports = Self => { gestdoc_id: firstDms.id }, myOptions); - const [expence] = await Self.rawSql(`SELECT expenceFk value FROM vn.agencyTermConfig`, null, myOptions); + const expence = await models.AgencyTermConfig.findOne(null, myOptions); const [taxTypeSage] = await Self.rawSql(` SELECT IFNULL(s.taxTypeSageFk, CodigoIva) value @@ -76,12 +76,12 @@ module.exports = Self => { await models.InvoiceInTax.create({ invoiceInFk: newInvoiceIn.id, taxableBase: firstRow.totalPrice, - expenseFk: expence.value, + expenseFk: expence.expenceFk, taxTypeSageFk: taxTypeSage.value, transactionTypeSageFk: transactionTypeSage.value }, myOptions); - await Self.rawSql(`CALL invoiceInDueDay_calculate(?)`, [newInvoiceIn.id], myOptions); + // await Self.rawSql(`CALL invoiceInDueDay_calculate(?)`, [newInvoiceIn.id], myOptions); for (let agencyTerm of rows) { const route = await models.Route.findById(agencyTerm.routeFk, null, myOptions); 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 d141dcadb..0ad85e3fb 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,6 @@ const models = require('vn-loopback/server/server').models; -describe('AgencyTerm createInvoiceIn()', () => { +xdescribe('AgencyTerm createInvoiceIn()', () => { const rows = [ { routeFk: 2, @@ -28,12 +28,14 @@ describe('AgencyTerm createInvoiceIn()', () => { const oldInvoiceInDueDay = await models.InvoiceInDueDay.findById(invoiceInDueDayId, null, options); const oldInvoiceInTax = await models.InvoiceInTax.findById(invoiceInTaxId, null, options); - await models.AgencyTerm.createInvoiceIn(rows, dms, options); + // await models.AgencyTerm.createInvoiceIn(rows, dms, options); const [newInvoiceIn] = await models.InvoiceIn.rawSql('SELECT MAX(id) id FROM invoiceIn', null, options); const [newInvoiceInDueDay] = await models.InvoiceInDueDay.rawSql('SELECT MAX(id) id FROM invoiceInDueDay', null, options); const [newInvoiceInTax] = await models.InvoiceInTax.rawSql('SELECT MAX(id) id FROM invoiceInTax', null, options); + conso; + expect(newInvoiceIn.id).toBeGreaterThan(oldInvoiceIn.id); expect(newInvoiceInDueDay.id).toBeGreaterThan(oldInvoiceInDueDay.id); expect(newInvoiceInTax.id).toBeGreaterThan(oldInvoiceInTax.id); diff --git a/modules/route/back/model-config.json b/modules/route/back/model-config.json index 5d5c5cc18..31aaad9f5 100644 --- a/modules/route/back/model-config.json +++ b/modules/route/back/model-config.json @@ -2,6 +2,9 @@ "AgencyTerm": { "dataSource": "vn" }, + "AgencyTermConfig": { + "dataSource": "vn" + }, "Route": { "dataSource": "vn" }, diff --git a/modules/route/back/models/agency-term-config.json b/modules/route/back/models/agency-term-config.json new file mode 100644 index 000000000..c94fc266b --- /dev/null +++ b/modules/route/back/models/agency-term-config.json @@ -0,0 +1,24 @@ +{ + "name": "AgencyTermConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "agencyTermConfig" + } + }, + "properties": { + "expenceFk": { + "type": "string", + "id": true + }, + "vatAccountSupported": { + "type": "string" + }, + "vatPercentage": { + "type": "number" + }, + "transaction": { + "type": "string" + } + } +} From e8d7ce7cc744dcfcf0148b6585feb1f3dfc7c3eb Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 7 Mar 2022 14:50:51 +0100 Subject: [PATCH 11/23] refactor(ticket): change role productionBoss to deliveryBoss --- modules/ticket/back/methods/ticket/componentUpdate.js | 4 ++-- modules/ticket/back/methods/ticket/isEditable.js | 4 ++-- modules/ticket/back/methods/ticket/priceDifference.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/ticket/back/methods/ticket/componentUpdate.js b/modules/ticket/back/methods/ticket/componentUpdate.js index 2294e6d25..d9fe259ea 100644 --- a/modules/ticket/back/methods/ticket/componentUpdate.js +++ b/modules/ticket/back/methods/ticket/componentUpdate.js @@ -116,8 +116,8 @@ module.exports = Self => { if (!isEditable) throw new UserError(`The sales of this ticket can't be modified`); - const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss', myOptions); - if (!isProductionBoss) { + const isDeliveryBoss = await models.Account.hasRole(userId, 'deliveryBoss', myOptions); + if (!isDeliveryBoss) { const zoneShipped = await models.Agency.getShipped( args.landed, args.addressFk, diff --git a/modules/ticket/back/methods/ticket/isEditable.js b/modules/ticket/back/methods/ticket/isEditable.js index a444691ac..5b9a397a1 100644 --- a/modules/ticket/back/methods/ticket/isEditable.js +++ b/modules/ticket/back/methods/ticket/isEditable.js @@ -31,10 +31,10 @@ module.exports = Self => { }, myOptions); const isSalesAssistant = await Self.app.models.Account.hasRole(userId, 'salesAssistant', myOptions); - const isProductionBoss = await Self.app.models.Account.hasRole(userId, 'productionBoss', myOptions); + const isDeliveryBoss = await Self.app.models.Account.hasRole(userId, 'deliveryBoss', myOptions); const isBuyer = await Self.app.models.Account.hasRole(userId, 'buyer', myOptions); - const isValidRole = isSalesAssistant || isProductionBoss || isBuyer; + const isValidRole = isSalesAssistant || isDeliveryBoss || isBuyer; let alertLevel = state ? state.alertLevel : null; let ticket = await Self.app.models.Ticket.findById(id, { diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index e0ffac55a..0e8cc2e06 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -78,8 +78,8 @@ module.exports = Self => { if (!isEditable) throw new UserError(`The sales of this ticket can't be modified`); - const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss', myOptions); - if (!isProductionBoss) { + const isDeliveryBoss = await models.Account.hasRole(userId, 'deliveryBoss', myOptions); + if (!isDeliveryBoss) { const zoneShipped = await models.Agency.getShipped( args.landed, args.addressId, From 97f2341ae0a6a26ff3c4d21db327ff435416a440 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 8 Mar 2022 13:42:44 +0100 Subject: [PATCH 12/23] pull request changes --- .../00-aclAgency.sql | 0 .../00-aclAgencyTerm.sql | 0 .../00-agencyTerm.sql | 0 .../back/methods/agency-term/createInvoiceIn.js | 14 +++++++++----- modules/route/back/methods/agency-term/filter.js | 12 +++++------- .../agency-term/specs/createInvoiceIn.spec.js | 7 +++---- .../methods/agency-term/specs/filter.spec.js | 2 +- .../agency-term/createInvoiceIn/index.spec.js | 4 ++-- modules/route/front/agency-term/index/index.js | 16 +++++----------- .../route/front/agency-term/index/index.spec.js | 6 +++--- modules/route/front/agency-term/locale/es.yml | 2 -- 11 files changed, 28 insertions(+), 35 deletions(-) rename db/changes/{10420-valentines => 10430-ash}/00-aclAgency.sql (100%) rename db/changes/{10420-valentines => 10430-ash}/00-aclAgencyTerm.sql (100%) rename db/changes/{10420-valentines => 10430-ash}/00-agencyTerm.sql (100%) diff --git a/db/changes/10420-valentines/00-aclAgency.sql b/db/changes/10430-ash/00-aclAgency.sql similarity index 100% rename from db/changes/10420-valentines/00-aclAgency.sql rename to db/changes/10430-ash/00-aclAgency.sql diff --git a/db/changes/10420-valentines/00-aclAgencyTerm.sql b/db/changes/10430-ash/00-aclAgencyTerm.sql similarity index 100% rename from db/changes/10420-valentines/00-aclAgencyTerm.sql rename to db/changes/10430-ash/00-aclAgencyTerm.sql diff --git a/db/changes/10420-valentines/00-agencyTerm.sql b/db/changes/10430-ash/00-agencyTerm.sql similarity index 100% rename from db/changes/10420-valentines/00-agencyTerm.sql rename to db/changes/10430-ash/00-agencyTerm.sql diff --git a/modules/route/back/methods/agency-term/createInvoiceIn.js b/modules/route/back/methods/agency-term/createInvoiceIn.js index 2a0d24509..836655bd3 100644 --- a/modules/route/back/methods/agency-term/createInvoiceIn.js +++ b/modules/route/back/methods/agency-term/createInvoiceIn.js @@ -1,20 +1,22 @@ module.exports = Self => { Self.remoteMethod('createInvoiceIn', { - description: 'create a invoce in from one or more agency terms', + description: 'Creates an invoiceIn from one or more agency terms', accessType: 'WRITE', accepts: [{ arg: 'rows', type: ['object'], required: true, - description: `the rows from which the invoice in will be created`, + description: `The rows from which the invoiceIn will be created`, }, { arg: 'dms', type: ['object'], required: true, - description: 'the dms file' + description: 'The dms file attached' }], returns: { + type: 'object', + root: true }, http: { path: `/createInvoiceIn`, @@ -49,7 +51,7 @@ module.exports = Self => { booked: firstRow.created, operated: firstRow.created, bookEntried: firstRow.created, - gestdoc_id: firstDms.id + dmsFk: firstDms.id, }, myOptions); const expence = await models.AgencyTermConfig.findOne(null, myOptions); @@ -81,7 +83,7 @@ module.exports = Self => { transactionTypeSageFk: transactionTypeSage.value }, myOptions); - // await Self.rawSql(`CALL invoiceInDueDay_calculate(?)`, [newInvoiceIn.id], myOptions); + await Self.rawSql(`CALL invoiceInDueDay_calculate(?)`, [newInvoiceIn.id], myOptions); for (let agencyTerm of rows) { const route = await models.Route.findById(agencyTerm.routeFk, null, myOptions); @@ -91,6 +93,8 @@ module.exports = Self => { } if (tx) await tx.commit(); + + return newInvoiceIn; } catch (e) { if (tx) await tx.rollback(); throw e; diff --git a/modules/route/back/methods/agency-term/filter.js b/modules/route/back/methods/agency-term/filter.js index 48a85e629..0bca9ddf7 100644 --- a/modules/route/back/methods/agency-term/filter.js +++ b/modules/route/back/methods/agency-term/filter.js @@ -1,5 +1,4 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; -const mergeFilters = require('vn-loopback/util/filter').mergeFilters; module.exports = Self => { Self.remoteMethodCtx('filter', { @@ -30,9 +29,8 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - let stmts = []; - let stmt; - stmt = new ParameterizedSQL( + const stmts = []; + const stmt = new ParameterizedSQL( `SELECT * FROM ( SELECT r.id routeFk, @@ -65,9 +63,9 @@ module.exports = Self => { stmt.merge(conn.makeSuffix(filter)); - let agencyTerm = stmts.push(stmt) - 1; - let sql = ParameterizedSQL.join(stmts, ';'); - let result = await conn.executeStmt(sql, myOptions); + const agencyTerm = stmts.push(stmt) - 1; + const sql = ParameterizedSQL.join(stmts, ';'); + const result = await conn.executeStmt(sql, myOptions); const models = Self.app.models; for (let agencyTerm of result) 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 0ad85e3fb..fc7afeb10 100644 --- a/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js +++ b/modules/route/back/methods/agency-term/specs/createInvoiceIn.spec.js @@ -1,5 +1,6 @@ const models = require('vn-loopback/server/server').models; +// Include test when the database export is done xdescribe('AgencyTerm createInvoiceIn()', () => { const rows = [ { @@ -15,7 +16,7 @@ xdescribe('AgencyTerm createInvoiceIn()', () => { } ]; - it('should make a invoice in', async() => { + it('should make an invoiceIn', async() => { const tx = await models.AgencyTerm.beginTransaction({}); const options = {transaction: tx}; @@ -28,14 +29,12 @@ xdescribe('AgencyTerm createInvoiceIn()', () => { const oldInvoiceInDueDay = await models.InvoiceInDueDay.findById(invoiceInDueDayId, null, options); const oldInvoiceInTax = await models.InvoiceInTax.findById(invoiceInTaxId, null, options); - // await models.AgencyTerm.createInvoiceIn(rows, dms, options); + await models.AgencyTerm.createInvoiceIn(rows, dms, options); const [newInvoiceIn] = await models.InvoiceIn.rawSql('SELECT MAX(id) id FROM invoiceIn', null, options); const [newInvoiceInDueDay] = await models.InvoiceInDueDay.rawSql('SELECT MAX(id) id FROM invoiceInDueDay', null, options); const [newInvoiceInTax] = await models.InvoiceInTax.rawSql('SELECT MAX(id) id FROM invoiceInTax', null, options); - conso; - expect(newInvoiceIn.id).toBeGreaterThan(oldInvoiceIn.id); expect(newInvoiceInDueDay.id).toBeGreaterThan(oldInvoiceInDueDay.id); expect(newInvoiceInTax.id).toBeGreaterThan(oldInvoiceInTax.id); diff --git a/modules/route/back/methods/agency-term/specs/filter.spec.js b/modules/route/back/methods/agency-term/specs/filter.spec.js index 665af0b45..69a7f987c 100644 --- a/modules/route/back/methods/agency-term/specs/filter.spec.js +++ b/modules/route/back/methods/agency-term/specs/filter.spec.js @@ -3,7 +3,7 @@ const models = require('vn-loopback/server/server').models; describe('AgencyTerm filter()', () => { const authUserId = 9; - it('should all return the tickets matching the filter', async() => { + it('should return all the tickets matching the filter', async() => { const tx = await models.AgencyTerm.beginTransaction({}); try { diff --git a/modules/route/front/agency-term/createInvoiceIn/index.spec.js b/modules/route/front/agency-term/createInvoiceIn/index.spec.js index 1c64eee93..d6d9883a7 100644 --- a/modules/route/front/agency-term/createInvoiceIn/index.spec.js +++ b/modules/route/front/agency-term/createInvoiceIn/index.spec.js @@ -62,10 +62,10 @@ describe('AgencyTerm', () => { describe('setDefaultParams()', () => { it('should perform a GET query and define the dms property on controller', () => { - const params2 = {filter: { + const params = {filter: { where: {code: 'invoiceIn'} }}; - let serializedParams = $httpParamSerializer(params2); + const serializedParams = $httpParamSerializer(params); $httpBackend.expect('GET', `DmsTypes/findOne?${serializedParams}`).respond({id: 1, code: 'invoiceIn'}); controller.params = {supplierName: 'Plants SL'}; controller.setDefaultParams(); diff --git a/modules/route/front/agency-term/index/index.js b/modules/route/front/agency-term/index/index.js index 89d71134b..ece7f18da 100644 --- a/modules/route/front/agency-term/index/index.js +++ b/modules/route/front/agency-term/index/index.js @@ -41,26 +41,20 @@ class Controller extends Section { exprBuilder(param, value) { switch (param) { + case 'agencyFk': + return {'a.agencyModeName': value}; + case 'supplierFk': + return {'a.supplierName': value}; case 'routeFk': return {'a.routeFk': value}; case 'created': - return {'a.created': value}; - case 'agencyFk': - return {'a.agencyModeName': value}; case 'agencyAgreement': - return {'a.agencyAgreement': value}; case 'packages': - return {'a.packages': value}; case 'm3': - return {'a.m3': value}; case 'kmTotal': - return {'a.kmTotal': value}; case 'price': - return {'a.price': value}; case 'invoiceInFk': - return {'a.invoiceInFk': value}; - case 'supplierFk': - return {'a.supplierName': value}; + return {[`a.${param}`]: value}; } } diff --git a/modules/route/front/agency-term/index/index.spec.js b/modules/route/front/agency-term/index/index.spec.js index 18a49284a..55c40daa5 100644 --- a/modules/route/front/agency-term/index/index.spec.js +++ b/modules/route/front/agency-term/index/index.spec.js @@ -45,7 +45,7 @@ describe('AgencyTerm', () => { }); describe('preview()', () => { - it('should show the dialog summary', () => { + it('should show the summary dialog', () => { controller.$.summary = {show: () => {}}; jest.spyOn(controller.$.summary, 'show'); @@ -63,7 +63,7 @@ describe('AgencyTerm', () => { }); describe('createInvoiceIn()', () => { - it('should throw an error if are checked more than one autonomous', () => { + it('should throw an error if more than one autonomous are checked', () => { jest.spyOn(controller.vnApp, 'showError'); const data = controller.$.model.data; data[0].checked = true; @@ -74,7 +74,7 @@ describe('AgencyTerm', () => { expect(controller.vnApp.showError).toHaveBeenCalled(); }); - it('should call the function go() on $state to go to the file managment', () => { + it('should call the function go() on $state to go to the file management', () => { jest.spyOn(controller.$state, 'go'); const data = controller.$.model.data; data[0].checked = true; diff --git a/modules/route/front/agency-term/locale/es.yml b/modules/route/front/agency-term/locale/es.yml index 1ba1d9ef5..3a97e6c52 100644 --- a/modules/route/front/agency-term/locale/es.yml +++ b/modules/route/front/agency-term/locale/es.yml @@ -1,5 +1,3 @@ -picture: Foto -Buy requests: Peticiones de compra Agency route: Agencia ruta Agency Agreement: Agencia acuerdo Autonomous: Autónomos From 97f856afccb0b5bbd2a75123fd3f3f9c7294fb3e Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 11 Mar 2022 12:24:53 +0100 Subject: [PATCH 13/23] corrected comment --- .../back/methods/agency-term/specs/createInvoiceIn.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 fc7afeb10..81686144d 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,6 @@ const models = require('vn-loopback/server/server').models; -// Include test when the database export is done +// Include after #3638 export database xdescribe('AgencyTerm createInvoiceIn()', () => { const rows = [ { From 0fd556dd2a1ffac75fb2858b2a5cf288800b0ce1 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 11 Mar 2022 13:23:02 +0100 Subject: [PATCH 14/23] fix(worker): fix calendar e2e --- e2e/paths/03-worker/05_calendar.spec.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/e2e/paths/03-worker/05_calendar.spec.js b/e2e/paths/03-worker/05_calendar.spec.js index 08ef71f13..6d3d7bd4d 100644 --- a/e2e/paths/03-worker/05_calendar.spec.js +++ b/e2e/paths/03-worker/05_calendar.spec.js @@ -9,7 +9,7 @@ describe('Worker calendar path', () => { browser = await getBrowser(); page = browser.page; await page.loginAndModule('hr', 'worker'); - await page.accessToSearchResult('Hank Pym'); + await page.accessToSearchResult('Charles Xavier'); await page.accessToSection('worker.card.calendar'); }); @@ -18,12 +18,6 @@ describe('Worker calendar path', () => { }); describe('as hr', () => { - it('should check 5 total holidays have been used so far before testing anything', async() => { - const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText'); - - expect(result).toContain(' 5 '); - }); - it('should set two days as holidays on the calendar and check the total holidays increased by 1.5', async() => { await page.waitToClick(selectors.workerCalendar.holidays); await page.waitForTimeout(reasonableTimeBetweenClicks); @@ -56,14 +50,14 @@ describe('Worker calendar path', () => { const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText'); - expect(result).toContain(' 6.5 '); + expect(result).toContain(' 1.5 '); }); }); describe(`as salesBoss`, () => { it(`should log in and get to Hank's calendar`, async() => { await page.loginAndModule('salesBoss', 'worker'); - await page.accessToSearchResult('Hank Pym'); + await page.accessToSearchResult('Charles Xavier'); await page.accessToSection('worker.card.calendar'); }); @@ -101,14 +95,14 @@ describe('Worker calendar path', () => { it('should check the total holidays used are back to what it was', async() => { const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText'); - expect(result).toContain(' 5 '); + expect(result).toContain(' 0 '); }); }); describe(`as Hank`, () => { it(`should log in and get to his calendar`, async() => { await page.loginAndModule('HankPym', 'worker'); - await page.accessToSearchResult('Hank Pym'); + await page.accessToSearchResult('Charles Xavier'); await page.accessToSection('worker.card.calendar'); }); @@ -122,7 +116,7 @@ describe('Worker calendar path', () => { it('should check the total holidays used are now the initial ones', async() => { const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText'); - expect(result).toContain(' 5 '); + expect(result).toContain(' 0 '); }); it('should use the year selector to go to the previous year', async() => { From 31eb22c1b41519b597f05fa535ab48b9c84b53d6 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 14 Mar 2022 11:34:09 +0100 Subject: [PATCH 15/23] feat(db): update users to role deliveryBoss --- db/changes/10430-ash/00-deliveryBoss.sql | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 db/changes/10430-ash/00-deliveryBoss.sql diff --git a/db/changes/10430-ash/00-deliveryBoss.sql b/db/changes/10430-ash/00-deliveryBoss.sql new file mode 100644 index 000000000..a4bcdcd0c --- /dev/null +++ b/db/changes/10430-ash/00-deliveryBoss.sql @@ -0,0 +1,3 @@ +UPDATE `account`.`user` +SET `role` = 57 +WHERE id IN (2294, 4365, 7294); \ No newline at end of file From f774b1f7846876678e8516e8dce51e3b3db3f0a1 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 15 Mar 2022 09:13:35 +0100 Subject: [PATCH 16/23] typo --- modules/zone/front/delivery-days/index.js | 6 +++--- modules/zone/front/delivery-days/index.spec.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/zone/front/delivery-days/index.js b/modules/zone/front/delivery-days/index.js index 21c65678f..e4d5e72e9 100644 --- a/modules/zone/front/delivery-days/index.js +++ b/modules/zone/front/delivery-days/index.js @@ -69,14 +69,14 @@ class Controller extends Section { if (!$events.length) return; const day = $days[0]; - const zonesIds = []; + const zoneIds = []; for (let event of $events) - zonesIds.push(event.zoneFk); + zoneIds.push(event.zoneFk); this.$.zoneEvents.show($event.target); const params = { - zonesId: zonesIds, + zoneIds: zoneIds, date: day }; diff --git a/modules/zone/front/delivery-days/index.spec.js b/modules/zone/front/delivery-days/index.spec.js index 3d71bc93f..63c87fbea 100644 --- a/modules/zone/front/delivery-days/index.spec.js +++ b/modules/zone/front/delivery-days/index.spec.js @@ -110,7 +110,7 @@ describe('Zone Component vnZoneDeliveryDays', () => { {zoneFk: 8} ]; const params = { - zonesId: [1, 2, 8], + zoneIds: [1, 2, 8], date: [day][0] }; const response = [{id: 1, hour: ''}]; From 2f53733151c66f1c60ab6ccf9d10de470d7a21b5 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 15 Mar 2022 15:05:09 +0100 Subject: [PATCH 17/23] refactor translates --- loopback/locale/es.json | 2 +- modules/route/front/agency-term/locale/es.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/loopback/locale/es.json b/loopback/locale/es.json index e929876d4..7fcbc3f05 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -220,5 +220,5 @@ "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", "You don't have privileges to create pay back": "No tienes permisos para crear un abono", "The item is required": "El artículo es requerido", - "reference duplicated": "reference duplicated" + "reference duplicated": "Referencia duplicada" } \ No newline at end of file diff --git a/modules/route/front/agency-term/locale/es.yml b/modules/route/front/agency-term/locale/es.yml index 3a97e6c52..0f6797188 100644 --- a/modules/route/front/agency-term/locale/es.yml +++ b/modules/route/front/agency-term/locale/es.yml @@ -1,5 +1,5 @@ Agency route: Agencia ruta -Agency Agreement: Agencia acuerdo +Agency Agreement: Acuerdo agencia Autonomous: Autónomos Two autonomous cannot be counted at the same time: Dos autonónomos no pueden ser contabilizados al mismo tiempo You cannot attach more than one document: No puedes adjuntar más de un documento \ No newline at end of file From 39b3e35725815b2be54b6897ae7eb9738d460e98 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 15 Mar 2022 15:11:58 +0100 Subject: [PATCH 18/23] change description --- e2e/paths/03-worker/05_calendar.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/paths/03-worker/05_calendar.spec.js b/e2e/paths/03-worker/05_calendar.spec.js index 6d3d7bd4d..e97b7fe7c 100644 --- a/e2e/paths/03-worker/05_calendar.spec.js +++ b/e2e/paths/03-worker/05_calendar.spec.js @@ -55,7 +55,7 @@ describe('Worker calendar path', () => { }); describe(`as salesBoss`, () => { - it(`should log in and get to Hank's calendar`, async() => { + it(`should log in and get to Charles Xavier's calendar`, async() => { await page.loginAndModule('salesBoss', 'worker'); await page.accessToSearchResult('Charles Xavier'); await page.accessToSection('worker.card.calendar'); @@ -99,9 +99,9 @@ describe('Worker calendar path', () => { }); }); - describe(`as Hank`, () => { + describe(`as Charles Xavier`, () => { it(`should log in and get to his calendar`, async() => { - await page.loginAndModule('HankPym', 'worker'); + await page.loginAndModule('CharlesXavier', 'worker'); await page.accessToSearchResult('Charles Xavier'); await page.accessToSection('worker.card.calendar'); }); From 22002c2ee927c9544747716cdf61c5c9d11eb907 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 16 Mar 2022 14:24:18 +0100 Subject: [PATCH 19/23] Added storage pdf folder --- .gitignore | 1 - storage/pdfs/.keep | 0 2 files changed, 1 deletion(-) create mode 100644 storage/pdfs/.keep diff --git a/.gitignore b/.gitignore index 04a977352..f38e335c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ coverage node_modules dist -storage npm-debug.log .eslintcache datasources.*.json diff --git a/storage/pdfs/.keep b/storage/pdfs/.keep new file mode 100644 index 000000000..e69de29bb From e5bbff80d444b29ceeac8405a4312370796d310d Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 16 Mar 2022 14:24:51 +0100 Subject: [PATCH 20/23] Added storage on gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f38e335c7..04a977352 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ coverage node_modules dist +storage npm-debug.log .eslintcache datasources.*.json From 1e275eb4e35770748baf99623b0e47482620c2e1 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 16 Mar 2022 14:26:56 +0100 Subject: [PATCH 21/23] Invoice folder --- .gitignore | 1 - storage/pdfs/{ => invoice}/.keep | 0 2 files changed, 1 deletion(-) rename storage/pdfs/{ => invoice}/.keep (100%) diff --git a/.gitignore b/.gitignore index 04a977352..f38e335c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ coverage node_modules dist -storage npm-debug.log .eslintcache datasources.*.json diff --git a/storage/pdfs/.keep b/storage/pdfs/invoice/.keep similarity index 100% rename from storage/pdfs/.keep rename to storage/pdfs/invoice/.keep From 9439757158b561044c246b83ea2e8932517d82c9 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 16 Mar 2022 14:27:16 +0100 Subject: [PATCH 22/23] Added again --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f38e335c7..04a977352 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ coverage node_modules dist +storage npm-debug.log .eslintcache datasources.*.json From 00c53a770964510f2feaca9888a82bb0f0e3d687 Mon Sep 17 00:00:00 2001 From: joan Date: Fri, 18 Mar 2022 11:06:16 +0100 Subject: [PATCH 23/23] 3668 - Deprecated field "isOfficial" --- back/models/company.json | 3 --- modules/ticket/front/index/index.html | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/back/models/company.json b/back/models/company.json index 80ad026e4..eb349477b 100644 --- a/back/models/company.json +++ b/back/models/company.json @@ -18,9 +18,6 @@ }, "expired": { "type": "date" - }, - "isOfficial": { - "type": "boolean" } }, diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index 852675f76..36af86001 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -24,7 +24,7 @@ State Zone Warehouse - Total + Total