diff --git a/db/changes/234201/00-supplierAccountCheckLength.sql b/db/changes/234201/00-supplierAccountCheckLength.sql new file mode 100644 index 000000000..55a68e37b --- /dev/null +++ b/db/changes/234201/00-supplierAccountCheckLength.sql @@ -0,0 +1,6 @@ +UPDATE `vn`.`supplier` + SET account = LPAD(id,10,'0') + WHERE account IS NULL; + +ALTER TABLE `vn`.`supplier` ADD CONSTRAINT supplierAccountTooShort CHECK (LENGTH(account) = 10); +ALTER TABLE `vn`.`supplier` MODIFY COLUMN account varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT 4100000000 NOT NULL COMMENT 'Default accounting code for suppliers.'; diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 8c50cd9d8..6e478c000 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -216,6 +216,7 @@ "The worker has hours recorded that day": "El trabajador tiene horas fichadas ese día", "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", + "The account size must be exactly 10 characters": "El tamaño de la cuenta debe ser exactamente de 10 caracteres", "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", "You don't have privileges to create refund": "No tienes permisos para crear un abono", "The item is required": "El artículo es requerido", diff --git a/modules/client/back/methods/client/incotermsAuthorizationEmail.js b/modules/client/back/methods/client/incotermsAuthorizationEmail.js index 4a21f20b0..9b3686b07 100644 --- a/modules/client/back/methods/client/incotermsAuthorizationEmail.js +++ b/modules/client/back/methods/client/incotermsAuthorizationEmail.js @@ -33,6 +33,12 @@ module.exports = Self => { type: 'number', description: 'The company id', required: true + }, + { + arg: 'addressId', + type: 'number', + description: 'The address id', + required: true } ], returns: { diff --git a/modules/client/back/methods/client/incotermsAuthorizationHtml.js b/modules/client/back/methods/client/incotermsAuthorizationHtml.js index 0a6bba0a8..af585b1ae 100644 --- a/modules/client/back/methods/client/incotermsAuthorizationHtml.js +++ b/modules/client/back/methods/client/incotermsAuthorizationHtml.js @@ -21,6 +21,12 @@ module.exports = Self => { type: 'number', description: 'The company id', required: true + }, + { + arg: 'addressId', + type: 'number', + description: 'The address id', + required: true } ], returns: [ diff --git a/modules/client/back/methods/client/incotermsAuthorizationPdf.js b/modules/client/back/methods/client/incotermsAuthorizationPdf.js index d37e473f1..ffe17c72f 100644 --- a/modules/client/back/methods/client/incotermsAuthorizationPdf.js +++ b/modules/client/back/methods/client/incotermsAuthorizationPdf.js @@ -21,6 +21,12 @@ module.exports = Self => { type: 'number', description: 'The company id', required: true + }, + { + arg: 'addressId', + type: 'number', + description: 'The address id', + required: true } ], returns: [ diff --git a/modules/client/front/sample/create/index.html b/modules/client/front/sample/create/index.html index 5df2b29ef..9dce7ec72 100644 --- a/modules/client/front/sample/create/index.html +++ b/modules/client/front/sample/create/index.html @@ -8,11 +8,12 @@ auto-load="true" url="Samples/visible" fields="[ - 'id', + 'id', 'code', - 'description', + 'description', 'model', 'hasCompany', + 'hasAddress', 'hasPreview', 'datepickerEnabled' ]" @@ -65,10 +66,36 @@ model="ClientSample.companyFk" data="companiesData" show-field="code" - label="Company" + label="Company" ng-if="sampleType.selection.hasCompany" required="true"> + + + {{::!isActive ? '(Inactive)' : ''}} + {{::nickname}} + + , {{::street}}, {{::city}}, {{::province.name}} - {{::agencyMode.name}} + + + + + + + { + if (res.data) + this.addresses = res.data; + }); + } + + getClientDefaultAddress(value) { + let query = `Clients/${value}`; + this.$http.get(query).then(res => { + if (res.data) + this.addressId = res.data.defaultAddressFk; + }); + } } Controller.$inject = ['$element', '$scope', 'vnEmail']; diff --git a/modules/supplier/back/methods/supplier/specs/newSupplier.spec.js b/modules/supplier/back/methods/supplier/specs/newSupplier.spec.js index c368ec1b8..5fc2ea752 100644 --- a/modules/supplier/back/methods/supplier/specs/newSupplier.spec.js +++ b/modules/supplier/back/methods/supplier/specs/newSupplier.spec.js @@ -32,6 +32,7 @@ describe('Supplier newSupplier()', () => { const result = await models.Supplier.newSupplier(ctx, options); expect(result.name).toEqual('newSupplier'); + await tx.rollback(); } catch (e) { await tx.rollback(); throw e; diff --git a/modules/supplier/back/models/specs/supplier.spec.js b/modules/supplier/back/models/specs/supplier.spec.js index f317f1fb9..fbd3a00db 100644 --- a/modules/supplier/back/models/specs/supplier.spec.js +++ b/modules/supplier/back/models/specs/supplier.spec.js @@ -123,5 +123,21 @@ describe('loopback model Supplier', () => { throw e; } }); + + it('should update the account attribute when a new supplier is created', async() => { + const tx = await models.Supplier.beginTransaction({}); + const options = {transaction: tx}; + + try { + const newSupplier = await models.Supplier.create({name: 'Alfred Pennyworth'}, options); + const fetchedSupplier = await models.Supplier.findById(newSupplier.id, null, options); + + expect(Number(fetchedSupplier.account)).toEqual(4100000000 + newSupplier.id); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); }); diff --git a/modules/supplier/back/models/supplier.js b/modules/supplier/back/models/supplier.js index 96042c9a0..5cf357c13 100644 --- a/modules/supplier/back/models/supplier.js +++ b/modules/supplier/back/models/supplier.js @@ -117,6 +117,16 @@ module.exports = Self => { throw new UserError('You can not modify is pay method checked'); }); + Self.observe('after save', async function(ctx) { + if (ctx.instance && ctx.isNewInstance) { + const {id} = ctx.instance; + const {Supplier} = Self.app.models; + + const supplier = await Supplier.findById(id, null, ctx.options); + await supplier?.updateAttribute('account', Number(supplier.account) + id, ctx.options); + } + }); + Self.validateAsync('name', 'countryFk', hasSupplierSameName, { message: 'A supplier with the same name already exists. Change the country.' }); diff --git a/modules/supplier/front/create/index.html b/modules/supplier/front/create/index.html index c3efcf6ae..eb6e7261e 100644 --- a/modules/supplier/front/create/index.html +++ b/modules/supplier/front/create/index.html @@ -18,7 +18,6 @@ +
+
+
+

{{ $t('title') }}

+

{{ $t('description') }}: {{ data.action }} {{ `(${this.username})` }}

+
+ + {{ `${key}:` }} {{ value }}
+
+
+
+
+
+ diff --git a/print/templates/email/modified-collection-volumetry/modified-collection-volumetry.js b/print/templates/email/modified-collection-volumetry/modified-collection-volumetry.js new file mode 100755 index 000000000..4345ead47 --- /dev/null +++ b/print/templates/email/modified-collection-volumetry/modified-collection-volumetry.js @@ -0,0 +1,25 @@ +const Component = require(`vn-print/core/component`); +const emailBody = new Component('email-body'); +const models = require('vn-loopback/server/server').models; + +module.exports = { + name: 'modified-collection-volumetry', + components: { + 'email-body': emailBody.build(), + }, + async serverPrefetch() { + this.username = (this.data.userFk) ? await this.getUsername(this.data.userFk) : 'system'; + }, + methods: { + async getUsername(id) { + const account = await models.VnUser.findById(id); + return account.name; + } + }, + props: { + data: { + type: Object, + required: true + } + } +}; diff --git a/print/templates/reports/incoterms-authorization/incoterms-authorization.html b/print/templates/reports/incoterms-authorization/incoterms-authorization.html index 99a5e9caa..8c0a327ab 100644 --- a/print/templates/reports/incoterms-authorization/incoterms-authorization.html +++ b/print/templates/reports/incoterms-authorization/incoterms-authorization.html @@ -3,16 +3,16 @@

