From 704cb71b61631478b54445b1542dc7a55091b281 Mon Sep 17 00:00:00 2001 From: alexandre Date: Wed, 7 Dec 2022 13:53:59 +0100 Subject: [PATCH] refs #4866 instance log added and e2e done --- .../collection/spec/getCollection.spec.js | 2 +- e2e/helpers/selectors.js | 5 +- .../05-ticket/01-sale/02_edit_sale.spec.js | 9 ++ front/salix/components/index.js | 1 + .../salix/components/instance-log/index.html | 69 ++++++++++++ front/salix/components/instance-log/index.js | 106 ++++++++++++++++++ .../components/instance-log/locale/es.yml | 15 +++ .../salix/components/instance-log/style.scss | 43 +++++++ modules/ticket/front/sale/index.html | 63 +++++++---- modules/ticket/front/sale/locale/es.yml | 5 +- 10 files changed, 291 insertions(+), 27 deletions(-) create mode 100644 front/salix/components/instance-log/index.html create mode 100644 front/salix/components/instance-log/index.js create mode 100644 front/salix/components/instance-log/locale/es.yml create mode 100644 front/salix/components/instance-log/style.scss diff --git a/back/methods/collection/spec/getCollection.spec.js b/back/methods/collection/spec/getCollection.spec.js index e87efb4a0..edc8e4dfc 100644 --- a/back/methods/collection/spec/getCollection.spec.js +++ b/back/methods/collection/spec/getCollection.spec.js @@ -1,6 +1,6 @@ const models = require('vn-loopback/server/server').models; -describe('ticket getCollection()', () => { +fdescribe('ticket getCollection()', () => { it('should return a list of collections', async() => { let ctx = {req: {accessToken: {userId: 1107}}}; let response = await models.Collection.getCollection(ctx); diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index e374e266e..6c2ebf6a9 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -678,7 +678,10 @@ export default { moveToTicketButton: '.vn-popover.shown vn-icon[icon="arrow_forward_ios"]', moveToNewTicketButton: '.vn-popover.shown vn-button[label="New ticket"]', stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="State"]', - moreMenuState: 'body > div > div > div.content > div.filter.ng-scope > vn-textfield' + moreMenuState: 'body > div > div > div.content > div.filter.ng-scope > vn-textfield', + firstSaleHistoryButton: 'vn-ticket-sale vn-tr:nth-child(1) vn-icon-button[icon="history"]', + firstSaleHistory: 'form vn-table div > vn-tbody > vn-tr', + closeHistory: 'div.window vn-button[icon="clear"]' }, ticketTracking: { createStateButton: 'vn-float-button' diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js index 67dfd83bf..9d6fddbe6 100644 --- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js @@ -196,6 +196,15 @@ describe('Ticket Edit sale path', () => { expect(result).toContain('22.50'); }); + it('should check in the history that logs has been added', async() => { + await page.waitToClick(selectors.ticketSales.firstSaleHistoryButton); + await page.waitForSelector(selectors.ticketSales.firstSaleHistory); + const result = await page.countElement(selectors.ticketSales.firstSaleHistory); + + expect(result).toBeGreaterThan(0); + await page.waitToClick(selectors.ticketSales.closeHistory); + }); + it('should recalculate price of sales', async() => { await page.waitToClick(selectors.ticketSales.firstSaleCheckbox); await page.waitToClick(selectors.ticketSales.secondSaleCheckbox); diff --git a/front/salix/components/index.js b/front/salix/components/index.js index dbe9fe81a..fccf99521 100644 --- a/front/salix/components/index.js +++ b/front/salix/components/index.js @@ -19,3 +19,4 @@ import './user-popover'; import './upload-photo'; import './bank-entity'; import './log'; +import './instance-log'; diff --git a/front/salix/components/instance-log/index.html b/front/salix/components/instance-log/index.html new file mode 100644 index 000000000..2393bc8e1 --- /dev/null +++ b/front/salix/components/instance-log/index.html @@ -0,0 +1,69 @@ + + + + + + + + + + Date + User + Action + Changes + + + + + + {{::log.creationDate | date:'dd/MM/yyyy HH:mm'}} + + + {{::log.user.name || 'System' | translate}} + + + + {{::$ctrl.actionsText[log.action]}} + + + + + + + + + + + + + + + + + +
FieldBeforeAfter
{{prop.name}}{{::$ctrl.formatValue(prop.old)}}{{::$ctrl.formatValue(prop.new)}}
+ +
+ {{::log.description}} +
+
+
+
+
+
+ +
+
+
+ + diff --git a/front/salix/components/instance-log/index.js b/front/salix/components/instance-log/index.js new file mode 100644 index 000000000..4c17cde0b --- /dev/null +++ b/front/salix/components/instance-log/index.js @@ -0,0 +1,106 @@ +import ngModule from '../../module'; +import './style.scss'; +import Section from '../section'; + +export default class Controller extends Section { + constructor($element, $) { + super($element, $); + this.actionsText = { + 'insert': 'Creates', + 'update': 'Updates', + 'delete': 'Deletes', + 'select': 'Views' + }; ``; + } + + open() { + this.filter = { + where: + {changedModel: this.changedModel, + changedModelId: this.changedModelId}, + include: [{ + relation: 'user', + scope: { + fields: ['name'], + include: { + relation: 'worker', + scope: { + fields: ['id'] + } + } + }, + }], + }; + this.$.instanceLog.show(); + } + + get logs() { + return this._logs; + } + + set logs(value) { + this._logs = value; + if (!this.logs) return; + const validations = window.validations; + for (const log of value) { + const locale = validations[log.changedModel] && validations[log.changedModel].locale + ? validations[log.changedModel].locale : {}; + log.oldProperties = this.getInstance(log.oldInstance, locale); + log.newProperties = this.getInstance(log.newInstance, locale); + let props = [].concat(log.oldProperties.map(p => p.key), log.newProperties.map(p => p.key)); + props = [...new Set(props)]; + log.props = []; + for (const prop of props) { + const matchOldProp = log.oldProperties.find(p => p.key === prop); + const matchNewProp = log.newProperties.find(p => p.key === prop); + log.props.push({ + name: prop, + old: matchOldProp ? matchOldProp.value : null, + new: matchNewProp ? matchNewProp.value : null, + }); + } + } + } + + formatValue(value) { + switch (typeof value) { + case 'boolean': + return value ? '✓' : '✗'; + default: + return value; + } + } + + getInstance(instance, locale) { + const properties = []; + let validDate = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/; + + if (typeof instance == 'object' && instance != null) { + Object.keys(instance).forEach(property => { + if (validDate.test(instance[property])) + instance[property] = new Date(instance[property]).toLocaleString('es-ES'); + const key = locale[property] || property; + properties.push({key, value: instance[property]}); + }); + return properties; + } + return null; + } + + showWorkerDescriptor(event, workerId) { + if (!workerId) return; + this.$.workerDescriptor.show(event.target, workerId); + } +} + +ngModule.vnComponent('vnInstanceLog', { + controller: Controller, + template: require('./index.html'), + bindings: { + model: '<', + originId: '<', + changedModel: '<', + changedModelId: '<', + url: '@' + } +}); diff --git a/front/salix/components/instance-log/locale/es.yml b/front/salix/components/instance-log/locale/es.yml new file mode 100644 index 000000000..d341095d8 --- /dev/null +++ b/front/salix/components/instance-log/locale/es.yml @@ -0,0 +1,15 @@ +Date: Fecha +Model: Modelo +Action: Acción +Author: Autor +Before: Antes +After: Despues +History: Historial +Name: Nombre +Creates: Crea +Updates: Actualiza +Deletes: Elimina +Views: Visualiza +System: Sistema +note: nota +Changes: Cambios diff --git a/front/salix/components/instance-log/style.scss b/front/salix/components/instance-log/style.scss new file mode 100644 index 000000000..d62f1ac06 --- /dev/null +++ b/front/salix/components/instance-log/style.scss @@ -0,0 +1,43 @@ +@import "variables"; + +vn-instance-log { + vn-td { + vertical-align: initial !important; + } + .changes { + display: none; + } + .label { + color: $color-font-secondary; + } + .value { + color: $color-font; + } + + @media screen and (max-width: 1570px) { + vn-table .expendable { + display: none; + } + .changes { + padding-top: 10px; + display: block; + } + } + .attributes { + width: 100%; + white-space: inherit !important; + + tr { + height: 10px; + + & > td { + padding: 2px; + width: 33%; + } + & > td.field, + & > th.field { + color: gray; + } + } + } +} diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index c624b1a95..c2f45b552 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -30,7 +30,7 @@ ng-click="moreOptions.show($event)" ng-show="$ctrl.hasSelectedSales()"> - - @@ -68,6 +68,7 @@ Disc Amount Packaging + @@ -84,13 +85,13 @@ vn-tooltip="{{::$ctrl.$t('Claim')}}: {{::sale.claim.claimFk}}"> - - @@ -108,21 +109,21 @@ - - {{::sale.visible}} - {{::sale.available}} @@ -195,7 +196,7 @@ translate-attr="{title: !$ctrl.isLocked ? 'Edit discount' : ''}" ng-click="$ctrl.showEditDiscountPopover($event, sale)" ng-if="sale.id"> - {{(sale.discount / 100) | percentage}} + {{(sale.discount / 100) | percentage}} @@ -204,6 +205,22 @@ {{::sale.item.itemPackingTypeFk | dashIfEmpty}} + + + + + + + @@ -383,8 +400,8 @@ - {{::ticket.id}} @@ -392,22 +409,22 @@ {{::ticket.agencyName}} {{::ticket.address}} - {{::ticket.nickname}} - {{::ticket.name}} - {{::ticket.street}} - {{::ticket.postalCode}} + {{::ticket.nickname}} + {{::ticket.name}} + {{::ticket.street}} + {{::ticket.postalCode}} {{::ticket.city}} @@ -502,4 +519,4 @@ vn-acl-action="remove"> Refund - \ No newline at end of file + diff --git a/modules/ticket/front/sale/locale/es.yml b/modules/ticket/front/sale/locale/es.yml index 072e57534..2668b7811 100644 --- a/modules/ticket/front/sale/locale/es.yml +++ b/modules/ticket/front/sale/locale/es.yml @@ -13,9 +13,9 @@ New ticket: Nuevo ticket Edit price: Editar precio You are going to delete lines of the ticket: Vas a eliminar lineas del ticket This ticket will be removed from current route! Continue anyway?: ¡Se eliminará el ticket de la ruta actual! ¿Continuar de todas formas? -You have to allow pop-ups in your web browser to use this functionality: +You have to allow pop-ups in your web browser to use this functionality: Debes permitir los pop-pups en tu navegador para que esta herramienta funcione correctamente -Disc: Dto +Disc: Dto Available: Disponible What is the day of receipt of the ticket?: ¿Cual es el día de preparación del pedido? Add claim: Crear reclamación @@ -39,3 +39,4 @@ Packaging: Encajado Refund: Abono Promotion mana: Maná promoción Claim mana: Maná reclamación +History: Historial