#998 worker.index, back tests fixed
This commit is contained in:
parent
bb88c9cfe4
commit
f47fe9c1cc
|
@ -29,27 +29,9 @@
|
||||||
"Warehouse": {
|
"Warehouse": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"Worker": {
|
|
||||||
"dataSource": "vn"
|
|
||||||
},
|
|
||||||
"WorkerMana": {
|
|
||||||
"dataSource": "vn"
|
|
||||||
},
|
|
||||||
"WorkerTeam": {
|
|
||||||
"dataSource": "vn"
|
|
||||||
},
|
|
||||||
"WorkerTeamCollegues": {
|
|
||||||
"dataSource": "vn"
|
|
||||||
},
|
|
||||||
"Sip": {
|
"Sip": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"PersonMedia": {
|
|
||||||
"dataSource": "vn"
|
|
||||||
},
|
|
||||||
"PersonDepartment": {
|
|
||||||
"dataSource": "vn"
|
|
||||||
},
|
|
||||||
"Route": {
|
"Route": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
|
|
@ -57,10 +57,7 @@ module.exports = Self => {
|
||||||
*/
|
*/
|
||||||
Self.hasRole = async function(userId, name) {
|
Self.hasRole = async function(userId, name) {
|
||||||
let roles = await Self.getRoles(userId);
|
let roles = await Self.getRoles(userId);
|
||||||
|
return roles.find(role => role == name);
|
||||||
return roles.find(role => {
|
|
||||||
return role.toLowerCase() == name.toLowerCase();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,7 +78,6 @@ module.exports = Self => {
|
||||||
for (role of result)
|
for (role of result)
|
||||||
roles.push(role.name);
|
roles.push(role.name);
|
||||||
|
|
||||||
|
|
||||||
return roles;
|
return roles;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
{
|
|
||||||
"name": "PersonDepartment",
|
|
||||||
"base": "VnModel",
|
|
||||||
"options": {
|
|
||||||
"mysql": {
|
|
||||||
"table": "personDepartment"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "String"
|
|
||||||
},
|
|
||||||
"firstName": {
|
|
||||||
"type": "String"
|
|
||||||
},
|
|
||||||
"workerFk": {
|
|
||||||
"id": true,
|
|
||||||
"type": "Number"
|
|
||||||
},
|
|
||||||
"department": {
|
|
||||||
"type": "Number"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"relations": {
|
|
||||||
"worker": {
|
|
||||||
"type": "belongsTo",
|
|
||||||
"model": "Worker",
|
|
||||||
"foreignKey": "workerFk"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
{
|
|
||||||
"name": "PersonMedia",
|
|
||||||
"base": "VnModel",
|
|
||||||
"options": {
|
|
||||||
"mysql": {
|
|
||||||
"table": "personMedia"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"mediaValue": {
|
|
||||||
"type": "String"
|
|
||||||
},
|
|
||||||
"workerFk": {
|
|
||||||
"id": true,
|
|
||||||
"type": "Number"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"relations": {
|
|
||||||
"worker": {
|
|
||||||
"type": "belongsTo",
|
|
||||||
"model": "Worker",
|
|
||||||
"foreignKey": "workerFk"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,10 +5,11 @@
|
||||||
* be understandable by people who do not have a technical profile.
|
* be understandable by people who do not have a technical profile.
|
||||||
*/
|
*/
|
||||||
module.exports = class UserError extends Error {
|
module.exports = class UserError extends Error {
|
||||||
constructor(message, ...translateArgs) {
|
constructor(message, code, ...translateArgs) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = 'UserError';
|
this.name = 'UserError';
|
||||||
this.statusCode = 400;
|
this.statusCode = 400;
|
||||||
|
this.code = code;
|
||||||
this.translateArgs = translateArgs;
|
this.translateArgs = translateArgs;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,7 +29,7 @@ module.exports = Self => {
|
||||||
let token = ctx.req.accessToken;
|
let token = ctx.req.accessToken;
|
||||||
let currentUserId = token && token.userId;
|
let currentUserId = token && token.userId;
|
||||||
|
|
||||||
isSalesAssistant = await models.Account.hasRole(currentUserId, 'SalesAssistant');
|
isSalesAssistant = await models.Account.hasRole(currentUserId, 'salesAssistant');
|
||||||
|
|
||||||
if (!isSalesAssistant) {
|
if (!isSalesAssistant) {
|
||||||
let oldClaim = await models.Claim.findById(params.id);
|
let oldClaim = await models.Claim.findById(params.id);
|
||||||
|
|
|
@ -6,10 +6,9 @@ module.exports = Self => {
|
||||||
accessType: 'WRITE',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'params',
|
arg: 'params',
|
||||||
type: 'object',
|
|
||||||
required: true,
|
|
||||||
description: 'ticketFk, stateFk',
|
description: 'ticketFk, stateFk',
|
||||||
http: {source: 'body'}
|
type: 'object',
|
||||||
|
required: true
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
@ -17,33 +16,30 @@ module.exports = Self => {
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
path: `/changeState`,
|
path: `/changeState`,
|
||||||
verb: 'post'
|
verb: 'POST'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.changeState = async(ctx, params) => {
|
Self.changeState = async(ctx, params) => {
|
||||||
|
let userId = ctx.req.accessToken.userId;
|
||||||
let models = Self.app.models;
|
let models = Self.app.models;
|
||||||
let isProduction;
|
|
||||||
let isEditable = await Self.app.models.Ticket.isEditable(params.ticketFk);
|
let isEditable = await models.Ticket.isEditable(params.ticketFk);
|
||||||
let assignedState = await Self.app.models.State.findOne({where: {code: 'PICKER_DESIGNED'}});
|
let assignedState = await models.State.findOne({where: {code: 'PICKER_DESIGNED'}});
|
||||||
let isAssigned = assignedState.id === params.stateFk;
|
let isAssigned = assignedState.id === params.stateFk;
|
||||||
let currentUserId;
|
|
||||||
|
|
||||||
if (ctx.req.accessToken) {
|
let isProduction = await models.Account.hasRole(userId, 'production');
|
||||||
let token = ctx.req.accessToken;
|
let isSalesPerson = await models.Account.hasRole(userId, 'salesPerson');
|
||||||
currentUserId = token && token.userId;
|
let isAllowed = isProduction || isSalesPerson && isEditable && isAssigned;
|
||||||
isProduction = await models.Account.hasRole(currentUserId, 'production');
|
|
||||||
isSalesperson = await models.Account.hasRole(currentUserId, 'salesPerson');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!isEditable && !isProduction) || (isEditable && !isAssigned && isSalesperson) || (!isSalesperson && !isProduction))
|
if (!isAllowed)
|
||||||
throw new UserError(`You don't have enough privileges to change the state of this ticket`);
|
throw new UserError(`You don't have enough privileges`, 'ACCESS_DENIED');
|
||||||
|
|
||||||
if (!isAssigned) {
|
if (!isAssigned) {
|
||||||
let worker = await models.Worker.findOne({where: {userFk: currentUserId}});
|
let worker = await models.Worker.findOne({where: {userFk: userId}});
|
||||||
params.workerFk = worker.id;
|
params.workerFk = worker.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await Self.app.models.TicketTracking.create(params);
|
return await models.TicketTracking.create(params);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,41 +16,44 @@ describe('ticket changeState()', () => {
|
||||||
it('should throw an error if the ticket is not editable and the user isnt production', async() => {
|
it('should throw an error if the ticket is not editable and the user isnt production', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 18}}};
|
let ctx = {req: {accessToken: {userId: 18}}};
|
||||||
let params = {ticketFk: 2, stateFk: 3};
|
let params = {ticketFk: 2, stateFk: 3};
|
||||||
let error;
|
|
||||||
|
let errCode;
|
||||||
try {
|
try {
|
||||||
await app.models.TicketTracking.changeState(ctx, params);
|
await app.models.TicketTracking.changeState(ctx, params);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e;
|
errCode = e.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(error).toEqual(new Error(`You don't have enough privileges to change the state of this ticket`));
|
expect(errCode).toBe('ACCESS_DENIED');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if the state is assigned and theres not worker in params', async() => {
|
it('should throw an error if the state is assigned and theres not worker in params', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 18}}};
|
let ctx = {req: {accessToken: {userId: 18}}};
|
||||||
let assignedState = await app.models.State.findOne({where: {code: 'PICKER_DESIGNED'}});
|
let assignedState = await app.models.State.findOne({where: {code: 'PICKER_DESIGNED'}});
|
||||||
let params = {ticketFk: 11, stateFk: assignedState.id};
|
let params = {ticketFk: 11, stateFk: assignedState.id};
|
||||||
let error;
|
|
||||||
|
let errCode;
|
||||||
try {
|
try {
|
||||||
await app.models.TicketTracking.changeState(ctx, params);
|
await app.models.TicketTracking.changeState(ctx, params);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e;
|
errCode = e.details.codes.workerFk[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(error.message).toEqual('La instancia `TicketTracking` no es válida. Detalles: `workerFk` Worker cannot be blank (value: undefined).');
|
expect(errCode).toEqual('presence');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if a worker thats not production tries to change the state to one thats not assigned', async() => {
|
it('should throw an error if a worker thats not production tries to change the state to one thats not assigned', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 110}}};
|
let ctx = {req: {accessToken: {userId: 110}}};
|
||||||
let params = {ticketFk: 11, stateFk: 3};
|
let params = {ticketFk: 11, stateFk: 3};
|
||||||
let error;
|
|
||||||
|
let errCode;
|
||||||
try {
|
try {
|
||||||
await app.models.TicketTracking.changeState(ctx, params);
|
await app.models.TicketTracking.changeState(ctx, params);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e;
|
errCode = e.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(error.message).toEqual(`You don't have enough privileges to change the state of this ticket`);
|
expect(errCode).toBe('ACCESS_DENIED');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to create a ticket tracking line for a not editable ticket if the user has the production role', async() => {
|
it('should be able to create a ticket tracking line for a not editable ticket if the user has the production role', async() => {
|
||||||
|
|
|
@ -24,7 +24,7 @@ module.exports = Self => {
|
||||||
Self.deleted = async(ctx, params) => {
|
Self.deleted = async(ctx, params) => {
|
||||||
let claimOfATicket = await Self.app.models.Claim.findOne({where: {ticketFk: params.id}});
|
let claimOfATicket = await Self.app.models.Claim.findOne({where: {ticketFk: params.id}});
|
||||||
if (claimOfATicket)
|
if (claimOfATicket)
|
||||||
throw new UserError('You must delete the claim id %d first', claimOfATicket.id);
|
throw new UserError('You must delete the claim id %d first', 'DELETE_CLAIM_FIRST', claimOfATicket.id);
|
||||||
|
|
||||||
let currentTicket = await Self.app.models.Ticket.findById(params.id);
|
let currentTicket = await Self.app.models.Ticket.findById(params.id);
|
||||||
await currentTicket.updateAttributes({isDeleted: '1'});
|
await currentTicket.updateAttributes({isDeleted: '1'});
|
||||||
|
|
|
@ -1 +1,20 @@
|
||||||
{}
|
{
|
||||||
|
"Worker": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"WorkerMana": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"WorkerTeam": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"WorkerTeamCollegues": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"WorkerMedia": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"WorkerDepartment": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "WorkerDepartment",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "personDepartment"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"workerFk": {
|
||||||
|
"id": true,
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"department": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"worker": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Worker",
|
||||||
|
"foreignKey": "workerFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "WorkerMedia",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "personMedia"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"workerFk": {
|
||||||
|
"id": true,
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"mediaValue": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"worker": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Worker",
|
||||||
|
"foreignKey": "workerFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,16 @@
|
||||||
"model": "Account",
|
"model": "Account",
|
||||||
"foreignKey": "userFk"
|
"foreignKey": "userFk"
|
||||||
},
|
},
|
||||||
|
"client": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Client",
|
||||||
|
"foreignKey": "userFk"
|
||||||
|
},
|
||||||
|
"department": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "WorkerDepartment",
|
||||||
|
"foreignKey": "id"
|
||||||
|
},
|
||||||
"collegues": {
|
"collegues": {
|
||||||
"type": "hasMany",
|
"type": "hasMany",
|
||||||
"model": "WorkerTeamCollegues",
|
"model": "WorkerTeamCollegues",
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="/agency/api/Workers"
|
url="/agency/api/Workers"
|
||||||
filter="::$ctrl.filter"
|
include="::$ctrl.include"
|
||||||
limit="20"
|
limit="20"
|
||||||
data="workers"
|
data="workers"
|
||||||
auto-load="true">
|
auto-load="false">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<div class="index-block">
|
<div class="index-block">
|
||||||
<div class="vn-list">
|
<div class="vn-list">
|
||||||
|
@ -23,12 +23,21 @@
|
||||||
class="vn-list-item">
|
class="vn-list-item">
|
||||||
<vn-horizontal ng-click="$ctrl.onClick($event)">
|
<vn-horizontal ng-click="$ctrl.onClick($event)">
|
||||||
<vn-one>
|
<vn-one>
|
||||||
<h6>{{::$ctrl.worker.name}}</h6>
|
<h6>{{::worker.firstName}} {{::worker.name}}</h6>
|
||||||
<vn-label-value label="Id"
|
<vn-label-value label="Id"
|
||||||
value="{{::worker.id}}">
|
value="{{::worker.id}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value label="Name"
|
<vn-label-value label="User"
|
||||||
value="{{::worker.name}}">
|
value="{{::worker.user.name}}">
|
||||||
|
</vn-label-value>
|
||||||
|
<vn-label-value label="Email"
|
||||||
|
value="{{::worker.user.email}}">
|
||||||
|
</vn-label-value>
|
||||||
|
<vn-label-value label="Fiscal identifier"
|
||||||
|
value="{{::worker.client.fi}}">
|
||||||
|
</vn-label-value>
|
||||||
|
<vn-label-value label="Department"
|
||||||
|
value="{{::worker.department.department}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
<vn-horizontal class="buttons">
|
<vn-horizontal class="buttons">
|
||||||
|
|
|
@ -4,7 +4,19 @@ export default class Controller {
|
||||||
constructor($) {
|
constructor($) {
|
||||||
Object.assign(this, {
|
Object.assign(this, {
|
||||||
$,
|
$,
|
||||||
selectedWorker: null
|
selectedWorker: null,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'user',
|
||||||
|
scope: {fields: ['name', 'email']}
|
||||||
|
}, {
|
||||||
|
relation: 'client',
|
||||||
|
scope: {fields: ['fi']}
|
||||||
|
}, {
|
||||||
|
relation: 'department',
|
||||||
|
scope: {fields: ['department']}
|
||||||
|
}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +25,12 @@ export default class Controller {
|
||||||
case 'search':
|
case 'search':
|
||||||
return /^\d+$/.test(value)
|
return /^\d+$/.test(value)
|
||||||
? {id: value}
|
? {id: value}
|
||||||
: {name: {like: `%${value}%`}};
|
: {or: [
|
||||||
|
{firstName: {like: `%${value}%`}},
|
||||||
|
{name: {like: `%${value}%`}}
|
||||||
|
]};
|
||||||
case 'name':
|
case 'name':
|
||||||
|
case 'firstName':
|
||||||
return {[param]: {like: `%${value}%`}};
|
return {[param]: {like: `%${value}%`}};
|
||||||
case 'id':
|
case 'id':
|
||||||
return {[param]: value};
|
return {[param]: value};
|
||||||
|
|
|
@ -17,6 +17,13 @@
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
vn-one
|
vn-one
|
||||||
label="Name"
|
label="Name"
|
||||||
|
model="filter.firstName">
|
||||||
|
</vn-textfield>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield
|
||||||
|
vn-one
|
||||||
|
label="Last name"
|
||||||
model="filter.name">
|
model="filter.name">
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
Loading…
Reference in New Issue