diff --git a/print/templates/reports/incoterms-authorization/incoterms-authorization.js b/print/templates/reports/incoterms-authorization/incoterms-authorization.js index 53425487e..22ae13167 100755 --- a/print/templates/reports/incoterms-authorization/incoterms-authorization.js +++ b/print/templates/reports/incoterms-authorization/incoterms-authorization.js @@ -7,6 +7,7 @@ module.exports = { this.client = await this.findOneFromDef('client', [this.id]); this.checkMainEntity(this.client); this.company = await this.findOneFromDef('company', [this.companyId]); + this.address = await this.findOneFromDef('address', [this.addressId]); }, props: { id: { @@ -17,6 +18,10 @@ module.exports = { companyId: { type: Number, required: true + }, + addressId: { + type: Number, + required: true } } }; diff --git a/print/templates/reports/incoterms-authorization/locale/es.yml b/print/templates/reports/incoterms-authorization/locale/es.yml index 6936ebda9..ef63e9e3c 100644 --- a/print/templates/reports/incoterms-authorization/locale/es.yml +++ b/print/templates/reports/incoterms-authorization/locale/es.yml @@ -1,28 +1,25 @@ reportName: autorizacion-incoterms description: '{socialName} una sociedad debidamente constituida con responsabilidad limitada -y registrada conforme al derecho de sociedades de {country} y aquí representada por -___________________. {socialName}, con domicilio en {address}, +y registrada conforme al derecho de sociedades de {country} y aquí representada por {socialName}, con domicilio en {address}, CIF {fiscalID}. En adelante denominada {name}.' issued: 'En {0}, a {1} de {2} de {3}' client: 'Cliente {0}' declaration: '{socialName} declara por la presente que:' declarations: - - 'Todas las compras realizadas por {socialName} con {companyName} se -entregan, Ex Works (Incoterms), en el almacén de {companyName} situado en -{companyCity}.' - - '{socialName} reconoce que es importante para {companyName} tener -comprobante de la entrega intracomunitaria de la mercancía a {destinationCountry} para + - 'Todas las compras realizadas por {socialName} con {companyName} se entregan según las condiciones definidas en el incoterm.' + - '{socialName} reconoce que es importante para {companyName} tener +comprobante de la entrega intracomunitaria de la mercancía a {destinationCountry} para poder facturar con 0% de IVA.' - - 'Por tanto, al firmar este acuerdo, {socialName} declara que todos los bienes que + - 'Por tanto, al firmar este acuerdo, {socialName} declara que todos los bienes que se compren a {companyName} serán entregados a {destinationCountry}.' - - 'Además, {socialName} deberá, a primera solicitud de {companyName}, -proporcionar una prueba de que todos los productos comprados a {companyName} han + - 'Además, {socialName} deberá, a primera solicitud de {companyName}, +proporcionar una prueba de que todos los productos comprados a {companyName} han sido entregados en {destinationCountry}.' - - 'Además de lo anterior, {companyName} proporcionará a {socialName} -un resumen mensual en el que se incluyen todas las facturas (y las entregas correspondientes). -{socialName} firmará y devolverá el resumen mensual a {companyName}, + - 'Además de lo anterior, {companyName} proporcionará a {socialName} +un resumen mensual en el que se incluyen todas las facturas (y las entregas correspondientes). +{socialName} firmará y devolverá el resumen mensual a {companyName}, S.L. dentro de los 5 días posteriores a la recepción del resumen.' -signer: +signer: representative: Representante representativeRole: Cargo del representante signed: Fecha de firma @@ -39,4 +36,4 @@ months: - 'Septiembre' - 'Octubre' - 'Noviembre' - - 'Diciembre' \ No newline at end of file + - 'Diciembre' diff --git a/print/templates/reports/incoterms-authorization/locale/pt.yml b/print/templates/reports/incoterms-authorization/locale/pt.yml index 2d33e6a1a..996c0961e 100644 --- a/print/templates/reports/incoterms-authorization/locale/pt.yml +++ b/print/templates/reports/incoterms-authorization/locale/pt.yml @@ -1,28 +1,27 @@ reportName: autorizacion-incoterms description: '{socialName} uma sociedade devidamente constituída com responsabilidade limitada e registada -conforme ao direito de sociedades da {country} e aqui representada por -___________________. {socialName}, com domicílio em {address}, +conforme ao direito de sociedades da {country} e aqui representada por {socialName}, com domicílio em {address}, CIF {fiscalID}. Em adiante denominada {name}.' issued: 'Em {0}, em {1} de {2} de {3}' client: 'Cliente {0}' declaration: '{socialName} declara através da presente que:' declarations: - - 'Todas as compras realizadas por {socialName} a {companyName} se entregam, + - 'Todas as compras realizadas por {socialName} a {companyName} se entregam, Ex Works (Incoterms), no armazém da {companyName} situado em {companyCity}.' - - '{socialName} reconhece ser importante para {companyName} - ter o comprovante da entrega intracomunitária da mercadoria a {destinationCountry} + - '{socialName} reconhece ser importante para {companyName} + ter o comprovante da entrega intracomunitária da mercadoria em {destinationCountry} para poder faturar com 0% de IVA.' - - 'Portanto, ao assinar este acordo, {socialName} declara que todos os bens + - 'Portanto, ao assinar este acordo, {socialName} declara que todos os bens que se comprem na {companyName} serão entregues na {destinationCountry}.' - 'Além disto, {socialName} deverá, na primeira solicitude da {companyName}, - proporcionar uma prova de que todos os produtos comprados na {companyName} - foram entregues na {destinationCountry}.' - - 'Além do anterio, {companyName} proporcionará a {socialName} + proporcionar uma prova de que todos os produtos comprados em {companyName} + foram entregues em {destinationCountry}.' + - 'Além do anterior, {companyName} proporcionará a {socialName} um resumo mensal onde se incluem todas as faturas (e as entregas correspondentes). {socialName} assinará e devolverá o resumo mensal à {companyName}, dentro dos 5 dias posteriores à receção do resumo.' -signer: +signer: representative: Representante representativeRole: Cargo de representante signed: Data da assinatura @@ -39,4 +38,4 @@ months: - 'Setembro' - 'Outubro' - 'Novembro' - - 'Dezembro' \ No newline at end of file + - 'Dezembro' diff --git a/print/templates/reports/incoterms-authorization/sql/address.sql b/print/templates/reports/incoterms-authorization/sql/address.sql new file mode 100644 index 000000000..a432c5e53 --- /dev/null +++ b/print/templates/reports/incoterms-authorization/sql/address.sql @@ -0,0 +1,9 @@ +SELECT + a.nickname, + a.street, + a.postalCode, + a.city, + p.name province +FROM address a + LEFT JOIN province p ON p.id = a.provinceFk +WHERE a.id = ? diff --git a/print/templates/reports/incoterms-authorization/sql/company.sql b/print/templates/reports/incoterms-authorization/sql/company.sql index 39c3290d1..8d94859e1 100644 --- a/print/templates/reports/incoterms-authorization/sql/company.sql +++ b/print/templates/reports/incoterms-authorization/sql/company.sql @@ -1,8 +1,8 @@ -SELECT +SELECT s.name, s.city, cl.name AS manager FROM company c JOIN supplier s ON s.id = c.id JOIN client cl ON cl.id = c.workerManagerFk -WHERE c.id = ? \ No newline at end of file +WHERE c.id = ?