const UserError = require('vn-loopback/util/user-error'); const validateTin = require('vn-loopback/util/validateTin'); const LoopBackContext = require('loopback-context'); module.exports = Self => { require('../methods/supplier/filter')(Self); require('../methods/supplier/getSummary')(Self); require('../methods/supplier/updateFiscalData')(Self); require('../methods/supplier/consumption')(Self); require('../methods/supplier/freeAgencies')(Self); require('../methods/supplier/campaignMetricsPdf')(Self); require('../methods/supplier/campaignMetricsEmail')(Self); require('../methods/supplier/newSupplier')(Self); require('../methods/supplier/getItemsPackaging')(Self); require('../methods/supplier/getWithPackaging')(Self); Self.validatesPresenceOf('name', { message: 'The social name cannot be empty' }); Self.validatesPresenceOf('city', { message: 'City cannot be empty' }); Self.validatesPresenceOf('nif', { message: 'The nif cannot be empty' }); Self.validatesUniquenessOf('nif', { message: 'TIN must be unique' }); Self.validateAsync('nif', tinIsValid, { message: 'Invalid TIN' }); Self.validatesLengthOf('postCode', { allowNull: true, allowBlank: true, min: 3, max: 10 }); Self.validateAsync('postCode', hasValidPostcode, { message: `The postcode doesn't exist. Please enter a correct one` }); Self.validatesFormatOf('name', { message: 'Name should be uppercase', allowNull: false, allowBlank: false, with: /^[^a-z]*$/ }); async function hasValidPostcode(err, done) { if (!this.postcode) return done(); const models = Self.app.models; const postcode = await models.Postcode.findById(this.postcode); if (!postcode) err(); done(); } async function tinIsValid(err, done) { if (!this.countryFk) return done(); const filter = { fields: ['code'], where: {id: this.countryFk} }; const country = await Self.app.models.Country.findOne(filter); const code = country ? country.code.toLowerCase() : null; const countryCode = this.nif?.toLowerCase().substring(0, 2); if (!validateTin(this.nif, code) || (this.isVies && countryCode == code)) err(); done(); } function isAlpha(value) { const regexp = new RegExp(/^[ñça-zA-Z0-9\s]*$/i); return regexp.test(value); } Self.validateAsync('payMethodFk', hasSupplierAccount, { message: 'You can not select this payment method without a registered bankery account' }); async function hasSupplierAccount(err, done) { if (!this.payMethodFk) return done(); const payMethod = await Self.app.models.PayMethod.findById(this.payMethodFk); const supplierAccount = await Self.app.models.SupplierAccount.findOne({where: {supplierFk: this.id}}); const hasIban = supplierAccount && supplierAccount.iban; const isMissingIban = payMethod && payMethod.isIbanRequiredForSuppliers && !hasIban; if (isMissingIban) err(); done(); } Self.observe('before save', async function(ctx) { if (ctx.isNewInstance) return; const changes = ctx.data || ctx.instance; const orgData = ctx.currentInstance; const loopBackContext = LoopBackContext.getCurrentContext(); const accessToken = {req: loopBackContext.active}; const editPayMethodCheck = await Self.app.models.ACL.checkAccessAcl(accessToken, 'Supplier', 'editPayMethodCheck', 'WRITE'); const isPayMethodChecked = changes.isPayMethodChecked || orgData.isPayMethodChecked; const hasChanges = orgData && changes; const isPayMethodCheckedChanged = hasChanges && orgData.isPayMethodChecked != isPayMethodChecked; if (!editPayMethodCheck && isPayMethodCheckedChanged) 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.' }); async function hasSupplierSameName(err, done) { if (!this.name || !this.countryFk) return done(); const supplier = await Self.app.models.Supplier.findOne( { where: { name: this.name, countryFk: this.countryFk }, fields: ['id'] }); if (supplier && supplier.id != this.id) err(); done(); } Self.observe('before save', async function(ctx) { const changes = ctx.data || ctx.instance; const orgData = ctx.currentInstance; const name = changes.name || orgData.name; const hasChanges = orgData && changes; const nameChanged = hasChanges && orgData.name != name; if ((nameChanged) && !isAlpha(name)) throw new UserError('The social name has an invalid format'); }); };