diff --git a/client/client/src/billing-data/index.html b/client/client/src/billing-data/index.html index 46518b73a..b6ff8cbb2 100644 --- a/client/client/src/billing-data/index.html +++ b/client/client/src/billing-data/index.html @@ -30,6 +30,7 @@ vn-one label="IBAN" field="$ctrl.client.iban" + on-change="$ctrl.autofillBic()" vn-acl="salesAssistant"> { if (shouldNotify) this.notifyChanges(); @@ -57,7 +58,7 @@ export default class Controller { } onBankEntityResponse(response) { - if (response == 'ACCEPT') + if (response == 'ACCEPT') { try { if (!this.newBankEntity.name) throw new Error(`Name can't be empty`); @@ -72,9 +73,26 @@ export default class Controller { this.vnApp.showError(this.$translate.instant(e.message)); return false; } - + } return true; } + + autofillBic() { + if (!this.client.iban) return; + + let countryCode = this.client.iban.substr(0, 2); + let bankEntityId = parseInt(this.client.iban.substr(4, 4)); + let filter = {where: {id: bankEntityId}}; + + if (countryCode != 'ES') return; + + let json = encodeURIComponent(JSON.stringify(filter)); + this.client.bankEntityFk = undefined; + this.$http.get(`/client/api/BankEntities?filter=${json}`).then(response => { + if (response.data) + this.client.bankEntityFk = response.data.id; + }); + } } Controller.$inject = ['$scope', '$http', 'vnApp', '$translate']; diff --git a/client/client/src/billing-data/index.spec.js b/client/client/src/billing-data/index.spec.js index f875eb0a0..141afcf08 100644 --- a/client/client/src/billing-data/index.spec.js +++ b/client/client/src/billing-data/index.spec.js @@ -1,7 +1,7 @@ import './index'; import {watcher} from '../../../helpers/watcherHelper'; -describe('Client', () => { +fdescribe('Client', () => { describe('Component vnClientBillingData', () => { let $componentController; let $httpBackend; @@ -106,5 +106,35 @@ describe('Client', () => { $httpBackend.flush(); }); }); + + describe('autofillBic() should perform a GET query if client iban is specified and country code is "ES".', () => { + it(`Should not define bankEntityFk property`, () => { + controller.client.payMethodFk = 5; + controller.client.iban = 'ES9121000418450200051332'; + let expectedFilter = {where: {id: 2100}}; + let json = encodeURIComponent(JSON.stringify(expectedFilter)); + + $httpBackend.when('GET', `/client/api/BankEntities?filter=${json}`).respond('done'); + $httpBackend.expect('GET', `/client/api/BankEntities?filter=${json}`); + controller.autofillBic(); + $httpBackend.flush(); + + expect(controller.client.bankEntityFk).toBeUndefined(); + }); + + it(`Should define bankEntityFk property`, () => { + controller.client.payMethodFk = 5; + controller.client.iban = 'ES1501280010120123456789'; + let expectedFilter = {where: {id: 128}}; + let json = encodeURIComponent(JSON.stringify(expectedFilter)); + + $httpBackend.when('GET', `/client/api/BankEntities?filter=${json}`).respond({id: 128}); + $httpBackend.expect('GET', `/client/api/BankEntities?filter=${json}`); + controller.autofillBic(); + $httpBackend.flush(); + + expect(controller.client.bankEntityFk).toEqual(128); + }); + }); }); }); diff --git a/client/salix/src/components/left-menu/left-menu.js b/client/salix/src/components/left-menu/left-menu.js index 204d7ddc1..8777ed3f1 100644 --- a/client/salix/src/components/left-menu/left-menu.js +++ b/client/salix/src/components/left-menu/left-menu.js @@ -17,7 +17,7 @@ export default class LeftMenu { for (let item of menu) { let route = states[item.state]; let newItem = { - icon: item.icon, + icon: item.icon, childs: [] }; @@ -29,15 +29,15 @@ export default class LeftMenu { for (let child of item.childs) { let route = states[child.state]; - if(!route) continue; - + if (!route) continue; + newItem.description = item.description; newItem.childs.push({ description: route.self.description, icon: child.icon, state: child.state }); - }; + } } items.push(newItem); diff --git a/services/loopback/common/locale/en.json b/services/loopback/common/locale/en.json index b188713ed..ce3b0afea 100644 --- a/services/loopback/common/locale/en.json +++ b/services/loopback/common/locale/en.json @@ -1,42 +1,21 @@ { - "PHONE_INVALID_FORMAT": "The phone format is invalid", - "You are not allowed to change the credit": "You are not allowed to change the credit", - "Unable to mark the equivalence surcharge": "Unable to mark the equivalence surcharge", - "The default consignee can not be unchecked": "The default consignee can not be unchecked", - "Unable to default a disabled consignee": "Unable to default a disabled consignee", - "Can't be blank": "Can't be blank", - "Invalid TIN": "Invalid TIN", - "TIN must be unique": "TIN must be unique", - "A client with that Web User name already exists": "A client with that Web User name already exists", - "Is invalid": "Is invalid", - "Quantity cannot be zero": "Quantity cannot be zero", - "Enter an integer different to zero": "Enter an integer different to zero", - "The company name must be unique": "The company name must be unique", - "Invalid email": "Invalid email", - "The IBAN does not have the correct format": "The IBAN does not have the correct format", - "That payment method requires an IBAN": "That payment method requires an IBAN", "State cannot be blank": "State cannot be blank", - "Cannot change the payment method if no salesperson": "Cannot change the payment method if no salesperson", - "Only manager can change the credit": "Only manager can change the credit", - "Name cannot be blank": "Name cannot be blank", - "Phone cannot be blank": "Phone cannot be blank", - "Observation type cannot be blank": "Observation type cannot be blank", - "NO_AGENCY_AVAILABLE": "NO_AGENCY_AVAILABLE", - "can't be blank": "can't be blank", "Cannot be blank": "Cannot be blank", - "Description should have maximum of 45 characters": "Description should have maximum of 45 characters", - "Period cannot be blank": "Period cannot be blank", + "Observation type cannot be blank": "Observation type cannot be blank", "The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero", "The grade must be an integer greater than or equal to zero": "The grade must be an integer greater than or equal to zero", + "Invalid email": "Invalid email", + "Name cannot be blank": "Name cannot be blank", + "Phone cannot be blank": "Phone cannot be blank", + "Description should have maximum of 45 characters": "Description should have maximum of 45 characters", + "Period cannot be blank": "Period cannot be blank", "Sample type cannot be blank": "Sample type cannot be blank", - "The package cannot be blank": "The package cannot be blank", - "The warehouse can't be repeated": "The warehouse can't be repeated", - "The new quantity should be smaller than the old one": "The new quantity should be smaller than the old one", - "Package cannot be blank": "Package cannot be blank", - "The sales of this ticket can't be modified": "The sales of this ticket can't be modified", - "You don't have enough privileges to do that": "You don't have enough privileges to do that", - "You don't have enough privileges to change that field": "You don't have enough privileges to change that field", - "You don't have enough privileges": "You don't have enough privileges", + "That payment method requires an IBAN": "That payment method requires an IBAN", + "That payment method requires a BIC": "That payment method requires a BIC", + "The default consignee can not be unchecked": "The default consignee can not be unchecked", "You can't make changes on a client with verified data": "You can't make changes on a client with verified data", - "That payment method requires a BIC": "That payment method requires a BIC" + "Enter an integer different to zero": "Enter an integer different to zero", + "Package cannot be blank": "Package cannot be blank", + "The new quantity should be smaller than the old one": "The new quantity should be smaller than the old one", + "The sales of this ticket can't be modified": "The sales of this ticket can't be modified" } \ No newline at end of file diff --git a/services/loopback/common/locale/es.json b/services/loopback/common/locale/es.json index 26e0cb4fb..18744ca8a 100644 --- a/services/loopback/common/locale/es.json +++ b/services/loopback/common/locale/es.json @@ -15,7 +15,8 @@ "The company name must be unique": "La razón social debe ser única", "Invalid email": "Correo electrónico inválido", "The IBAN does not have the correct format": "El IBAN no tiene el formato correcto", - "That payment method requires an IBAN": "El método de pago seleccionado requiere que se especifique el IBAN", + "That payment method requires an IBAN": "El método de pago seleccionado requiere un IBAN", + "That payment method requires a BIC": "El método de pago seleccionado requiere un BIC", "State cannot be blank": "El estado no puede estar en blanco", "Cannot change the payment method if no salesperson": "No se puede cambiar la forma de pago si no hay comercial asignado", "can't be blank": "El campo no puede estar vacío", @@ -56,6 +57,5 @@ "The sales of this ticket can't be modified": "Los movimientos de este tiquet no pueden ser modificadas", "You can't create an order for a inactive client": "You can't create an order for a inactive client", "You can't create an order for a client that doesn't has tax data verified": "You can't create an order for a client that doesn't has tax data verified", - "You don't have enough privileges": "You don't have enough privileges", - "That payment method requires a BIC": "That payment method requires a BIC" + "You don't have enough privileges": "You don't have enough privileges" } \ No newline at end of file diff --git a/services/loopback/common/models/client.js b/services/loopback/common/models/client.js index 124f7e0ae..f339b7393 100644 --- a/services/loopback/common/models/client.js +++ b/services/loopback/common/models/client.js @@ -91,6 +91,30 @@ module.exports = Self => { err(); } + Self.validateAsync('payMethodFk', hasIban, { + message: 'That payment method requires an IBAN' + }); + + function hasIban(err, done) { + Self.app.models.PayMethod.findById(this.payMethodFk, (_, instance) => { + if (instance && instance.ibanRequired && !this.iban) + err(); + done(); + }); + } + + Self.validateAsync('bankEntityFk', hasBic, { + message: 'That payment method requires a BIC' + }); + + function hasBic(err, done) { + Self.app.models.PayMethod.findById(this.payMethodFk, (_, instance) => { + if (instance && instance.ibanRequired && !this.bankEntityFk) + err(); + done(); + }); + } + Self.observe('before save', async function(ctx) { let changes = ctx.data || ctx.instance; let orgData = ctx.currentInstance; @@ -131,16 +155,6 @@ module.exports = Self => { }; await Self.app.models.ClientCredit.create(newCredit); } - - if (finalState && finalState.payMethodFk) { - let payMethod = await Self.app.models.PayMethod.findById(finalState.payMethodFk); - - if (payMethod && payMethod.ibanRequired && !finalState.iban) - throw new UserError('That payment method requires an IBAN'); - - if (payMethod && payMethod.ibanRequired && !finalState.bankEntityFk) - throw new UserError('That payment method requires a BIC'); - } }); async function validateCreditChange(ctx, finalState) {