cambios en validacion de credito de cliente
This commit is contained in:
parent
a0955cf50d
commit
3d52031dc2
|
@ -193,6 +193,9 @@ class Autocomplete extends Component {
|
||||||
if (search && !this.finding) {
|
if (search && !this.finding) {
|
||||||
this.maxRow = false;
|
this.maxRow = false;
|
||||||
let filter = {where: {name: {regexp: search}}};
|
let filter = {where: {name: {regexp: search}}};
|
||||||
|
if (this.filter && this.filter.where) {
|
||||||
|
Object.assign(filter.where, this.filter.where);
|
||||||
|
}
|
||||||
let json = JSON.stringify(filter);
|
let json = JSON.stringify(filter);
|
||||||
this.finding = true;
|
this.finding = true;
|
||||||
this.$http.get(`${this.url}?filter=${json}`).then(
|
this.$http.get(`${this.url}?filter=${json}`).then(
|
||||||
|
@ -230,6 +233,9 @@ class Autocomplete extends Component {
|
||||||
filter.limit = this.maxRow;
|
filter.limit = this.maxRow;
|
||||||
filter.order = this.order;
|
filter.order = this.order;
|
||||||
}
|
}
|
||||||
|
if (this.filter) {
|
||||||
|
Object.assign(filter, this.filter);
|
||||||
|
}
|
||||||
|
|
||||||
let json = JSON.stringify(filter);
|
let json = JSON.stringify(filter);
|
||||||
|
|
||||||
|
@ -317,7 +323,8 @@ module.component('vnAutocomplete', {
|
||||||
field: '=',
|
field: '=',
|
||||||
label: '@',
|
label: '@',
|
||||||
multiple: '@?',
|
multiple: '@?',
|
||||||
order: '@?'
|
order: '@?',
|
||||||
|
filter: '<?'
|
||||||
},
|
},
|
||||||
transclude: {
|
transclude: {
|
||||||
tplItem: '?tplItem'
|
tplItem: '?tplItem'
|
||||||
|
|
|
@ -23,10 +23,16 @@
|
||||||
|
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
field="$ctrl.delivery.driver"
|
field="$ctrl.delivery.driver"
|
||||||
url="/route/api/Deliveries/activeDrivers"
|
url="/route/api/Vehicles/activeDrivers"
|
||||||
label="Driver"></vn-autocomplete>
|
label="Driver"></vn-autocomplete>
|
||||||
|
|
||||||
<vn-textfield vn-one label="Vehicle" field="$ctrl.delivery.vehicle"></vn-textfield>
|
<vn-autocomplete vn-one
|
||||||
|
field="$ctrl.delivery.vehicle"
|
||||||
|
url="/route/api/Vehicles/comboVehicles"
|
||||||
|
label="Vehicle"
|
||||||
|
order="tradeMark ASC"
|
||||||
|
filter="{where: {isActive:1, warehouseFk:1}}"
|
||||||
|
></vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
|
var app = require('../../../server/server');
|
||||||
|
|
||||||
module.exports = function(Client) {
|
module.exports = function(Client) {
|
||||||
var CREDIT_CARD = 5;
|
var CREDIT_CARD = 5;
|
||||||
|
var models = app.models;
|
||||||
|
|
||||||
Client.observe('before save', function(ctx, next) {
|
Client.observe('before save', function(ctx, next) {
|
||||||
if (ctx.currentInstance) {
|
if (ctx.currentInstance) {
|
||||||
let dataChange = Object.assign({}, ctx.data);
|
let dataChange = Object.assign({}, ctx.data);
|
||||||
|
let userId = ctx.options.accessToken.userId;
|
||||||
|
|
||||||
Object.assign(ctx.data, doIfNullSalesPerson(ctx.currentInstance));
|
Object.assign(ctx.data, doIfNullSalesPerson(ctx.currentInstance));
|
||||||
|
|
||||||
if (!ctx.data.dueDay)
|
if (!ctx.data.dueDay)
|
||||||
|
@ -12,12 +16,12 @@ module.exports = function(Client) {
|
||||||
|
|
||||||
if (dataChange.hasOwnProperty('equalizationTax') && !canMarkEqualizationTax(ctx.data))
|
if (dataChange.hasOwnProperty('equalizationTax') && !canMarkEqualizationTax(ctx.data))
|
||||||
next(generateErrorEqualizationTax());
|
next(generateErrorEqualizationTax());
|
||||||
|
else if (dataChange.hasOwnProperty('credit'))
|
||||||
|
canChangeCredit(dataChange, userId, next);
|
||||||
else
|
else
|
||||||
next();
|
next();
|
||||||
|
} else if (ctx.where && ctx.where.id) {
|
||||||
} else {
|
Client.findById(ctx.where.id, (_, instance) => {
|
||||||
Client.findById(ctx.where.id, (_, instance) => {
|
|
||||||
|
|
||||||
Object.assign(ctx.data, doIfNullSalesPerson(instance));
|
Object.assign(ctx.data, doIfNullSalesPerson(instance));
|
||||||
|
|
||||||
if (instance
|
if (instance
|
||||||
|
@ -33,6 +37,9 @@ module.exports = function(Client) {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// newInstance
|
||||||
|
next();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -59,5 +66,87 @@ module.exports = function(Client) {
|
||||||
error.status = 500;
|
error.status = 500;
|
||||||
return error;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ module.exports = function(Client) {
|
||||||
});
|
});
|
||||||
|
|
||||||
Client.createUserProfile = (data, callback) => {
|
Client.createUserProfile = (data, callback) => {
|
||||||
let firstEmail = data.email.split(',')[0];
|
let firstEmail = data.email ? data.email.split(',')[0] : null;
|
||||||
let user = {
|
let user = {
|
||||||
name: data.userName,
|
name: data.userName,
|
||||||
email: firstEmail,
|
email: firstEmail,
|
||||||
|
@ -41,14 +41,14 @@ module.exports = function(Client) {
|
||||||
email: data.email
|
email: data.email
|
||||||
};
|
};
|
||||||
|
|
||||||
Client.create(client, {transaction}, (error, client) => {
|
Client.create(client, {transaction}, (error, newClient) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
transaction.rollback();
|
transaction.rollback();
|
||||||
return callback(error);
|
return callback(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
callback(null, true);
|
callback(null, newClient);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@ var app = require('../../server/server');
|
||||||
|
|
||||||
module.exports = function(Self) {
|
module.exports = function(Self) {
|
||||||
var models = app.models;
|
var models = app.models;
|
||||||
var loopBackContext = require('loopback-context');
|
|
||||||
// Methods
|
// Methods
|
||||||
|
|
||||||
require('../methods/client/activate.js')(Self);
|
require('../methods/client/activate.js')(Self);
|
||||||
|
@ -15,7 +15,7 @@ module.exports = function(Self) {
|
||||||
require('../methods/client/roles.js')(Self);
|
require('../methods/client/roles.js')(Self);
|
||||||
require('../methods/client/salesperson.js')(Self);
|
require('../methods/client/salesperson.js')(Self);
|
||||||
require('../methods/client/addressesPropagateRe.js')(Self);
|
require('../methods/client/addressesPropagateRe.js')(Self);
|
||||||
|
|
||||||
// Validations
|
// Validations
|
||||||
|
|
||||||
Self.validatesUniquenessOf('name', {
|
Self.validatesUniquenessOf('name', {
|
||||||
|
@ -49,20 +49,21 @@ module.exports = function(Self) {
|
||||||
});
|
});
|
||||||
|
|
||||||
var validateIban = require('../validations/validateIban');
|
var validateIban = require('../validations/validateIban');
|
||||||
Self.validateBinded('iban',validateIban,{
|
Self.validateBinded('iban', validateIban, {
|
||||||
message:'El iban no tiene el formato correcto'
|
message: 'El iban no tiene el formato correcto'
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.validate('payMethod', hasSalesMan, {
|
Self.validate('payMethod', hasSalesMan, {
|
||||||
message: 'No se puede cambiar la forma de pago si no hay comercial asignado'
|
message: 'No se puede cambiar la forma de pago si no hay comercial asignado'
|
||||||
});
|
});
|
||||||
function hasSalesMan(err) {
|
function hasSalesMan(err) {
|
||||||
if(this.payMethod && !this.salesPerson)
|
if (this.payMethod && !this.salesPerson)
|
||||||
err();
|
err();
|
||||||
}
|
}
|
||||||
Self.validateAsync('payMethodFk', hasIban, {
|
Self.validateAsync('payMethodFk', hasIban, {
|
||||||
message: 'El método de pago seleccionado requiere que se especifique el IBAN'
|
message: 'El método de pago seleccionado requiere que se especifique el IBAN'
|
||||||
});
|
});
|
||||||
|
|
||||||
function hasIban(err, done) {
|
function hasIban(err, done) {
|
||||||
models.PayMethod.findById(this.payMethodFk, (_, instance) => {
|
models.PayMethod.findById(this.payMethodFk, (_, instance) => {
|
||||||
if (instance && instance.ibanRequired && !this.iban)
|
if (instance && instance.ibanRequired && !this.iban)
|
||||||
|
@ -70,87 +71,4 @@ module.exports = function(Self) {
|
||||||
done();
|
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,5 +1,5 @@
|
||||||
module.exports = (Delivery) => {
|
module.exports = (Vehicle) => {
|
||||||
Delivery.remoteMethod('activeDrivers', {
|
Vehicle.remoteMethod('activeDrivers', {
|
||||||
description: 'returns actives employees with driver role',
|
description: 'returns actives employees with driver role',
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
|
@ -20,7 +20,7 @@ module.exports = (Delivery) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Delivery.activeDrivers = (filter, callback) => {
|
Vehicle.activeDrivers = (filter, callback) => {
|
||||||
let skip = filter.skip || 0;
|
let skip = filter.skip || 0;
|
||||||
let limit = filter.limit || 10;
|
let limit = filter.limit || 10;
|
||||||
let where = getCondition(filter.where);
|
let where = getCondition(filter.where);
|
||||||
|
@ -33,7 +33,7 @@ module.exports = (Delivery) => {
|
||||||
ORDER BY em.name ASC
|
ORDER BY em.name ASC
|
||||||
LIMIT ${limit} OFFSET ${skip}`;
|
LIMIT ${limit} OFFSET ${skip}`;
|
||||||
|
|
||||||
Delivery.rawSql(query, [], callback)
|
Vehicle.rawSql(query, [], callback)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
callback(null, formatDriver(response));
|
callback(null, formatDriver(response));
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
|
||||||
module.exports = function(Self) {
|
module.exports = function(Self) {
|
||||||
require('../methods/filter.js')(Self);
|
require('../methods/filterRoutes.js')(Self);
|
||||||
require('../methods/drivers.js')(Self);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
module.exports = function(Self) {
|
||||||
|
require('../methods/comboVehicles.js')(Self);
|
||||||
|
require('../methods/drivers.js')(Self);
|
||||||
|
};
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -32,5 +32,8 @@
|
||||||
},
|
},
|
||||||
"Agency": {
|
"Agency": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"Vehicle": {
|
||||||
|
"dataSource": "vn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue