From 3d52031dc21f4032bc3277e47d097ace0c8fb96d Mon Sep 17 00:00:00 2001 From: Dani Herrero Date: Wed, 18 Oct 2017 12:51:33 +0200 Subject: [PATCH] cambios en validacion de credito de cliente --- client/core/src/autocomplete/autocomplete.js | 9 +- client/route/src/create/create.html | 10 +- .../common/methods/client/before-save.js | 97 ++++++++++++++++++- .../client/common/methods/client/create.js | 6 +- services/client/common/models/client.js | 96 ++---------------- .../route/common/methods/comboVehicles.js | 42 ++++++++ services/route/common/methods/drivers.js | 8 +- .../methods/{filter.js => filterRoutes.js} | 0 services/route/common/models/delivery.js | 3 +- services/route/common/models/vehicle.js | 5 + services/route/common/models/vehicle.json | 33 +++++++ services/route/server/model-config.json | 3 + 12 files changed, 207 insertions(+), 105 deletions(-) create mode 100644 services/route/common/methods/comboVehicles.js rename services/route/common/methods/{filter.js => filterRoutes.js} (100%) create mode 100644 services/route/common/models/vehicle.js create mode 100644 services/route/common/models/vehicle.json diff --git a/client/core/src/autocomplete/autocomplete.js b/client/core/src/autocomplete/autocomplete.js index a4e04a9be..ad5e9c6a1 100644 --- a/client/core/src/autocomplete/autocomplete.js +++ b/client/core/src/autocomplete/autocomplete.js @@ -193,6 +193,9 @@ class Autocomplete extends Component { if (search && !this.finding) { this.maxRow = false; let filter = {where: {name: {regexp: search}}}; + if (this.filter && this.filter.where) { + Object.assign(filter.where, this.filter.where); + } let json = JSON.stringify(filter); this.finding = true; this.$http.get(`${this.url}?filter=${json}`).then( @@ -230,6 +233,9 @@ class Autocomplete extends Component { filter.limit = this.maxRow; filter.order = this.order; } + if (this.filter) { + Object.assign(filter, this.filter); + } let json = JSON.stringify(filter); @@ -317,7 +323,8 @@ module.component('vnAutocomplete', { field: '=', label: '@', multiple: '@?', - order: '@?' + order: '@?', + filter: ' - + diff --git a/services/client/common/methods/client/before-save.js b/services/client/common/methods/client/before-save.js index e8d892be8..56090b8cf 100644 --- a/services/client/common/methods/client/before-save.js +++ b/services/client/common/methods/client/before-save.js @@ -1,10 +1,14 @@ +var app = require('../../../server/server'); module.exports = function(Client) { var CREDIT_CARD = 5; + var models = app.models; Client.observe('before save', function(ctx, next) { if (ctx.currentInstance) { let dataChange = Object.assign({}, ctx.data); + let userId = ctx.options.accessToken.userId; + Object.assign(ctx.data, doIfNullSalesPerson(ctx.currentInstance)); if (!ctx.data.dueDay) @@ -12,12 +16,12 @@ module.exports = function(Client) { if (dataChange.hasOwnProperty('equalizationTax') && !canMarkEqualizationTax(ctx.data)) next(generateErrorEqualizationTax()); + else if (dataChange.hasOwnProperty('credit')) + canChangeCredit(dataChange, userId, next); else next(); - - } else { - Client.findById(ctx.where.id, (_, instance) => { - + } else if (ctx.where && ctx.where.id) { + Client.findById(ctx.where.id, (_, instance) => { Object.assign(ctx.data, doIfNullSalesPerson(instance)); if (instance @@ -33,6 +37,9 @@ module.exports = function(Client) { next(); } }); + } else { + // newInstance + next(); } }); @@ -59,5 +66,87 @@ module.exports = function(Client) { error.status = 500; return error; } + + function generateErrorCredit() { + var error = new Error(); + error.message = "No tienes privilegios para modificar el crédito"; + error.status = 500; + return error; + } + + function canChangeCredit(data, userId, done) { + let filter = { + fields: ['roleFk'], + where: { + maxAmount: {gt: data.credit} + } + }; + + models.ClientCreditLimit.find(filter, + (_, res) => limitCb(_, res)); + + function limitCb(_, instances) { + let requiredRoles = []; + for (instance of instances) + requiredRoles.push(instance.roleFk); + + let where = { + roleId: {inq: requiredRoles}, + principalType: 'USER', + principalId: userId + }; + models.RoleMapping.count(where, + (_, res) => roleCb(_, res)); + } + function roleCb(_, count) { + // si el usuario no tiene alguno de los roles no continua + if (count <= 0) { + done(generateErrorCredit()); + return; + } + // si tiene el rol hay que validar que el último movimiento no fuese crédito 0 insertado por gerencia + validate(); + } + + // Si se puso a 0 por gerencia, solo gerencia puede aumentarlo + function validate() { + let query = 'SELECT * FROM ClientCredit WHERE clientFk = ? ORDER BY created DESC LIMIT 1'; + Client.dataSource.connector.execute(query, [data.id], + (_, res) => maxCb(_, res)); + } + + function maxCb(_, instances) { + if (!instances) { + done(generateErrorCredit()); + return; + } + + if (instances.length !== 1 || instances[0].employeeFk == userId || instances[0].amount > 0) { + done(); + return; + } + + // el ultimo registro tiene valor 0, hay que comprobar que no fue editado por un gerente + let sql = `SELECT count(distinct r.id) as hasManagerRole + FROM ClientCredit cc + JOIN Employee em ON (em.id = cc.employeeFk) + JOIN Account ac ON (ac.id = em.userFk) + JOIN RoleMapping rm ON (rm.principalId = ac.id) + JOIN Role r on (r.id = rm.roleId) + WHERE rm.principalType = 'USER' + AND cc.employeeFk = ${instances[0].employeeFk} + AND r.\`name\` = 'manager'`; + + Client.dataSource.connector.execute(sql, [], (_, res) => clientCreditCb(_, res)); + } + + function clientCreditCb(_, instance) { + if (!instance || (instance.length && instance[0].hasManagerRole > 0)) { + done(generateErrorCredit()); + return; + } + done(); + } + } }; diff --git a/services/client/common/methods/client/create.js b/services/client/common/methods/client/create.js index 84ff937d2..58e947e3f 100644 --- a/services/client/common/methods/client/create.js +++ b/services/client/common/methods/client/create.js @@ -19,7 +19,7 @@ module.exports = function(Client) { }); Client.createUserProfile = (data, callback) => { - let firstEmail = data.email.split(',')[0]; + let firstEmail = data.email ? data.email.split(',')[0] : null; let user = { name: data.userName, email: firstEmail, @@ -41,14 +41,14 @@ module.exports = function(Client) { email: data.email }; - Client.create(client, {transaction}, (error, client) => { + Client.create(client, {transaction}, (error, newClient) => { if (error) { transaction.rollback(); return callback(error); } transaction.commit(); - callback(null, true); + callback(null, newClient); }); }); }); diff --git a/services/client/common/models/client.js b/services/client/common/models/client.js index 19953fa24..321e4f055 100644 --- a/services/client/common/models/client.js +++ b/services/client/common/models/client.js @@ -2,7 +2,7 @@ var app = require('../../server/server'); module.exports = function(Self) { var models = app.models; - var loopBackContext = require('loopback-context'); + // Methods require('../methods/client/activate.js')(Self); @@ -15,7 +15,7 @@ module.exports = function(Self) { require('../methods/client/roles.js')(Self); require('../methods/client/salesperson.js')(Self); require('../methods/client/addressesPropagateRe.js')(Self); - + // Validations Self.validatesUniquenessOf('name', { @@ -49,20 +49,21 @@ module.exports = function(Self) { }); var validateIban = require('../validations/validateIban'); - Self.validateBinded('iban',validateIban,{ - message:'El iban no tiene el formato correcto' + Self.validateBinded('iban', validateIban, { + message: 'El iban no tiene el formato correcto' }); Self.validate('payMethod', hasSalesMan, { message: 'No se puede cambiar la forma de pago si no hay comercial asignado' }); function hasSalesMan(err) { - if(this.payMethod && !this.salesPerson) + if (this.payMethod && !this.salesPerson) err(); } Self.validateAsync('payMethodFk', hasIban, { message: 'El método de pago seleccionado requiere que se especifique el IBAN' }); + function hasIban(err, done) { models.PayMethod.findById(this.payMethodFk, (_, instance) => { if (instance && instance.ibanRequired && !this.iban) @@ -70,87 +71,4 @@ module.exports = function(Self) { done(); }); } - - Self.validateAsync('credit', validateCredit, { - message: 'No tienes privilegios para modificar el crédito' - }); - function validateCredit(err, done) { - let ctx = loopBackContext.getCurrentContext(); - let accessToken = ctx && ctx.get('accessToken'); - let userId = accessToken.userId; - let self = this; - - // Comprueba si el rol del usuario puede asignar esa cantidad - // para ello mira que roles pueden asignar la cantidad que el usuario ha indicado - let filter = { - fields: ['roleFk'], - where: { - maxAmount: {gt: self.credit} - } - }; - models.ClientCreditLimit.find(filter, - (_, res) => limitCb(_, res)); - - function limitCb(_, instances) { - let requiredRoles = []; - for (instance of instances) - requiredRoles.push (instance.roleFk); - - let where = { - roleId: {inq: requiredRoles}, - principalType: 'USER', - principalId: userId - }; - models.RoleMapping.count(where, - (_, res) => roleCb(_, res)); - } - function roleCb(_, count) { - //si el usuario no tiene alguno de los roles no continua - if (!(count > 0)) { - err(); - done(); - } else - validate(); //si tiene el rol hay que validar que el último movimiento no fuese crédito 0 insertado por gerencia - } - - // Si se puso a 0 por gerencia, solo gerencia puede aumentarlo - function validate() { - let query = 'SELECT * FROM ClientCredit WHERE clientFk = ? ORDER BY created DESC LIMIT 1'; - Self.dataSource.connector.execute (query, [self.id], - (_, res) => maxCb(_, res)); - } - - function maxCb(_, instances) { - //console.log('maxCb', instances); - if(!instances){ - err(); - return; - } - - if (instances.length !== 1 || instances[0].employeeFk == userId || instances[0].amount > 0) { - done(); - return; - } - - //el ultimo registro tiene valor 0, hay que comprobar que no fue editado por un gerente - let sql = `SELECT count(distinct r.id) as hasManagerRole - FROM ClientCredit cc - JOIN Employee em ON (em.id = cc.employeeFk) - JOIN Account ac ON (ac.id = em.userFk) - JOIN RoleMapping rm ON (rm.principalId = ac.id) - JOIN Role r on (r.id = rm.roleId) - WHERE rm.principalType = 'USER' - AND cc.employeeFk = ${instances[0].employeeFk} - AND r.\`name\` = 'manager'`; - - Self.dataSource.connector.execute(sql, [], (_, res) => clientCreditCb(_, res)); - } - - function clientCreditCb(_, instance) { - if (!instance || (instance.length && instance[0].hasManagerRole > 0 )) - err(); - done(); - } - } - -}; \ No newline at end of file +}; diff --git a/services/route/common/methods/comboVehicles.js b/services/route/common/methods/comboVehicles.js new file mode 100644 index 000000000..aeef16bde --- /dev/null +++ b/services/route/common/methods/comboVehicles.js @@ -0,0 +1,42 @@ +module.exports = (Vehicle) => { + Vehicle.remoteMethod('comboVehicles', { + description: 'returns list of vehicles', + accessType: 'READ', + accepts: [{ + arg: 'filter', + type: 'Object', + required: false, + description: 'Filter defining where and paginated data', + http: {source: 'query'} + }], + returns: { + arg: 'data', + type: 'Vehicle', + root: true + }, + http: { + path: `/comboVehicles`, + verb: 'get' + } + }); + + Vehicle.comboVehicles = (filter, callback) => { + Vehicle.find(filter, (_, instances) => { + callback(null, formatOutput(instances)); + }); + }; + + function formatOutput(instances) { + let results = []; + + for (let instance of instances) { + let numberPlate = ` ${instance.numberPlate}` || ''; + results.push({ + id: instance.id, + name: `${instance.tradeMark} ${instance.model}${numberPlate}` + }); + } + + return results; + } +}; \ No newline at end of file diff --git a/services/route/common/methods/drivers.js b/services/route/common/methods/drivers.js index bc23f139c..de51f471b 100644 --- a/services/route/common/methods/drivers.js +++ b/services/route/common/methods/drivers.js @@ -1,5 +1,5 @@ -module.exports = (Delivery) => { - Delivery.remoteMethod('activeDrivers', { +module.exports = (Vehicle) => { + Vehicle.remoteMethod('activeDrivers', { description: 'returns actives employees with driver role', accessType: 'READ', accepts: [{ @@ -20,7 +20,7 @@ module.exports = (Delivery) => { } }); - Delivery.activeDrivers = (filter, callback) => { + Vehicle.activeDrivers = (filter, callback) => { let skip = filter.skip || 0; let limit = filter.limit || 10; let where = getCondition(filter.where); @@ -33,7 +33,7 @@ module.exports = (Delivery) => { ORDER BY em.name ASC LIMIT ${limit} OFFSET ${skip}`; - Delivery.rawSql(query, [], callback) + Vehicle.rawSql(query, [], callback) .then(response => { callback(null, formatDriver(response)); }) diff --git a/services/route/common/methods/filter.js b/services/route/common/methods/filterRoutes.js similarity index 100% rename from services/route/common/methods/filter.js rename to services/route/common/methods/filterRoutes.js diff --git a/services/route/common/models/delivery.js b/services/route/common/models/delivery.js index 90d8a1600..5bb764ee3 100644 --- a/services/route/common/models/delivery.js +++ b/services/route/common/models/delivery.js @@ -1,5 +1,4 @@ module.exports = function(Self) { - require('../methods/filter.js')(Self); - require('../methods/drivers.js')(Self); + require('../methods/filterRoutes.js')(Self); }; diff --git a/services/route/common/models/vehicle.js b/services/route/common/models/vehicle.js new file mode 100644 index 000000000..6d6c3a113 --- /dev/null +++ b/services/route/common/models/vehicle.js @@ -0,0 +1,5 @@ + +module.exports = function(Self) { + require('../methods/comboVehicles.js')(Self); + require('../methods/drivers.js')(Self); +}; diff --git a/services/route/common/models/vehicle.json b/services/route/common/models/vehicle.json new file mode 100644 index 000000000..b330dedb7 --- /dev/null +++ b/services/route/common/models/vehicle.json @@ -0,0 +1,33 @@ +{ + "name": "Vehicle", + "base": "VnModel", + "properties": { + "id": { + "id": true, + "type": "Number", + "forceId": false + }, + "numberPlate": { + "type": "Number" + }, + "tradeMark":{ + "type": "String" + }, + "model":{ + "type": "String" + }, + "companyFk": { + "type": "Number" + }, + "warehouseFk": { + "type": "Number" + }, + "m3": { + "type": "Number" + }, + "isActive": { + "type": "Boolean" + } + } + } + \ No newline at end of file diff --git a/services/route/server/model-config.json b/services/route/server/model-config.json index b67cc7bae..032bbc862 100644 --- a/services/route/server/model-config.json +++ b/services/route/server/model-config.json @@ -32,5 +32,8 @@ }, "Agency": { "dataSource": "vn" + }, + "Vehicle": { + "dataSource": "vn" } }