diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 04e46cf94..9f7767a96 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -311,9 +311,10 @@ export default { searchButton: 'vn-ticket-index vn-searchbar vn-icon[icon="search"]', moreMenu: 'vn-ticket-index vn-icon-menu[vn-id="more-button"] > div > vn-icon', moreMenuTurns: 'vn-ticket-index vn-icon-menu vn-drop-down > vn-popover li:nth-child(2)', - sixthWeeklyTicketTurn: 'vn-ticket-weekly > form > div > vn-card > div > vn-table > div > vn-tbody > vn-tr:nth-child(6) > vn-td:nth-child(3) > vn-autocomplete > div > div > input', + sixthWeeklyTicketTurn: 'vn-ticket-weekly vn-table vn-tr:nth-child(6) vn-autocomplete[field="weekly.weekDay"] input', weeklyTicket: 'vn-ticket-weekly vn-table > div > vn-tbody > vn-tr', - sixthWeeklyTicketDeleteIcon: 'vn-ticket-weekly > form vn-tbody > vn-tr:nth-child(6) > vn-td:nth-child(6) > vn-icon-button[icon="delete"]' + sixthWeeklyTicketDeleteIcon: 'vn-ticket-weekly vn-tr:nth-child(6) vn-icon-button[icon="delete"]', + acceptDeleteTurn: 'vn-ticket-weekly > vn-confirm[vn-id="deleteWeekly"] button[response="ACCEPT"]' }, createTicketView: { clientAutocomplete: 'vn-ticket-create vn-autocomplete[field="$ctrl.clientFk"]', diff --git a/e2e/paths/05-ticket-module/09_ticket_weekly.spec.js b/e2e/paths/05-ticket-module/09_ticket_weekly.spec.js index 4b7a5266b..2c63b74c1 100644 --- a/e2e/paths/05-ticket-module/09_ticket_weekly.spec.js +++ b/e2e/paths/05-ticket-module/09_ticket_weekly.spec.js @@ -49,7 +49,7 @@ describe('Ticket descriptor path', () => { expect(url.hash).toContain('/summary'); }); - it('should add the ticket to thirsday turn using the descriptor more menu', async() => { + it('should add the ticket to thursday turn using the descriptor more menu', async() => { const result = await nightmare .waitToClick(selectors.ticketDescriptor.moreMenu) .waitToClick(selectors.ticketDescriptor.moreMenuAddToTurn) @@ -142,6 +142,7 @@ describe('Ticket descriptor path', () => { it('should delete the weekly ticket 11', async() => { const result = await nightmare .waitToClick(selectors.ticketsIndex.sixthWeeklyTicketDeleteIcon) + .waitToClick(selectors.ticketsIndex.acceptDeleteTurn) .waitForLastSnackbar(); expect(result).toEqual('Data saved!'); diff --git a/modules/ticket/back/methods/ticket-weekly/filter.js b/modules/ticket/back/methods/ticket-weekly/filter.js new file mode 100644 index 000000000..7d1b56374 --- /dev/null +++ b/modules/ticket/back/methods/ticket-weekly/filter.js @@ -0,0 +1,70 @@ + +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: `If it's and integer searchs by id, otherwise it searchs by client id`, + 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 {or: [ + {ticketFk: value}, + {clientFk: value} + ]}; + } + }); + + filter = mergeFilters(ctx.args.filter, {where}); + + let stmts = []; + let stmt; + + stmt = new ParameterizedSQL( + `SELECT t.id AS ticketFk, c.id AS clientFk, c.name AS clientName, tw.weekDay, + wh.name AS warehouseName, w.id AS workerFk, u.nickName + FROM ticketWeekly tw + JOIN ticket t ON t.id = tw.ticketFk + JOIN client c ON c.id = t.clientFk + JOIN worker w ON w.id = c.salesPersonFk + JOIN account.user u ON u.id = w.userFk + JOIN warehouse wh ON wh.id = t.warehouseFk` + ); + + + stmt.merge(conn.makeSuffix(filter)); + let itemsIndex = stmts.push(stmt) - 1; + + let sql = ParameterizedSQL.join(stmts, ';'); + let result = await conn.executeStmt(sql); + return itemsIndex === 0 ? result : result[itemsIndex]; + }; +}; diff --git a/modules/ticket/back/models/ticket-weekly.js b/modules/ticket/back/models/ticket-weekly.js new file mode 100644 index 000000000..8456ef49a --- /dev/null +++ b/modules/ticket/back/models/ticket-weekly.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/ticket-weekly/filter')(Self); +}; diff --git a/modules/ticket/front/routes.json b/modules/ticket/front/routes.json index e16de74f5..5c47901f3 100644 --- a/modules/ticket/front/routes.json +++ b/modules/ticket/front/routes.json @@ -181,7 +181,7 @@ "component": "vn-ticket-log", "description": "Log" }, { - "url" : "/weekly", + "url" : "/weekly?q", "state": "ticket.weekly", "component": "vn-ticket-weekly", "description": "Weekly" diff --git a/modules/ticket/front/weekly/index.html b/modules/ticket/front/weekly/index.html index 3ae3bf7e0..708e15ba2 100644 --- a/modules/ticket/front/weekly/index.html +++ b/modules/ticket/front/weekly/index.html @@ -1,14 +1,25 @@ + primary-key="ticketFk"> -
+
+
+ + + + + + +
@@ -30,27 +41,35 @@ - - {{::weekly.ticket.client.name}} + + {{::weekly.clientName}} - - {{::weekly.ticket.warehouse.name}} - {{::weekly.ticket.client.salesPerson.firstName}} {{::weekly.ticket.client.salesPerson.name}} + {{::weekly.warehouseName}} + + + {{::weekly.nickName}} + + @@ -60,14 +79,17 @@
- +
- + + - \ No newline at end of file + question="You are going to delete this turn" + message="This turn will be removed! Continue anyway?"> + diff --git a/modules/ticket/front/weekly/index.js b/modules/ticket/front/weekly/index.js index 0d2355a17..ddac0d1b5 100644 --- a/modules/ticket/front/weekly/index.js +++ b/modules/ticket/front/weekly/index.js @@ -2,35 +2,13 @@ import ngModule from '../module'; import './style.scss'; export default class Controller { - constructor($scope, vnApp, $translate) { - this.$scope = $scope; + constructor($scope, vnApp, $translate, $http) { + this.$ = $scope; this.vnApp = vnApp; - this._ = $translate; + this.$translate = $translate; + this.$http = $http; this.ticketSelected = null; - this.filter = { - include: { - relation: 'ticket', - scope: { - fields: ['id', 'clientFk', 'companyFk', 'warehouseFk'], - include: [ - { - relation: 'client', - scope: { - fields: ['salesPersonFk', 'name'], - include: { - relation: 'salesPerson', - scope: { - fields: ['id', 'firstName', 'name'] - } - } - } - }, - {relation: 'warehouse'} - ] - } - } - }; this.weekdays = [ {id: 0, name: 'Monday'}, @@ -43,28 +21,53 @@ export default class Controller { ]; } - onSave() { - this.vnApp.showSuccess(this._.instant('Data saved!')); + onWeekdayUpdate(ticketFk, weekDay) { + const params = {ticketFk, weekDay}; + this.$http.patch('/ticket/api/TicketWeeklies/', params).then(() => { + this.vnApp.showSuccess(this.$translate.instant('Data saved!')); + }); } + deleteWeekly(index) { + this.ticketIndex = index; + this.$.deleteWeekly.show(); + event.stopImmediatePropagation(); + } + + onSearch(params) { + if (params) + this.$.model.applyFilter(null, params); + else + this.$.model.clear(); + } + + showClientDescriptor(event, clientFk) { - this.$scope.clientDescriptor.clientFk = clientFk; - this.$scope.clientDescriptor.parent = event.target; - this.$scope.clientDescriptor.show(); + this.$.clientDescriptor.clientFk = clientFk; + this.$.clientDescriptor.parent = event.target; + this.$.clientDescriptor.show(); event.preventDefault(); event.stopImmediatePropagation(); } showTicketDescriptor(event, ticketFk) { - this.$scope.ticketDescriptor.ticketFk = ticketFk; - this.$scope.ticketDescriptor.parent = event.target; - this.$scope.ticketDescriptor.show(); + this.$.ticketDescriptor.ticketFk = ticketFk; + this.$.ticketDescriptor.parent = event.target; + this.$.ticketDescriptor.show(); + event.preventDefault(); + event.stopImmediatePropagation(); + } + + showWorkerDescriptor(event, workerFk) { + this.$.workerDescriptor.workerFk = workerFk; + this.$.workerDescriptor.parent = event.target; + this.$.workerDescriptor.show(); event.preventDefault(); event.stopImmediatePropagation(); } onDescriptorLoad() { - this.$scope.popover.relocate(); + this.$.popover.relocate(); } preventNavigation(event) { @@ -72,13 +75,19 @@ export default class Controller { event.stopImmediatePropagation(); } - deleteWeekly(expedition) { - this.expeditionId = expedition.id; - this.$scope.deleteWeekly.show(); + returnDialog(response) { + const ticket = this.$.model.data[this.ticketIndex]; + if (response === 'ACCEPT') { + this.$http.delete(`/ticket/api/TicketWeeklies/${ticket.ticketFk}`).then(() => { + this.vnApp.showSuccess(this.$translate.instant('Data saved!')); + this.$.model.remove(this.ticketIndex); + }); + } } } -Controller.$inject = ['$scope', 'vnApp', '$translate']; + +Controller.$inject = ['$scope', 'vnApp', '$translate', '$http']; ngModule.component('vnTicketWeekly', { template: require('./index.html'), diff --git a/modules/ticket/front/weekly/locale/es.yml b/modules/ticket/front/weekly/locale/es.yml index 949e2bcb8..e4e7ef068 100644 --- a/modules/ticket/front/weekly/locale/es.yml +++ b/modules/ticket/front/weekly/locale/es.yml @@ -1,2 +1,6 @@ Turn: Turno Ticket ID: ID Ticket +Weekly: Turnos +You are going to delete this turn: Vas a eliminar este turno +This turn will be removed! Continue anyway?: Se eliminará este turno! ¿Continuar de todas formas? +Search turns by id or client id: Busca turnos por el identificador o el identificador del cliente \ No newline at end of file