From db148c81772ece50e5a6800ddc2336de8c08d6aa Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 4 May 2021 12:44:21 +0200 Subject: [PATCH 01/21] 2863 - Added monitor module --- front/module-import.js | 3 +- modules/monitor/back/model-config.json | 2 + modules/monitor/front/index.js | 5 + modules/monitor/front/index/index.html | 160 ++++++++++++++++++ modules/monitor/front/index/index.js | 18 ++ modules/monitor/front/index/locale/es.yml | 5 + modules/monitor/front/locale/es.yml | 1 + modules/monitor/front/log/index.html | 1 + modules/monitor/front/log/index.js | 7 + modules/monitor/front/main/index.html | 12 ++ modules/monitor/front/main/index.js | 9 + modules/monitor/front/module.js | 3 + modules/monitor/front/routes.json | 29 ++++ modules/monitor/front/search-panel/index.html | 46 +++++ modules/monitor/front/search-panel/index.js | 7 + .../monitor/front/search-panel/locale/es.yml | 4 + 16 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 modules/monitor/back/model-config.json create mode 100644 modules/monitor/front/index.js create mode 100644 modules/monitor/front/index/index.html create mode 100644 modules/monitor/front/index/index.js create mode 100644 modules/monitor/front/index/locale/es.yml create mode 100644 modules/monitor/front/locale/es.yml create mode 100644 modules/monitor/front/log/index.html create mode 100644 modules/monitor/front/log/index.js create mode 100644 modules/monitor/front/main/index.html create mode 100644 modules/monitor/front/main/index.js create mode 100644 modules/monitor/front/module.js create mode 100644 modules/monitor/front/routes.json create mode 100644 modules/monitor/front/search-panel/index.html create mode 100644 modules/monitor/front/search-panel/index.js create mode 100644 modules/monitor/front/search-panel/locale/es.yml diff --git a/front/module-import.js b/front/module-import.js index 888a6ce7bb..ab1eb73d69 100755 --- a/front/module-import.js +++ b/front/module-import.js @@ -16,10 +16,11 @@ export default function moduleImport(moduleName) { case 'travel' : return import('travel/front'); case 'worker' : return import('worker/front'); case 'invoiceOut' : return import('invoiceOut/front'); - case 'invoiceIn' : return import('invoiceIn/front'); + case 'invoiceIn' : return import('invoiceIn/front'); case 'route' : return import('route/front'); case 'entry' : return import('entry/front'); case 'account' : return import('account/front'); case 'supplier' : return import('supplier/front'); + case 'monitor' : return import('monitor/front'); } } diff --git a/modules/monitor/back/model-config.json b/modules/monitor/back/model-config.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/modules/monitor/back/model-config.json @@ -0,0 +1,2 @@ +{ +} diff --git a/modules/monitor/front/index.js b/modules/monitor/front/index.js new file mode 100644 index 0000000000..cb25b3b8ca --- /dev/null +++ b/modules/monitor/front/index.js @@ -0,0 +1,5 @@ +export * from './module'; + +import './main'; +import './index/'; +import './search-panel'; diff --git a/modules/monitor/front/index/index.html b/modules/monitor/front/index/index.html new file mode 100644 index 0000000000..d04478bbc0 --- /dev/null +++ b/modules/monitor/front/index/index.html @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + Id + Salesperson + Date + Hour + Closure + Alias + Province + State + Zone + Warehouse + Total + + + + + + + + + + + + + + + + + + + + + + {{::ticket.id}} + + + {{::ticket.userName | dashIfEmpty}} + + + + + {{::ticket.shipped | date: 'dd/MM/yyyy'}} + + + {{::ticket.shipped | date: 'HH:mm'}} + {{::ticket.zoneLanding | date: 'HH:mm'}} + + + {{::ticket.nickname}} + + + {{::ticket.province}} + + + {{::ticket.refFk}} + + + {{ticket.state}} + + + + + {{::ticket.zoneName | dashIfEmpty}} + + + {{::ticket.warehouse}} + + + {{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}} + + + + + + + + + + + + + + + + + b + + + + c + + + \ No newline at end of file diff --git a/modules/monitor/front/index/index.js b/modules/monitor/front/index/index.js new file mode 100644 index 0000000000..bd138d59af --- /dev/null +++ b/modules/monitor/front/index/index.js @@ -0,0 +1,18 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +export default class Controller extends Section { + openSummary(supplier, event) { + if (event.defaultPrevented) return; + event.preventDefault(); + event.stopPropagation(); + + this.supplierSelected = supplier; + this.$.dialogSummarySupplier.show(); + } +} + +ngModule.vnComponent('vnMonitorIndex', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/monitor/front/index/locale/es.yml b/modules/monitor/front/index/locale/es.yml new file mode 100644 index 0000000000..ad8a4f0bb7 --- /dev/null +++ b/modules/monitor/front/index/locale/es.yml @@ -0,0 +1,5 @@ +Payment deadline: Plazo de pago +Pay day: Dia de pago +Account: Cuenta +Pay method: Metodo de pago +Tax number: Nif \ No newline at end of file diff --git a/modules/monitor/front/locale/es.yml b/modules/monitor/front/locale/es.yml new file mode 100644 index 0000000000..abb6a9775c --- /dev/null +++ b/modules/monitor/front/locale/es.yml @@ -0,0 +1 @@ +Accounts: Cuentas \ No newline at end of file diff --git a/modules/monitor/front/log/index.html b/modules/monitor/front/log/index.html new file mode 100644 index 0000000000..7895b585e1 --- /dev/null +++ b/modules/monitor/front/log/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/monitor/front/log/index.js b/modules/monitor/front/log/index.js new file mode 100644 index 0000000000..52a491c708 --- /dev/null +++ b/modules/monitor/front/log/index.js @@ -0,0 +1,7 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +ngModule.vnComponent('vnSupplierLog', { + template: require('./index.html'), + controller: Section, +}); diff --git a/modules/monitor/front/main/index.html b/modules/monitor/front/main/index.html new file mode 100644 index 0000000000..9a7c8bc873 --- /dev/null +++ b/modules/monitor/front/main/index.html @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/modules/monitor/front/main/index.js b/modules/monitor/front/main/index.js new file mode 100644 index 0000000000..42fc159d51 --- /dev/null +++ b/modules/monitor/front/main/index.js @@ -0,0 +1,9 @@ +import ngModule from '../module'; +import ModuleMain from 'salix/components/module-main'; + +export default class Monitor extends ModuleMain {} + +ngModule.vnComponent('vnMonitor', { + controller: Monitor, + template: require('./index.html') +}); diff --git a/modules/monitor/front/module.js b/modules/monitor/front/module.js new file mode 100644 index 0000000000..3a3125fe73 --- /dev/null +++ b/modules/monitor/front/module.js @@ -0,0 +1,3 @@ +import {ng} from 'core/vendor'; + +export default ng.module('monitor', ['salix']); diff --git a/modules/monitor/front/routes.json b/modules/monitor/front/routes.json new file mode 100644 index 0000000000..f0c2d9e981 --- /dev/null +++ b/modules/monitor/front/routes.json @@ -0,0 +1,29 @@ +{ + "module": "monitor", + "name": "Monitors", + "icon" : "icon-supplier", + "dependencies": ["ticket", "item"], + "validations" : true, + "menus": { + "main": [ + {"state": "monitor.index", "icon": "leaderboard"} + ], + "card": [] + }, + "keybindings": [], + "routes": [ + { + "url": "/monitor", + "state": "monitor", + "abstract": true, + "component": "vn-monitor", + "description": "Monitors" + }, + { + "url": "/index?q", + "state": "monitor.index", + "component": "vn-monitor-index", + "description": "Sales monitor" + } + ] +} \ No newline at end of file diff --git a/modules/monitor/front/search-panel/index.html b/modules/monitor/front/search-panel/index.html new file mode 100644 index 0000000000..161c8a98cd --- /dev/null +++ b/modules/monitor/front/search-panel/index.html @@ -0,0 +1,46 @@ +
+
+ + + + + + + + + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/modules/monitor/front/search-panel/index.js b/modules/monitor/front/search-panel/index.js new file mode 100644 index 0000000000..6223b5670a --- /dev/null +++ b/modules/monitor/front/search-panel/index.js @@ -0,0 +1,7 @@ +import ngModule from '../module'; +import SearchPanel from 'core/components/searchbar/search-panel'; + +ngModule.vnComponent('vnSupplierSearchPanel', { + template: require('./index.html'), + controller: SearchPanel +}); diff --git a/modules/monitor/front/search-panel/locale/es.yml b/modules/monitor/front/search-panel/locale/es.yml new file mode 100644 index 0000000000..77253a4efa --- /dev/null +++ b/modules/monitor/front/search-panel/locale/es.yml @@ -0,0 +1,4 @@ +Province: Provincia +Country: País +Tax number: NIF / CIF +Search suppliers by id, name or alias: Busca proveedores por id, nombre o alias \ No newline at end of file From f1c30ca6d1f6ced7785ae4186435285f96b4fedc Mon Sep 17 00:00:00 2001 From: jgallego Date: Thu, 6 May 2021 08:13:17 +0200 Subject: [PATCH 02/21] cambio landed por created --- modules/client/back/methods/client/createReceipt.js | 3 +-- .../route/back/methods/route/getSuggestedTickets.js | 10 ++-------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/modules/client/back/methods/client/createReceipt.js b/modules/client/back/methods/client/createReceipt.js index 976ff7cf27..a96575c5e2 100644 --- a/modules/client/back/methods/client/createReceipt.js +++ b/modules/client/back/methods/client/createReceipt.js @@ -83,9 +83,8 @@ module.exports = function(Self) { throw new UserError('Invalid account'); await Self.rawSql( - `CALL vn.ledger_doCompensation(?, ?, ?, ?, ?, ?, ?)`, + `CALL vn.ledger_doCompensation(CURDATE(), ?, ?, ?, ?, ?, ?)`, [ - Date(), args.compensationAccount, args.bankFk, accountingType.receiptDescription + args.compensationAccount, diff --git a/modules/route/back/methods/route/getSuggestedTickets.js b/modules/route/back/methods/route/getSuggestedTickets.js index 12bde16841..5699cf6546 100644 --- a/modules/route/back/methods/route/getSuggestedTickets.js +++ b/modules/route/back/methods/route/getSuggestedTickets.js @@ -20,12 +20,6 @@ module.exports = Self => { }); Self.getSuggestedTickets = async id => { - const ticketsInRoute = await Self.app.models.Ticket.find({ - where: {routeFk: id}, - fields: ['id'] - }); - const idsToExclude = ticketsInRoute.map(ticket => ticket.id); - const route = await Self.app.models.Route.findById(id); const zoneAgencyModes = await Self.app.models.ZoneAgencyMode.find({ @@ -48,8 +42,8 @@ module.exports = Self => { where: { agencyModeFk: route.agencyModeFk, zoneFk: {inq: zoneIds}, - id: {nin: idsToExclude}, - created: {between: [minDate, maxDate]} + routeFk: null, + landed: {between: [minDate, maxDate]} }, include: [ { From 19b35f5f6c3cabdc1538ab559af46bb88f8502a9 Mon Sep 17 00:00:00 2001 From: jgallego Date: Fri, 7 May 2021 07:52:03 +0200 Subject: [PATCH 03/21] landed en lugar de shipped --- modules/route/back/methods/route/getSuggestedTickets.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/route/back/methods/route/getSuggestedTickets.js b/modules/route/back/methods/route/getSuggestedTickets.js index 5699cf6546..c2afd60b4a 100644 --- a/modules/route/back/methods/route/getSuggestedTickets.js +++ b/modules/route/back/methods/route/getSuggestedTickets.js @@ -31,19 +31,17 @@ module.exports = Self => { const zoneIds = []; for (let zoneAgencyMode of zoneAgencyModes) zoneIds.push(zoneAgencyMode.zoneFk); - const minDate = new Date(route.created); minDate.setHours(0, 0, 0, 0); const maxDate = new Date(route.created); maxDate.setHours(23, 59, 59, 59); - let tickets = await Self.app.models.Ticket.find({ where: { agencyModeFk: route.agencyModeFk, zoneFk: {inq: zoneIds}, routeFk: null, - landed: {between: [minDate, maxDate]} + shipped: {between: [minDate, maxDate]} }, include: [ { From 84cd89d7f769fbdaa2437a5f389bc181c93ea534 Mon Sep 17 00:00:00 2001 From: jgallego Date: Fri, 7 May 2021 08:45:20 +0200 Subject: [PATCH 04/21] modifica la descripcion de la compensacion --- loopback/locale/en.json | 3 ++- modules/client/back/methods/client/createReceipt.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 1e06078134..6bdaddd9b1 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -96,5 +96,6 @@ "Swift / BIC cannot be empty": "Swift / BIC cannot be empty", "Role name must be written in camelCase": "Role name must be written in camelCase", "Client assignment has changed": "I did change the salesperson ~*\"<{{previousWorkerName}}>\"*~ by *\"<{{currentWorkerName}}>\"* from the client [{{clientName}} ({{clientId}})]({{{url}}})", - "None": "None" + "None": "None", + "error densidad = 0": "error densidad = 0" } \ No newline at end of file diff --git a/modules/client/back/methods/client/createReceipt.js b/modules/client/back/methods/client/createReceipt.js index a96575c5e2..cb7d7aabaa 100644 --- a/modules/client/back/methods/client/createReceipt.js +++ b/modules/client/back/methods/client/createReceipt.js @@ -87,7 +87,7 @@ module.exports = function(Self) { [ args.compensationAccount, args.bankFk, - accountingType.receiptDescription + args.compensationAccount, + accountingType.receiptDescription + clientOriginal.accountingAccount, args.amountPaid, args.companyFk, clientOriginal.accountingAccount From dc44af148ddcd5c3ef0726a8985b382e192fcce2 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 11 May 2021 09:43:15 +0200 Subject: [PATCH 05/21] 2863 - Added sales monitor --- db/changes/10310-mothersDay/00-ACL.sql | 4 +- db/dump/fixtures.sql | 73 +++- front/core/components/button/style.scss | 8 + front/core/components/table/index.js | 15 +- front/core/components/table/style.scss | 38 ++- .../methods/sales-monitor/clientsFilter.js | 60 ++++ .../methods/sales-monitor/ordersFilter.js | 68 ++++ .../back/methods/sales-monitor/salesFilter.js | 319 ++++++++++++++++++ .../sales-monitor/specs/clientsFilter.spec.js | 11 + .../sales-monitor/specs/ordersFilter.spec.js | 11 + .../sales-monitor/specs/salesFilter.spec.js | 106 ++++++ modules/monitor/back/model-config.json | 3 + modules/monitor/back/models/sales-monitor.js | 5 + .../monitor/back/models/sales-monitor.json | 11 + modules/monitor/front/index.js | 4 + .../monitor/front/index/clients/index.html | 101 ++++++ modules/monitor/front/index/clients/index.js | 30 ++ modules/monitor/front/index/index.html | 159 +-------- modules/monitor/front/index/index.js | 2 +- modules/monitor/front/index/locale/es.yml | 9 +- modules/monitor/front/index/orders/index.html | 85 +++++ modules/monitor/front/index/orders/index.js | 8 + modules/monitor/front/index/orders/style.scss | 16 + .../front/index/search-panel/index.html | 138 ++++++++ .../monitor/front/index/search-panel/index.js | 59 ++++ .../front/index/search-panel/index.spec.js | 71 ++++ .../front/index/search-panel/locale/en.yml | 4 + .../front/index/search-panel/locale/es.yml | 21 ++ modules/monitor/front/index/style.scss | 20 ++ .../monitor/front/index/tickets/index.html | 206 +++++++++++ modules/monitor/front/index/tickets/index.js | 105 ++++++ .../monitor/front/index/tickets/style.scss | 19 ++ modules/monitor/front/locale/es.yml | 3 +- modules/monitor/front/routes.json | 2 +- 34 files changed, 1623 insertions(+), 171 deletions(-) create mode 100644 modules/monitor/back/methods/sales-monitor/clientsFilter.js create mode 100644 modules/monitor/back/methods/sales-monitor/ordersFilter.js create mode 100644 modules/monitor/back/methods/sales-monitor/salesFilter.js create mode 100644 modules/monitor/back/methods/sales-monitor/specs/clientsFilter.spec.js create mode 100644 modules/monitor/back/methods/sales-monitor/specs/ordersFilter.spec.js create mode 100644 modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js create mode 100644 modules/monitor/back/models/sales-monitor.js create mode 100644 modules/monitor/back/models/sales-monitor.json create mode 100644 modules/monitor/front/index/clients/index.html create mode 100644 modules/monitor/front/index/clients/index.js create mode 100644 modules/monitor/front/index/orders/index.html create mode 100644 modules/monitor/front/index/orders/index.js create mode 100644 modules/monitor/front/index/orders/style.scss create mode 100644 modules/monitor/front/index/search-panel/index.html create mode 100644 modules/monitor/front/index/search-panel/index.js create mode 100644 modules/monitor/front/index/search-panel/index.spec.js create mode 100644 modules/monitor/front/index/search-panel/locale/en.yml create mode 100644 modules/monitor/front/index/search-panel/locale/es.yml create mode 100644 modules/monitor/front/index/style.scss create mode 100644 modules/monitor/front/index/tickets/index.html create mode 100644 modules/monitor/front/index/tickets/index.js create mode 100644 modules/monitor/front/index/tickets/style.scss diff --git a/db/changes/10310-mothersDay/00-ACL.sql b/db/changes/10310-mothersDay/00-ACL.sql index a2ae1e40f0..1067c02f74 100644 --- a/db/changes/10310-mothersDay/00-ACL.sql +++ b/db/changes/10310-mothersDay/00-ACL.sql @@ -1,2 +1,4 @@ INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) -VALUES ('SupplierAddress', '*', '*', 'ALLOW', 'ROLE', 'employee'); +VALUES + ('SupplierAddress', '*', '*', 'ALLOW', 'ROLE', 'employee'), + ('SalesMonitor', '*', '*', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index f386ad7806..79ab9f7639 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -277,7 +277,7 @@ INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city (106, 'DavidCharlesHaller', '53136686Q', 'Legion', 'Charles Xavier', 'City of New York, New York, USA', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'DavidCharlesHaller@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, 19, 0, 1), (107, 'Hank Pym', '09854837G', 'Ant man', 'Hawk', 'Anthill, San Francisco, California', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'HankPym@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 0, 0, NULL, 0, 0, 19, 0, 1), (108, 'Charles Xavier', '22641921P', 'Professor X', 'Beast', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1), - (109, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 0, 0, NULL, 0, 0, 19, 0, 1), + (109, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 0, 0, NULL, 0, 0, 9, 0, 1), (110, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 0, 0, NULL, 0, 0, NULL, 0, 1), (111, 'Missing', NULL, 'Missing man', 'Anton', 'The space, Universe far away', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, NULL, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1), (112, 'Trash', NULL, 'Garbage man', 'Unknown name', 'New York city, Underground', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, NULL, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1); @@ -1559,6 +1559,66 @@ INSERT INTO `hedera`.`orderRowComponent`(`rowFk`, `componentFk`, `price`) (30, 37, 2), (30, 39, 0.01); +INSERT INTO `hedera`.`visit`(`id`, `firstAgentFk`) + VALUES + (1, NULL), + (2, NULL), + (3, NULL), + (4, NULL), + (5, NULL), + (6, NULL), + (7, NULL), + (8, NULL), + (9, NULL); + +INSERT INTO `hedera`.`visitAgent`(`id`, `visitFk`) + VALUES + (1, 1), + (2, 2), + (3, 3), + (4, 4), + (5, 5), + (6, 6), + (7, 7), + (8, 8), + (9, 9); + +INSERT INTO `hedera`.`visitAccess`(`id`, `agentFk`, `stamp`) + VALUES + (1, 1, CURDATE()), + (2, 2, CURDATE()), + (3, 3, CURDATE()), + (4, 4, CURDATE()), + (5, 5, CURDATE()), + (6, 6, CURDATE()), + (7, 7, CURDATE()), + (8, 8, CURDATE()), + (9, 9, CURDATE()); + +INSERT INTO `hedera`.`visitUser`(`id`, `accessFk`, `userFk`, `stamp`) + VALUES + (1, 1, 101, CURDATE()), + (2, 2, 101, CURDATE()), + (3, 3, 101, CURDATE()), + (4, 4, 102, CURDATE()), + (5, 5, 102, CURDATE()), + (6, 6, 102, CURDATE()), + (7, 7, 103, CURDATE()), + (8, 8, 103, CURDATE()), + (9, 9, 103, CURDATE()); + +INSERT INTO `hedera`.`userSession`(`created`, `lastUpdate`, `ssid`, `data`, `userVisitFk`) + VALUES + (CURDATE(), CURDATE(), '121', 'data', 1), + (CURDATE(), CURDATE(), '122', 'data', 2), + (CURDATE(), CURDATE(), '123', 'data', 3), + (CURDATE(), CURDATE(), '124', 'data', 4), + (CURDATE(), CURDATE(), '125', 'data', 5), + (CURDATE(), CURDATE(), '126', 'data', 6), + (CURDATE(), CURDATE(), '127', 'data', 7), + (CURDATE(), CURDATE(), '128', 'data', 8), + (CURDATE(), CURDATE(), '129', 'data', 9); + INSERT INTO `vn`.`clientContact`(`id`, `clientFk`, `name`, `phone`) VALUES (1, 101, 'contact 1', 666777888), @@ -1688,11 +1748,12 @@ INSERT INTO `vn`.`receipt`(`id`, `invoiceFk`, `amountPaid`, `amountUnpaid`, `pay INSERT INTO `vn`.`workerTeam`(`id`, `team`, `workerFk`) VALUES (1, 1, 9), - (2, 1, 18), - (3, 2, 101), - (4, 2, 102), - (5, 3, 103), - (6, 3, 104); + (2, 2, 18), + (3, 2, 19), + (4, 3, 101), + (5, 3, 102), + (6, 4, 103), + (7, 4, 104); INSERT INTO `vn`.`ticketRequest`(`id`, `description`, `requesterFk`, `attenderFk`, `quantity`, `itemFk`, `price`, `isOk`, `saleFk`, `ticketFk`, `created`) VALUES diff --git a/front/core/components/button/style.scss b/front/core/components/button/style.scss index a3fc386e20..bb784c52a0 100644 --- a/front/core/components/button/style.scss +++ b/front/core/components/button/style.scss @@ -123,4 +123,12 @@ } } } + &.small { + height: 24px; + font-size: .75rem; + + & > button { + padding: 0 6px; + } + } } diff --git a/front/core/components/table/index.js b/front/core/components/table/index.js index eadb10cb59..a114ea379c 100644 --- a/front/core/components/table/index.js +++ b/front/core/components/table/index.js @@ -23,10 +23,21 @@ export default class Table { this.model.refresh(); } - $onChanges() { + isScrollable() { + return this.table.classList.contains('scrollable'); + } + + $postLink() { + if (this.isScrollable()) { + const childCells = this.table.querySelector('vn-tbody'); + console.log(childCells); + } + } + + /* $onChanges() { if (this.model && !this.model.data) this.applyOrder(); - } + } */ setActiveArrow() { let columns = this.table.querySelectorAll('vn-thead vn-th'); diff --git a/front/core/components/table/style.scss b/front/core/components/table/style.scss index 08106add4d..258061f1bc 100644 --- a/front/core/components/table/style.scss +++ b/front/core/components/table/style.scss @@ -20,7 +20,6 @@ vn-table { font-weight: normal; } & > * > vn-th[field] { - position: relative; overflow: visible; cursor: pointer } @@ -83,6 +82,11 @@ vn-table { } &[shrink-date] { width: 100px; + max-width: 100px; + } + &[shrink-datetime] { + width: 150px; + max-width: 150px; } &[expand] { max-width: 400px; @@ -182,4 +186,36 @@ vn-table { font-size: 1.375rem; text-align: center; } +} + + +vn-table.scrollable, +vn-table.scrollable > .vn-table, +.vn-table.scrollable { + border-collapse: separate; + overflow: auto; + + vn-thead, thead { + border-bottom: 0px solid transparent + } + + vn-thead th, + vn-thead vn-th, + thead vn-th, + thead th { + border-bottom: 2px solid $color-spacer; + background-color: #FFF; + position: sticky; + top: 0 + } +} + +vn-table.scrollable.sm, +.vn-table.scrollable.sm { + max-height: 300px +} + +vn-table.scrollable.lg, +.vn-table.scrollable.lg { + max-height: 700px } \ No newline at end of file diff --git a/modules/monitor/back/methods/sales-monitor/clientsFilter.js b/modules/monitor/back/methods/sales-monitor/clientsFilter.js new file mode 100644 index 0000000000..72b1307daa --- /dev/null +++ b/modules/monitor/back/methods/sales-monitor/clientsFilter.js @@ -0,0 +1,60 @@ + +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; + +module.exports = Self => { + Self.remoteMethod('clientsFilter', { + description: 'Find all instances of the model matched by filter from the data source.', + accepts: [ + { + arg: 'ctx', + type: 'object', + http: {source: 'context'} + }, + { + arg: 'filter', + type: 'object', + description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string` + } + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: '/clientsFilter', + verb: 'GET' + } + }); + + Self.clientsFilter = async(ctx, filter) => { + const userId = ctx.req.accessToken.userId; + const conn = Self.dataSource.connector; + + const stmt = new ParameterizedSQL(` + SELECT + u.name AS salesPerson, + IFNULL(sc.workerSubstitute, c.salesPersonFk) AS salesPersonFk, + c.id AS clientFk, + c.name AS clientName, + s.lastUpdate AS dated, + wtc.workerFk + FROM hedera.userSession s + JOIN hedera.visitUser v ON v.id = s.userVisitFk + JOIN client c ON c.id = v.userFk + LEFT JOIN account.user u ON c.salesPersonFk = u.id + LEFT JOIN worker w ON c.salesPersonFk = w.id + LEFT JOIN sharingCart sc ON sc.workerFk = c.salesPersonFk + AND CURDATE() BETWEEN sc.started AND sc.ended + LEFT JOIN workerTeamCollegues wtc + ON wtc.collegueFk = IFNULL(sc.workerSubstitute, c.salesPersonFk)`); + + if (!filter.where) filter.where = {}; + + const where = filter.where; + where['wtc.workerFk'] = userId; + + stmt.merge(conn.makeSuffix(filter)); + + return conn.executeStmt(stmt); + }; +}; diff --git a/modules/monitor/back/methods/sales-monitor/ordersFilter.js b/modules/monitor/back/methods/sales-monitor/ordersFilter.js new file mode 100644 index 0000000000..8c945a4c6e --- /dev/null +++ b/modules/monitor/back/methods/sales-monitor/ordersFilter.js @@ -0,0 +1,68 @@ + +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; + +module.exports = Self => { + Self.remoteMethod('ordersFilter', { + description: 'Find all instances of the model matched by filter from the data source.', + accepts: [ + { + arg: 'ctx', + type: 'object', + http: {source: 'context'} + }, + { + arg: 'filter', + type: 'object', + description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string` + } + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: '/ordersFilter', + verb: 'GET' + } + }); + + Self.ordersFilter = async(ctx, filter) => { + const userId = ctx.req.accessToken.userId; + const conn = Self.dataSource.connector; + + const stmt = new ParameterizedSQL(` + SELECT + c.id AS clientFk, + c.name AS clientName, + a.nickname, + o.id, + o.date_make, + o.date_send, + o.customer_id, + COUNT(item_id) AS totalRows, + ROUND(SUM(amount * price)) * 1 AS import, + u.id AS salesPersonFk, + u.name AS salesPerson, + am.name AS agencyName + FROM hedera.order o + JOIN hedera.order_row orw ON o.id = orw.order_id + JOIN client c ON c.id = o.customer_id + JOIN address a ON a.id = o.address_id + JOIN agencyMode am ON am.id = o.agency_id + JOIN user u ON u.id = c.salesPersonFk + JOIN workerTeamCollegues wtc ON c.salesPersonFk = wtc.collegueFk`); + + if (!filter.where) filter.where = {}; + + const where = filter.where; + where['o.confirmed'] = false; + where['o.date_send'] = {gt: '2001-01-01'}; + where['wtc.workerFk'] = userId; + + stmt.merge(conn.makeWhere(filter.where)); + stmt.merge(conn.makeGroupBy('o.id')); + stmt.merge(conn.makeLimit(filter)); + + return conn.executeStmt(stmt); + }; +}; diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js new file mode 100644 index 0000000000..726e5bfaf0 --- /dev/null +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -0,0 +1,319 @@ + +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; +const buildFilter = require('vn-loopback/util/filter').buildFilter; +const mergeFilters = require('vn-loopback/util/filter').mergeFilters; +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethod('salesFilter', { + description: 'Find all instances of the model matched by filter from the data source.', + accepts: [ + { + arg: 'ctx', + type: 'object', + http: {source: 'context'} + }, { + arg: 'filter', + type: 'object', + description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string` + }, { + arg: 'search', + type: 'string', + description: `If it's and number searchs by id, otherwise it searchs by nickname` + }, { + arg: 'from', + type: 'date', + description: `The from date filter` + }, { + arg: 'to', + type: 'date', + description: `The to date filter` + }, { + arg: 'nickname', + type: 'string', + description: `The nickname filter` + }, { + arg: 'id', + type: 'number', + description: `The ticket id filter` + }, { + arg: 'clientFk', + type: 'number', + description: `The client id filter` + }, { + arg: 'agencyModeFk', + type: 'number', + description: `The agency mode id filter` + }, { + arg: 'warehouseFk', + type: 'number', + description: `The warehouse id filter` + }, { + arg: 'salesPersonFk', + type: 'number', + description: `The salesperson id filter` + }, { + arg: 'provinceFk', + type: 'number', + description: `The province id filter` + }, { + arg: 'stateFk', + type: 'number', + description: `The state id filter` + }, { + arg: 'myTeam', + type: 'boolean', + description: `Whether to show only tickets for the current logged user team (For now it shows only the current user tickets)` + }, { + arg: 'problems', + type: 'boolean', + description: `Whether to show only tickets with problems` + }, { + arg: 'pending', + type: 'boolean', + description: `Whether to show only tickets with state 'Pending'` + }, { + arg: 'mine', + type: 'boolean', + description: `Whether to show only tickets for the current logged user` + }, { + arg: 'orderFk', + type: 'number', + description: `The order id filter` + }, { + arg: 'refFk', + type: 'string', + description: `The invoice reference filter` + }, { + arg: 'alertLevel', + type: 'number', + description: `The alert level of the tickets` + } + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: '/salesFilter', + verb: 'GET' + } + }); + + Self.salesFilter = async(ctx, filter) => { + const userId = ctx.req.accessToken.userId; + const conn = Self.dataSource.connector; + const models = Self.app.models; + const args = ctx.args; + + // Apply filter by team + const teamMembersId = []; + if (args.myTeam != null) { + const worker = await models.Worker.findById(userId, { + include: { + relation: 'collegues' + } + }); + const collegues = worker.collegues() || []; + collegues.forEach(collegue => { + teamMembersId.push(collegue.collegueFk); + }); + + if (teamMembersId.length == 0) + teamMembersId.push(userId); + } + + if (ctx.args && args.to) { + const dateTo = args.to; + dateTo.setHours(23, 59, 0, 0); + } + + const where = buildFilter(ctx.args, (param, value) => { + switch (param) { + case 'search': + return /^\d+$/.test(value) + ? {'t.id': {inq: value}} + : {'t.nickname': {like: `%${value}%`}}; + case 'from': + return {'t.shipped': {gte: value}}; + case 'to': + return {'t.shipped': {lte: value}}; + case 'nickname': + return {'t.nickname': {like: `%${value}%`}}; + case 'refFk': + return {'t.refFk': value}; + case 'salesPersonFk': + return {'c.salesPersonFk': value}; + case 'provinceFk': + return {'a.provinceFk': value}; + case 'stateFk': + return {'ts.stateFk': value}; + case 'mine': + case 'myTeam': + if (value) + return {'c.salesPersonFk': {inq: teamMembersId}}; + else + return {'c.salesPersonFk': {nin: teamMembersId}}; + + case 'alertLevel': + return {'ts.alertLevel': value}; + case 'pending': + if (value) { + return {and: [ + {'st.alertLevel': 0}, + {'st.code': {nin: [ + 'OK', + 'BOARDING', + 'PRINTED', + 'PRINTED_AUTO', + 'PICKER_DESIGNED' + ]}} + ]}; + } else { + return {and: [ + {'st.alertLevel': {gt: 0}} + ]}; + } + case 'id': + case 'clientFk': + case 'agencyModeFk': + case 'warehouseFk': + param = `t.${param}`; + return {[param]: value}; + } + }); + + filter = mergeFilters(filter, {where}); + + let stmts = []; + let stmt; + + stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.filter'); + stmt = new ParameterizedSQL( + `CREATE TEMPORARY TABLE tmp.filter + (INDEX (id)) + ENGINE = MEMORY + SELECT + t.id, + t.shipped, + CAST(DATE(t.shipped) AS CHAR) AS shippedDate, + HOUR(t.shipped) AS shippedHour, + t.nickname, + t.refFk, + t.routeFk, + t.warehouseFk, + t.clientFk, + t.totalWithoutVat, + t.totalWithVat, + io.id AS invoiceOutId, + a.provinceFk, + p.name AS province, + w.name AS warehouse, + am.name AS agencyMode, + am.id AS agencyModeFk, + st.name AS state, + wk.lastName AS salesPerson, + ts.stateFk AS stateFk, + ts.alertLevel AS alertLevel, + ts.code AS alertLevelCode, + u.name AS userName, + c.salesPersonFk, + z.hour AS zoneLanding, + HOUR(z.hour) AS zoneHour, + MINUTE(z.hour) AS zoneMinute, + z.name AS zoneName, + z.id AS zoneFk, + CAST(z.hour AS CHAR) AS hour + FROM ticket t + LEFT JOIN invoiceOut io ON t.refFk = io.ref + LEFT JOIN zone z ON z.id = t.zoneFk + LEFT JOIN address a ON a.id = t.addressFk + LEFT JOIN province p ON p.id = a.provinceFk + LEFT JOIN warehouse w ON w.id = t.warehouseFk + LEFT JOIN agencyMode am ON am.id = t.agencyModeFk + LEFT JOIN ticketState ts ON ts.ticketFk = t.id + LEFT JOIN state st ON st.id = ts.stateFk + LEFT JOIN client c ON c.id = t.clientFk + LEFT JOIN worker wk ON wk.id = c.salesPersonFk + LEFT JOIN account.user u ON u.id = wk.userFk`); + + if (args.orderFk) { + stmt.merge({ + sql: `JOIN orderTicket ot ON ot.ticketFk = t.id AND ot.orderFk = ?`, + params: [args.orderFk] + }); + } + + stmt.merge(conn.makeWhere(filter.where)); + stmts.push(stmt); + + stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticketGetProblems'); + + stmts.push(` + CREATE TEMPORARY TABLE tmp.ticketGetProblems + (INDEX (ticketFk)) + ENGINE = MEMORY + SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped + FROM tmp.filter f + LEFT JOIN alertLevel al ON al.alertLevel = f.alertLevel + WHERE (al.code = 'FREE' OR f.alertLevel IS NULL) + AND f.shipped >= CURDATE()`); + + stmts.push('CALL ticketGetProblems(FALSE)'); + + stmt = new ParameterizedSQL(` + SELECT + f.*, + tp.* + FROM tmp.filter f + LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id`); + + if (args.problems != undefined && (!args.from && !args.to)) + throw new UserError('Choose a date range or days forward'); + + let condition; + let hasProblem; + let range; + let hasWhere; + switch (args.problems) { + case true: + condition = `or`; + hasProblem = true; + range = 0; + hasWhere = true; + break; + + case false: + condition = `and`; + hasProblem = null; + range = null; + hasWhere = true; + break; + } + + let problems = {[condition]: [ + {'tp.isFreezed': hasProblem}, + {'tp.risk': hasProblem}, + {'tp.hasTicketRequest': hasProblem}, + {'tp.isAvailable': range} + ]}; + + if (hasWhere) + stmt.merge(conn.makeWhere(problems)); + + stmt.merge(conn.makeOrderBy(filter.order)); + stmt.merge(conn.makeLimit(filter)); + let ticketsIndex = stmts.push(stmt) - 1; + + stmts.push( + `DROP TEMPORARY TABLE + tmp.filter, + tmp.ticket, + tmp.ticketGetProblems`); + + let sql = ParameterizedSQL.join(stmts, ';'); + let result = await conn.executeStmt(sql); + + return result[ticketsIndex]; + }; +}; diff --git a/modules/monitor/back/methods/sales-monitor/specs/clientsFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/clientsFilter.spec.js new file mode 100644 index 0000000000..c01c65433b --- /dev/null +++ b/modules/monitor/back/methods/sales-monitor/specs/clientsFilter.spec.js @@ -0,0 +1,11 @@ +const app = require('vn-loopback/server/server'); + +fdescribe('SalesMonitor clientsFilter()', () => { + it('should return the clients web activity', async() => { + const ctx = {req: {accessToken: {userId: 18}}, args: {}}; + const filter = {order: 'dated DESC'}; + const result = await app.models.SalesMonitor.clientsFilter(ctx, filter); + + expect(result.length).toEqual(9); + }); +}); diff --git a/modules/monitor/back/methods/sales-monitor/specs/ordersFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/ordersFilter.spec.js new file mode 100644 index 0000000000..df2d9ef29f --- /dev/null +++ b/modules/monitor/back/methods/sales-monitor/specs/ordersFilter.spec.js @@ -0,0 +1,11 @@ +const app = require('vn-loopback/server/server'); + +describe('SalesMonitor ordersFilter()', () => { + it('should return the orders activity', async() => { + const ctx = {req: {accessToken: {userId: 18}}, args: {}}; + const filter = {order: 'dated DESC'}; + const result = await app.models.SalesMonitor.ordersFilter(ctx, filter); + + expect(result.length).toEqual(12); + }); +}); diff --git a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js new file mode 100644 index 0000000000..64cc35bfa0 --- /dev/null +++ b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js @@ -0,0 +1,106 @@ +const app = require('vn-loopback/server/server'); + +describe('SalesMonitor salesFilter()', () => { + it('should return the tickets matching the filter', async() => { + const ctx = {req: {accessToken: {userId: 9}}, args: {}}; + const filter = {order: 'id DESC'}; + const result = await app.models.SalesMonitor.salesFilter(ctx, filter); + + expect(result.length).toEqual(24); + }); + + it('should return the tickets matching the problems on true', async() => { + const yesterday = new Date(); + yesterday.setHours(0, 0, 0, 0); + const today = new Date(); + today.setHours(23, 59, 59, 59); + + const ctx = {req: {accessToken: {userId: 9}}, args: { + problems: true, + from: yesterday, + to: today + }}; + const filter = {}; + const result = await app.models.SalesMonitor.salesFilter(ctx, filter); + + expect(result.length).toEqual(3); + }); + + it('should return the tickets matching the problems on false', async() => { + const yesterday = new Date(); + yesterday.setDate(yesterday.getDate() - 1); + yesterday.setHours(0, 0, 0, 0); + const today = new Date(); + today.setHours(23, 59, 59, 59); + + const ctx = {req: {accessToken: {userId: 9}}, args: { + problems: false, + from: yesterday, + to: today + }}; + const filter = {}; + const result = await app.models.SalesMonitor.salesFilter(ctx, filter); + + expect(result.length).toEqual(7); + }); + + it('should return the tickets matching the problems on null', async() => { + const ctx = {req: {accessToken: {userId: 9}}, args: {problems: null}}; + const filter = {}; + const result = await app.models.SalesMonitor.salesFilter(ctx, filter); + + expect(result.length).toEqual(24); + }); + + it('should return the tickets matching the orderId 11', async() => { + const ctx = {req: {accessToken: {userId: 9}}, args: {orderFk: 11}}; + const filter = {}; + const result = await app.models.SalesMonitor.salesFilter(ctx, filter); + const firstRow = result[0]; + + expect(result.length).toEqual(1); + expect(firstRow.id).toEqual(11); + }); + + it('should return the tickets with grouped state "Pending" and not "Ok" nor "BOARDING"', async() => { + const ctx = {req: {accessToken: {userId: 9}}, args: {pending: true}}; + const filter = {}; + const result = await app.models.SalesMonitor.salesFilter(ctx, filter); + + const length = result.length; + const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; + + expect(length).toEqual(7); + expect(anyResult.state).toMatch(/(Libre|Arreglar)/); + }); + + it('should return the tickets that are not pending', async() => { + const ctx = {req: {accessToken: {userId: 9}}, args: {pending: false}}; + const filter = {}; + const result = await app.models.SalesMonitor.salesFilter(ctx, filter); + const firstRow = result[0]; + const secondRow = result[1]; + const thirdRow = result[2]; + + expect(result.length).toEqual(12); + expect(firstRow.state).toEqual('Entregado'); + expect(secondRow.state).toEqual('Entregado'); + expect(thirdRow.state).toEqual('Entregado'); + }); + + it('should return the tickets from the worker team', async() => { + const ctx = {req: {accessToken: {userId: 18}}, args: {myTeam: true}}; + const filter = {}; + const result = await app.models.SalesMonitor.salesFilter(ctx, filter); + + expect(result.length).toEqual(20); + }); + + it('should return the tickets that are not from the worker team', async() => { + const ctx = {req: {accessToken: {userId: 18}}, args: {myTeam: false}}; + const filter = {}; + const result = await app.models.SalesMonitor.salesFilter(ctx, filter); + + expect(result.length).toEqual(4); + }); +}); diff --git a/modules/monitor/back/model-config.json b/modules/monitor/back/model-config.json index 2c63c08510..3ba94c18d6 100644 --- a/modules/monitor/back/model-config.json +++ b/modules/monitor/back/model-config.json @@ -1,2 +1,5 @@ { + "SalesMonitor": { + "dataSource": "vn" + } } diff --git a/modules/monitor/back/models/sales-monitor.js b/modules/monitor/back/models/sales-monitor.js new file mode 100644 index 0000000000..63479cb9ac --- /dev/null +++ b/modules/monitor/back/models/sales-monitor.js @@ -0,0 +1,5 @@ +module.exports = Self => { + require('../methods/sales-monitor/salesFilter')(Self); + require('../methods/sales-monitor/clientsFilter')(Self); + require('../methods/sales-monitor/ordersFilter')(Self); +}; diff --git a/modules/monitor/back/models/sales-monitor.json b/modules/monitor/back/models/sales-monitor.json new file mode 100644 index 0000000000..eabdcf853a --- /dev/null +++ b/modules/monitor/back/models/sales-monitor.json @@ -0,0 +1,11 @@ +{ + "name": "SalesMonitor", + "base": "VnModel", + "acls": [{ + "property": "status", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] +} + \ No newline at end of file diff --git a/modules/monitor/front/index.js b/modules/monitor/front/index.js index cb25b3b8ca..292363b1dc 100644 --- a/modules/monitor/front/index.js +++ b/modules/monitor/front/index.js @@ -3,3 +3,7 @@ export * from './module'; import './main'; import './index/'; import './search-panel'; +import './index/tickets'; +import './index/clients'; +import './index/orders'; +import './index/search-panel'; diff --git a/modules/monitor/front/index/clients/index.html b/modules/monitor/front/index/clients/index.html new file mode 100644 index 0000000000..807cd7845e --- /dev/null +++ b/modules/monitor/front/index/clients/index.html @@ -0,0 +1,101 @@ + + + + + Clients on website + + + + + + + + + + + Hour + Salesperson + Client + + + + + + + {{::visit.dated | date: 'HH:mm'}} + + + + + {{::visit.salesPerson | dashIfEmpty}} + + + + + {{::visit.clientName}} + + + + + +
+ No results +
+ + +
+ + + + + + + + Filter by selection + + + Exclude selection + + + Remove filter + + + Remove all filters + + + Copy value + + + \ No newline at end of file diff --git a/modules/monitor/front/index/clients/index.js b/modules/monitor/front/index/clients/index.js new file mode 100644 index 0000000000..ce7e2ed090 --- /dev/null +++ b/modules/monitor/front/index/clients/index.js @@ -0,0 +1,30 @@ +import ngModule from '../../module'; +import Section from 'salix/components/section'; + +export default class Controller extends Section { + exprBuilder(param, value) { + switch (param) { + case 'dated': + return {'s.lastUpdate': { + between: this.dateRange(value)} + }; + case 'clientFk': + case 'salesPersonFk': + return {[`c.${param}`]: value}; + } + } + + dateRange(value) { + const minHour = new Date(value); + minHour.setHours(0, 0, 0, 0); + const maxHour = new Date(value); + maxHour.setHours(23, 59, 59, 59); + + return [minHour, maxHour]; + } +} + +ngModule.vnComponent('vnMonitorSalesClients', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/monitor/front/index/index.html b/modules/monitor/front/index/index.html index d04478bbc0..9374648913 100644 --- a/modules/monitor/front/index/index.html +++ b/modules/monitor/front/index/index.html @@ -1,160 +1,13 @@ - - - - - - - - - - - - - Id - Salesperson - Date - Hour - Closure - Alias - Province - State - Zone - Warehouse - Total - - - - - - - - - - - - - - - - - - - - - - {{::ticket.id}} - - - {{::ticket.userName | dashIfEmpty}} - - - - - {{::ticket.shipped | date: 'dd/MM/yyyy'}} - - - {{::ticket.shipped | date: 'HH:mm'}} - {{::ticket.zoneLanding | date: 'HH:mm'}} - - - {{::ticket.nickname}} - - - {{::ticket.province}} - - - {{::ticket.refFk}} - - - {{ticket.state}} - - - - - {{::ticket.zoneName | dashIfEmpty}} - - - {{::ticket.warehouse}} - - - {{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}} - - - - - - - - - - - - - + + + - - - b - + + - c + \ No newline at end of file diff --git a/modules/monitor/front/index/index.js b/modules/monitor/front/index/index.js index bd138d59af..9be66d6d80 100644 --- a/modules/monitor/front/index/index.js +++ b/modules/monitor/front/index/index.js @@ -1,6 +1,6 @@ import ngModule from '../module'; import Section from 'salix/components/section'; - +import './style.scss'; export default class Controller extends Section { openSummary(supplier, event) { if (event.defaultPrevented) return; diff --git a/modules/monitor/front/index/locale/es.yml b/modules/monitor/front/index/locale/es.yml index ad8a4f0bb7..b709d09228 100644 --- a/modules/monitor/front/index/locale/es.yml +++ b/modules/monitor/front/index/locale/es.yml @@ -1,5 +1,4 @@ -Payment deadline: Plazo de pago -Pay day: Dia de pago -Account: Cuenta -Pay method: Metodo de pago -Tax number: Nif \ No newline at end of file +Tickets monitor: Monitor de tickets +Clients on website: Clientes activos en la web +Recent order actions: Acciones recientes en pedidos +Search tickets: Buscar tickets \ No newline at end of file diff --git a/modules/monitor/front/index/orders/index.html b/modules/monitor/front/index/orders/index.html new file mode 100644 index 0000000000..d68815bd33 --- /dev/null +++ b/modules/monitor/front/index/orders/index.html @@ -0,0 +1,85 @@ + + + + + Recent order actions + + + + + + + + + + + Date + Client + Import + + + + + + + {{::order.date_send | date: 'dd/MM/yyyy'}} + + + + + {{::order.clientName}} + + + {{::order.import | currency: 'EUR':2}} + + + + + {{::order.date_make | date: 'dd/MM/yyyy HH:mm'}} + + + + + {{::order.agencyName | dashIfEmpty}} + + + + + {{::order.salesPerson | dashIfEmpty}} + + + + + +
+ No results +
+ + +
+ + + + diff --git a/modules/monitor/front/index/orders/index.js b/modules/monitor/front/index/orders/index.js new file mode 100644 index 0000000000..0a4c8c04f3 --- /dev/null +++ b/modules/monitor/front/index/orders/index.js @@ -0,0 +1,8 @@ +import ngModule from '../../module'; +import Section from 'salix/components/section'; +import './style.scss'; + +ngModule.vnComponent('vnMonitorSalesOrders', { + template: require('./index.html'), + controller: Section +}); diff --git a/modules/monitor/front/index/orders/style.scss b/modules/monitor/front/index/orders/style.scss new file mode 100644 index 0000000000..5f80472fe4 --- /dev/null +++ b/modules/monitor/front/index/orders/style.scss @@ -0,0 +1,16 @@ +@import "variables"; + +vn-monitor-sales-orders { + .dark-row { + background-color: lighten($color-marginal, 15%); + color: gray; + + vn-td { + border-bottom: 2px solid $color-marginal + } + } + + vn-tbody vn-tr:nth-child(3) { + height: inherit + } +} \ No newline at end of file diff --git a/modules/monitor/front/index/search-panel/index.html b/modules/monitor/front/index/search-panel/index.html new file mode 100644 index 0000000000..d0b77b9dea --- /dev/null +++ b/modules/monitor/front/index/search-panel/index.html @@ -0,0 +1,138 @@ +
+
+ + + + + + + + + + +
+ + + + + + Or + + + + + +
+ + + + + {{firstName}} {{name}} + + + + + + + + + + + + {{name}} + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/modules/monitor/front/index/search-panel/index.js b/modules/monitor/front/index/search-panel/index.js new file mode 100644 index 0000000000..057d555e46 --- /dev/null +++ b/modules/monitor/front/index/search-panel/index.js @@ -0,0 +1,59 @@ +import ngModule from '../../module'; +import SearchPanel from 'core/components/searchbar/search-panel'; + +class Controller extends SearchPanel { + constructor($, $element) { + super($, $element); + this.filter = this.$.filter; + + this.getGroupedStates(); + } + + getGroupedStates() { + let groupedStates = []; + this.$http.get('AlertLevels').then(res => { + for (let state of res.data) { + groupedStates.push({ + alertLevel: state.alertLevel, + code: state.code, + name: this.$t(state.code) + }); + } + this.groupedStates = groupedStates; + }); + } + + get from() { + return this._from; + } + + set from(value) { + this._from = value; + this.filter.scopeDays = null; + } + + get to() { + return this._to; + } + + set to(value) { + this._to = value; + this.filter.scopeDays = null; + } + + get scopeDays() { + return this._scopeDays; + } + + set scopeDays(value) { + this._scopeDays = value; + + this.filter.from = null; + this.filter.to = null; + } +} + +ngModule.vnComponent('vnMonitorSalesSearchPanel', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/monitor/front/index/search-panel/index.spec.js b/modules/monitor/front/index/search-panel/index.spec.js new file mode 100644 index 0000000000..f3a2f39edd --- /dev/null +++ b/modules/monitor/front/index/search-panel/index.spec.js @@ -0,0 +1,71 @@ +import './index'; + +describe('Ticket Component vnTicketSearchPanel', () => { + let $httpBackend; + let controller; + + beforeEach(ngModule('ticket')); + + beforeEach(inject(($componentController, _$httpBackend_) => { + $httpBackend = _$httpBackend_; + controller = $componentController('vnTicketSearchPanel', {$element: null}); + controller.$t = () => {}; + controller.filter = {}; + })); + + describe('getGroupedStates()', () => { + it('should set an array of groupedStates with the adition of a name translation', () => { + jest.spyOn(controller, '$t').mockReturnValue('miCodigo'); + const data = [ + { + alertLevel: 9999, + code: 'myCode' + } + ]; + $httpBackend.whenGET('AlertLevels').respond(data); + controller.getGroupedStates(); + $httpBackend.flush(); + + expect(controller.groupedStates).toEqual([{ + alertLevel: 9999, + code: 'myCode', + name: 'miCodigo' + }]); + }); + }); + + describe('from() setter', () => { + it('should clear the scope days when setting the from property', () => { + controller.filter.scopeDays = 1; + + controller.from = new Date(); + + expect(controller.filter.scopeDays).toBeNull(); + expect(controller.from).toBeDefined(); + }); + }); + + describe('to() setter', () => { + it('should clear the scope days when setting the to property', () => { + controller.filter.scopeDays = 1; + + controller.to = new Date(); + + expect(controller.filter.scopeDays).toBeNull(); + expect(controller.to).toBeDefined(); + }); + }); + + describe('scopeDays() setter', () => { + it('should clear the date range when setting the scopeDays property', () => { + controller.filter.from = new Date(); + controller.filter.to = new Date(); + + controller.scopeDays = 1; + + expect(controller.filter.from).toBeNull(); + expect(controller.filter.to).toBeNull(); + expect(controller.scopeDays).toBeDefined(); + }); + }); +}); diff --git a/modules/monitor/front/index/search-panel/locale/en.yml b/modules/monitor/front/index/search-panel/locale/en.yml new file mode 100644 index 0000000000..21ba978db3 --- /dev/null +++ b/modules/monitor/front/index/search-panel/locale/en.yml @@ -0,0 +1,4 @@ +FREE: Free +DELIVERED: Delivered +ON_PREPARATION: On preparation +PACKED: Packed \ No newline at end of file diff --git a/modules/monitor/front/index/search-panel/locale/es.yml b/modules/monitor/front/index/search-panel/locale/es.yml new file mode 100644 index 0000000000..5872609f99 --- /dev/null +++ b/modules/monitor/front/index/search-panel/locale/es.yml @@ -0,0 +1,21 @@ +Ticket id: Id ticket +Client id: Id cliente +Nickname: Alias +From: Desde +To: Hasta +Agency: Agencia +Warehouse: Almacén +Sales person: Comercial +Province: Provincia +My team: Mi equipo +Order id: Id cesta +Grouped States: Estado agrupado +Days onward: Días adelante +With problems: Con problemas +Pending: Pendiente +FREE: Libre +DELIVERED: Servido +ON_PREPARATION: En preparacion +PACKED: Encajado +Cannot choose a range of dates and days onward at the same time: No se puede selecionar un rango de fechas y días en adelante a la vez +Or: O \ No newline at end of file diff --git a/modules/monitor/front/index/style.scss b/modules/monitor/front/index/style.scss new file mode 100644 index 0000000000..4e0d9df2fd --- /dev/null +++ b/modules/monitor/front/index/style.scss @@ -0,0 +1,20 @@ +@import "variables"; +@import "effects"; + +vn-monitor-index { + .header { + padding: 12px 0; + color: gray; + font-size: 1.2rem; + + & > vn-none > vn-icon { + @extend %clickable-light; + color: $color-button; + font-size: 1.4rem; + } + } + .empty-rows { + color: $color-font-secondary; + text-align: center; + } +} \ No newline at end of file diff --git a/modules/monitor/front/index/tickets/index.html b/modules/monitor/front/index/tickets/index.html new file mode 100644 index 0000000000..049223ef2e --- /dev/null +++ b/modules/monitor/front/index/tickets/index.html @@ -0,0 +1,206 @@ + + + + + + + + + Tickets monitor + + + + + + + + + + + + Client + Salesperson + Date + Hour + Closure + Province + State + Zone + Total + + + + + + + + + + + + + + + + + + + + {{::ticket.nickname}} + + + + + {{::ticket.userName | dashIfEmpty}} + + + + + {{::ticket.shipped | date: 'dd/MM/yyyy'}} + + + {{::ticket.shipped | date: 'HH:mm'}} + {{::ticket.zoneLanding | date: 'HH:mm'}} + {{::ticket.province}} + + + {{::ticket.refFk}} + + + {{ticket.state}} + + + + + {{::ticket.zoneName | dashIfEmpty}} + + + + + {{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + Filter by selection + + + Exclude selection + + + Remove filter + + + Remove all filters + + + Copy value + + + diff --git a/modules/monitor/front/index/tickets/index.js b/modules/monitor/front/index/tickets/index.js new file mode 100644 index 0000000000..26581f1f60 --- /dev/null +++ b/modules/monitor/front/index/tickets/index.js @@ -0,0 +1,105 @@ +import ngModule from '../../module'; +import Section from 'salix/components/section'; +import './style.scss'; + +export default class Controller extends Section { + constructor($element, $) { + super($element, $); + + this.filterParams = this.fetchParams({ + scopeDays: 1 + }); + } + + fetchParams($params) { + if (!Object.entries($params).length) + $params.scopeDays = 1; + + if (typeof $params.scopeDays === 'number') { + const from = new Date(); + from.setHours(0, 0, 0, 0); + + const to = new Date(from.getTime()); + to.setDate(to.getDate() + $params.scopeDays); + to.setHours(23, 59, 59, 999); + + Object.assign($params, {from, to}); + } + + return $params; + } + + compareDate(date) { + let today = new Date(); + today.setHours(0, 0, 0, 0); + let timeTicket = new Date(date); + timeTicket.setHours(0, 0, 0, 0); + + let comparation = today - timeTicket; + + if (comparation == 0) + return 'warning'; + if (comparation < 0) + return 'success'; + } + + stateColor(ticket) { + if (ticket.alertLevelCode === 'OK') + return 'success'; + else if (ticket.alertLevelCode === 'FREE') + return 'notice'; + else if (ticket.alertLevel === 1) + return 'warning'; + else if (ticket.alertLevel === 0) + return 'alert'; + } + + totalPriceColor(ticket) { + const total = parseInt(ticket.totalWithVat); + if (total > 0 && total < 50) + return 'warning'; + } + + exprBuilder(param, value) { + switch (param) { + case 'stateFk': + return {'ts.stateFk': value}; + case 'salesPersonFk': + return {'c.salesPersonFk': value}; + case 'provinceFk': + return {'a.provinceFk': value}; + case 'hour': + return {'z.hour': value}; + case 'shipped': + return {'t.shipped': { + between: this.dateRange(value)} + }; + case 'id': + case 'refFk': + case 'zoneFk': + case 'nickname': + case 'agencyModeFk': + case 'warehouseFk': + return {[`t.${param}`]: value}; + } + } + + dateRange(value) { + const minHour = new Date(value); + minHour.setHours(0, 0, 0, 0); + const maxHour = new Date(value); + maxHour.setHours(23, 59, 59, 59); + + return [minHour, maxHour]; + } + + preview(ticket) { + this.selectedTicket = ticket; + this.$.summary.show(); + } +} + +ngModule.vnComponent('vnMonitorSalesTickets', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/monitor/front/index/tickets/style.scss b/modules/monitor/front/index/tickets/style.scss new file mode 100644 index 0000000000..b89ce8dbe8 --- /dev/null +++ b/modules/monitor/front/index/tickets/style.scss @@ -0,0 +1,19 @@ +vn-monitor-sales-tickets { + @media screen and (max-width: 1440px) { + .expendable { + display: none; + } + } + + vn-th.icon-field, + vn-th.icon-field *, + vn-td.icon-field, + vn-td.icon-field * { + padding: 0 + } + + vn-td.icon-field > vn-icon { + margin-left: 3px; + margin-right: 3px; + } +} \ No newline at end of file diff --git a/modules/monitor/front/locale/es.yml b/modules/monitor/front/locale/es.yml index abb6a9775c..da3b3f6232 100644 --- a/modules/monitor/front/locale/es.yml +++ b/modules/monitor/front/locale/es.yml @@ -1 +1,2 @@ -Accounts: Cuentas \ No newline at end of file +Monitors: Monitores +Sales monitor: Monitor de ventas \ No newline at end of file diff --git a/modules/monitor/front/routes.json b/modules/monitor/front/routes.json index f0c2d9e981..2b60b3572e 100644 --- a/modules/monitor/front/routes.json +++ b/modules/monitor/front/routes.json @@ -2,7 +2,7 @@ "module": "monitor", "name": "Monitors", "icon" : "icon-supplier", - "dependencies": ["ticket", "item"], + "dependencies": ["ticket", "worker", "client"], "validations" : true, "menus": { "main": [ From 88616862cbbaf1891a27426f38bb8318acc30b31 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 12 May 2021 09:12:46 +0200 Subject: [PATCH 06/21] Updated unit tests --- .../sales-monitor/specs/clientsFilter.spec.js | 2 +- .../front/index/search-panel/index.spec.js | 6 +- .../monitor/front/index/tickets/index.spec.js | 133 ++++++++++++++++++ .../back/methods/order/specs/filter.spec.js | 6 +- .../back/methods/ticket/specs/filter.spec.js | 8 +- 5 files changed, 144 insertions(+), 11 deletions(-) create mode 100644 modules/monitor/front/index/tickets/index.spec.js diff --git a/modules/monitor/back/methods/sales-monitor/specs/clientsFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/clientsFilter.spec.js index c01c65433b..c930b5dfbc 100644 --- a/modules/monitor/back/methods/sales-monitor/specs/clientsFilter.spec.js +++ b/modules/monitor/back/methods/sales-monitor/specs/clientsFilter.spec.js @@ -1,6 +1,6 @@ const app = require('vn-loopback/server/server'); -fdescribe('SalesMonitor clientsFilter()', () => { +describe('SalesMonitor clientsFilter()', () => { it('should return the clients web activity', async() => { const ctx = {req: {accessToken: {userId: 18}}, args: {}}; const filter = {order: 'dated DESC'}; diff --git a/modules/monitor/front/index/search-panel/index.spec.js b/modules/monitor/front/index/search-panel/index.spec.js index f3a2f39edd..0d19fd35fe 100644 --- a/modules/monitor/front/index/search-panel/index.spec.js +++ b/modules/monitor/front/index/search-panel/index.spec.js @@ -1,14 +1,14 @@ import './index'; -describe('Ticket Component vnTicketSearchPanel', () => { +describe('Monitor Component vnMonitorSalesSearchPanel', () => { let $httpBackend; let controller; - beforeEach(ngModule('ticket')); + beforeEach(ngModule('monitor')); beforeEach(inject(($componentController, _$httpBackend_) => { $httpBackend = _$httpBackend_; - controller = $componentController('vnTicketSearchPanel', {$element: null}); + controller = $componentController('vnMonitorSalesSearchPanel', {$element: null}); controller.$t = () => {}; controller.filter = {}; })); diff --git a/modules/monitor/front/index/tickets/index.spec.js b/modules/monitor/front/index/tickets/index.spec.js new file mode 100644 index 0000000000..fc689140a6 --- /dev/null +++ b/modules/monitor/front/index/tickets/index.spec.js @@ -0,0 +1,133 @@ +import './index.js'; +describe('Component vnMonitorSalesTickets', () => { + let controller; + let $window; + let tickets = [{ + id: 1, + clientFk: 1, + checked: false, + totalWithVat: 10.5 + }, { + id: 2, + clientFk: 1, + checked: true, + totalWithVat: 20.5 + }, { + id: 3, + clientFk: 1, + checked: true, + totalWithVat: 30 + }]; + + beforeEach(ngModule('monitor')); + + beforeEach(inject(($componentController, _$window_) => { + $window = _$window_; + const $element = angular.element(''); + controller = $componentController('vnMonitorSalesTickets', {$element}); + })); + + describe('fetchParams()', () => { + it('should return a range of dates with passed scope days', () => { + let params = controller.fetchParams({ + scopeDays: 2 + }); + const from = new Date(); + from.setHours(0, 0, 0, 0); + const to = new Date(from.getTime()); + to.setDate(to.getDate() + params.scopeDays); + to.setHours(23, 59, 59, 999); + + const expectedParams = { + from, + scopeDays: params.scopeDays, + to + }; + + expect(params).toEqual(expectedParams); + }); + + it('should return default value for scope days', () => { + let params = controller.fetchParams({ + scopeDays: 1 + }); + + expect(params.scopeDays).toEqual(1); + }); + + it('should return the given scope days', () => { + let params = controller.fetchParams({ + scopeDays: 2 + }); + + expect(params.scopeDays).toEqual(2); + }); + }); + + describe('compareDate()', () => { + it('should return warning when the date is the present', () => { + let today = new Date(); + let result = controller.compareDate(today); + + expect(result).toEqual('warning'); + }); + + it('should return sucess when the date is in the future', () => { + let futureDate = new Date(); + futureDate = futureDate.setDate(futureDate.getDate() + 10); + let result = controller.compareDate(futureDate); + + expect(result).toEqual('success'); + }); + + it('should return undefined when the date is in the past', () => { + let pastDate = new Date(); + pastDate = pastDate.setDate(pastDate.getDate() - 10); + let result = controller.compareDate(pastDate); + + expect(result).toEqual(undefined); + }); + }); + + describe('stateColor()', () => { + it('should return "success" when the alertLevelCode property is "OK"', () => { + const result = controller.stateColor({alertLevelCode: 'OK'}); + + expect(result).toEqual('success'); + }); + + it('should return "notice" when the alertLevelCode property is "FREE"', () => { + const result = controller.stateColor({alertLevelCode: 'FREE'}); + + expect(result).toEqual('notice'); + }); + + it('should return "warning" when the alertLevel property is "1', () => { + const result = controller.stateColor({alertLevel: 1}); + + expect(result).toEqual('warning'); + }); + + it('should return "alert" when the alertLevel property is "0"', () => { + const result = controller.stateColor({alertLevel: 0}); + + expect(result).toEqual('alert'); + }); + }); + + 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 + }); + controller.preview(event, tickets[0]); + + expect(controller.$.summary.show).toHaveBeenCalledWith(); + }); + }); +}); diff --git a/modules/order/back/methods/order/specs/filter.spec.js b/modules/order/back/methods/order/specs/filter.spec.js index 1e6022ccb7..1cc434cf1a 100644 --- a/modules/order/back/methods/order/specs/filter.spec.js +++ b/modules/order/back/methods/order/specs/filter.spec.js @@ -23,11 +23,11 @@ describe('order filter()', () => { }); it('should call the filter method with a complex advanced search', async() => { - const filter = {where: {'o.confirmed': false, 'c.salesPersonFk': 19}}; + const filter = {where: {'o.confirmed': false, 'c.salesPersonFk': 18}}; const result = await app.models.Order.filter(ctx, filter); - expect(result.length).toEqual(7); - expect(result[0].id).toEqual(16); + expect(result.length).toEqual(9); + expect(result[0].id).toEqual(7); }); it('should return the orders matching the showEmpty on false', async() => { diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js index 2ca8bcf44e..7798b156e1 100644 --- a/modules/ticket/back/methods/ticket/specs/filter.spec.js +++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js @@ -89,18 +89,18 @@ describe('ticket filter()', () => { }); it('should return the tickets from the worker team', async() => { - const ctx = {req: {accessToken: {userId: 9}}, args: {myTeam: true}}; + const ctx = {req: {accessToken: {userId: 18}}, args: {myTeam: true}}; const filter = {}; const result = await app.models.Ticket.filter(ctx, filter); - expect(result.length).toEqual(17); + expect(result.length).toEqual(20); }); it('should return the tickets that are not from the worker team', async() => { - const ctx = {req: {accessToken: {userId: 9}}, args: {myTeam: false}}; + const ctx = {req: {accessToken: {userId: 18}}, args: {myTeam: false}}; const filter = {}; const result = await app.models.Ticket.filter(ctx, filter); - expect(result.length).toEqual(7); + expect(result.length).toEqual(4); }); }); From 2e7d56cc268d8fb1b9487dd340793b186652357e Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 12 May 2021 12:11:27 +0200 Subject: [PATCH 07/21] Test fixes --- front/core/components/table/index.js | 5 ----- front/core/components/th/index.js | 5 ++++- modules/entry/front/latest-buys/index.html | 3 ++- modules/entry/front/routes.json | 2 +- modules/order/front/index/index.html | 2 +- modules/ticket/front/request/create/index.html | 2 +- modules/ticket/front/sale/index.html | 5 +++-- modules/travel/front/extra-community/index.html | 5 +++-- modules/zone/front/upcoming-deliveries/index.html | 5 +++-- 9 files changed, 18 insertions(+), 16 deletions(-) diff --git a/front/core/components/table/index.js b/front/core/components/table/index.js index a114ea379c..81eff872ce 100644 --- a/front/core/components/table/index.js +++ b/front/core/components/table/index.js @@ -34,11 +34,6 @@ export default class Table { } } - /* $onChanges() { - if (this.model && !this.model.data) - this.applyOrder(); - } */ - setActiveArrow() { let columns = this.table.querySelectorAll('vn-thead vn-th'); columns.forEach(column => { diff --git a/front/core/components/th/index.js b/front/core/components/th/index.js index b9ea8fde8a..341558fb1c 100644 --- a/front/core/components/th/index.js +++ b/front/core/components/th/index.js @@ -14,8 +14,11 @@ export default class Th { $onInit() { if (!this.field) return; - if (this.defaultOrder) + if (this.defaultOrder) { this.order = this.defaultOrder; + this.table.applyOrder(this.field, this.order); + this.updateArrow(); + } this.updateArrow(); } diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html index 277b1b3475..5fa0924855 100644 --- a/modules/entry/front/latest-buys/index.html +++ b/modules/entry/front/latest-buys/index.html @@ -2,7 +2,8 @@ vn-id="model" url="Buys/latestBuysFilter" limit="20" - data="$ctrl.buys"> + data="$ctrl.buys" + auto-load="true"> Client Confirmed Created - Landed + Landed Hour Agency Total diff --git a/modules/ticket/front/request/create/index.html b/modules/ticket/front/request/create/index.html index f7280b2de3..8d25358b52 100644 --- a/modules/ticket/front/request/create/index.html +++ b/modules/ticket/front/request/create/index.html @@ -20,7 +20,7 @@ ng-model="$ctrl.ticketRequest.attenderFk" url="Workers/activeWithRole" show-field="nickname" - where="{role: 'buyer'}" + where="{role: {inq: ['logistic', 'buyer']}}" search-function="{firstName: $search}"> diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index d4dfe1a8a9..5bba457caf 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -1,7 +1,8 @@ - + data="$ctrl.sales" + auto-load="true"> + limit="20" + auto-load="true"> + data="details" + auto-load="true"> From b828609d33a349dfd6e0cbbd6944e511464bf59a Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 12 May 2021 12:39:45 +0200 Subject: [PATCH 08/21] Ammends --- front/salix/locale/es.yml | 1 + modules/monitor/front/index/orders/index.html | 4 ++-- modules/monitor/front/index/tickets/index.html | 2 +- modules/monitor/front/index/tickets/style.scss | 4 ++++ modules/monitor/front/locale/es.yml | 1 - modules/monitor/front/routes.json | 4 ++-- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/front/salix/locale/es.yml b/front/salix/locale/es.yml index ae7eb1da7d..5e877c372e 100644 --- a/front/salix/locale/es.yml +++ b/front/salix/locale/es.yml @@ -47,6 +47,7 @@ Invoices in: Fact. recibidas Entries: Entradas Users: Usuarios Suppliers: Proveedores +Monitors: Monitores # Common diff --git a/modules/monitor/front/index/orders/index.html b/modules/monitor/front/index/orders/index.html index d68815bd33..42bb470b31 100644 --- a/modules/monitor/front/index/orders/index.html +++ b/modules/monitor/front/index/orders/index.html @@ -20,9 +20,9 @@ - Date + Date Client - Import + Import diff --git a/modules/monitor/front/index/tickets/index.html b/modules/monitor/front/index/tickets/index.html index 049223ef2e..8fc3e09d99 100644 --- a/modules/monitor/front/index/tickets/index.html +++ b/modules/monitor/front/index/tickets/index.html @@ -2,7 +2,7 @@ vn-id="model" params="::$ctrl.filterParams" url="SalesMonitors/salesFilter" - limit="18" + limit="20" order="shippedDate DESC, shippedHour ASC, zoneLanding ASC, id"> diff --git a/modules/monitor/front/index/tickets/style.scss b/modules/monitor/front/index/tickets/style.scss index b89ce8dbe8..f3931e6ec7 100644 --- a/modules/monitor/front/index/tickets/style.scss +++ b/modules/monitor/front/index/tickets/style.scss @@ -16,4 +16,8 @@ vn-monitor-sales-tickets { margin-left: 3px; margin-right: 3px; } + + vn-table.scrollable.lg { + height: 736px + } } \ No newline at end of file diff --git a/modules/monitor/front/locale/es.yml b/modules/monitor/front/locale/es.yml index da3b3f6232..7d7e72f6b2 100644 --- a/modules/monitor/front/locale/es.yml +++ b/modules/monitor/front/locale/es.yml @@ -1,2 +1 @@ -Monitors: Monitores Sales monitor: Monitor de ventas \ No newline at end of file diff --git a/modules/monitor/front/routes.json b/modules/monitor/front/routes.json index 2b60b3572e..8fc995e4cf 100644 --- a/modules/monitor/front/routes.json +++ b/modules/monitor/front/routes.json @@ -1,12 +1,12 @@ { "module": "monitor", "name": "Monitors", - "icon" : "icon-supplier", + "icon" : "grid_view", "dependencies": ["ticket", "worker", "client"], "validations" : true, "menus": { "main": [ - {"state": "monitor.index", "icon": "leaderboard"} + {"state": "monitor.index", "icon": "grid_view"} ], "card": [] }, From eecba426eea4a63d1d3ea27499c3f35c80507696 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 12 May 2021 13:00:54 +0200 Subject: [PATCH 09/21] Removed unused class --- modules/monitor/front/index/clients/index.html | 2 +- modules/monitor/front/index/orders/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/monitor/front/index/clients/index.html b/modules/monitor/front/index/clients/index.html index 807cd7845e..bfa496199c 100644 --- a/modules/monitor/front/index/clients/index.html +++ b/modules/monitor/front/index/clients/index.html @@ -17,7 +17,7 @@ - + Hour diff --git a/modules/monitor/front/index/orders/index.html b/modules/monitor/front/index/orders/index.html index 42bb470b31..293b1fd8c0 100644 --- a/modules/monitor/front/index/orders/index.html +++ b/modules/monitor/front/index/orders/index.html @@ -17,7 +17,7 @@ - + Date From 6f5df10413962eb2663d9e8cb80feddb00718fab Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 12 May 2021 13:06:36 +0200 Subject: [PATCH 10/21] Removed controller --- modules/monitor/front/index/index.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/modules/monitor/front/index/index.js b/modules/monitor/front/index/index.js index 9be66d6d80..4807cf1c98 100644 --- a/modules/monitor/front/index/index.js +++ b/modules/monitor/front/index/index.js @@ -1,18 +1,8 @@ import ngModule from '../module'; import Section from 'salix/components/section'; import './style.scss'; -export default class Controller extends Section { - openSummary(supplier, event) { - if (event.defaultPrevented) return; - event.preventDefault(); - event.stopPropagation(); - - this.supplierSelected = supplier; - this.$.dialogSummarySupplier.show(); - } -} ngModule.vnComponent('vnMonitorIndex', { template: require('./index.html'), - controller: Controller + controller: Section }); From 65f0cb461249623d3ff5367e46f31318c9c8fdda Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 12 May 2021 13:14:41 +0200 Subject: [PATCH 11/21] More ammends --- modules/monitor/front/log/index.html | 1 - modules/monitor/front/log/index.js | 7 ------- modules/monitor/front/main/index.html | 8 -------- 3 files changed, 16 deletions(-) delete mode 100644 modules/monitor/front/log/index.html delete mode 100644 modules/monitor/front/log/index.js diff --git a/modules/monitor/front/log/index.html b/modules/monitor/front/log/index.html deleted file mode 100644 index 7895b585e1..0000000000 --- a/modules/monitor/front/log/index.html +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/modules/monitor/front/log/index.js b/modules/monitor/front/log/index.js deleted file mode 100644 index 52a491c708..0000000000 --- a/modules/monitor/front/log/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import ngModule from '../module'; -import Section from 'salix/components/section'; - -ngModule.vnComponent('vnSupplierLog', { - template: require('./index.html'), - controller: Section, -}); diff --git a/modules/monitor/front/main/index.html b/modules/monitor/front/main/index.html index 9a7c8bc873..6e04f06d02 100644 --- a/modules/monitor/front/main/index.html +++ b/modules/monitor/front/main/index.html @@ -1,11 +1,3 @@ - From 873fc54dff6662e2329cfd0c177e154e19e07762 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 12 May 2021 13:18:58 +0200 Subject: [PATCH 12/21] More ammends --- modules/monitor/front/index.js | 1 - .../front/index/search-panel/locale/en.yml | 4 -- .../front/index/search-panel/locale/es.yml | 21 --------- modules/monitor/front/search-panel/index.html | 46 ------------------- modules/monitor/front/search-panel/index.js | 7 --- .../monitor/front/search-panel/locale/es.yml | 4 -- 6 files changed, 83 deletions(-) delete mode 100644 modules/monitor/front/index/search-panel/locale/en.yml delete mode 100644 modules/monitor/front/index/search-panel/locale/es.yml delete mode 100644 modules/monitor/front/search-panel/index.html delete mode 100644 modules/monitor/front/search-panel/index.js delete mode 100644 modules/monitor/front/search-panel/locale/es.yml diff --git a/modules/monitor/front/index.js b/modules/monitor/front/index.js index 292363b1dc..19ea06b5a1 100644 --- a/modules/monitor/front/index.js +++ b/modules/monitor/front/index.js @@ -2,7 +2,6 @@ export * from './module'; import './main'; import './index/'; -import './search-panel'; import './index/tickets'; import './index/clients'; import './index/orders'; diff --git a/modules/monitor/front/index/search-panel/locale/en.yml b/modules/monitor/front/index/search-panel/locale/en.yml deleted file mode 100644 index 21ba978db3..0000000000 --- a/modules/monitor/front/index/search-panel/locale/en.yml +++ /dev/null @@ -1,4 +0,0 @@ -FREE: Free -DELIVERED: Delivered -ON_PREPARATION: On preparation -PACKED: Packed \ No newline at end of file diff --git a/modules/monitor/front/index/search-panel/locale/es.yml b/modules/monitor/front/index/search-panel/locale/es.yml deleted file mode 100644 index 5872609f99..0000000000 --- a/modules/monitor/front/index/search-panel/locale/es.yml +++ /dev/null @@ -1,21 +0,0 @@ -Ticket id: Id ticket -Client id: Id cliente -Nickname: Alias -From: Desde -To: Hasta -Agency: Agencia -Warehouse: Almacén -Sales person: Comercial -Province: Provincia -My team: Mi equipo -Order id: Id cesta -Grouped States: Estado agrupado -Days onward: Días adelante -With problems: Con problemas -Pending: Pendiente -FREE: Libre -DELIVERED: Servido -ON_PREPARATION: En preparacion -PACKED: Encajado -Cannot choose a range of dates and days onward at the same time: No se puede selecionar un rango de fechas y días en adelante a la vez -Or: O \ No newline at end of file diff --git a/modules/monitor/front/search-panel/index.html b/modules/monitor/front/search-panel/index.html deleted file mode 100644 index 161c8a98cd..0000000000 --- a/modules/monitor/front/search-panel/index.html +++ /dev/null @@ -1,46 +0,0 @@ -
-
- - - - - - - - - - - - - - - - - - - -
-
\ No newline at end of file diff --git a/modules/monitor/front/search-panel/index.js b/modules/monitor/front/search-panel/index.js deleted file mode 100644 index 6223b5670a..0000000000 --- a/modules/monitor/front/search-panel/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import ngModule from '../module'; -import SearchPanel from 'core/components/searchbar/search-panel'; - -ngModule.vnComponent('vnSupplierSearchPanel', { - template: require('./index.html'), - controller: SearchPanel -}); diff --git a/modules/monitor/front/search-panel/locale/es.yml b/modules/monitor/front/search-panel/locale/es.yml deleted file mode 100644 index 77253a4efa..0000000000 --- a/modules/monitor/front/search-panel/locale/es.yml +++ /dev/null @@ -1,4 +0,0 @@ -Province: Provincia -Country: País -Tax number: NIF / CIF -Search suppliers by id, name or alias: Busca proveedores por id, nombre o alias \ No newline at end of file From 9363726d67447b12cc1a31a2ba7975d455bcdbb9 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 12 May 2021 13:37:01 +0200 Subject: [PATCH 13/21] Updated unit test --- modules/entry/front/latest-buys/index.spec.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/entry/front/latest-buys/index.spec.js b/modules/entry/front/latest-buys/index.spec.js index 658a2dc86c..6f86650c9d 100644 --- a/modules/entry/front/latest-buys/index.spec.js +++ b/modules/entry/front/latest-buys/index.spec.js @@ -66,6 +66,13 @@ describe('Entry', () => { describe('onEditAccept()', () => { it(`should perform a query to update columns`, () => { + $httpBackend.whenGET('UserConfigViews/getConfig?tableCode=latestBuys').respond([]); + $httpBackend.whenGET('Buys/latestBuysFilter?filter=%7B%22limit%22:20%7D').respond([ + {entryFk: 1}, + {entryFk: 2}, + {entryFk: 3}, + {entryFk: 4} + ]); controller.editedColumn = {field: 'my field', newValue: 'the new value'}; let query = 'Buys/editLatestBuys'; From 6a3cb7f724ac0acee7a6d47babbba935ce5522ae Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 12 May 2021 14:17:28 +0200 Subject: [PATCH 14/21] Added new version --- db/changes/10320-monitors/.keep | 1 + 1 file changed, 1 insertion(+) create mode 100644 db/changes/10320-monitors/.keep diff --git a/db/changes/10320-monitors/.keep b/db/changes/10320-monitors/.keep new file mode 100644 index 0000000000..3a94d75a80 --- /dev/null +++ b/db/changes/10320-monitors/.keep @@ -0,0 +1 @@ +Delete me \ No newline at end of file From b3cbf9374c3fb78b53c300932369585434ffbf4e Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 12 May 2021 14:22:29 +0200 Subject: [PATCH 15/21] Hotfix: Catalog items without ink --- modules/order/back/methods/order/catalogFilter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/order/back/methods/order/catalogFilter.js b/modules/order/back/methods/order/catalogFilter.js index b2d49054d0..4502435b53 100644 --- a/modules/order/back/methods/order/catalogFilter.js +++ b/modules/order/back/methods/order/catalogFilter.js @@ -118,8 +118,8 @@ module.exports = Self => { FROM tmp.ticketCalculateItem tci JOIN vn.item i ON i.id = tci.itemFk JOIN vn.itemType it ON it.id = i.typeFk - JOIN vn.ink ON ink.id = i.inkFk - JOIN vn.worker w on w.id = it.workerFk`); + JOIN vn.worker w on w.id = it.workerFk + LEFT JOIN vn.ink ON ink.id = i.inkFk`); // Apply order by tag if (orderBy.isTag) { From 7e4b540af11d839374a98c7128af45a9389e5b94 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 12 May 2021 14:47:00 +0200 Subject: [PATCH 16/21] Updated company address --- print/core/components/email-footer/locale/es.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/print/core/components/email-footer/locale/es.yml b/print/core/components/email-footer/locale/es.yml index 7f4b130454..1269a3e607 100644 --- a/print/core/components/email-footer/locale/es.yml +++ b/print/core/components/email-footer/locale/es.yml @@ -1,7 +1,7 @@ buttons: webAcccess: Visita nuestra Web info: Ayúdanos a mejorar -fiscalAddress: VERDNATURA LEVANTE SL, B97367486 Avda. Espioca, 100, 46460 Silla +fiscalAddress: VERDNATURA LEVANTE SL, B97367486 C/ Fenollar, 2. 46680 ALGEMESI · www.verdnatura.es · clientes@verdnatura.es disclaimer: '- AVISO - Este mensaje es privado y confidencial, y debe ser utilizado exclusivamente por la persona destinataria del mismo. Si has recibido este mensaje From 8af66a7ca594008f93efc7b248bddd3c090edfc8 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 12 May 2021 15:11:07 +0200 Subject: [PATCH 17/21] HOTFIX: Sort by column --- front/core/components/table/index.js | 7 ------- modules/monitor/back/methods/sales-monitor/ordersFilter.js | 2 +- modules/monitor/front/index/orders/index.html | 6 +++--- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/front/core/components/table/index.js b/front/core/components/table/index.js index 81eff872ce..f795ca9713 100644 --- a/front/core/components/table/index.js +++ b/front/core/components/table/index.js @@ -27,13 +27,6 @@ export default class Table { return this.table.classList.contains('scrollable'); } - $postLink() { - if (this.isScrollable()) { - const childCells = this.table.querySelector('vn-tbody'); - console.log(childCells); - } - } - setActiveArrow() { let columns = this.table.querySelectorAll('vn-thead vn-th'); columns.forEach(column => { diff --git a/modules/monitor/back/methods/sales-monitor/ordersFilter.js b/modules/monitor/back/methods/sales-monitor/ordersFilter.js index 8c945a4c6e..bc9ab3bdff 100644 --- a/modules/monitor/back/methods/sales-monitor/ordersFilter.js +++ b/modules/monitor/back/methods/sales-monitor/ordersFilter.js @@ -61,7 +61,7 @@ module.exports = Self => { stmt.merge(conn.makeWhere(filter.where)); stmt.merge(conn.makeGroupBy('o.id')); - stmt.merge(conn.makeLimit(filter)); + stmt.merge(conn.makePagination(filter)); return conn.executeStmt(stmt); }; diff --git a/modules/monitor/front/index/orders/index.html b/modules/monitor/front/index/orders/index.html index 293b1fd8c0..9bb4d36086 100644 --- a/modules/monitor/front/index/orders/index.html +++ b/modules/monitor/front/index/orders/index.html @@ -1,8 +1,8 @@ - + order="date_make DESC"> @@ -20,7 +20,7 @@ - Date + Date Client Import From e6e91ced99ebd25661a64fae904dd20db6728544 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 13 May 2021 08:56:26 +0200 Subject: [PATCH 18/21] 2905 - Restore ticket shipped and landed --- db/dump/structure.sql | 6 +- modules/ticket/back/methods/ticket/restore.js | 22 +++++- .../back/methods/ticket/specs/restore.spec.js | 72 ++++++++++--------- 3 files changed, 59 insertions(+), 41 deletions(-) diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 8bc0aed8f2..407770aef2 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -36802,11 +36802,7 @@ BEGIN `body` = CONCAT(account.myUserGetName(), ' ha modificado el ticket ', NEW.id); END IF; - - IF !(DATE(NEW.shipped) <=> DATE(OLD.shipped)) AND DATE(NEW.shipped) = CURDATE() THEN - INSERT INTO tmp.ticketDate_updated(ticketFk, oldShipped, newShipped, workerFk) - VALUES (NEW.id, OLD.shipped, NEW.shipped, vn.getUser()); - END IF; + END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index 19429f61b2..6a0d65a174 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -21,9 +21,15 @@ module.exports = Self => { } }); - Self.restore = async(ctx, id) => { + Self.restore = async(ctx, id, options) => { const models = Self.app.models; const $t = ctx.req.__; // $translate + + let myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + const ticket = await models.Ticket.findById(id, { include: [{ relation: 'client', @@ -31,7 +37,7 @@ module.exports = Self => { fields: ['id', 'salesPersonFk'] } }] - }); + }, myOptions); const now = new Date(); const maxDate = new Date(ticket.updated); @@ -51,6 +57,16 @@ module.exports = Self => { await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); } - return ticket.updateAttribute('isDeleted', false); + const fullYear = new Date().getFullYear(); + const newShipped = ticket.shipped; + const newLanded = ticket.landed; + newShipped.setFullYear(fullYear); + newLanded.setFullYear(fullYear); + + return ticket.updateAttributes({ + shipped: newShipped, + landed: newLanded, + isDeleted: false + }, myOptions); }; }; diff --git a/modules/ticket/back/methods/ticket/specs/restore.spec.js b/modules/ticket/back/methods/ticket/specs/restore.spec.js index 97cf78f91b..52135fc542 100644 --- a/modules/ticket/back/methods/ticket/specs/restore.spec.js +++ b/modules/ticket/back/methods/ticket/specs/restore.spec.js @@ -4,6 +4,7 @@ const models = app.models; describe('ticket restore()', () => { const employeeUser = 110; + const ticketId = 18; const activeCtx = { accessToken: {userId: employeeUser}, headers: { @@ -13,45 +14,30 @@ describe('ticket restore()', () => { }; const ctx = {req: activeCtx}; - let createdTicket; - - beforeEach(async done => { + beforeEach(() => { spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ active: activeCtx }); - try { - const sampleTicket = await models.Ticket.findById(11); - sampleTicket.id = undefined; - - createdTicket = await models.Ticket.create(sampleTicket); - } catch (error) { - console.error(error); - } - - done(); - }); - - afterEach(async done => { - try { - await models.Ticket.destroyById(createdTicket.id); - } catch (error) { - console.error(error); - } - - done(); }); it('should throw an error if the given ticket has past the deletion time', async() => { let error; + const tx = await app.models.Ticket.beginTransaction({}); const now = new Date(); now.setHours(now.getHours() - 1); try { - const ticket = await models.Ticket.findById(createdTicket.id); - await ticket.updateAttributes({isDeleted: true, updated: now}); - await app.models.Ticket.restore(ctx, createdTicket.id); + const options = {transaction: tx}; + const ticket = await models.Ticket.findById(ticketId, null, options); + await ticket.updateAttributes({ + isDeleted: true, + updated: now + }, options); + await app.models.Ticket.restore(ctx, ticketId, options); + await tx.rollback(); } catch (e) { + await tx.rollback(); error = e; } @@ -59,17 +45,37 @@ describe('ticket restore()', () => { }); it('should restore the ticket making its state no longer deleted', async() => { + const tx = await app.models.Ticket.beginTransaction({}); const now = new Date(); - const ticketBeforeUpdate = await models.Ticket.findById(createdTicket.id); - await ticketBeforeUpdate.updateAttributes({isDeleted: true, updated: now}); - const ticketAfterUpdate = await models.Ticket.findById(createdTicket.id); + try { + const options = {transaction: tx}; - expect(ticketAfterUpdate.isDeleted).toBeTruthy(); + const ticketBeforeUpdate = await models.Ticket.findById(ticketId, null, options); + await ticketBeforeUpdate.updateAttributes({ + isDeleted: true, + updated: now + }, options); - await models.Ticket.restore(ctx, createdTicket.id); - const ticketAfterRestore = await models.Ticket.findById(createdTicket.id); + const ticketAfterUpdate = await models.Ticket.findById(ticketId, null, options); - expect(ticketAfterRestore.isDeleted).toBeFalsy(); + expect(ticketAfterUpdate.isDeleted).toBeTruthy(); + + await models.Ticket.restore(ctx, ticketId, options); + const ticketAfterRestore = await models.Ticket.findById(ticketId, null, options); + + const fullYear = now.getFullYear(); + const shippedFullYear = ticketAfterRestore.shipped.getFullYear(); + const landedFullYear = ticketAfterRestore.landed.getFullYear(); + + expect(ticketAfterRestore.isDeleted).toBeFalsy(); + expect(shippedFullYear).toEqual(fullYear); + expect(landedFullYear).toEqual(fullYear); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } }); }); From af49a66911297fd2cd5c773b8dd753858aee2eac Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 13 May 2021 08:57:49 +0200 Subject: [PATCH 19/21] Unit test fix --- .../back/methods/sales-monitor/specs/ordersFilter.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/monitor/back/methods/sales-monitor/specs/ordersFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/ordersFilter.spec.js index df2d9ef29f..26894f25d5 100644 --- a/modules/monitor/back/methods/sales-monitor/specs/ordersFilter.spec.js +++ b/modules/monitor/back/methods/sales-monitor/specs/ordersFilter.spec.js @@ -3,7 +3,7 @@ const app = require('vn-loopback/server/server'); describe('SalesMonitor ordersFilter()', () => { it('should return the orders activity', async() => { const ctx = {req: {accessToken: {userId: 18}}, args: {}}; - const filter = {order: 'dated DESC'}; + const filter = {order: 'date_make DESC'}; const result = await app.models.SalesMonitor.ordersFilter(ctx, filter); expect(result.length).toEqual(12); From 4a1d286a95451e078029462c2a87761aeb1e5b88 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 13 May 2021 09:17:49 +0200 Subject: [PATCH 20/21] 2907 - Proper claim rate percentage --- modules/client/front/summary/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/client/front/summary/index.html b/modules/client/front/summary/index.html index b1ec1f7810..8a4f6eec74 100644 --- a/modules/client/front/summary/index.html +++ b/modules/client/front/summary/index.html @@ -234,7 +234,7 @@ value="{{$ctrl.summary.mana.mana | currency: 'EUR':2}}"> + value="{{$ctrl.claimRate($ctrl.summary.claimsRatio.priceIncreasing / 100) | percentage}}"> From 6fdb91fdc8768ed1fb4095495f1f4036f83a2561 Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 13 May 2021 10:20:22 +0200 Subject: [PATCH 21/21] Removed line --- modules/ticket/back/methods/ticket/restore.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/ticket/back/methods/ticket/restore.js b/modules/ticket/back/methods/ticket/restore.js index 6a0d65a174..a3a79dc7cf 100644 --- a/modules/ticket/back/methods/ticket/restore.js +++ b/modules/ticket/back/methods/ticket/restore.js @@ -24,8 +24,7 @@ module.exports = Self => { Self.restore = async(ctx, id, options) => { const models = Self.app.models; const $t = ctx.req.__; // $translate - - let myOptions = {}; + const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options);