added transactions to several endpoints
This commit is contained in:
parent
61fb997717
commit
1e8ab4d348
|
@ -24,11 +24,16 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.sendCheckingPresence = async(ctx, recipientId, message) => {
|
Self.sendCheckingPresence = async(ctx, recipientId, message, options) => {
|
||||||
if (!recipientId) return false;
|
if (!recipientId) return false;
|
||||||
|
|
||||||
|
let myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const account = await models.Account.findById(recipientId);
|
const account = await models.Account.findById(recipientId, null, myOptions);
|
||||||
const userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
|
|
||||||
if (recipientId == userId) return false;
|
if (recipientId == userId) return false;
|
||||||
|
@ -37,14 +42,14 @@ module.exports = Self => {
|
||||||
throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${userId}`);
|
throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${userId}`);
|
||||||
|
|
||||||
const query = `SELECT worker_isWorking(?) isWorking`;
|
const query = `SELECT worker_isWorking(?) isWorking`;
|
||||||
const [result] = await Self.rawSql(query, [recipientId]);
|
const [result] = await Self.rawSql(query, [recipientId], myOptions);
|
||||||
|
|
||||||
if (!result.isWorking) {
|
if (!result.isWorking) {
|
||||||
const workerDepartment = await models.WorkerDepartment.findById(recipientId, {
|
const workerDepartment = await models.WorkerDepartment.findById(recipientId, {
|
||||||
include: {
|
include: {
|
||||||
relation: 'department'
|
relation: 'department'
|
||||||
}
|
}
|
||||||
});
|
}, myOptions);
|
||||||
const department = workerDepartment && workerDepartment.department();
|
const department = workerDepartment && workerDepartment.department();
|
||||||
const channelName = department && department.chatName;
|
const channelName = department && department.chatName;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,10 @@ module.exports = Self => {
|
||||||
Self.getTickets = async(filter, options) => {
|
Self.getTickets = async(filter, options) => {
|
||||||
const conn = Self.dataSource.connector;
|
const conn = Self.dataSource.connector;
|
||||||
|
|
||||||
|
let myOptions = {};
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const stmt = new ParameterizedSQL(
|
const stmt = new ParameterizedSQL(
|
||||||
`SELECT
|
`SELECT
|
||||||
t.id,
|
t.id,
|
||||||
|
@ -66,7 +70,9 @@ module.exports = Self => {
|
||||||
|
|
||||||
stmt.merge(conn.makeSuffix(filter));
|
stmt.merge(conn.makeSuffix(filter));
|
||||||
|
|
||||||
const tickets = await conn.executeStmt(stmt, options);
|
const tickets = await conn.executeStmt(stmt, myOptions);
|
||||||
|
|
||||||
|
if (tickets.length === 1 && !tickets[0].id) return;
|
||||||
|
|
||||||
return tickets;
|
return tickets;
|
||||||
};
|
};
|
||||||
|
|
|
@ -113,7 +113,7 @@
|
||||||
<vn-confirm
|
<vn-confirm
|
||||||
vn-id="confirm"
|
vn-id="confirm"
|
||||||
question="Delete ticket from route?"
|
question="Delete ticket from route?"
|
||||||
on-accept="$ctrl.removeTicketFromRoute()">
|
on-accept="$ctrl.removeTicketFromRoute($index)">
|
||||||
</vn-confirm>
|
</vn-confirm>
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="possibleTicketsModel"
|
vn-id="possibleTicketsModel"
|
||||||
|
|
|
@ -66,7 +66,7 @@ class Controller extends Section {
|
||||||
|
|
||||||
let url = 'http://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=';
|
let url = 'http://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=';
|
||||||
lines.forEach(line => {
|
lines.forEach(line => {
|
||||||
addresses = addresses + '+to:' + line.address.postalCode + ' ' + line.address.city + ' ' + line.address.street;
|
addresses = addresses + '+to:' + line.postalCode + ' ' + line.city + ' ' + line.street;
|
||||||
});
|
});
|
||||||
|
|
||||||
window.open(url + addresses, '_blank');
|
window.open(url + addresses, '_blank');
|
||||||
|
@ -78,10 +78,11 @@ class Controller extends Section {
|
||||||
this.$.confirm.show();
|
this.$.confirm.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
removeTicketFromRoute() {
|
removeTicketFromRoute($index) {
|
||||||
let params = {routeFk: null};
|
let params = {routeFk: null};
|
||||||
let query = `Tickets/${this.selectedTicket}/`;
|
let query = `Tickets/${this.selectedTicket}/`;
|
||||||
this.$http.patch(query, params).then(() => {
|
this.$http.patch(query, params).then(() => {
|
||||||
|
this.$.model.remove($index);
|
||||||
this.vnApp.showSuccess(this.$t('Ticket removed from route'));
|
this.vnApp.showSuccess(this.$t('Ticket removed from route'));
|
||||||
this.updateVolume();
|
this.updateVolume();
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,48 +9,57 @@ module.exports = Self => {
|
||||||
accepts: [
|
accepts: [
|
||||||
{
|
{
|
||||||
arg: 'ctx',
|
arg: 'ctx',
|
||||||
type: 'Object',
|
type: 'object',
|
||||||
http: {source: 'context'}
|
http: {source: 'context'}
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'filter',
|
arg: 'filter',
|
||||||
type: 'Object',
|
type: 'object',
|
||||||
description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string`
|
description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string`
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'search',
|
arg: 'search',
|
||||||
type: 'String',
|
type: 'string',
|
||||||
description: `If it's and integer searchs by id, otherwise it searchs by nickname`
|
description: `If it's and integer searchs by id, otherwise it searchs by nickname`
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'ticketFk',
|
arg: 'ticketFk',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
description: `Searchs by ticketFk`
|
description: `Searchs by ticketFk`
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'warehouseFk',
|
arg: 'warehouseFk',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
description: `Search by warehouse`
|
description: `Search by warehouse`
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'attenderFk',
|
arg: 'attenderFk',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
description: `Search requests attended by a given worker id`
|
description: `Search requests attended by a given worker id`
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'mine',
|
arg: 'mine',
|
||||||
type: 'Boolean',
|
type: 'boolean',
|
||||||
description: `Search requests attended by the current user`
|
description: `Search requests attended by the current user`
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'from',
|
arg: 'from',
|
||||||
type: 'Date',
|
type: 'date',
|
||||||
description: `Date from`
|
description: `Date from`
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'to',
|
arg: 'to',
|
||||||
type: 'Date',
|
type: 'date',
|
||||||
description: `Date to`
|
description: `Date to`
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'state',
|
arg: 'state',
|
||||||
type: 'String',
|
type: 'string',
|
||||||
description: `Search request by request state`
|
description: `Search request by request state`
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['Object'],
|
type: ['object'],
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
|
|
|
@ -5,65 +5,76 @@ module.exports = Self => {
|
||||||
Self.remoteMethodCtx('componentUpdate', {
|
Self.remoteMethodCtx('componentUpdate', {
|
||||||
description: 'Save ticket sale components',
|
description: 'Save ticket sale components',
|
||||||
accessType: 'WRITE',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [
|
||||||
|
{
|
||||||
arg: 'id',
|
arg: 'id',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'The ticket id',
|
description: 'The ticket id',
|
||||||
http: {source: 'path'}
|
http: {source: 'path'}
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'clientFk',
|
arg: 'clientFk',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
description: 'The client id',
|
description: 'The client id',
|
||||||
required: true
|
required: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'agencyModeFk',
|
arg: 'agencyModeFk',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
description: 'The agencyMode id',
|
description: 'The agencyMode id',
|
||||||
required: true
|
required: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'addressFk',
|
arg: 'addressFk',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
description: 'The address id',
|
description: 'The address id',
|
||||||
required: true
|
required: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'zoneFk',
|
arg: 'zoneFk',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
description: 'The zone id',
|
description: 'The zone id',
|
||||||
required: true
|
required: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'warehouseFk',
|
arg: 'warehouseFk',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
description: 'The warehouse id',
|
description: 'The warehouse id',
|
||||||
required: true
|
required: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'companyFk',
|
arg: 'companyFk',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
description: 'The company id',
|
description: 'The company id',
|
||||||
required: true
|
required: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'shipped',
|
arg: 'shipped',
|
||||||
type: 'Date',
|
type: 'date',
|
||||||
description: 'The shipped date',
|
description: 'The shipped date',
|
||||||
required: true
|
required: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'landed',
|
arg: 'landed',
|
||||||
type: 'Date',
|
type: 'date',
|
||||||
description: 'The landing date',
|
description: 'The landing date',
|
||||||
required: true
|
required: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'isDeleted',
|
arg: 'isDeleted',
|
||||||
type: 'Boolean',
|
type: 'boolean',
|
||||||
description: 'Ticket is deleted',
|
description: 'Ticket is deleted',
|
||||||
required: true
|
required: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'option',
|
arg: 'option',
|
||||||
type: 'Number',
|
type: 'number',
|
||||||
description: 'Action id',
|
description: 'Action id',
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['Object'],
|
type: ['object'],
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
|
@ -72,31 +83,53 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.componentUpdate = async(ctx, id, clientFk, agencyModeFk, addressFk, zoneFk, warehouseFk,
|
Self.componentUpdate = async(ctx, options) => {
|
||||||
companyFk, shipped, landed, isDeleted, option) => {
|
const args = ctx.args;
|
||||||
|
let tx;
|
||||||
|
let myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
const userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const $t = ctx.req.__; // $translate
|
const $t = ctx.req.__; // $translate
|
||||||
const isEditable = await models.Ticket.isEditable(ctx, id);
|
const isEditable = await models.Ticket.isEditable(ctx, args.id, myOptions);
|
||||||
|
|
||||||
if (!isEditable)
|
if (!isEditable)
|
||||||
throw new UserError(`The sales of this ticket can't be modified`);
|
throw new UserError(`The sales of this ticket can't be modified`);
|
||||||
|
|
||||||
const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss');
|
const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss', myOptions);
|
||||||
if (!isProductionBoss) {
|
if (!isProductionBoss) {
|
||||||
const zoneShipped = await models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk);
|
const zoneShipped = await models.Agency.getShipped(args.landed, args.addressFk, args.agencyModeFk, args.warehouseFk, myOptions);
|
||||||
|
|
||||||
if (!zoneShipped || zoneShipped.zoneFk != zoneFk)
|
if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk)
|
||||||
throw new UserError(`You don't have privileges to change the zone`);
|
throw new UserError(`You don't have privileges to change the zone`);
|
||||||
}
|
}
|
||||||
const observationTypeDelivery = await models.ObservationType.findOne({
|
const observationTypeDelivery = await models.ObservationType.findOne({
|
||||||
where: {code: 'delivery'}
|
where: {code: 'delivery'}
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
const originalTicket = await models.Ticket.findOne({
|
const originalTicket = await models.Ticket.findOne({
|
||||||
where: {id: id},
|
where: {id: args.id},
|
||||||
fields: ['id', 'clientFk', 'agencyModeFk', 'addressFk', 'zoneFk',
|
fields: [
|
||||||
'warehouseFk', 'companyFk', 'shipped', 'landed', 'isDeleted'],
|
'id',
|
||||||
|
'clientFk',
|
||||||
|
'agencyModeFk',
|
||||||
|
'addressFk',
|
||||||
|
'zoneFk',
|
||||||
|
'warehouseFk',
|
||||||
|
'companyFk',
|
||||||
|
'shipped',
|
||||||
|
'landed',
|
||||||
|
'isDeleted'
|
||||||
|
],
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
relation: 'client',
|
relation: 'client',
|
||||||
|
@ -104,8 +137,9 @@ module.exports = Self => {
|
||||||
fields: 'salesPersonFk'
|
fields: 'salesPersonFk'
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
});
|
}, myOptions);
|
||||||
const updatedTicket = Object.assign({}, ctx.args);
|
|
||||||
|
const updatedTicket = Object.assign({}, args);
|
||||||
delete updatedTicket.ctx;
|
delete updatedTicket.ctx;
|
||||||
delete updatedTicket.option;
|
delete updatedTicket.option;
|
||||||
|
|
||||||
|
@ -113,50 +147,49 @@ module.exports = Self => {
|
||||||
const hasToBeUnrouted = true;
|
const hasToBeUnrouted = true;
|
||||||
const query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
const query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
||||||
const res = await Self.rawSql(query, [
|
const res = await Self.rawSql(query, [
|
||||||
id,
|
args.id,
|
||||||
clientFk,
|
args.clientFk,
|
||||||
agencyModeFk,
|
args.agencyModeFk,
|
||||||
addressFk,
|
args.addressFk,
|
||||||
zoneFk,
|
args.zoneFk,
|
||||||
warehouseFk,
|
args.warehouseFk,
|
||||||
companyFk,
|
args.companyFk,
|
||||||
shipped,
|
args.shipped,
|
||||||
landed,
|
args.landed,
|
||||||
isDeleted,
|
args.isDeleted,
|
||||||
hasToBeUnrouted,
|
hasToBeUnrouted,
|
||||||
option
|
args.option
|
||||||
]);
|
], myOptions);
|
||||||
|
|
||||||
if (originalTicket.addressFk != updatedTicket.addressFk) {
|
if (originalTicket.addressFk != updatedTicket.addressFk) {
|
||||||
const ticketObservation = await models.TicketObservation.findOne({
|
const ticketObservation = await models.TicketObservation.findOne({
|
||||||
where: {
|
where: {
|
||||||
ticketFk: id,
|
ticketFk: args.id,
|
||||||
observationTypeFk: observationTypeDelivery.id}
|
observationTypeFk: observationTypeDelivery.id}
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
if (ticketObservation)
|
if (ticketObservation)
|
||||||
await ticketObservation.destroy();
|
await ticketObservation.destroy(myOptions);
|
||||||
|
|
||||||
const address = await models.Address.findOne({
|
const address = await models.Address.findOne({
|
||||||
where: {id: addressFk},
|
where: {id: args.addressFk},
|
||||||
include: {
|
include: {
|
||||||
relation: 'observations',
|
relation: 'observations',
|
||||||
scope: {
|
scope: {
|
||||||
where: {observationTypeFk: observationTypeDelivery.id},
|
where: {observationTypeFk: observationTypeDelivery.id},
|
||||||
include: {
|
include: {
|
||||||
relation: 'observationType'
|
relation: 'observationType'
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}, myOptions);
|
||||||
const [observation] = address.observations();
|
const [observation] = address.observations();
|
||||||
if (observation) {
|
if (observation) {
|
||||||
await models.TicketObservation.create({
|
await models.TicketObservation.create({
|
||||||
ticketFk: id,
|
ticketFk: args.id,
|
||||||
observationTypeFk: observation.observationTypeFk,
|
observationTypeFk: observation.observationTypeFk,
|
||||||
description: observation.description
|
description: observation.description
|
||||||
});
|
}, myOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,14 +198,14 @@ module.exports = Self => {
|
||||||
const newProperties = await loggable.translateValues(Self, changes.new);
|
const newProperties = await loggable.translateValues(Self, changes.new);
|
||||||
|
|
||||||
await models.TicketLog.create({
|
await models.TicketLog.create({
|
||||||
originFk: id,
|
originFk: args.id,
|
||||||
userFk: userId,
|
userFk: userId,
|
||||||
action: 'update',
|
action: 'update',
|
||||||
changedModel: 'Ticket',
|
changedModel: 'Ticket',
|
||||||
changedModelId: id,
|
changedModelId: args.id,
|
||||||
oldInstance: oldProperties,
|
oldInstance: oldProperties,
|
||||||
newInstance: newProperties
|
newInstance: newProperties
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
const salesPersonId = originalTicket.client().salesPersonFk;
|
const salesPersonId = originalTicket.client().salesPersonFk;
|
||||||
if (salesPersonId) {
|
if (salesPersonId) {
|
||||||
|
@ -187,13 +220,19 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const message = $t('Changed this data from the ticket', {
|
const message = $t('Changed this data from the ticket', {
|
||||||
ticketId: id,
|
ticketId: args.id,
|
||||||
ticketUrl: `${origin}/#!/ticket/${id}/summary`,
|
ticketUrl: `${origin}/#!/ticket/${args.id}/summary`,
|
||||||
changes: changesMade
|
changes: changesMade
|
||||||
});
|
});
|
||||||
await models.Chat.sendCheckingPresence(ctx, salesPersonId, message);
|
await models.Chat.sendCheckingPresence(ctx, salesPersonId, message, myOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,15 +19,19 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.isEditable = async(ctx, id) => {
|
Self.isEditable = async(ctx, id, options) => {
|
||||||
const userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
let state = await Self.app.models.TicketState.findOne({
|
let state = await Self.app.models.TicketState.findOne({
|
||||||
where: {ticketFk: id}
|
where: {ticketFk: id}
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
const isSalesAssistant = await Self.app.models.Account.hasRole(userId, 'salesAssistant');
|
const isSalesAssistant = await Self.app.models.Account.hasRole(userId, 'salesAssistant', myOptions);
|
||||||
const isProductionBoss = await Self.app.models.Account.hasRole(userId, 'productionBoss');
|
const isProductionBoss = await Self.app.models.Account.hasRole(userId, 'productionBoss', myOptions);
|
||||||
const isValidRole = isSalesAssistant || isProductionBoss;
|
const isValidRole = isSalesAssistant || isProductionBoss;
|
||||||
|
|
||||||
let alertLevel = state ? state.alertLevel : null;
|
let alertLevel = state ? state.alertLevel : null;
|
||||||
|
@ -41,8 +45,8 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
});
|
}, myOptions);
|
||||||
const isLocked = await Self.app.models.Ticket.isLocked(id);
|
const isLocked = await Self.app.models.Ticket.isLocked(id, myOptions);
|
||||||
|
|
||||||
const alertLevelGreaterThanZero = (alertLevel && alertLevel > 0);
|
const alertLevelGreaterThanZero = (alertLevel && alertLevel > 0);
|
||||||
const isNormalClient = ticket && ticket.client().type().code == 'normal';
|
const isNormalClient = ticket && ticket.client().type().code == 'normal';
|
||||||
|
|
|
@ -19,10 +19,15 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.isLocked = async id => {
|
Self.isLocked = async(id, options) => {
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const ticket = await Self.app.models.Ticket.findById(id, {
|
const ticket = await Self.app.models.Ticket.findById(id, {
|
||||||
fields: ['isDeleted', 'refFk']
|
fields: ['isDeleted', 'refFk']
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
const isDeleted = ticket && ticket.isDeleted;
|
const isDeleted = ticket && ticket.isDeleted;
|
||||||
const isInvoiced = ticket && ticket.refFk;
|
const isInvoiced = ticket && ticket.refFk;
|
||||||
|
|
|
@ -13,10 +13,10 @@ describe('ticket componentUpdate()', () => {
|
||||||
let secondvalueBeforeChange;
|
let secondvalueBeforeChange;
|
||||||
let componentOfSaleSeven;
|
let componentOfSaleSeven;
|
||||||
let componentOfSaleEight;
|
let componentOfSaleEight;
|
||||||
|
let componentValue;
|
||||||
|
|
||||||
beforeAll(async done => {
|
beforeAll(async() => {
|
||||||
try {
|
const deliveryComponenet = await app.models.Component.findOne({where: {code: 'delivery'}});
|
||||||
let deliveryComponenet = await app.models.Component.findOne({where: {code: 'delivery'}});
|
|
||||||
deliveryComponentId = deliveryComponenet.id;
|
deliveryComponentId = deliveryComponenet.id;
|
||||||
componentOfSaleSeven = `SELECT value FROM vn.saleComponent WHERE saleFk = 7 AND componentFk = ${deliveryComponentId}`;
|
componentOfSaleSeven = `SELECT value FROM vn.saleComponent WHERE saleFk = 7 AND componentFk = ${deliveryComponentId}`;
|
||||||
componentOfSaleEight = `SELECT value FROM vn.saleComponent WHERE saleFk = 8 AND componentFk = ${deliveryComponentId}`;
|
componentOfSaleEight = `SELECT value FROM vn.saleComponent WHERE saleFk = 8 AND componentFk = ${deliveryComponentId}`;
|
||||||
|
@ -26,28 +26,30 @@ describe('ticket componentUpdate()', () => {
|
||||||
|
|
||||||
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleEight);
|
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleEight);
|
||||||
secondvalueBeforeChange = componentValue.value;
|
secondvalueBeforeChange = componentValue.value;
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change the agencyMode to modify the sale components value and then undo the changes', async() => {
|
it('should change the agencyMode to modify the sale components value', async() => {
|
||||||
const clientID = 102;
|
const tx = await app.models.SaleComponent.beginTransaction({});
|
||||||
const addressID = 122;
|
|
||||||
const agencyModeID = 8;
|
try {
|
||||||
const warehouseID = 1;
|
const options = {transaction: tx};
|
||||||
const zoneID = 5;
|
|
||||||
const shipped = today;
|
const args = {
|
||||||
const companyID = 442;
|
id: ticketID,
|
||||||
const isDeleted = false;
|
clientFk: 102,
|
||||||
const landed = tomorrow;
|
agencyModeFk: 8,
|
||||||
const option = 1;
|
addressFk: 122,
|
||||||
|
zoneFk: 5,
|
||||||
|
warehouseFk: 1,
|
||||||
|
companyFk: 442,
|
||||||
|
shipped: today,
|
||||||
|
landed: tomorrow,
|
||||||
|
isDeleted: false,
|
||||||
|
option: 1
|
||||||
|
};
|
||||||
|
|
||||||
let ctx = {
|
let ctx = {
|
||||||
args: {clientFk: clientID,
|
args: args,
|
||||||
agencyModeFk: agencyModeID},
|
|
||||||
req: {
|
req: {
|
||||||
accessToken: {userId: userID},
|
accessToken: {userId: userID},
|
||||||
headers: {origin: 'http://localhost'},
|
headers: {origin: 'http://localhost'},
|
||||||
|
@ -57,63 +59,46 @@ describe('ticket componentUpdate()', () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
await app.models.Ticket.componentUpdate(ctx, ticketID, clientID, agencyModeID, addressID,
|
await app.models.Ticket.componentUpdate(ctx, options);
|
||||||
zoneID, warehouseID, companyID, shipped, landed, isDeleted, option);
|
|
||||||
|
|
||||||
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven);
|
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven, null, options);
|
||||||
let firstvalueAfterChange = componentValue.value;
|
let firstvalueAfterChange = componentValue.value;
|
||||||
|
|
||||||
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleEight);
|
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleEight, null, options);
|
||||||
let secondvalueAfterChange = componentValue.value;
|
let secondvalueAfterChange = componentValue.value;
|
||||||
|
|
||||||
expect(firstvalueBeforeChange).not.toEqual(firstvalueAfterChange);
|
expect(firstvalueBeforeChange).not.toEqual(firstvalueAfterChange);
|
||||||
expect(secondvalueBeforeChange).not.toEqual(secondvalueAfterChange);
|
expect(secondvalueBeforeChange).not.toEqual(secondvalueAfterChange);
|
||||||
|
|
||||||
// restores
|
await tx.rollback();
|
||||||
const restores = {
|
} catch (e) {
|
||||||
clientID: 102,
|
await tx.rollback();
|
||||||
addressID: 122,
|
throw e;
|
||||||
agencyModeID: 7,
|
}
|
||||||
warehouseID: 1,
|
|
||||||
zoneID: 3,
|
|
||||||
shipped: today,
|
|
||||||
companyID: 442,
|
|
||||||
isDeleted: false,
|
|
||||||
landed: tomorrow,
|
|
||||||
option: 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.clientFk = restores.clientID;
|
|
||||||
ctx.agencyModeFk = restores.agencyModeID;
|
|
||||||
|
|
||||||
await app.models.Ticket.componentUpdate(ctx, ticketID, restores.clientID, restores.agencyModeID, restores.addressID,
|
|
||||||
restores.zoneID, restores.warehouseID, restores.companyID, restores.shipped, restores.landed, restores.isDeleted, restores.option);
|
|
||||||
|
|
||||||
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven);
|
|
||||||
firstvalueAfterChange = componentValue.value;
|
|
||||||
|
|
||||||
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleEight);
|
|
||||||
secondvalueAfterChange = componentValue.value;
|
|
||||||
|
|
||||||
expect(firstvalueBeforeChange).toEqual(firstvalueAfterChange);
|
|
||||||
expect(secondvalueBeforeChange).toEqual(secondvalueAfterChange);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change the addressFk and check that delivery observations have been changed and then undo the changes', async() => {
|
it('should change the addressFk and check that delivery observations have been changed', async() => {
|
||||||
const clientID = 102;
|
const tx = await app.models.SaleComponent.beginTransaction({});
|
||||||
const addressID = 122;
|
|
||||||
const newAddressID = 2;
|
try {
|
||||||
const agencyModeID = 8;
|
const options = {transaction: tx};
|
||||||
const warehouseID = 1;
|
|
||||||
const zoneID = 5;
|
const args = {
|
||||||
const shipped = today;
|
id: ticketID,
|
||||||
const companyID = 442;
|
clientFk: 102,
|
||||||
const isDeleted = false;
|
agencyModeFk: 8,
|
||||||
const landed = tomorrow;
|
addressFk: 2,
|
||||||
const option = 1;
|
zoneFk: 5,
|
||||||
|
warehouseFk: 1,
|
||||||
|
companyFk: 442,
|
||||||
|
shipped: today,
|
||||||
|
landed: tomorrow,
|
||||||
|
isDeleted: false,
|
||||||
|
option: 1
|
||||||
|
};
|
||||||
|
|
||||||
const ctx = {
|
const ctx = {
|
||||||
args: {clientFk: clientID,
|
args: args,
|
||||||
agencyModeFk: agencyModeID},
|
|
||||||
req: {
|
req: {
|
||||||
accessToken: {userId: userID},
|
accessToken: {userId: userID},
|
||||||
headers: {origin: 'http://localhost'},
|
headers: {origin: 'http://localhost'},
|
||||||
|
@ -124,36 +109,29 @@ describe('ticket componentUpdate()', () => {
|
||||||
};
|
};
|
||||||
const observationTypeDelivery = await app.models.ObservationType.findOne({
|
const observationTypeDelivery = await app.models.ObservationType.findOne({
|
||||||
where: {code: 'delivery'}
|
where: {code: 'delivery'}
|
||||||
});
|
}, options);
|
||||||
const originalTicketObservation = await app.models.TicketObservation.findOne({
|
const originalTicketObservation = await app.models.TicketObservation.findOne({
|
||||||
where: {
|
where: {
|
||||||
ticketFk: ticketID,
|
ticketFk: args.id,
|
||||||
observationTypeFk: observationTypeDelivery.id}
|
observationTypeFk: observationTypeDelivery.id}
|
||||||
});
|
}, options);
|
||||||
|
|
||||||
expect(originalTicketObservation).toBeDefined();
|
expect(originalTicketObservation).toBeDefined();
|
||||||
|
|
||||||
await app.models.Ticket.componentUpdate(ctx, ticketID, clientID, agencyModeID, newAddressID,
|
await app.models.Ticket.componentUpdate(ctx, options);
|
||||||
zoneID, warehouseID, companyID, shipped, landed, isDeleted, option);
|
|
||||||
|
|
||||||
const removedTicketObservation = await app.models.TicketObservation.findOne({
|
const removedTicketObservation = await app.models.TicketObservation.findOne({
|
||||||
where: {
|
where: {
|
||||||
ticketFk: ticketID,
|
ticketFk: ticketID,
|
||||||
observationTypeFk: observationTypeDelivery.id}
|
observationTypeFk: observationTypeDelivery.id}
|
||||||
});
|
}, options);
|
||||||
|
|
||||||
expect(removedTicketObservation).toBeNull();
|
expect(removedTicketObservation).toBeNull();
|
||||||
|
|
||||||
// restores
|
await tx.rollback();
|
||||||
await app.models.Ticket.componentUpdate(ctx, ticketID, clientID, agencyModeID, addressID,
|
} catch (e) {
|
||||||
zoneID, warehouseID, companyID, shipped, landed, isDeleted, option);
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
const restoredTicketObservation = await app.models.TicketObservation.findOne({
|
}
|
||||||
where: {
|
|
||||||
ticketFk: ticketID,
|
|
||||||
observationTypeFk: observationTypeDelivery.id}
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(restoredTicketObservation.description).toEqual(originalTicketObservation.description);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,15 +2,33 @@ const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('ticket isEditable()', () => {
|
describe('ticket isEditable()', () => {
|
||||||
it('should return false if the given ticket does not exist', async() => {
|
it('should return false if the given ticket does not exist', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 9}}};
|
const tx = await app.models.Ticket.beginTransaction({});
|
||||||
let result = await app.models.Ticket.isEditable(ctx, 99999);
|
let result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const ctx = {
|
||||||
|
req: {accessToken: {userId: 9}}
|
||||||
|
};
|
||||||
|
|
||||||
|
result = await app.models.Ticket.isEditable(ctx, 9999, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
expect(result).toEqual(false);
|
expect(result).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should return false if the given ticket isn't invoiced but isDeleted`, async() => {
|
it(`should return false if the given ticket isn't invoiced but isDeleted`, async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 9}}};
|
const tx = await app.models.Ticket.beginTransaction({});
|
||||||
let deletedTicket = await app.models.Ticket.findOne({
|
let result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const deletedTicket = await app.models.Ticket.findOne({
|
||||||
where: {
|
where: {
|
||||||
invoiceOut: null,
|
invoiceOut: null,
|
||||||
isDeleted: true
|
isDeleted: true
|
||||||
|
@ -18,36 +36,101 @@ describe('ticket isEditable()', () => {
|
||||||
fields: ['id']
|
fields: ['id']
|
||||||
});
|
});
|
||||||
|
|
||||||
let result = await app.models.Ticket.isEditable(ctx, deletedTicket.id);
|
const ctx = {
|
||||||
|
req: {accessToken: {userId: 9}}
|
||||||
|
};
|
||||||
|
|
||||||
|
result = await app.models.Ticket.isEditable(ctx, deletedTicket.id, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
expect(result).toEqual(false);
|
expect(result).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true if the given ticket is editable', async() => {
|
it('should return true if the given ticket is editable', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 9}}};
|
const tx = await app.models.Ticket.beginTransaction({});
|
||||||
|
let result;
|
||||||
|
|
||||||
let result = await app.models.Ticket.isEditable(ctx, 16);
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const ctx = {
|
||||||
|
req: {accessToken: {userId: 9}}
|
||||||
|
};
|
||||||
|
|
||||||
|
result = await app.models.Ticket.isEditable(ctx, 16, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
expect(result).toEqual(true);
|
expect(result).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be able to edit a deleted or invoiced ticket even for salesAssistant', async() => {
|
it('should not be able to edit a deleted or invoiced ticket even for salesAssistant', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 21}}};
|
const tx = await app.models.Ticket.beginTransaction({});
|
||||||
let result = await app.models.Ticket.isEditable(ctx, 19);
|
let result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const ctx = {
|
||||||
|
req: {accessToken: {userId: 21}}
|
||||||
|
};
|
||||||
|
|
||||||
|
result = await app.models.Ticket.isEditable(ctx, 19, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
expect(result).toEqual(false);
|
expect(result).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be able to edit a deleted or invoiced ticket even for productionBoss', async() => {
|
it('should not be able to edit a deleted or invoiced ticket even for productionBoss', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 50}}};
|
const tx = await app.models.Ticket.beginTransaction({});
|
||||||
let result = await app.models.Ticket.isEditable(ctx, 19);
|
let result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const ctx = {
|
||||||
|
req: {accessToken: {userId: 50}}
|
||||||
|
};
|
||||||
|
|
||||||
|
result = await app.models.Ticket.isEditable(ctx, 19, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
expect(result).toEqual(false);
|
expect(result).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be able to edit a deleted or invoiced ticket even for salesPerson', async() => {
|
it('should not be able to edit a deleted or invoiced ticket even for salesPerson', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 18}}};
|
const tx = await app.models.Ticket.beginTransaction({});
|
||||||
let result = await app.models.Ticket.isEditable(ctx, 19);
|
let result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const ctx = {
|
||||||
|
req: {accessToken: {userId: 18}}
|
||||||
|
};
|
||||||
|
|
||||||
|
result = await app.models.Ticket.isEditable(ctx, 19, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
expect(result).toEqual(false);
|
expect(result).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,7 +34,12 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getShipped = async(landed, addressFk, agencyModeFk, warehouseFk) => {
|
Self.getShipped = async(landed, addressFk, agencyModeFk, warehouseFk, options) => {
|
||||||
|
let myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
let stmts = [];
|
let stmts = [];
|
||||||
stmts.push(new ParameterizedSQL(
|
stmts.push(new ParameterizedSQL(
|
||||||
`CALL vn.zone_getShippedWarehouse(?, ?, ?)`, [
|
`CALL vn.zone_getShippedWarehouse(?, ?, ?)`, [
|
||||||
|
@ -44,14 +49,14 @@ module.exports = Self => {
|
||||||
]
|
]
|
||||||
));
|
));
|
||||||
|
|
||||||
let rsIndex = stmts.push(new ParameterizedSQL(
|
const rsIndex = stmts.push(new ParameterizedSQL(
|
||||||
`SELECT * FROM tmp.zoneGetShipped WHERE warehouseFk = ?`, [
|
`SELECT * FROM tmp.zoneGetShipped WHERE warehouseFk = ?`, [
|
||||||
warehouseFk
|
warehouseFk
|
||||||
]
|
]
|
||||||
)) - 1;
|
)) - 1;
|
||||||
|
|
||||||
let sql = ParameterizedSQL.join(stmts, ';');
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||||||
let shipped = await Self.rawStmt(sql);
|
const shipped = await Self.rawStmt(sql, myOptions);
|
||||||
|
|
||||||
return shipped[rsIndex][0];
|
return shipped[rsIndex][0];
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,27 +2,49 @@ const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('agency getShipped()', () => {
|
describe('agency getShipped()', () => {
|
||||||
it('should return a shipment date', async() => {
|
it('should return a shipment date', async() => {
|
||||||
|
const tx = await app.models.Agency.beginTransaction({});
|
||||||
|
let result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const landed = new Date();
|
const landed = new Date();
|
||||||
landed.setDate(landed.getDate() + 1);
|
landed.setDate(landed.getDate() + 1);
|
||||||
const addressFk = 121;
|
const addressFk = 121;
|
||||||
const agencyModeFk = 7;
|
const agencyModeFk = 7;
|
||||||
const warehouseFk = 1;
|
const warehouseFk = 1;
|
||||||
|
|
||||||
let result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk);
|
result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
expect(result).toBeDefined();
|
expect(result).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not return a shipment date', async() => {
|
it('should not return a shipment date', async() => {
|
||||||
|
const tx = await app.models.Agency.beginTransaction({});
|
||||||
|
let result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
let newDate = new Date();
|
let newDate = new Date();
|
||||||
newDate.setMonth(newDate.getMonth() - 1);
|
newDate.setMonth(newDate.getMonth() - 1);
|
||||||
|
|
||||||
const landed = newDate;
|
const landed = newDate;
|
||||||
const addressFk = 121;
|
const addressFk = 121;
|
||||||
const agencyModeFk = 7;
|
const agencyModeFk = 7;
|
||||||
const warehouseFk = 1;
|
const warehouseFk = 1;
|
||||||
|
|
||||||
let result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk);
|
result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue