diff --git a/db/changes/10440-fallas/00-claim_packages.sql b/db/changes/10440-fallas/00-claim_packages.sql index fa62fbec9b..3d82eb7b6a 100644 --- a/db/changes/10440-fallas/00-claim_packages.sql +++ b/db/changes/10440-fallas/00-claim_packages.sql @@ -1 +1 @@ -ALTER TABLE `vn`.`claim` ADD packages smallint(10) unsigned DEFAULT 0 NULL COMMENT 'packages received by the client'; \ No newline at end of file +ALTER TABLE `vn`.`claim` ADD packages smallint(10) unsigned DEFAULT 0 NULL COMMENT 'packages received by the client'; diff --git a/db/changes/10451-april/00-ClientUnpaid.sql b/db/changes/10451-april/00-ClientUnpaid.sql new file mode 100644 index 0000000000..d84fe494a0 --- /dev/null +++ b/db/changes/10451-april/00-ClientUnpaid.sql @@ -0,0 +1,10 @@ +CREATE TABLE `vn`.`clientUnpaid` ( + `clientFk` int(11) NOT NULL, + `dated` date NOT NULL, + `amount` double DEFAULT 0, + PRIMARY KEY (`clientFk`), + CONSTRAINT `clientUnpaid_clientFk` FOREIGN KEY (`clientFk`) REFERENCES `client` (`id`) ON UPDATE CASCADE +); + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES('ClientUnpaid', '*', '*', 'ALLOW', 'ROLE', 'administrative'); \ No newline at end of file diff --git a/db/changes/10451-april/00-aclSaleRefund.sql b/db/changes/10451-april/00-aclSaleRefund.sql new file mode 100644 index 0000000000..79baba63d8 --- /dev/null +++ b/db/changes/10451-april/00-aclSaleRefund.sql @@ -0,0 +1,6 @@ +UPDATE `salix`.`ACL` + SET `property`='refund' +WHERE `model`='Sale' AND `property`='payBack'; + +INSERT INTO `salix`.`ACL`(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) +VALUES('Sale', 'refundAll', 'WRITE', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/changes/10451-april/00-ticket_doRefund.sql b/db/changes/10451-april/00-ticket_doRefund.sql new file mode 100644 index 0000000000..5540ff8cfc --- /dev/null +++ b/db/changes/10451-april/00-ticket_doRefund.sql @@ -0,0 +1,113 @@ +DROP PROCEDURE IF EXISTS vn.ticket_doRefund; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_doRefund`(IN vOriginTicket INT, OUT vNewTicket INT) +BEGIN + + DECLARE vDone BIT DEFAULT 0; + DECLARE vCustomer MEDIUMINT; + DECLARE vWarehouse TINYINT; + DECLARE vCompany MEDIUMINT; + DECLARE vAddress MEDIUMINT; + DECLARE vRefundAgencyMode INT; + DECLARE vItemFk INT; + DECLARE vQuantity DECIMAL (10,2); + DECLARE vConcept VARCHAR(50); + DECLARE vPrice DECIMAL (10,2); + DECLARE vDiscount TINYINT; + DECLARE vSaleNew INT; + DECLARE vSaleMain INT; + DECLARE vZoneFk INT; + DECLARE vDescription VARCHAR(50); + DECLARE vTaxClassFk INT; + DECLARE vTicketServiceTypeFk INT; + + DECLARE cSales CURSOR FOR + SELECT * + FROM tmp.sale; + + DECLARE cTicketServices CURSOR FOR + SELECT * + FROM tmp.ticketService; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1; + + SELECT id INTO vRefundAgencyMode + FROM agencyMode WHERE `name` = 'ABONO'; + + SELECT clientFk, warehouseFk, companyFk, addressFk + INTO vCustomer, vWarehouse, vCompany, vAddress + FROM ticket + WHERE id = vOriginTicket; + + SELECT id INTO vZoneFk + FROM zone WHERE agencyModeFk = vRefundAgencyMode + LIMIT 1; + + INSERT INTO vn.ticket ( + clientFk, + shipped, + addressFk, + agencyModeFk, + nickname, + warehouseFk, + companyFk, + landed, + zoneFk + ) + SELECT + vCustomer, + CURDATE(), + vAddress, + vRefundAgencyMode, + a.nickname, + vWarehouse, + vCompany, + CURDATE(), + vZoneFk + FROM address a + WHERE a.id = vAddress; + + SET vNewTicket = LAST_INSERT_ID(); + + SET vDone := 0; + OPEN cSales; + FETCH cSales INTO vSaleMain, vItemFk, vQuantity, vConcept, vPrice, vDiscount; + + WHILE NOT vDone DO + + INSERT INTO vn.sale(ticketFk, itemFk, quantity, concept, price, discount) + VALUES( vNewTicket, vItemFk, vQuantity, vConcept, vPrice, vDiscount ); + + SET vSaleNew = LAST_INSERT_ID(); + + INSERT INTO vn.saleComponent(saleFk,componentFk,`value`) + SELECT vSaleNew,componentFk,`value` + FROM vn.saleComponent + WHERE saleFk = vSaleMain; + + FETCH cSales INTO vSaleMain, vItemFk, vQuantity, vConcept, vPrice, vDiscount; + + END WHILE; + CLOSE cSales; + + SET vDone := 0; + OPEN cTicketServices; + FETCH cTicketServices INTO vDescription, vQuantity, vPrice, vTaxClassFk, vTicketServiceTypeFk; + + WHILE NOT vDone DO + + INSERT INTO vn.ticketService(description, quantity, price, taxClassFk, ticketFk, ticketServiceTypeFk) + VALUES(vDescription, vQuantity, vPrice, vTaxClassFk, vNewTicket, vTicketServiceTypeFk); + + FETCH cTicketServices INTO vDescription, vQuantity, vPrice, vTaxClassFk, vTicketServiceTypeFk; + + END WHILE; + CLOSE cTicketServices; + + INSERT INTO vn.ticketRefund(refundTicketFk, originalTicketFk) + VALUES(vNewTicket, vOriginTicket); + +END$$ +DELIMITER ; diff --git a/db/changes/10451-april/delete-me.keep b/db/changes/10451-april/delete-me.keep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/e2e/helpers/extensions.js b/e2e/helpers/extensions.js index 789c800b59..7bf56e2c8d 100644 --- a/e2e/helpers/extensions.js +++ b/e2e/helpers/extensions.js @@ -181,12 +181,12 @@ let actions = { }, reloadSection: async function(state) { - await this.click('vn-icon[icon="preview"]'); + await this.click('vn-icon[icon="launch"]'); await this.accessToSection(state); }, forceReloadSection: async function(sectionRoute) { - await this.waitToClick('vn-icon[icon="preview"]'); + await this.waitToClick('vn-icon[icon="launch"]'); await this.waitToClick('button[response="accept"]'); await this.waitForSelector('vn-card.summary'); await this.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`); diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index d664cfbad9..799eb8fe70 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -321,6 +321,12 @@ export default { deleteFirstPhone: 'vn-client-contact vn-icon[icon="delete"]', saveButton: 'button[type=submit]' }, + clientUnpaid: { + hasDataCheckBox: 'vn-client-unpaid vn-check[ng-model="watcher.hasData"]', + dated: 'vn-client-unpaid vn-date-picker[ng-model="$ctrl.clientUnpaid.dated"]', + amount: 'vn-client-unpaid vn-input-number[ng-model="$ctrl.clientUnpaid.amount"]', + saveButton: 'vn-submit[label="Save"]' + }, itemsIndex: { createItemButton: `vn-float-button`, firstSearchResult: 'vn-item-index tbody tr:nth-child(1)', @@ -570,7 +576,7 @@ export default { moreMenuUnmarkReseved: 'vn-item[name="unreserve"]', moreMenuUpdateDiscount: 'vn-item[name="discount"]', moreMenuRecalculatePrice: 'vn-item[name="calculatePrice"]', - moreMenuPayBack: 'vn-item[name="payBack"]', + moreMenuRefund: 'vn-item[name="refund"]', moreMenuUpdateDiscountInput: 'vn-input-number[ng-model="$ctrl.edit.discount"] input', transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text', transferQuantityCell: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable', @@ -958,7 +964,7 @@ export default { supplierRef: 'vn-invoice-in-summary vn-label-value:nth-child(2) > section > span' }, invoiceInDescriptor: { - summaryIcon: 'vn-invoice-in-descriptor a[title="Preview"]', + summaryIcon: 'vn-invoice-in-descriptor a[title="Go to module summary"]', moreMenu: 'vn-invoice-in-descriptor vn-icon-button[icon=more_vert]', moreMenuDeleteInvoiceIn: '.vn-menu [name="deleteInvoice"]', moreMenuCloneInvoiceIn: '.vn-menu [name="cloneInvoice"]', diff --git a/e2e/paths/02-client/22_unpaid.spec.js b/e2e/paths/02-client/22_unpaid.spec.js new file mode 100644 index 0000000000..441dba96fd --- /dev/null +++ b/e2e/paths/02-client/22_unpaid.spec.js @@ -0,0 +1,41 @@ +import selectors from '../../helpers/selectors.js'; +import getBrowser from '../../helpers/puppeteer'; + +describe('Client unpaid path', () => { + let browser; + let page; + + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + await page.loginAndModule('administrative', 'client'); + await page.accessToSearchResult('Charles Xavier'); + await page.accessToSection('client.card.unpaid'); + await page.waitForState('client.card.unpaid'); + }); + + afterAll(async() => { + await browser.close(); + }); + + it('should set cliet unpaid', async() => { + await page.waitToClick(selectors.clientUnpaid.hasDataCheckBox); + + await page.pickDate(selectors.clientUnpaid.dated); + await page.write(selectors.clientUnpaid.amount, '500'); + }); + + it('should save unpaid', async() => { + await page.waitToClick(selectors.clientUnpaid.saveButton); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain('Data saved!'); + }); + + it('should confirm the unpaid have been saved', async() => { + await page.reloadSection('client.card.unpaid'); + const result = await page.waitToGetProperty(selectors.clientUnpaid.amount, 'value'); + + expect(result).toEqual('500'); + }); +}); 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 9726847080..d776f417dd 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 @@ -213,10 +213,10 @@ describe('Ticket Edit sale path', () => { await page.accessToSection('ticket.card.sale'); }); - it('should select the third sale and create a pay back', async() => { + it('should select the third sale and create a refund', async() => { await page.waitToClick(selectors.ticketSales.firstSaleCheckbox); await page.waitToClick(selectors.ticketSales.moreMenu); - await page.waitToClick(selectors.ticketSales.moreMenuPayBack); + await page.waitToClick(selectors.ticketSales.moreMenuRefund); await page.waitForState('ticket.card.sale'); }); diff --git a/e2e/paths/10-travel/03_descriptor.spec.js b/e2e/paths/10-travel/03_descriptor.spec.js index 619228f354..f459ef0437 100644 --- a/e2e/paths/10-travel/03_descriptor.spec.js +++ b/e2e/paths/10-travel/03_descriptor.spec.js @@ -134,7 +134,7 @@ describe('Travel descriptor path', () => { }); it('should navigate to the summary and then clone the travel and its entries using the descriptor menu to get redirected to the cloned travel basic data', async() => { - await page.waitToClick('vn-icon[icon="preview"]'); // summary icon + await page.waitToClick('vn-icon[icon="launch"]'); await page.waitForState('travel.card.summary'); await page.waitForTimeout(1000); await page.waitToClick(selectors.travelDescriptor.dotMenu); diff --git a/front/core/styles/icons/salixfont.css b/front/core/styles/icons/salixfont.css index e37ccbc1fd..5307722461 100644 --- a/front/core/styles/icons/salixfont.css +++ b/front/core/styles/icons/salixfont.css @@ -23,10 +23,21 @@ -moz-osx-font-smoothing: grayscale; } - +.icon-agency-term:before { + content: "\e950"; +} +.icon-deaulter:before { + content: "\e94b"; +} .icon-100:before { content: "\e95a"; } +.icon-history:before { + content: "\e968"; +} +.icon-Person:before { + content: "\e901"; +} .icon-accessory:before { content: "\e90a"; } @@ -74,6 +85,7 @@ } .icon-bucket:before { content: "\e97a"; + color: #000; } .icon-buscaman:before { content: "\e93b"; @@ -83,26 +95,32 @@ } .icon-calc_volum .path1:before { content: "\e915"; + color: rgb(0, 0, 0); } .icon-calc_volum .path2:before { content: "\e916"; margin-left: -1em; + color: rgb(0, 0, 0); } .icon-calc_volum .path3:before { content: "\e917"; margin-left: -1em; + color: rgb(0, 0, 0); } .icon-calc_volum .path4:before { content: "\e918"; margin-left: -1em; + color: rgb(0, 0, 0); } .icon-calc_volum .path5:before { content: "\e919"; margin-left: -1em; + color: rgb(0, 0, 0); } .icon-calc_volum .path6:before { content: "\e91a"; margin-left: -1em; + color: rgb(255, 255, 255); } .icon-calendar:before { content: "\e93d"; @@ -137,9 +155,6 @@ .icon-credit:before { content: "\e927"; } -.icon-defaulter:before { - content: "\e94b"; -} .icon-deletedTicket:before { content: "\e935"; } @@ -206,9 +221,6 @@ .icon-headercol:before { content: "\e958"; } -.icon-history:before { - content: "\e968"; -} .icon-info:before { content: "\e952"; } @@ -281,9 +293,6 @@ .icon-pbx:before { content: "\e93c"; } -.icon-Person:before { - content: "\e901"; -} .icon-pets:before { content: "\e947"; } diff --git a/front/core/styles/icons/salixfont.eot b/front/core/styles/icons/salixfont.eot index 9325d3dae5..48cc864135 100644 Binary files a/front/core/styles/icons/salixfont.eot and b/front/core/styles/icons/salixfont.eot differ diff --git a/front/core/styles/icons/salixfont.svg b/front/core/styles/icons/salixfont.svg index 22c33c181e..2b8b1ac8a0 100644 --- a/front/core/styles/icons/salixfont.svg +++ b/front/core/styles/icons/salixfont.svg @@ -15,7 +15,7 @@ - + @@ -87,6 +87,7 @@ + diff --git a/front/core/styles/icons/salixfont.ttf b/front/core/styles/icons/salixfont.ttf index 05df06213d..4b090731cd 100644 Binary files a/front/core/styles/icons/salixfont.ttf and b/front/core/styles/icons/salixfont.ttf differ diff --git a/front/core/styles/icons/salixfont.woff b/front/core/styles/icons/salixfont.woff index 70fca22945..502fed1180 100644 Binary files a/front/core/styles/icons/salixfont.woff and b/front/core/styles/icons/salixfont.woff differ diff --git a/front/salix/components/descriptor-popover/style.scss b/front/salix/components/descriptor-popover/style.scss index 6ae8675bfa..7203c8e8ef 100644 --- a/front/salix/components/descriptor-popover/style.scss +++ b/front/salix/components/descriptor-popover/style.scss @@ -4,8 +4,14 @@ vn-descriptor-content > .descriptor { width: 256px; - & > .header > a:first-child { - visibility: hidden; - } + & > .header { + a:first-child { + display: none; + } + vn-icon-button:nth-child(2) { + display: block; + } + } + } } diff --git a/front/salix/components/descriptor/index.html b/front/salix/components/descriptor/index.html index 5b4c6f12c3..e7a5b62976 100644 --- a/front/salix/components/descriptor/index.html +++ b/front/salix/components/descriptor/index.html @@ -12,10 +12,15 @@ name="goToModuleIndex"> + + - + vn-icon-button:nth-child(2) { + display: none; + } } & > .body { display: block; diff --git a/front/salix/locale/es.yml b/front/salix/locale/es.yml index 5e877c372e..4e93ae18ee 100644 --- a/front/salix/locale/es.yml +++ b/front/salix/locale/es.yml @@ -13,6 +13,8 @@ Preview: Vista previa Profile: Perfil Push on applications menu: Para abrir un módulo pulsa en el menú de aplicaciones Go to module index: Ir al índice del módulo +Go to module summary: Ir a la vista previa del módulo +Show summary: Mostrar vista previa What is new: Novedades de la versión Settings: Ajustes diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 9310ae436d..77bd21780f 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -219,7 +219,7 @@ "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día", "You can not modify is pay method checked": "No se puede modificar el campo método de pago validado", "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", - "You don't have privileges to create pay back": "No tienes permisos para crear un abono", + "You don't have privileges to create refund": "No tienes permisos para crear un abono", "The item is required": "El artículo es requerido", "The agency is already assigned to another autonomous": "La agencia ya está asignada a otro autónomo", "date in the future": "Fecha en el futuro", diff --git a/modules/account/front/descriptor/index.html b/modules/account/front/descriptor/index.html index d01e953c2f..c709c1ec02 100644 --- a/modules/account/front/descriptor/index.html +++ b/modules/account/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.user.nickname" + summary="$ctrl.$.summary"> Change password + + + \ No newline at end of file diff --git a/modules/claim/front/descriptor/index.html b/modules/claim/front/descriptor/index.html index 1337c62423..56fd0bb35d 100644 --- a/modules/claim/front/descriptor/index.html +++ b/modules/claim/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.claim.client.name" + summary="$ctrl.$.summary"> - \ No newline at end of file + + + + \ No newline at end of file diff --git a/modules/client/back/model-config.json b/modules/client/back/model-config.json index 38f5c94272..b6bf715b1b 100644 --- a/modules/client/back/model-config.json +++ b/modules/client/back/model-config.json @@ -44,6 +44,9 @@ "ClientType": { "dataSource": "vn" }, + "ClientUnpaid": { + "dataSource": "vn" + }, "Defaulter": { "dataSource": "vn" }, diff --git a/modules/client/back/models/client-unpaid.json b/modules/client/back/models/client-unpaid.json new file mode 100644 index 0000000000..a3d1a684c2 --- /dev/null +++ b/modules/client/back/models/client-unpaid.json @@ -0,0 +1,28 @@ +{ + "name": "ClientUnpaid", + "base": "VnModel", + "options": { + "mysql": { + "table": "clientUnpaid" + } + }, + "properties": { + "clientFk": { + "type": "number", + "id": true + }, + "dated": { + "type": "date" + }, + "amount": { + "type": "Number" + } + }, + "relations": { + "client": { + "type": "belongsTo", + "model": "Client", + "foreignKey": "clientFk" + } + } +} \ No newline at end of file diff --git a/modules/client/front/descriptor/index.html b/modules/client/front/descriptor/index.html index e75246ebe6..de7a86d3b8 100644 --- a/modules/client/front/descriptor/index.html +++ b/modules/client/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.client.name" + summary="$ctrl.$.summary"> - \ No newline at end of file + + + + diff --git a/modules/client/front/index.js b/modules/client/front/index.js index d9f3a8a177..ea732beea1 100644 --- a/modules/client/front/index.js +++ b/modules/client/front/index.js @@ -46,3 +46,4 @@ import './consumption'; import './consumption-search-panel'; import './defaulter'; import './notification'; +import './unpaid'; diff --git a/modules/client/front/locale/es.yml b/modules/client/front/locale/es.yml index 107931377a..4eb99318c4 100644 --- a/modules/client/front/locale/es.yml +++ b/modules/client/front/locale/es.yml @@ -61,4 +61,5 @@ Log: Historial Consumption: Consumo Compensation Account: Cuenta para compensar Amount to return: Cantidad a devolver -Delivered amount: Cantidad entregada \ No newline at end of file +Delivered amount: Cantidad entregada +Unpaid: Impagado \ No newline at end of file diff --git a/modules/client/front/routes.json b/modules/client/front/routes.json index 8398a87453..293243470d 100644 --- a/modules/client/front/routes.json +++ b/modules/client/front/routes.json @@ -32,7 +32,8 @@ {"state": "client.card.creditInsurance.index", "icon": "icon-solunion"}, {"state": "client.card.contact", "icon": "contact_phone"}, {"state": "client.card.webPayment", "icon": "icon-onlinepayment"}, - {"state": "client.card.dms.index", "icon": "cloud_upload"} + {"state": "client.card.dms.index", "icon": "cloud_upload"}, + {"state": "client.card.unpaid", "icon": "icon-defaulter"} ] } ] @@ -374,6 +375,12 @@ "state": "client.notification", "component": "vn-client-notification", "description": "Notifications" + }, { + "url": "/unpaid", + "state": "client.card.unpaid", + "component": "vn-client-unpaid", + "acl": ["administrative"], + "description": "Unpaid" } ] } diff --git a/modules/client/front/unpaid/index.html b/modules/client/front/unpaid/index.html new file mode 100644 index 0000000000..5f6edfe10c --- /dev/null +++ b/modules/client/front/unpaid/index.html @@ -0,0 +1,51 @@ +
+ + +
+ + + + + + + + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/modules/client/front/unpaid/index.js b/modules/client/front/unpaid/index.js new file mode 100644 index 0000000000..a8ff643864 --- /dev/null +++ b/modules/client/front/unpaid/index.js @@ -0,0 +1,14 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +export default class Controller extends Section { + setDefaultDate(hasData) { + if (hasData && !this.clientUnpaid.dated) + this.clientUnpaid.dated = new Date(); + } +} + +ngModule.vnComponent('vnClientUnpaid', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/client/front/unpaid/index.spec.js b/modules/client/front/unpaid/index.spec.js new file mode 100644 index 0000000000..bfeb7df193 --- /dev/null +++ b/modules/client/front/unpaid/index.spec.js @@ -0,0 +1,38 @@ +import './index'; + +describe('client unpaid', () => { + describe('Component vnClientUnpaid', () => { + let controller; + + beforeEach(ngModule('client')); + + beforeEach(inject($componentController => { + const $element = angular.element(''); + controller = $componentController('vnClientUnpaid', {$element}); + })); + + describe('setDefaultDate()', () => { + it(`should not set today date if has dated`, () => { + const hasData = true; + const yesterday = new Date(); + yesterday.setDate(yesterday.getDate() - 1); + + controller.clientUnpaid = { + dated: yesterday + }; + controller.setDefaultDate(hasData); + + expect(controller.clientUnpaid.dated).toEqual(yesterday); + }); + + it(`should set today if not has dated`, () => { + const hasData = true; + + controller.clientUnpaid = {}; + controller.setDefaultDate(hasData); + + expect(controller.clientUnpaid.dated).toBeDefined(); + }); + }); + }); +}); diff --git a/modules/client/front/unpaid/locale/es.yml b/modules/client/front/unpaid/locale/es.yml new file mode 100644 index 0000000000..d88764407b --- /dev/null +++ b/modules/client/front/unpaid/locale/es.yml @@ -0,0 +1 @@ +Unpaid client: Cliente impagado \ No newline at end of file diff --git a/modules/entry/front/descriptor/index.html b/modules/entry/front/descriptor/index.html index 04bef0024e..f0e2439bb3 100644 --- a/modules/entry/front/descriptor/index.html +++ b/modules/entry/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.entry.supplier.nickname" + summary="$ctrl.$.summary"> + + + \ No newline at end of file diff --git a/modules/invoiceIn/front/descriptor/index.html b/modules/invoiceIn/front/descriptor/index.html index a51743091c..33f9ee8c65 100644 --- a/modules/invoiceIn/front/descriptor/index.html +++ b/modules/invoiceIn/front/descriptor/index.html @@ -1,4 +1,7 @@ - + - \ No newline at end of file + + + + \ No newline at end of file diff --git a/modules/invoiceOut/front/descriptor/index.html b/modules/invoiceOut/front/descriptor/index.html index 135eae0e1b..92f0b9de54 100644 --- a/modules/invoiceOut/front/descriptor/index.html +++ b/modules/invoiceOut/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.invoiceOut.ref" + summary="$ctrl.$.summary"> - \ No newline at end of file + + + + \ No newline at end of file diff --git a/modules/item/back/model-config.json b/modules/item/back/model-config.json index d134d9283d..004aeb4b97 100644 --- a/modules/item/back/model-config.json +++ b/modules/item/back/model-config.json @@ -29,6 +29,9 @@ "ItemLog": { "dataSource": "vn" }, + "ItemPackingType": { + "dataSource": "vn" + }, "ItemPlacement": { "dataSource": "vn" }, diff --git a/modules/item/front/descriptor/index.html b/modules/item/front/descriptor/index.html index 87def91459..321545b38f 100644 --- a/modules/item/front/descriptor/index.html +++ b/modules/item/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.item.name" + summary="$ctrl.$.summary"> + + +
- - diff --git a/modules/order/front/descriptor/index.html b/modules/order/front/descriptor/index.html index a96da252b2..538789027a 100644 --- a/modules/order/front/descriptor/index.html +++ b/modules/order/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.order.client.name" + summary="$ctrl.$.summary"> - \ No newline at end of file + + + + \ No newline at end of file diff --git a/modules/route/front/descriptor/index.html b/modules/route/front/descriptor/index.html index bda46952ae..fc1d3419c5 100644 --- a/modules/route/front/descriptor/index.html +++ b/modules/route/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.route.name" + summary="$ctrl.$.summary"> - \ No newline at end of file + + + + \ No newline at end of file diff --git a/modules/route/front/routes.json b/modules/route/front/routes.json index 0d66a56979..f5e7d9ae85 100644 --- a/modules/route/front/routes.json +++ b/modules/route/front/routes.json @@ -7,7 +7,7 @@ "menus": { "main": [ {"state": "route.index", "icon": "icon-delivery"}, - {"state": "route.agencyTerm.index", "icon": "contact_support"} + {"state": "route.agencyTerm.index", "icon": "icon-agency-term"} ], "card": [ {"state": "route.card.basicData", "icon": "settings"}, diff --git a/modules/supplier/front/descriptor/index.html b/modules/supplier/front/descriptor/index.html index dcc065eff8..4691bfe9bb 100644 --- a/modules/supplier/front/descriptor/index.html +++ b/modules/supplier/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.supplier.name" + summary="$ctrl.$.summary">
+ + + \ No newline at end of file diff --git a/modules/supplier/front/routes.json b/modules/supplier/front/routes.json index 35519b89a4..86bfba40cf 100644 --- a/modules/supplier/front/routes.json +++ b/modules/supplier/front/routes.json @@ -15,7 +15,7 @@ {"state": "supplier.card.address.index", "icon": "icon-delivery"}, {"state": "supplier.card.account", "icon": "icon-account"}, {"state": "supplier.card.contact", "icon": "contact_phone"}, - {"state": "supplier.card.agencyTerm.index", "icon": "contact_support"}, + {"state": "supplier.card.agencyTerm.index", "icon": "icon-agency-term"}, {"state": "supplier.card.log", "icon": "history"}, {"state": "supplier.card.consumption", "icon": "show_chart"} ] diff --git a/modules/ticket/back/methods/sale/payBack.js b/modules/ticket/back/methods/sale/refund.js similarity index 77% rename from modules/ticket/back/methods/sale/payBack.js rename to modules/ticket/back/methods/sale/refund.js index 098da4d5a8..9c87f23d38 100644 --- a/modules/ticket/back/methods/sale/payBack.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -1,7 +1,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethodCtx('payBack', { + Self.remoteMethodCtx('refund', { description: 'Create ticket with the selected lines changing the sign to the quantites', accessType: 'WRITE', accepts: [{ @@ -21,12 +21,12 @@ module.exports = Self => { root: true }, http: { - path: `/payBack`, + path: `/refund`, verb: 'post' } }); - Self.payBack = async(ctx, sales, ticketId, options) => { + Self.refund = async(ctx, sales, ticketId, options) => { const myOptions = {}; let tx; @@ -47,21 +47,35 @@ module.exports = Self => { const hasValidRole = isClaimManager || isSalesAssistant; if (!hasValidRole) - throw new UserError(`You don't have privileges to create pay back`); + throw new UserError(`You don't have privileges to create refund`); for (let sale of sales) salesIds.push(sale.id); const query = ` DROP TEMPORARY TABLE IF EXISTS tmp.sale; + DROP TEMPORARY TABLE IF EXISTS tmp.ticketService; + CREATE TEMPORARY TABLE tmp.sale SELECT s.id, s.itemFk, - s.quantity, s.concept, s.price, s.discount FROM sale s WHERE s.id IN (?); + + CREATE TEMPORARY TABLE tmp.ticketService( + description VARCHAR(50), + quantity DECIMAL (10,2), + price DECIMAL (10,2), + taxClassFk INT, + ticketServiceTypeFk INT + ); + CALL vn.ticket_doRefund(?, @newTicket); - DROP TEMPORARY TABLE tmp.sale;`; + + DROP TEMPORARY TABLE tmp.sale; + DROP TEMPORARY TABLE tmp.ticketService;`; await Self.rawSql(query, [salesIds, ticketId], myOptions); + const [newTicket] = await Self.rawSql('SELECT @newTicket id', null, myOptions); ticketId = newTicket.id; diff --git a/modules/ticket/back/methods/sale/refundAll.js b/modules/ticket/back/methods/sale/refundAll.js new file mode 100644 index 0000000000..6fcd27f0a6 --- /dev/null +++ b/modules/ticket/back/methods/sale/refundAll.js @@ -0,0 +1,78 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('refundAll', { + description: 'Create ticket with all lines and services changing the sign to the quantites', + accessType: 'WRITE', + accepts: [{ + arg: 'ticketId', + type: 'number', + required: true, + description: 'The ticket id' + }], + returns: { + type: 'number', + root: true + }, + http: { + path: `/refundAll`, + verb: 'post' + } + }); + + Self.refundAll = async(ctx, ticketId, options) => { + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const userId = ctx.req.accessToken.userId; + + const isClaimManager = await Self.app.models.Account.hasRole(userId, 'claimManager'); + const isSalesAssistant = await Self.app.models.Account.hasRole(userId, 'salesAssistant'); + const hasValidRole = isClaimManager || isSalesAssistant; + + if (!hasValidRole) + throw new UserError(`You don't have privileges to create refund`); + + const query = ` + DROP TEMPORARY TABLE IF EXISTS tmp.sale; + DROP TEMPORARY TABLE IF EXISTS tmp.ticketService; + + CREATE TEMPORARY TABLE tmp.sale + SELECT s.id, s.itemFk, - s.quantity, s.concept, s.price, s.discount + FROM sale s + JOIN ticket t ON t.id = s.ticketFk + WHERE t.id IN (?); + + CREATE TEMPORARY TABLE tmp.ticketService + SELECT ts.description, - ts.quantity, ts.price, ts.taxClassFk, ts.ticketServiceTypeFk + FROM ticketService ts + WHERE ts.ticketFk IN (?); + + CALL vn.ticket_doRefund(?, @newTicket); + + DROP TEMPORARY TABLE tmp.sale; + DROP TEMPORARY TABLE tmp.ticketService;`; + + await Self.rawSql(query, [ticketId, ticketId, ticketId], myOptions); + + const [newTicket] = await Self.rawSql('SELECT @newTicket id', null, myOptions); + ticketId = newTicket.id; + + if (tx) await tx.commit(); + + return ticketId; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/ticket/back/methods/sale/specs/payBack.spec.js b/modules/ticket/back/methods/sale/specs/refund.spec.js similarity index 84% rename from modules/ticket/back/methods/sale/specs/payBack.spec.js rename to modules/ticket/back/methods/sale/specs/refund.spec.js index ffcf964563..40fd6c17ea 100644 --- a/modules/ticket/back/methods/sale/specs/payBack.spec.js +++ b/modules/ticket/back/methods/sale/specs/refund.spec.js @@ -1,6 +1,6 @@ const models = require('vn-loopback/server/server').models; -describe('sale payBack()', () => { +describe('sale refund()', () => { it('should create ticket with the selected lines changing the sign to the quantites', async() => { const tx = await models.Sale.beginTransaction({}); const ctx = {req: {accessToken: {userId: 9}}}; @@ -14,7 +14,7 @@ describe('sale payBack()', () => { try { const options = {transaction: tx}; - const response = await models.Sale.payBack(ctx, sales, ticketId, options); + const response = await models.Sale.refund(ctx, sales, ticketId, options); const [newTicketId] = await models.Sale.rawSql('SELECT MAX(t.id) id FROM vn.ticket t;', null, options); expect(response).toEqual(newTicketId.id); @@ -26,7 +26,7 @@ describe('sale payBack()', () => { } }); - it(`should throw an error if the user doesn't have privileges to create a pay back`, async() => { + it(`should throw an error if the user doesn't have privileges to create a refund`, async() => { const tx = await models.Sale.beginTransaction({}); const ctx = {req: {accessToken: {userId: 1}}}; @@ -40,7 +40,7 @@ describe('sale payBack()', () => { try { const options = {transaction: tx}; - await models.Sale.payBack(ctx, sales, ticketId, options); + await models.Sale.refund(ctx, sales, ticketId, options); await tx.rollback(); } catch (e) { @@ -49,6 +49,6 @@ describe('sale payBack()', () => { } expect(error).toBeDefined(); - expect(error.message).toEqual(`You don't have privileges to create pay back`); + expect(error.message).toEqual(`You don't have privileges to create refund`); }); }); diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index 9efd660570..2652aded2a 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -6,7 +6,8 @@ module.exports = Self => { require('../methods/sale/updateQuantity')(Self); require('../methods/sale/updateConcept')(Self); require('../methods/sale/recalculatePrice')(Self); - require('../methods/sale/payBack')(Self); + require('../methods/sale/refund')(Self); + require('../methods/sale/refundAll')(Self); require('../methods/sale/canEdit')(Self); Self.validatesPresenceOf('concept', { diff --git a/modules/ticket/front/descriptor-menu/index.html b/modules/ticket/front/descriptor-menu/index.html index 88ed4b46b2..c99575d423 100644 --- a/modules/ticket/front/descriptor-menu/index.html +++ b/modules/ticket/front/descriptor-menu/index.html @@ -139,6 +139,11 @@ translate> Recalculate components + + Refund all + @@ -292,4 +297,12 @@ on-accept="$ctrl.recalculateComponents()" question="Are you sure you want to recalculate the components?" message="Recalculate components"> + + + + \ No newline at end of file diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index 6465c43ace..1c80a6f9db 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -272,6 +272,14 @@ class Controller extends Section { .then(() => this.reload()) .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); } + + refundAll() { + const params = {ticketId: this.id}; + const query = `Sales/refundAll`; + return this.$http.post(query, params).then(res => { + this.$state.go('ticket.card.sale', {id: res.data}); + }); + } } Controller.$inject = ['$element', '$scope', 'vnReport', 'vnEmail']; diff --git a/modules/ticket/front/descriptor-menu/index.spec.js b/modules/ticket/front/descriptor-menu/index.spec.js index faf45504e0..75f3522aed 100644 --- a/modules/ticket/front/descriptor-menu/index.spec.js +++ b/modules/ticket/front/descriptor-menu/index.spec.js @@ -262,6 +262,19 @@ describe('Ticket Component vnTicketDescriptorMenu', () => { }); }); + describe('refundAll()', () => { + it('should make a query and go to ticket.card.sale', () => { + jest.spyOn(controller.$state, 'go').mockReturnValue(); + const expectedParams = {ticketId: ticket.id}; + + $httpBackend.expect('POST', `Sales/refundAll`, expectedParams).respond({ticketId: 16}); + controller.refundAll(); + $httpBackend.flush(); + + expect(controller.$state.go).toHaveBeenCalledWith('ticket.card.sale', {id: {ticketId: ticket.id}}); + }); + }); + describe('showSMSDialog()', () => { it('should set the destionationFk and destination properties and then call the sms open() method', () => { controller.$.sms = {open: () => {}}; diff --git a/modules/ticket/front/descriptor-menu/locale/es.yml b/modules/ticket/front/descriptor-menu/locale/es.yml index 761687e749..060d03154f 100644 --- a/modules/ticket/front/descriptor-menu/locale/es.yml +++ b/modules/ticket/front/descriptor-menu/locale/es.yml @@ -7,4 +7,5 @@ Send PDF: Enviar PDF Send CSV: Enviar CSV Send CSV Delivery Note: Enviar albarán en CSV Send PDF Delivery Note: Enviar albarán en PDF -Show Proforma: Ver proforma \ No newline at end of file +Show Proforma: Ver proforma +Refund all: Abonar todo \ No newline at end of file diff --git a/modules/ticket/front/descriptor/index.html b/modules/ticket/front/descriptor/index.html index 8d76888264..2c27b19cda 100644 --- a/modules/ticket/front/descriptor/index.html +++ b/modules/ticket/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.ticket.client.name" + summary="$ctrl.$.summary"> - \ No newline at end of file + + + + \ No newline at end of file diff --git a/modules/ticket/front/descriptor/locale/es.yml b/modules/ticket/front/descriptor/locale/es.yml index f56f29f92a..2a7bf360ff 100644 --- a/modules/ticket/front/descriptor/locale/es.yml +++ b/modules/ticket/front/descriptor/locale/es.yml @@ -29,4 +29,5 @@ SMS Minimum import: 'SMS Importe minimo' SMS Pending payment: 'SMS Pago pendiente' Restore ticket: Restaurar ticket You are going to restore this ticket: Vas a restaurar este ticket -Are you sure you want to restore this ticket?: ¿Seguro que quieres restaurar el ticket? \ No newline at end of file +Are you sure you want to restore this ticket?: ¿Seguro que quieres restaurar el ticket? +Are you sure you want to refund all?: ¿Seguro que quieres abonar todo? \ No newline at end of file diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index 18905f8590..836fadb9b9 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -512,10 +512,10 @@ Unmark as reserved - Pay Back + Refund \ No newline at end of file diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index a60c9cb965..bb8a81bc4c 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -479,12 +479,12 @@ class Controller extends Section { }); } - createPayBack() { + createRefund() { const sales = this.selectedValidSales(); if (!sales) return; const params = {sales: sales, ticketId: this.ticket.id}; - const query = `Sales/payBack`; + const query = `Sales/refund`; this.resetChanges(); this.$http.post(query, params).then(res => { this.$state.go('ticket.card.sale', {id: res.data}); diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index fc4d1b4f36..a8ac2f3de3 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -703,15 +703,15 @@ describe('Ticket', () => { }); }); - describe('createPayBack()', () => { + describe('createRefund()', () => { it('should make an HTTP POST query and then call to the $state go() method', () => { jest.spyOn(controller, 'selectedValidSales').mockReturnValue(controller.sales); jest.spyOn(controller, 'resetChanges'); jest.spyOn(controller.$state, 'go'); const expectedId = 9999; - $httpBackend.expect('POST', `Sales/payBack`).respond(200, expectedId); - controller.createPayBack(); + $httpBackend.expect('POST', `Sales/refund`).respond(200, expectedId); + controller.createRefund(); $httpBackend.flush(); expect(controller.resetChanges).toHaveBeenCalledWith(); diff --git a/modules/ticket/front/sale/locale/es.yml b/modules/ticket/front/sale/locale/es.yml index 7edb0a626d..aab8ff493d 100644 --- a/modules/ticket/front/sale/locale/es.yml +++ b/modules/ticket/front/sale/locale/es.yml @@ -36,6 +36,6 @@ Warehouse: Almacen Agency: Agencia Shipped: F. envio Packaging: Encajado -Pay Back: Abono +Refund: Abono Promotion mana: Maná promoción -Claim mana: Maná reclamación \ No newline at end of file +Claim mana: Maná reclamación diff --git a/modules/travel/front/descriptor/index.html b/modules/travel/front/descriptor/index.html index 28e908d18f..bbf5721fd9 100644 --- a/modules/travel/front/descriptor/index.html +++ b/modules/travel/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.travel.ref" + summary="$ctrl.$.summary"> @@ -42,3 +43,6 @@
+ + + \ No newline at end of file diff --git a/modules/worker/front/descriptor/index.html b/modules/worker/front/descriptor/index.html index 036b70eab2..01681ebb80 100644 --- a/modules/worker/front/descriptor/index.html +++ b/modules/worker/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.worker.firstName +' '+ $ctrl.worker.lastName" + summary="$ctrl.$.summary">
+ + + + description="$ctrl.zone.name" + summary="$ctrl.$.summary"> + + + +