3092-module_transactions #740
|
@ -1,15 +1,15 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('SalesMonitor salesFilter()', () => {
|
||||
it('should return the tickets matching the filter', async() => {
|
||||
it('should now return the tickets matching the filter', async() => {
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args: {}};
|
||||
const filter = {order: 'id DESC'};
|
||||
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const result = await models.SalesMonitor.salesFilter(ctx, filter);
|
||||
|
||||
expect(result.length).toEqual(24);
|
||||
});
|
||||
|
||||
it('should return the tickets matching the problems on true', async() => {
|
||||
it('should now return the tickets matching the problems on true', async() => {
|
||||
const yesterday = new Date();
|
||||
yesterday.setHours(0, 0, 0, 0);
|
||||
const today = new Date();
|
||||
|
@ -21,12 +21,12 @@ describe('SalesMonitor salesFilter()', () => {
|
|||
to: today
|
||||
}};
|
||||
const filter = {};
|
||||
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const result = await models.SalesMonitor.salesFilter(ctx, filter);
|
||||
|
||||
expect(result.length).toEqual(9);
|
||||
});
|
||||
|
||||
it('should return the tickets matching the problems on false', async() => {
|
||||
it('should now return the tickets matching the problems on false', async() => {
|
||||
const yesterday = new Date();
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
yesterday.setHours(0, 0, 0, 0);
|
||||
|
@ -39,33 +39,33 @@ describe('SalesMonitor salesFilter()', () => {
|
|||
to: today
|
||||
}};
|
||||
const filter = {};
|
||||
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const result = await models.SalesMonitor.salesFilter(ctx, filter);
|
||||
|
||||
expect(result.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('should return the tickets matching the problems on null', async() => {
|
||||
it('should now return the tickets matching the problems on null', async() => {
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args: {problems: null}};
|
||||
const filter = {};
|
||||
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const result = await models.SalesMonitor.salesFilter(ctx, filter);
|
||||
|
||||
expect(result.length).toEqual(24);
|
||||
});
|
||||
|
||||
it('should return the tickets matching the orderId 11', async() => {
|
||||
it('should now return the tickets matching the orderId 11', async() => {
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args: {orderFk: 11}};
|
||||
const filter = {};
|
||||
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const result = await models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const firstRow = result[0];
|
||||
|
||||
expect(result.length).toEqual(1);
|
||||
expect(firstRow.id).toEqual(11);
|
||||
});
|
||||
|
||||
it('should return the tickets with grouped state "Pending" and not "Ok" nor "BOARDING"', async() => {
|
||||
it('should now return the tickets with grouped state "Pending" and not "Ok" nor "BOARDING"', async() => {
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args: {pending: true}};
|
||||
const filter = {};
|
||||
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const result = await models.SalesMonitor.salesFilter(ctx, filter);
|
||||
|
||||
const length = result.length;
|
||||
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
|
||||
|
@ -74,10 +74,10 @@ describe('SalesMonitor salesFilter()', () => {
|
|||
expect(anyResult.state).toMatch(/(Libre|Arreglar)/);
|
||||
});
|
||||
|
||||
it('should return the tickets that are not pending', async() => {
|
||||
it('should now return the tickets that are not pending', async() => {
|
||||
const ctx = {req: {accessToken: {userId: 9}}, args: {pending: false}};
|
||||
const filter = {};
|
||||
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const result = await models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const firstRow = result[0];
|
||||
const secondRow = result[1];
|
||||
const thirdRow = result[2];
|
||||
|
@ -88,18 +88,18 @@ describe('SalesMonitor salesFilter()', () => {
|
|||
expect(thirdRow.state).toEqual('Entregado');
|
||||
});
|
||||
|
||||
it('should return the tickets from the worker team', async() => {
|
||||
it('should now return the tickets from the worker team', async() => {
|
||||
const ctx = {req: {accessToken: {userId: 18}}, args: {myTeam: true}};
|
||||
const filter = {};
|
||||
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const result = await models.SalesMonitor.salesFilter(ctx, filter);
|
||||
|
||||
expect(result.length).toEqual(20);
|
||||
});
|
||||
|
||||
it('should return the tickets that are not from the worker team', async() => {
|
||||
it('should now return the tickets that are not from the worker team', async() => {
|
||||
const ctx = {req: {accessToken: {userId: 18}}, args: {myTeam: false}};
|
||||
const filter = {};
|
||||
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const result = await models.SalesMonitor.salesFilter(ctx, filter);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
});
|
||||
|
@ -113,7 +113,7 @@ describe('SalesMonitor salesFilter()', () => {
|
|||
|
||||
const ctx = {req: {accessToken: {userId: 18}}, args: {}};
|
||||
const filter = {order: 'totalProblems DESC'};
|
||||
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const result = await models.SalesMonitor.salesFilter(ctx, filter);
|
||||
|
||||
const firstTicket = result.shift();
|
||||
const secondTicket = result.shift();
|
||||
|
@ -131,7 +131,7 @@ describe('SalesMonitor salesFilter()', () => {
|
|||
|
||||
const ctx = {req: {accessToken: {userId: 18}}, args: {}};
|
||||
const filter = {order: 'totalProblems ASC'};
|
||||
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
||||
const result = await models.SalesMonitor.salesFilter(ctx, filter);
|
||||
|
||||
const firstTicket = result.shift();
|
||||
const secondTicket = result.shift();
|
||||
|
|
|
@ -18,19 +18,23 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.isEditable = async(ctx, stateId) => {
|
||||
Self.isEditable = async(ctx, stateId, options) => {
|
||||
const accessToken = ctx.req.accessToken;
|
||||
const models = Self.app.models;
|
||||
const userId = accessToken.userId;
|
||||
const myOptions = {};
|
||||
|
||||
let isProduction = await models.Account.hasRole(userId, 'production');
|
||||
let isSalesPerson = await models.Account.hasRole(userId, 'salesPerson');
|
||||
let isAdministrative = await models.Account.hasRole(userId, 'administrative');
|
||||
let state = await models.State.findById(stateId);
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
let salesPersonAllowed = (isSalesPerson && (state.code == 'PICKER_DESIGNED' || state.code == 'PRINTED'));
|
||||
const isProduction = await models.Account.hasRole(userId, 'production', myOptions);
|
||||
const isSalesPerson = await models.Account.hasRole(userId, 'salesPerson', myOptions);
|
||||
const isAdministrative = await models.Account.hasRole(userId, 'administrative', myOptions);
|
||||
const state = await models.State.findById(stateId, null, myOptions);
|
||||
|
||||
let isAllowed = isProduction || isAdministrative || salesPersonAllowed || state.alertLevel == 0;
|
||||
const salesPersonAllowed = (isSalesPerson && (state.code == 'PICKER_DESIGNED' || state.code == 'PRINTED'));
|
||||
|
||||
const isAllowed = isProduction || isAdministrative || salesPersonAllowed || state.alertLevel == 0;
|
||||
return isAllowed;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,61 +1,127 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('state isEditable()', () => {
|
||||
it('should return false if the state is not editable by a specific role', async() => {
|
||||
const salesPersonRole = 18;
|
||||
const onDeliveryState = 13;
|
||||
let ctx = {req: {accessToken: {userId: salesPersonRole}}};
|
||||
let result = await app.models.State.isEditable(ctx, onDeliveryState);
|
||||
const tx = await models.State.beginTransaction({});
|
||||
|
||||
expect(result).toBe(false);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const salesPersonRole = 18;
|
||||
const onDeliveryState = 13;
|
||||
const ctx = {req: {accessToken: {userId: salesPersonRole}}};
|
||||
const result = await models.State.isEditable(ctx, onDeliveryState, options);
|
||||
|
||||
expect(result).toBe(false);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return true if the state is editable by a specific role', async() => {
|
||||
const salesPersonRole = 18;
|
||||
const asignedState = 20;
|
||||
let ctx = {req: {accessToken: {userId: salesPersonRole}}};
|
||||
let result = await app.models.State.isEditable(ctx, asignedState);
|
||||
const tx = await models.State.beginTransaction({});
|
||||
|
||||
expect(result).toBe(true);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const salesPersonRole = 18;
|
||||
const asignedState = 20;
|
||||
const ctx = {req: {accessToken: {userId: salesPersonRole}}};
|
||||
const result = await models.State.isEditable(ctx, asignedState, options);
|
||||
|
||||
expect(result).toBe(true);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return true again if the state is editable by a specific role', async() => {
|
||||
const employeeRole = 1;
|
||||
const fixingState = 1;
|
||||
let ctx = {req: {accessToken: {userId: employeeRole}}};
|
||||
let result = await app.models.State.isEditable(ctx, fixingState);
|
||||
const tx = await models.State.beginTransaction({});
|
||||
|
||||
expect(result).toBe(true);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const employeeRole = 1;
|
||||
const fixingState = 1;
|
||||
const ctx = {req: {accessToken: {userId: employeeRole}}};
|
||||
const result = await models.State.isEditable(ctx, fixingState, options);
|
||||
|
||||
expect(result).toBe(true);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return false if the state is not editable for the given role', async() => {
|
||||
const employeeRole = 1;
|
||||
const asignedState = 13;
|
||||
let ctx = {req: {accessToken: {userId: employeeRole}}};
|
||||
let result = await app.models.State.isEditable(ctx, asignedState);
|
||||
const tx = await models.State.beginTransaction({});
|
||||
|
||||
expect(result).toBe(false);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const employeeRole = 1;
|
||||
const asignedState = 13;
|
||||
const ctx = {req: {accessToken: {userId: employeeRole}}};
|
||||
const result = await models.State.isEditable(ctx, asignedState, options);
|
||||
|
||||
expect(result).toBe(false);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return true if the state is editable for the given role', async() => {
|
||||
const productionRole = 49;
|
||||
const onDeliveryState = 13;
|
||||
let ctx = {req: {accessToken: {userId: productionRole}}};
|
||||
let result = await app.models.State.isEditable(ctx, onDeliveryState);
|
||||
const tx = await models.State.beginTransaction({});
|
||||
|
||||
expect(result).toBe(true);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const productionRole = 49;
|
||||
const onDeliveryState = 13;
|
||||
const ctx = {req: {accessToken: {userId: productionRole}}};
|
||||
const result = await models.State.isEditable(ctx, onDeliveryState, options);
|
||||
|
||||
expect(result).toBe(true);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return true if the ticket is editable, the role is salesPerson and the ticket state is printed', async() => {
|
||||
const salesPersonRole = 18;
|
||||
const printedState = 4;
|
||||
const okState = 3;
|
||||
const ctx = {req: {accessToken: {userId: salesPersonRole}}};
|
||||
const tx = await models.State.beginTransaction({});
|
||||
|
||||
let canEditCurrent = await app.models.State.isEditable(ctx, printedState);
|
||||
let canAsignNew = await app.models.State.isEditable(ctx, okState);
|
||||
let result = canEditCurrent && canAsignNew;
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
expect(result).toBe(true);
|
||||
const salesPersonRole = 18;
|
||||
const printedState = 4;
|
||||
const okState = 3;
|
||||
const ctx = {req: {accessToken: {userId: salesPersonRole}}};
|
||||
|
||||
const canEditCurrent = await models.State.isEditable(ctx, printedState, options);
|
||||
const canAsignNew = await models.State.isEditable(ctx, okState, options);
|
||||
const result = canEditCurrent && canAsignNew;
|
||||
|
||||
expect(result).toBe(true);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -23,38 +23,64 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.changeState = async(ctx, params) => {
|
||||
let userId = ctx.req.accessToken.userId;
|
||||
let models = Self.app.models;
|
||||
Self.changeState = async(ctx, params, options) => {
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
|
||||
if (!params.stateFk && !params.code)
|
||||
throw new UserError('State cannot be blank');
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (params.code) {
|
||||
let state = await models.State.findOne({where: {code: params.code}, fields: ['id']});
|
||||
params.stateFk = state.id;
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
if (!params.workerFk) {
|
||||
let worker = await models.Worker.findOne({where: {userFk: userId}});
|
||||
params.workerFk = worker.id;
|
||||
try {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
|
||||
if (!params.stateFk && !params.code)
|
||||
throw new UserError('State cannot be blank');
|
||||
|
||||
if (params.code) {
|
||||
const state = await models.State.findOne({
|
||||
where: {code: params.code},
|
||||
fields: ['id']
|
||||
}, myOptions);
|
||||
|
||||
params.stateFk = state.id;
|
||||
}
|
||||
|
||||
if (!params.workerFk) {
|
||||
const worker = await models.Worker.findOne({
|
||||
where: {userFk: userId}
|
||||
}, myOptions);
|
||||
|
||||
params.workerFk = worker.id;
|
||||
}
|
||||
|
||||
const ticketState = await models.TicketState.findById(params.ticketFk, {
|
||||
fields: ['stateFk']
|
||||
}, myOptions);
|
||||
|
||||
let oldStateAllowed;
|
||||
if (ticketState)
|
||||
oldStateAllowed = await models.State.isEditable(ctx, ticketState.stateFk, myOptions);
|
||||
const newStateAllowed = await models.State.isEditable(ctx, params.stateFk, myOptions);
|
||||
|
||||
const isAllowed = (!ticketState || oldStateAllowed == true) && newStateAllowed == true;
|
||||
|
||||
if (!isAllowed)
|
||||
throw new UserError(`You don't have enough privileges`, 'ACCESS_DENIED');
|
||||
|
||||
const ticketTracking = await models.TicketTracking.create(params, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return ticketTracking;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
|
||||
let ticketState = await models.TicketState.findById(
|
||||
params.ticketFk,
|
||||
{fields: ['stateFk']}
|
||||
);
|
||||
|
||||
let oldStateAllowed;
|
||||
if (ticketState)
|
||||
oldStateAllowed = await models.State.isEditable(ctx, ticketState.stateFk);
|
||||
let newStateAllowed = await models.State.isEditable(ctx, params.stateFk);
|
||||
|
||||
let isAllowed = (!ticketState || oldStateAllowed == true) && newStateAllowed == true;
|
||||
|
||||
if (!isAllowed)
|
||||
throw new UserError(`You don't have enough privileges`, 'ACCESS_DENIED');
|
||||
|
||||
return models.TicketTracking.create(params);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,15 +1,34 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
describe('ticket changeState()', () => {
|
||||
const salesPersonId = 18;
|
||||
const employeeId = 1;
|
||||
const productionId = 49;
|
||||
let activeCtx = {
|
||||
const activeCtx = {
|
||||
accessToken: {userId: 9},
|
||||
};
|
||||
let ctx = {req: activeCtx};
|
||||
let ticket;
|
||||
const ctx = {req: activeCtx};
|
||||
const now = new Date();
|
||||
const sampleTicket = {
|
||||
shipped: now,
|
||||
landed: now,
|
||||
nickname: 'Many Places',
|
||||
packages: 0,
|
||||
updated: now,
|
||||
priority: 1,
|
||||
zoneFk: 3,
|
||||
zonePrice: 5,
|
||||
zoneBonus: 1,
|
||||
totalWithVat: 120,
|
||||
totalWithoutVat: 100,
|
||||
clientFk: 1106,
|
||||
warehouseFk: 1,
|
||||
addressFk: 126,
|
||||
routeFk: 6,
|
||||
companyFk: 442,
|
||||
agencyModeFk: 7
|
||||
};
|
||||
|
||||
beforeAll(async done => {
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
|
@ -19,92 +38,98 @@ describe('ticket changeState()', () => {
|
|||
done();
|
||||
});
|
||||
|
||||
beforeEach(async done => {
|
||||
try {
|
||||
let originalTicket = await app.models.Ticket.findOne({where: {id: 16}});
|
||||
originalTicket.id = null;
|
||||
ticket = await app.models.Ticket.create(originalTicket);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
afterEach(async done => {
|
||||
try {
|
||||
await app.models.Ticket.destroyById(ticket.id);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
afterAll(async done => {
|
||||
try {
|
||||
await app.models.Ticket.destroyById(ticket.id);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should throw if the ticket is not editable and the user isnt production', async() => {
|
||||
activeCtx.accessToken.userId = salesPersonId;
|
||||
let params = {ticketFk: 2, stateFk: 3};
|
||||
const tx = await models.TicketTracking.beginTransaction({});
|
||||
|
||||
let error;
|
||||
|
||||
let errCode;
|
||||
try {
|
||||
await app.models.TicketTracking.changeState(ctx, params);
|
||||
const options = {transaction: tx};
|
||||
|
||||
activeCtx.accessToken.userId = salesPersonId;
|
||||
const params = {ticketFk: 2, stateFk: 3};
|
||||
|
||||
await models.TicketTracking.changeState(ctx, params, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
errCode = e.code;
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(errCode).toBe('ACCESS_DENIED');
|
||||
expect(error.code).toBe('ACCESS_DENIED');
|
||||
});
|
||||
|
||||
it('should throw an error if a worker with employee role attemps to a forbidden state', async() => {
|
||||
activeCtx.accessToken.userId = employeeId;
|
||||
let params = {ticketFk: 11, stateFk: 13};
|
||||
const tx = await models.TicketTracking.beginTransaction({});
|
||||
|
||||
let error;
|
||||
|
||||
let errCode;
|
||||
try {
|
||||
await app.models.TicketTracking.changeState(ctx, params);
|
||||
const options = {transaction: tx};
|
||||
|
||||
activeCtx.accessToken.userId = employeeId;
|
||||
const params = {ticketFk: 11, stateFk: 13};
|
||||
|
||||
await models.TicketTracking.changeState(ctx, params, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
errCode = e.code;
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(errCode).toBe('ACCESS_DENIED');
|
||||
expect(error.code).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() => {
|
||||
activeCtx.accessToken.userId = productionId;
|
||||
let params = {ticketFk: ticket.id, stateFk: 3};
|
||||
const tx = await models.TicketTracking.beginTransaction({});
|
||||
|
||||
let ticketTracking = await app.models.TicketTracking.changeState(ctx, params);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
expect(ticketTracking.__data.ticketFk).toBe(params.ticketFk);
|
||||
expect(ticketTracking.__data.stateFk).toBe(params.stateFk);
|
||||
expect(ticketTracking.__data.workerFk).toBe(49);
|
||||
expect(ticketTracking.__data.id).toBeDefined();
|
||||
const ticket = await models.Ticket.create(sampleTicket, options);
|
||||
|
||||
// restores
|
||||
await app.models.TicketTracking.destroyById(ticketTracking.__data.id);
|
||||
activeCtx.accessToken.userId = productionId;
|
||||
const params = {ticketFk: ticket.id, stateFk: 3};
|
||||
|
||||
const ticketTracking = await models.TicketTracking.changeState(ctx, params, options);
|
||||
|
||||
expect(ticketTracking.__data.ticketFk).toBe(params.ticketFk);
|
||||
expect(ticketTracking.__data.stateFk).toBe(params.stateFk);
|
||||
expect(ticketTracking.__data.workerFk).toBe(49);
|
||||
expect(ticketTracking.__data.id).toBeDefined();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should update the ticket tracking line when the user is salesperson, uses the state assigned and a valid worker id', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 18}}};
|
||||
let assignedState = await app.models.State.findOne({where: {code: 'PICKER_DESIGNED'}});
|
||||
let params = {ticketFk: ticket.id, stateFk: assignedState.id, workerFk: 1};
|
||||
let res = await app.models.TicketTracking.changeState(ctx, params);
|
||||
const tx = await models.TicketTracking.beginTransaction({});
|
||||
|
||||
expect(res.__data.ticketFk).toBe(params.ticketFk);
|
||||
expect(res.__data.stateFk).toBe(params.stateFk);
|
||||
expect(res.__data.workerFk).toBe(params.workerFk);
|
||||
expect(res.__data.workerFk).toBe(1);
|
||||
expect(res.__data.id).toBeDefined();
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ticket = await models.Ticket.create(sampleTicket, options);
|
||||
const ctx = {req: {accessToken: {userId: 18}}};
|
||||
const assignedState = await models.State.findOne({where: {code: 'PICKER_DESIGNED'}}, options);
|
||||
const params = {ticketFk: ticket.id, stateFk: assignedState.id, workerFk: 1};
|
||||
const res = await models.TicketTracking.changeState(ctx, params, options);
|
||||
|
||||
expect(res.__data.ticketFk).toBe(params.ticketFk);
|
||||
expect(res.__data.stateFk).toBe(params.stateFk);
|
||||
expect(res.__data.workerFk).toBe(params.workerFk);
|
||||
expect(res.__data.workerFk).toBe(1);
|
||||
expect(res.__data.id).toBeDefined();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -12,12 +12,12 @@ module.exports = Self => {
|
|||
},
|
||||
{
|
||||
arg: 'shipped',
|
||||
type: 'Date',
|
||||
type: 'date',
|
||||
description: `The shipment date filter`
|
||||
},
|
||||
{
|
||||
arg: 'landed',
|
||||
type: 'Date',
|
||||
type: 'date',
|
||||
description: `The landing date filter`
|
||||
},
|
||||
{
|
||||
|
@ -142,7 +142,7 @@ module.exports = Self => {
|
|||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return await ticket;
|
||||
return ticket;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
|
|
|
@ -11,7 +11,7 @@ module.exports = Self => {
|
|||
http: {source: 'path'}
|
||||
}],
|
||||
returns: {
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
|
@ -20,12 +20,32 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.recalculateComponents = async(ctx, id) => {
|
||||
const isEditable = await Self.isEditable(ctx, id);
|
||||
Self.recalculateComponents = async(ctx, id, options) => {
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
|
||||
if (!isEditable)
|
||||
throw new UserError(`The current ticket can't be modified`);
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
return Self.rawSql('CALL vn.ticket_recalcComponents(?, NULL)', [id]);
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
try {
|
||||
const isEditable = await Self.isEditable(ctx, id, myOptions);
|
||||
|
||||
if (!isEditable)
|
||||
throw new UserError(`The current ticket can't be modified`);
|
||||
|
||||
const recalculation = await Self.rawSql('CALL vn.ticket_recalcComponents(?, NULL)', [id], myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return recalculation;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@ module.exports = Self => {
|
|||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'The ticket id',
|
||||
http: {source: 'path'}
|
||||
|
|
|
@ -5,23 +5,23 @@ module.exports = Self => {
|
|||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'The ticket id',
|
||||
http: {source: 'path'}
|
||||
},
|
||||
{
|
||||
arg: 'destination',
|
||||
type: 'String',
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
arg: 'message',
|
||||
type: 'String',
|
||||
type: 'string',
|
||||
required: true,
|
||||
}],
|
||||
returns: {
|
||||
type: 'Object',
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
|
@ -30,28 +30,46 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.sendSms = async(ctx, id, destination, message) => {
|
||||
Self.sendSms = async(ctx, id, destination, message, options) => {
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
|
||||
let sms = await Self.app.models.Sms.send(ctx, id, destination, message);
|
||||
let logRecord = {
|
||||
originFk: id,
|
||||
userFk: userId,
|
||||
action: 'insert',
|
||||
changedModel: 'sms',
|
||||
newInstance: {
|
||||
destinationFk: id,
|
||||
destination: destination,
|
||||
message: message,
|
||||
statusCode: sms.statusCode,
|
||||
status: sms.status
|
||||
}
|
||||
};
|
||||
try {
|
||||
const sms = await Self.app.models.Sms.send(ctx, id, destination, message);
|
||||
const logRecord = {
|
||||
originFk: id,
|
||||
userFk: userId,
|
||||
action: 'insert',
|
||||
changedModel: 'sms',
|
||||
newInstance: {
|
||||
destinationFk: id,
|
||||
destination: destination,
|
||||
message: message,
|
||||
statusCode: sms.statusCode,
|
||||
status: sms.status
|
||||
}
|
||||
};
|
||||
|
||||
const ticketLog = await Self.app.models.TicketLog.create(logRecord);
|
||||
const ticketLog = await Self.app.models.TicketLog.create(logRecord, myOptions);
|
||||
|
||||
sms.logId = ticketLog.id;
|
||||
sms.logId = ticketLog.id;
|
||||
|
||||
return sms;
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return sms;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@ module.exports = Self => {
|
|||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'The ticket id',
|
||||
http: {source: 'path'}
|
||||
|
@ -21,113 +21,133 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.setDeleted = async(ctx, id) => {
|
||||
Self.setDeleted = async(ctx, id, options) => {
|
||||
const models = Self.app.models;
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const isEditable = await Self.isEditable(ctx, id);
|
||||
const $t = ctx.req.__; // $translate
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
|
||||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
// Check if has sales with shelving
|
||||
const isSalesAssistant = await models.Account.hasRole(userId, 'salesAssistant');
|
||||
const sales = await models.Sale.find({
|
||||
include: {relation: 'itemShelvingSale'},
|
||||
where: {ticketFk: id}
|
||||
});
|
||||
const hasItemShelvingSales = sales.some(sale => {
|
||||
return sale.itemShelvingSale();
|
||||
});
|
||||
|
||||
if (hasItemShelvingSales && !isSalesAssistant)
|
||||
throw new UserError(`You cannot delete a ticket that part of it is being prepared`);
|
||||
|
||||
// Check for existing claim
|
||||
const claimOfATicket = await models.Claim.findOne({where: {ticketFk: id}});
|
||||
if (claimOfATicket)
|
||||
throw new UserError('You must delete the claim id %d first', 'DELETE_CLAIM_FIRST', claimOfATicket.id);
|
||||
|
||||
// Check for existing purchase requests
|
||||
const hasPurchaseRequests = await models.TicketRequest.count({
|
||||
ticketFk: id,
|
||||
isOk: true
|
||||
});
|
||||
|
||||
if (hasPurchaseRequests)
|
||||
throw new UserError('You must delete all the buy requests first');
|
||||
|
||||
// removes item shelvings
|
||||
if (hasItemShelvingSales && isSalesAssistant) {
|
||||
const promises = [];
|
||||
for (let sale of sales) {
|
||||
if (sale.itemShelvingSale()) {
|
||||
const itemShelvingSale = sale.itemShelvingSale();
|
||||
const destroyedShelving = models.ItemShelvingSale.destroyById(itemShelvingSale.id);
|
||||
promises.push(destroyedShelving);
|
||||
}
|
||||
}
|
||||
await Promise.all(promises);
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
// Remove ticket greuges
|
||||
const ticketGreuges = await models.Greuge.find({where: {ticketFk: id}});
|
||||
const ownGreuges = ticketGreuges.every(greuge => {
|
||||
return greuge.ticketFk == id;
|
||||
});
|
||||
if (ownGreuges) {
|
||||
for (const greuge of ticketGreuges) {
|
||||
const instance = await models.Greuge.findById(greuge.id);
|
||||
try {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const isEditable = await Self.isEditable(ctx, id, myOptions);
|
||||
|
||||
await instance.destroy();
|
||||
}
|
||||
}
|
||||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
const ticket = await models.Ticket.findById(id, {
|
||||
include: [{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['id', 'salesPersonFk'],
|
||||
include: {
|
||||
relation: 'salesPersonUser',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
// Check if has sales with shelving
|
||||
const isSalesAssistant = await models.Account.hasRole(userId, 'salesAssistant', myOptions);
|
||||
const sales = await models.Sale.find({
|
||||
include: {relation: 'itemShelvingSale'},
|
||||
where: {ticketFk: id}
|
||||
}, myOptions);
|
||||
const hasItemShelvingSales = sales.some(sale => {
|
||||
return sale.itemShelvingSale();
|
||||
});
|
||||
|
||||
if (hasItemShelvingSales && !isSalesAssistant)
|
||||
throw new UserError(`You cannot delete a ticket that part of it is being prepared`);
|
||||
|
||||
// Check for existing claim
|
||||
const claimOfATicket = await models.Claim.findOne({where: {ticketFk: id}}, myOptions);
|
||||
if (claimOfATicket)
|
||||
throw new UserError('You must delete the claim id %d first', 'DELETE_CLAIM_FIRST', claimOfATicket.id);
|
||||
|
||||
// Check for existing purchase requests
|
||||
const hasPurchaseRequests = await models.TicketRequest.count({
|
||||
ticketFk: id,
|
||||
isOk: true
|
||||
}, myOptions);
|
||||
|
||||
if (hasPurchaseRequests)
|
||||
throw new UserError('You must delete all the buy requests first');
|
||||
|
||||
// removes item shelvings
|
||||
if (hasItemShelvingSales && isSalesAssistant) {
|
||||
const promises = [];
|
||||
for (let sale of sales) {
|
||||
if (sale.itemShelvingSale()) {
|
||||
const itemShelvingSale = sale.itemShelvingSale();
|
||||
const destroyedShelving = models.ItemShelvingSale.destroyById(itemShelvingSale.id, myOptions);
|
||||
promises.push(destroyedShelving);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
relation: 'ship'
|
||||
}, {
|
||||
relation: 'stowaway'
|
||||
}]
|
||||
});
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
// Change state to "fixing" if contains an stowaway and remove the link between them
|
||||
let otherTicketId;
|
||||
if (ticket.stowaway())
|
||||
otherTicketId = ticket.stowaway().shipFk;
|
||||
else if (ticket.ship())
|
||||
otherTicketId = ticket.ship().id;
|
||||
|
||||
if (otherTicketId) {
|
||||
await models.Ticket.deleteStowaway(ctx, otherTicketId);
|
||||
await models.TicketTracking.changeState(ctx, {
|
||||
ticketFk: otherTicketId,
|
||||
code: 'FIXING'
|
||||
// Remove ticket greuges
|
||||
const ticketGreuges = await models.Greuge.find({where: {ticketFk: id}}, myOptions);
|
||||
const ownGreuges = ticketGreuges.every(greuge => {
|
||||
return greuge.ticketFk == id;
|
||||
});
|
||||
}
|
||||
if (ownGreuges) {
|
||||
for (const greuge of ticketGreuges) {
|
||||
const instance = await models.Greuge.findById(greuge.id, null, myOptions);
|
||||
|
||||
// Send notification to salesPerson
|
||||
const salesPersonUser = ticket.client().salesPersonUser();
|
||||
if (salesPersonUser) {
|
||||
const origin = ctx.req.headers.origin;
|
||||
const message = $t(`I have deleted the ticket id`, {
|
||||
id: id,
|
||||
url: `${origin}/#!/ticket/${id}/summary`
|
||||
});
|
||||
await models.Chat.send(ctx, `@${salesPersonUser.name}`, message);
|
||||
}
|
||||
await instance.destroy(myOptions);
|
||||
}
|
||||
}
|
||||
|
||||
return ticket.updateAttribute('isDeleted', true);
|
||||
const ticket = await models.Ticket.findById(id, {
|
||||
include: [{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['id', 'salesPersonFk'],
|
||||
include: {
|
||||
relation: 'salesPersonUser',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
relation: 'ship'
|
||||
}, {
|
||||
relation: 'stowaway'
|
||||
}]
|
||||
}, myOptions);
|
||||
|
||||
// Change state to "fixing" if contains an stowaway and remove the link between them
|
||||
let otherTicketId;
|
||||
if (ticket.stowaway())
|
||||
otherTicketId = ticket.stowaway().shipFk;
|
||||
else if (ticket.ship())
|
||||
otherTicketId = ticket.ship().id;
|
||||
|
||||
if (otherTicketId) {
|
||||
await models.Ticket.deleteStowaway(ctx, otherTicketId, myOptions);
|
||||
await models.TicketTracking.changeState(ctx, {
|
||||
ticketFk: otherTicketId,
|
||||
code: 'FIXING'
|
||||
}, myOptions);
|
||||
}
|
||||
|
||||
// Send notification to salesPerson
|
||||
const salesPersonUser = ticket.client().salesPersonUser();
|
||||
if (salesPersonUser) {
|
||||
const origin = ctx.req.headers.origin;
|
||||
const message = $t(`I have deleted the ticket id`, {
|
||||
id: id,
|
||||
url: `${origin}/#!/ticket/${id}/summary`
|
||||
});
|
||||
await models.Chat.send(ctx, `@${salesPersonUser.name}`, message);
|
||||
}
|
||||
|
||||
const updatedTicket = await ticket.updateAttribute('isDeleted', true, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return updatedTicket;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,24 +1,43 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('ticket recalculateComponents()', () => {
|
||||
const ticketId = 11;
|
||||
|
||||
it('should update the ticket components', async() => {
|
||||
const ctx = {req: {accessToken: {userId: 9}}};
|
||||
const response = await app.models.Ticket.recalculateComponents(ctx, ticketId);
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
expect(response.affectedRows).toBeDefined();
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {req: {accessToken: {userId: 9}}};
|
||||
const response = await models.Ticket.recalculateComponents(ctx, ticketId, options);
|
||||
|
||||
expect(response.affectedRows).toBeDefined();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw an error if the ticket is not editable', async() => {
|
||||
const ctx = {req: {accessToken: {userId: 9}}};
|
||||
const immutableTicketId = 1;
|
||||
await app.models.Ticket.recalculateComponents(ctx, immutableTicketId)
|
||||
.catch(response => {
|
||||
expect(response).toEqual(new Error(`The current ticket can't be modified`));
|
||||
error = response;
|
||||
});
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
expect(error).toBeDefined();
|
||||
let error;
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {req: {accessToken: {userId: 9}}};
|
||||
const immutableTicketId = 1;
|
||||
await models.Ticket.recalculateComponents(ctx, immutableTicketId, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error).toEqual(new Error(`The current ticket can't be modified`));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
const soap = require('soap');
|
||||
|
||||
describe('ticket sendSms()', () => {
|
||||
let logId;
|
||||
|
||||
afterAll(async done => {
|
||||
await app.models.TicketLog.destroyById(logId);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should send a message and log it', async() => {
|
||||
spyOn(soap, 'createClientAsync').and.returnValue('a so fake client');
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let id = 11;
|
||||
let destination = 222222222;
|
||||
let message = 'this is the message created in a test';
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let sms = await app.models.Ticket.sendSms(ctx, id, destination, message);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
logId = sms.logId;
|
||||
spyOn(soap, 'createClientAsync').and.returnValue('a so fake client');
|
||||
const ctx = {req: {accessToken: {userId: 9}}};
|
||||
const id = 11;
|
||||
const destination = 222222222;
|
||||
const message = 'this is the message created in a test';
|
||||
|
||||
let createdLog = await app.models.TicketLog.findById(logId);
|
||||
let json = JSON.parse(JSON.stringify(createdLog.newInstance));
|
||||
const sms = await models.Ticket.sendSms(ctx, id, destination, message, options);
|
||||
|
||||
expect(json.message).toEqual(message);
|
||||
const createdLog = await models.TicketLog.findById(sms.logId, null, options);
|
||||
const json = JSON.parse(JSON.stringify(createdLog.newInstance));
|
||||
|
||||
expect(json.message).toEqual(message);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
const LoopBackContext = require('loopback-context');
|
||||
const models = app.models;
|
||||
|
||||
describe('ticket setDeleted()', () => {
|
||||
const userId = 1106;
|
||||
|
@ -10,95 +9,110 @@ describe('ticket setDeleted()', () => {
|
|||
};
|
||||
|
||||
it('should throw an error if the given ticket has a claim', async() => {
|
||||
const ctx = {req: activeCtx};
|
||||
const ticketId = 16;
|
||||
let error;
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let error;
|
||||
try {
|
||||
await app.models.Ticket.setDeleted(ctx, ticketId);
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {req: activeCtx};
|
||||
const ticketId = 16;
|
||||
|
||||
await models.Ticket.setDeleted(ctx, ticketId, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.translateArgs[0]).toEqual(2);
|
||||
expect(error.message).toEqual('You must delete the claim id %d first');
|
||||
});
|
||||
|
||||
it('should delete the ticket, remove the stowaway link and change the stowaway ticket state to "FIXING" and get rid of the itemshelving', async() => {
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
active: activeCtx
|
||||
});
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: employeeUser},
|
||||
headers: {
|
||||
origin: 'http://localhost:5000'
|
||||
},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let sampleTicket = await models.Ticket.findById(12);
|
||||
let sampleStowaway = await models.Ticket.findById(13);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
sampleTicket.id = undefined;
|
||||
let shipTicket = await models.Ticket.create(sampleTicket);
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
active: activeCtx
|
||||
});
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: employeeUser},
|
||||
headers: {
|
||||
origin: 'http://localhost:5000'
|
||||
},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
|
||||
sampleStowaway.id = undefined;
|
||||
let stowawayTicket = await models.Ticket.create(sampleStowaway);
|
||||
const sampleTicket = await models.Ticket.findById(12);
|
||||
const sampleStowaway = await models.Ticket.findById(13);
|
||||
|
||||
await models.Stowaway.rawSql(`
|
||||
INSERT INTO vn.stowaway(id, shipFk)
|
||||
VALUES (?, ?)`, [stowawayTicket.id, shipTicket.id]);
|
||||
sampleTicket.id = undefined;
|
||||
const shipTicket = await models.Ticket.create(sampleTicket, options);
|
||||
|
||||
const boardingState = await models.State.findOne({
|
||||
where: {
|
||||
code: 'BOARDING'
|
||||
}
|
||||
});
|
||||
await models.TicketTracking.create({
|
||||
ticketFk: stowawayTicket.id,
|
||||
stateFk: boardingState.id,
|
||||
workerFk: ctx.req.accessToken.userId
|
||||
});
|
||||
sampleStowaway.id = undefined;
|
||||
const stowawayTicket = await models.Ticket.create(sampleStowaway, options);
|
||||
|
||||
const okState = await models.State.findOne({
|
||||
where: {
|
||||
code: 'OK'
|
||||
}
|
||||
});
|
||||
await models.TicketTracking.create({
|
||||
ticketFk: shipTicket.id,
|
||||
stateFk: okState.id,
|
||||
workerFk: ctx.req.accessToken.userId
|
||||
});
|
||||
await models.Stowaway.rawSql(`
|
||||
INSERT INTO vn.stowaway(id, shipFk)
|
||||
VALUES (?, ?)`, [stowawayTicket.id, shipTicket.id], options);
|
||||
|
||||
let stowawayTicketState = await models.TicketState.findOne({
|
||||
where: {
|
||||
ticketFk: stowawayTicket.id
|
||||
}
|
||||
});
|
||||
const boardingState = await models.State.findOne({
|
||||
where: {
|
||||
code: 'BOARDING'
|
||||
}
|
||||
}, options);
|
||||
|
||||
let stowaway = await models.Stowaway.findById(shipTicket.id);
|
||||
await models.TicketTracking.create({
|
||||
ticketFk: stowawayTicket.id,
|
||||
stateFk: boardingState.id,
|
||||
workerFk: ctx.req.accessToken.userId
|
||||
}, options);
|
||||
|
||||
expect(stowaway).toBeDefined();
|
||||
expect(stowawayTicketState.code).toEqual('BOARDING');
|
||||
const okState = await models.State.findOne({
|
||||
where: {
|
||||
code: 'OK'
|
||||
}
|
||||
}, options);
|
||||
|
||||
await models.Ticket.setDeleted(ctx, shipTicket.id);
|
||||
await models.TicketTracking.create({
|
||||
ticketFk: shipTicket.id,
|
||||
stateFk: okState.id,
|
||||
workerFk: ctx.req.accessToken.userId
|
||||
}, options);
|
||||
|
||||
stowawayTicketState = await models.TicketState.findOne({
|
||||
where: {
|
||||
ticketFk: stowawayTicket.id
|
||||
}
|
||||
});
|
||||
let stowawayTicketState = await models.TicketState.findOne({
|
||||
where: {
|
||||
ticketFk: stowawayTicket.id
|
||||
}
|
||||
}, options);
|
||||
|
||||
stowaway = await models.Stowaway.findById(shipTicket.id);
|
||||
let stowaway = await models.Stowaway.findById(shipTicket.id, null, options);
|
||||
|
||||
expect(stowaway).toBeNull();
|
||||
expect(stowawayTicketState.code).toEqual('FIXING');
|
||||
expect(stowaway).toBeDefined();
|
||||
expect(stowawayTicketState.code).toEqual('BOARDING');
|
||||
|
||||
// restores
|
||||
await models.Ticket.destroyById(shipTicket.id);
|
||||
await models.Ticket.destroyById(stowawayTicket.id);
|
||||
await models.Ticket.setDeleted(ctx, shipTicket.id, options);
|
||||
|
||||
stowawayTicketState = await models.TicketState.findOne({
|
||||
where: {
|
||||
ticketFk: stowawayTicket.id
|
||||
}
|
||||
}, options);
|
||||
|
||||
stowaway = await models.Stowaway.findById(shipTicket.id, null, options);
|
||||
|
||||
expect(stowaway).toBeNull();
|
||||
expect(stowawayTicketState.code).toEqual('FIXING');
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,28 +1,72 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('ticket summary()', () => {
|
||||
it('should return a summary object containing data from 1 ticket', async() => {
|
||||
let result = await app.models.Ticket.summary(1);
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
expect(result.id).toEqual(1);
|
||||
expect(result.nickname).toEqual('Bat cave');
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const result = await models.Ticket.summary(1, options);
|
||||
|
||||
expect(result.id).toEqual(1);
|
||||
expect(result.nickname).toEqual('Bat cave');
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return a summary object containing sales from 1 ticket', async() => {
|
||||
let result = await app.models.Ticket.summary(1);
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
expect(result.sales.length).toEqual(4);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const result = await models.Ticket.summary(1, options);
|
||||
|
||||
expect(result.sales.length).toEqual(4);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return a summary object containing totalWithoutVat for 1 ticket', async() => {
|
||||
let result = await app.models.Ticket.summary(1);
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
expect(result.totalWithoutVat).toEqual(jasmine.any(Number));
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const result = await models.Ticket.summary(1, options);
|
||||
|
||||
expect(result.totalWithoutVat).toEqual(jasmine.any(Number));
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return a summary object containing total for 1 ticket', async() => {
|
||||
let result = await app.models.Ticket.summary(1);
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
expect(result.totalWithVat).toEqual(jasmine.any(Number));
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const result = await models.Ticket.summary(1, options);
|
||||
|
||||
expect(result.totalWithVat).toEqual(jasmine.any(Number));
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
describe('sale transferSales()', () => {
|
||||
|
@ -8,160 +8,167 @@ describe('sale transferSales()', () => {
|
|||
};
|
||||
const ctx = {req: activeCtx};
|
||||
|
||||
let createdTicketsIds = [];
|
||||
|
||||
beforeAll(() => {
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
active: activeCtx
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(async done => {
|
||||
if (createdTicketsIds.length) {
|
||||
try {
|
||||
createdTicketsIds.forEach(async createdTicketId => {
|
||||
await app.models.Ticket.destroyById(createdTicketId);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
it('should throw an error as the ticket is not editable', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let error;
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const currentTicketId = 1;
|
||||
const receiverTicketId = undefined;
|
||||
const sales = [];
|
||||
|
||||
await models.Ticket.transferSales(ctx, currentTicketId, receiverTicketId, sales, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should throw an error as the ticket is not editable', async() => {
|
||||
let error;
|
||||
|
||||
const currentTicketId = 1;
|
||||
const receiverTicketId = undefined;
|
||||
const sales = [];
|
||||
|
||||
await app.models.Ticket.transferSales(ctx, currentTicketId, receiverTicketId, sales)
|
||||
.catch(response => {
|
||||
expect(response.message).toEqual(`The sales of this ticket can't be modified`);
|
||||
error = response;
|
||||
});
|
||||
|
||||
expect(error).toBeDefined();
|
||||
expect(error.message).toEqual(`The sales of this ticket can't be modified`);
|
||||
});
|
||||
|
||||
it('should throw an error if the receiving ticket is not editable', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let error;
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const currentTicketId = 16;
|
||||
const receiverTicketId = 1;
|
||||
const sales = [];
|
||||
const currentTicketId = 16;
|
||||
const receiverTicketId = 1;
|
||||
const sales = [];
|
||||
|
||||
await app.models.Ticket.transferSales(ctx, currentTicketId, receiverTicketId, sales)
|
||||
.catch(response => {
|
||||
expect(response.message).toEqual(`The sales of the receiver ticket can't be modified`);
|
||||
error = response;
|
||||
});
|
||||
await models.Ticket.transferSales(ctx, currentTicketId, receiverTicketId, sales, options);
|
||||
|
||||
expect(error).toBeDefined();
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(`The sales of the receiver ticket can't be modified`);
|
||||
});
|
||||
|
||||
it('should transfer the sales from one ticket to a new one then send them back and delete the created ticket', async() => {
|
||||
const formerTicketId = 11;
|
||||
let createdTicketId = undefined;
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let formerTicketSales = await app.models.Ticket.getSales(formerTicketId);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
expect(formerTicketSales.length).toEqual(2);
|
||||
const formerTicketId = 11;
|
||||
let createdTicketId = undefined;
|
||||
|
||||
let createdTicket = await app.models.Ticket.transferSales(
|
||||
ctx, formerTicketId, createdTicketId, formerTicketSales);
|
||||
let formerTicketSales = await models.Ticket.getSales(formerTicketId, options);
|
||||
|
||||
createdTicketId = createdTicket.id;
|
||||
createdTicketsIds.push(createdTicketId);
|
||||
expect(formerTicketSales.length).toEqual(2);
|
||||
|
||||
formerTicketSales = await app.models.Ticket.getSales(formerTicketId);
|
||||
createdTicketSales = await app.models.Ticket.getSales(createdTicketId);
|
||||
let createdTicket = await models.Ticket.transferSales(
|
||||
ctx, formerTicketId, createdTicketId, formerTicketSales, options);
|
||||
|
||||
expect(formerTicketSales.length).toEqual(0);
|
||||
expect(createdTicketSales.length).toEqual(2);
|
||||
createdTicketId = createdTicket.id;
|
||||
|
||||
await app.models.Ticket.transferSales(
|
||||
ctx, createdTicketId, formerTicketId, createdTicketSales);
|
||||
formerTicketSales = await models.Ticket.getSales(formerTicketId, options);
|
||||
createdTicketSales = await models.Ticket.getSales(createdTicketId, options);
|
||||
|
||||
formerTicketSales = await app.models.Ticket.getSales(formerTicketId);
|
||||
createdTicketSales = await app.models.Ticket.getSales(createdTicketId);
|
||||
expect(formerTicketSales.length).toEqual(0);
|
||||
expect(createdTicketSales.length).toEqual(2);
|
||||
|
||||
createdTicket = await app.models.Ticket.findById(createdTicketId);
|
||||
await models.Ticket.transferSales(
|
||||
ctx, createdTicketId, formerTicketId, createdTicketSales, options);
|
||||
|
||||
expect(createdTicket.isDeleted).toBeTruthy();
|
||||
expect(formerTicketSales.length).toEqual(2);
|
||||
expect(createdTicketSales.length).toEqual(0);
|
||||
formerTicketSales = await models.Ticket.getSales(formerTicketId, options);
|
||||
createdTicketSales = await models.Ticket.getSales(createdTicketId, options);
|
||||
|
||||
createdTicket = await models.Ticket.findById(createdTicketId, null, options);
|
||||
|
||||
expect(createdTicket.isDeleted).toBeTruthy();
|
||||
expect(formerTicketSales.length).toEqual(2);
|
||||
expect(createdTicketSales.length).toEqual(0);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
describe('sale transferPartialSales()', () => {
|
||||
it('should throw an error in the quantity to transfer exceeds the amount from the original sale', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let error;
|
||||
let currentTicket = await app.models.Ticket.findById(11);
|
||||
let currentTicketSales = await app.models.Ticket.getSales(currentTicket.id);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const currentTicketId = currentTicket.id;
|
||||
const receiverTicketId = undefined;
|
||||
const currentTicket = await models.Ticket.findById(11, null, options);
|
||||
const currentTicketSales = await models.Ticket.getSales(currentTicket.id, options);
|
||||
|
||||
currentTicketSales[0].quantity = 99;
|
||||
const currentTicketId = currentTicket.id;
|
||||
const receiverTicketId = undefined;
|
||||
|
||||
await app.models.Ticket.transferSales(
|
||||
ctx, currentTicketId, receiverTicketId, currentTicketSales)
|
||||
.catch(response => {
|
||||
expect(response.message).toEqual(`Invalid quantity`);
|
||||
error = response;
|
||||
});
|
||||
currentTicketSales[0].quantity = 99;
|
||||
|
||||
expect(error).toBeDefined();
|
||||
await models.Ticket.transferSales(
|
||||
ctx, currentTicketId, receiverTicketId, currentTicketSales, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(`Invalid quantity`);
|
||||
});
|
||||
|
||||
it('should transfer two sales to a new ticket but one shall be partial', async() => {
|
||||
const formerTicketId = 11;
|
||||
let createdTicketId = undefined;
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let formerTicketSales = await app.models.Ticket.getSales(formerTicketId);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const partialSaleId = formerTicketSales[0].id;
|
||||
const completeSaleId = formerTicketSales[1].id;
|
||||
let partialSaleTotalQuantity = formerTicketSales[0].quantity;
|
||||
const formerTicketId = 11;
|
||||
let createdTicketId = undefined;
|
||||
|
||||
expect(partialSaleTotalQuantity).toEqual(15);
|
||||
let formerTicketSales = await models.Ticket.getSales(formerTicketId, options);
|
||||
|
||||
formerTicketSales[0].quantity = 1;
|
||||
const completeSaleId = formerTicketSales[1].id;
|
||||
let partialSaleTotalQuantity = formerTicketSales[0].quantity;
|
||||
|
||||
let createdTicket = await app.models.Ticket.transferSales(
|
||||
ctx, formerTicketId, createdTicketId, formerTicketSales);
|
||||
expect(partialSaleTotalQuantity).toEqual(15);
|
||||
|
||||
createdTicketId = createdTicket.id;
|
||||
createdTicketsIds.push(createdTicket.id);
|
||||
formerTicketSales[0].quantity = 1;
|
||||
|
||||
formerTicketSales = await app.models.Ticket.getSales(formerTicketId);
|
||||
createdTicketSales = await app.models.Ticket.getSales(createdTicketId);
|
||||
let createdTicket = await models.Ticket.transferSales(
|
||||
ctx, formerTicketId, createdTicketId, formerTicketSales, options);
|
||||
|
||||
const [createdPartialSale] = createdTicketSales.filter(sale => {
|
||||
return sale.id != completeSaleId;
|
||||
});
|
||||
createdTicketId = createdTicket.id;
|
||||
|
||||
expect(formerTicketSales.length).toEqual(1);
|
||||
expect(formerTicketSales[0].quantity).toEqual(partialSaleTotalQuantity - 1);
|
||||
expect(createdTicketSales.length).toEqual(2);
|
||||
expect(createdPartialSale.quantity).toEqual(1);
|
||||
formerTicketSales = await models.Ticket.getSales(formerTicketId, options);
|
||||
createdTicketSales = await models.Ticket.getSales(createdTicketId, options);
|
||||
|
||||
let saleToRestore = await app.models.Sale.findById(partialSaleId);
|
||||
await saleToRestore.updateAttribute('quantity', partialSaleTotalQuantity);
|
||||
const [createdPartialSale] = createdTicketSales.filter(sale => {
|
||||
return sale.id != completeSaleId;
|
||||
});
|
||||
|
||||
let saleToReturnToTicket = await app.models.Sale.findById(completeSaleId);
|
||||
await saleToReturnToTicket.updateAttribute('ticketFk', formerTicketId);
|
||||
expect(formerTicketSales.length).toEqual(1);
|
||||
expect(formerTicketSales[0].quantity).toEqual(partialSaleTotalQuantity - 1);
|
||||
expect(createdTicketSales.length).toEqual(2);
|
||||
expect(createdPartialSale.quantity).toEqual(1);
|
||||
|
||||
formerTicketSales = await app.models.Ticket.getSales(formerTicketId);
|
||||
|
||||
const [returningPartialSale] = formerTicketSales.filter(sale => {
|
||||
return sale.id == partialSaleId;
|
||||
});
|
||||
|
||||
expect(returningPartialSale.quantity).toEqual(partialSaleTotalQuantity);
|
||||
expect(formerTicketSales.length).toEqual(2);
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,156 +1,171 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('sale updateDiscount()', () => {
|
||||
const originalSaleId = 8;
|
||||
let componentId;
|
||||
let originalSale;
|
||||
let salesPersonMana;
|
||||
|
||||
beforeAll(async done => {
|
||||
try {
|
||||
originalSale = await app.models.Sale.findById(originalSaleId);
|
||||
let manaDiscount = await app.models.Component.findOne({where: {code: 'buyerDiscount'}});
|
||||
componentId = manaDiscount.id;
|
||||
|
||||
let ticket = await app.models.Ticket.findById(originalSale.ticketFk);
|
||||
let client = await app.models.Client.findById(ticket.clientFk);
|
||||
salesPersonMana = await app.models.WorkerMana.findById(client.salesPersonFk);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
afterAll(async done => {
|
||||
try {
|
||||
await originalSale.save();
|
||||
await app.models.SaleComponent.updateAll({componentFk: componentId, saleFk: originalSaleId}, {value: 0});
|
||||
await salesPersonMana.save();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should throw an error if no sales were selected', async() => {
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
let error;
|
||||
const ticketId = 11;
|
||||
const sales = [];
|
||||
const newDiscount = 10;
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let error;
|
||||
try {
|
||||
await app.models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const ticketId = 11;
|
||||
const sales = [];
|
||||
const newDiscount = 10;
|
||||
|
||||
await models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.message).toEqual('Please select at least one sale');
|
||||
});
|
||||
|
||||
it('should throw an error if no sales belong to different tickets', async() => {
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
let error;
|
||||
const ticketId = 11;
|
||||
const sales = [1, 14];
|
||||
const newDiscount = 10;
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let error;
|
||||
try {
|
||||
await app.models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const ticketId = 11;
|
||||
const sales = [1, 14];
|
||||
const newDiscount = 10;
|
||||
|
||||
await models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.message).toEqual('All sales must belong to the same ticket');
|
||||
});
|
||||
|
||||
it('should throw an error if the ticket is invoiced already', async() => {
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
let error;
|
||||
const ticketId = 1;
|
||||
const sales = [1];
|
||||
const newDiscount = 100;
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let error;
|
||||
try {
|
||||
await app.models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const ticketId = 1;
|
||||
const sales = [1];
|
||||
const newDiscount = 100;
|
||||
|
||||
await models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(`The sales of this ticket can't be modified`);
|
||||
});
|
||||
|
||||
it('should update the discount if the salesPerson has mana', async() => {
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 18},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const ticketId = 11;
|
||||
const sales = [originalSaleId];
|
||||
const newDiscount = 100;
|
||||
let manaDiscount = await app.models.Component.findOne({where: {code: 'mana'}});
|
||||
componentId = manaDiscount.id;
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
await app.models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
let updatedSale = await app.models.Sale.findById(originalSaleId);
|
||||
let createdSaleComponent = await app.models.SaleComponent.findOne({
|
||||
where: {
|
||||
componentFk: componentId,
|
||||
saleFk: originalSaleId
|
||||
}
|
||||
});
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 18},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const ticketId = 11;
|
||||
const sales = [originalSaleId];
|
||||
const newDiscount = 100;
|
||||
const manaDiscount = await models.Component.findOne({where: {code: 'mana'}}, options);
|
||||
const componentId = manaDiscount.id;
|
||||
|
||||
expect(createdSaleComponent.componentFk).toEqual(componentId);
|
||||
expect(updatedSale.discount).toEqual(100);
|
||||
await models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount, options);
|
||||
|
||||
const updatedSale = await models.Sale.findById(originalSaleId, null, options);
|
||||
const createdSaleComponent = await models.SaleComponent.findOne({
|
||||
where: {
|
||||
componentFk: componentId,
|
||||
saleFk: originalSaleId
|
||||
}
|
||||
}, options);
|
||||
|
||||
expect(createdSaleComponent.componentFk).toEqual(componentId);
|
||||
expect(updatedSale.discount).toEqual(100);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should update the discount and add company discount component if the worker does not have mana', async() => {
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const ticketId = 11;
|
||||
const sales = [originalSaleId];
|
||||
const newDiscount = 100;
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
await app.models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
let updatedSale = await app.models.Sale.findById(originalSaleId);
|
||||
let createdSaleComponent = await app.models.SaleComponent.findOne({
|
||||
where: {
|
||||
componentFk: componentId,
|
||||
saleFk: originalSaleId
|
||||
}
|
||||
});
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const ticketId = 11;
|
||||
const sales = [originalSaleId];
|
||||
const newDiscount = 100;
|
||||
|
||||
expect(createdSaleComponent.componentFk).toEqual(componentId);
|
||||
expect(updatedSale.discount).toEqual(100);
|
||||
await models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount, options);
|
||||
|
||||
const updatedSale = await models.Sale.findById(originalSaleId, null, options);
|
||||
const manaDiscount = await models.Component.findOne({where: {code: 'buyerDiscount'}}, options);
|
||||
const componentId = manaDiscount.id;
|
||||
|
||||
const createdSaleComponent = await models.SaleComponent.findOne({
|
||||
where: {
|
||||
componentFk: componentId,
|
||||
saleFk: originalSaleId
|
||||
}
|
||||
}, options);
|
||||
|
||||
expect(createdSaleComponent.componentFk).toEqual(componentId);
|
||||
expect(updatedSale.discount).toEqual(100);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
const userId = 9;
|
||||
|
@ -11,34 +11,44 @@ describe('ticket updateEditableTicket()', () => {
|
|||
const validTicketId = 12;
|
||||
const invalidTicketId = 1;
|
||||
const data = {addressFk: 1};
|
||||
const originalData = {addressFk: 123};
|
||||
|
||||
afterAll(async done => {
|
||||
await app.models.Ticket.updateEditableTicket(ctx, validTicketId, originalData);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should now throw an error if the ticket is not editable', async() => {
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let error;
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
await app.models.Ticket.updateEditableTicket(ctx, invalidTicketId, data).catch(e => {
|
||||
await models.Ticket.updateEditableTicket(ctx, invalidTicketId, data, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}).finally(() => {
|
||||
expect(error.message).toEqual('This ticket can not be modified');
|
||||
});
|
||||
}
|
||||
|
||||
expect(error).toBeDefined();
|
||||
expect(error.message).toEqual('This ticket can not be modified');
|
||||
});
|
||||
|
||||
it('should edit the ticket address', async() => {
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
active: activeCtx
|
||||
});
|
||||
await app.models.Ticket.updateEditableTicket(ctx, validTicketId, data);
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let updatedTicket = await app.models.Ticket.findById(validTicketId);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
expect(updatedTicket.addressFk).toEqual(1);
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
active: activeCtx
|
||||
});
|
||||
await models.Ticket.updateEditableTicket(ctx, validTicketId, data, options);
|
||||
|
||||
const updatedTicket = await models.Ticket.findById(validTicketId, null, options);
|
||||
|
||||
expect(updatedTicket.addressFk).toEqual(1);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,19 +1,26 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('Ticket uploadFile()', () => {
|
||||
it(`should return an error for a user without enough privileges`, async() => {
|
||||
let ticketId = 15;
|
||||
let currentUserId = 1101;
|
||||
let ticketTypeId = 14;
|
||||
let ctx = {req: {accessToken: {userId: currentUserId}}, args: {dmsTypeId: ticketTypeId}};
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
let error;
|
||||
await app.models.Ticket.uploadFile(ctx, ticketId).catch(e => {
|
||||
error = e;
|
||||
}).finally(() => {
|
||||
expect(error.message).toEqual(`You don't have enough privileges`);
|
||||
});
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
expect(error).toBeDefined();
|
||||
const ticketId = 15;
|
||||
const currentUserId = 1101;
|
||||
const ticketTypeId = 14;
|
||||
const ctx = {req: {accessToken: {userId: currentUserId}}, args: {dmsTypeId: ticketTypeId}};
|
||||
|
||||
await models.Ticket.uploadFile(ctx, ticketId, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(`You don't have enough privileges`);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -19,10 +19,17 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.summary = async ticketFk => {
|
||||
let models = Self.app.models;
|
||||
let summaryObj = await getTicketData(Self, ticketFk);
|
||||
summaryObj.sales = await models.Ticket.getSales(ticketFk);
|
||||
Self.summary = async(ticketFk, options) => {
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const summaryObj = await getTicketData(Self, ticketFk, myOptions);
|
||||
|
||||
summaryObj.sales = await models.Ticket.getSales(ticketFk, myOptions);
|
||||
|
||||
summaryObj.packagings = await models.TicketPackaging.find({
|
||||
where: {ticketFk: ticketFk},
|
||||
include: [{relation: 'packaging',
|
||||
|
@ -33,24 +40,25 @@ module.exports = Self => {
|
|||
}
|
||||
}
|
||||
}]
|
||||
});
|
||||
summaryObj.requests = await getRequests(Self, ticketFk);
|
||||
}, myOptions);
|
||||
|
||||
summaryObj.requests = await getRequests(Self, ticketFk, myOptions);
|
||||
|
||||
summaryObj.services = await models.TicketService.find({
|
||||
where: {ticketFk: ticketFk},
|
||||
include: [{relation: 'taxClass'}]
|
||||
});
|
||||
}, myOptions);
|
||||
|
||||
return summaryObj;
|
||||
};
|
||||
|
||||
async function getTicketData(Self, ticketFk) {
|
||||
let filter = {
|
||||
async function getTicketData(Self, ticketFk, options) {
|
||||
const filter = {
|
||||
include: [
|
||||
{relation: 'warehouse', scope: {fields: ['name']}},
|
||||
{relation: 'agencyMode', scope: {fields: ['name']}},
|
||||
{relation: 'zone', scope: {fields: ['name']}},
|
||||
{
|
||||
relation: 'client',
|
||||
{relation: 'client',
|
||||
scope: {
|
||||
fields: ['salesPersonFk', 'name', 'phone', 'mobile'],
|
||||
include: {
|
||||
|
@ -99,11 +107,11 @@ module.exports = Self => {
|
|||
where: {id: ticketFk}
|
||||
};
|
||||
|
||||
return await Self.findOne(filter);
|
||||
return Self.findOne(filter, options);
|
||||
}
|
||||
|
||||
async function getRequests(Self, ticketFk) {
|
||||
let filter = {
|
||||
async function getRequests(Self, ticketFk, options) {
|
||||
const filter = {
|
||||
where: {
|
||||
ticketFk: ticketFk
|
||||
},
|
||||
|
@ -127,6 +135,6 @@ module.exports = Self => {
|
|||
}
|
||||
]
|
||||
};
|
||||
return await Self.app.models.TicketRequest.find(filter);
|
||||
return Self.app.models.TicketRequest.find(filter, options);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,25 +5,25 @@ module.exports = Self => {
|
|||
description: 'Transfer sales to a new or a given ticket',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'Origin ticket id',
|
||||
http: {source: 'path'}
|
||||
},
|
||||
{
|
||||
arg: 'ticketId',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
description: 'Destination ticket id',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
arg: 'sales',
|
||||
type: ['Object'],
|
||||
type: ['object'],
|
||||
description: 'The sales to transfer',
|
||||
required: true
|
||||
}],
|
||||
returns: {
|
||||
type: 'Object',
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
|
@ -32,28 +32,35 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.transferSales = async(ctx, id, ticketId, sales) => {
|
||||
let userId = ctx.req.accessToken.userId;
|
||||
Self.transferSales = async(ctx, id, ticketId, sales, options) => {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
|
||||
const isEditable = await models.Ticket.isEditable(ctx, id);
|
||||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (ticketId) {
|
||||
const isReceiverEditable = await models.Ticket.isEditable(ctx, ticketId);
|
||||
if (!isReceiverEditable)
|
||||
throw new UserError(`The sales of the receiver ticket can't be modified`);
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
let tx = await Self.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const originalTicket = await models.Ticket.findById(id, null, options);
|
||||
const isEditable = await models.Ticket.isEditable(ctx, id, myOptions);
|
||||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
if (ticketId) {
|
||||
const isReceiverEditable = await models.Ticket.isEditable(ctx, ticketId, myOptions);
|
||||
if (!isReceiverEditable)
|
||||
throw new UserError(`The sales of the receiver ticket can't be modified`);
|
||||
}
|
||||
|
||||
const originalTicket = await models.Ticket.findById(id, null, myOptions);
|
||||
const originalSales = await models.Sale.find({
|
||||
where: {ticketFk: id}
|
||||
}, options);
|
||||
}, myOptions);
|
||||
|
||||
if (!ticketId) {
|
||||
const ticket = await models.Ticket.findById(id);
|
||||
|
@ -61,7 +68,7 @@ module.exports = Self => {
|
|||
if (!canCreateTicket)
|
||||
throw new UserError(`You can't create a ticket for a inactive client`);
|
||||
|
||||
ticketId = await cloneTicket(originalTicket, options);
|
||||
ticketId = await cloneTicket(originalTicket, myOptions);
|
||||
}
|
||||
|
||||
const map = new Map();
|
||||
|
@ -80,10 +87,10 @@ module.exports = Self => {
|
|||
if (sale.quantity == originalSale.quantity) {
|
||||
await models.Sale.updateAll({
|
||||
id: sale.id
|
||||
}, {ticketFk: ticketId}, options);
|
||||
}, {ticketFk: ticketId}, myOptions);
|
||||
} else if (sale.quantity != originalSale.quantity) {
|
||||
await transferPartialSale(
|
||||
ticketId, originalSale, sale, options);
|
||||
ticketId, originalSale, sale, myOptions);
|
||||
}
|
||||
|
||||
// Log to original ticket
|
||||
|
@ -105,7 +112,7 @@ module.exports = Self => {
|
|||
concept: sale.concept,
|
||||
ticket: ticketId
|
||||
}
|
||||
}, options);
|
||||
}, myOptions);
|
||||
|
||||
// Log to destination ticket
|
||||
await models.TicketLog.create({
|
||||
|
@ -126,22 +133,22 @@ module.exports = Self => {
|
|||
concept: sale.concept,
|
||||
ticket: ticketId
|
||||
}
|
||||
}, options);
|
||||
}, myOptions);
|
||||
}
|
||||
|
||||
const isTicketEmpty = await models.Ticket.isEmpty(id, options);
|
||||
const isTicketEmpty = await models.Ticket.isEmpty(id, myOptions);
|
||||
if (isTicketEmpty) {
|
||||
await originalTicket.updateAttributes({
|
||||
isDeleted: true
|
||||
}, options);
|
||||
}, myOptions);
|
||||
}
|
||||
|
||||
await tx.commit();
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return {id: ticketId};
|
||||
} catch (error) {
|
||||
await tx.rollback();
|
||||
throw error;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -35,14 +35,21 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.updateDiscount = async(ctx, id, salesIds, newDiscount) => {
|
||||
Self.updateDiscount = async(ctx, id, salesIds, newDiscount, options) => {
|
||||
const $t = ctx.req.__; // $translate
|
||||
const models = Self.app.models;
|
||||
const tx = await Self.beginTransaction({});
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const filter = {
|
||||
where: {
|
||||
id: {inq: salesIds}
|
||||
|
@ -61,7 +68,7 @@ module.exports = Self => {
|
|||
}
|
||||
};
|
||||
|
||||
const sales = await models.Sale.find(filter, options);
|
||||
const sales = await models.Sale.find(filter, myOptions);
|
||||
|
||||
if (sales.length === 0)
|
||||
throw new UserError('Please select at least one sale');
|
||||
|
@ -71,15 +78,15 @@ module.exports = Self => {
|
|||
throw new UserError('All sales must belong to the same ticket');
|
||||
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const isLocked = await models.Ticket.isLocked(id);
|
||||
const roles = await models.Account.getRoles(userId);
|
||||
const isLocked = await models.Ticket.isLocked(id, myOptions);
|
||||
const roles = await models.Account.getRoles(userId, myOptions);
|
||||
const hasAllowedRoles = roles.filter(role =>
|
||||
role == 'salesPerson' || role == 'claimManager'
|
||||
);
|
||||
|
||||
const state = await Self.app.models.TicketState.findOne({
|
||||
where: {ticketFk: id}
|
||||
});
|
||||
}, myOptions);
|
||||
const alertLevel = state ? state.alertLevel : null;
|
||||
|
||||
if (isLocked || (!hasAllowedRoles && alertLevel > 0))
|
||||
|
@ -89,11 +96,11 @@ module.exports = Self => {
|
|||
where: {
|
||||
workerFk: userId
|
||||
},
|
||||
fields: 'amount'}, options);
|
||||
fields: 'amount'}, myOptions);
|
||||
|
||||
const componentCode = usesMana ? 'mana' : 'buyerDiscount';
|
||||
const discountComponent = await models.Component.findOne({
|
||||
where: {code: componentCode}}, options);
|
||||
where: {code: componentCode}}, myOptions);
|
||||
|
||||
const componentId = discountComponent.id;
|
||||
const promises = [];
|
||||
|
@ -105,9 +112,9 @@ module.exports = Self => {
|
|||
const newComponent = models.SaleComponent.upsert({
|
||||
saleFk: sale.id,
|
||||
value: value,
|
||||
componentFk: componentId}, options);
|
||||
componentFk: componentId}, myOptions);
|
||||
|
||||
const updatedSale = sale.updateAttribute('discount', newDiscount, options);
|
||||
const updatedSale = sale.updateAttribute('discount', newDiscount, myOptions);
|
||||
|
||||
promises.push(newComponent, updatedSale);
|
||||
changesMade += `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity}) ${oldDiscount}% ➔ *${newDiscount}%*`;
|
||||
|
@ -116,7 +123,7 @@ module.exports = Self => {
|
|||
await Promise.all(promises);
|
||||
|
||||
const query = `call vn.manaSpellersRequery(?)`;
|
||||
await Self.rawSql(query, [userId], options);
|
||||
await Self.rawSql(query, [userId], myOptions);
|
||||
|
||||
const ticket = await models.Ticket.findById(id, {
|
||||
include: {
|
||||
|
@ -130,7 +137,7 @@ module.exports = Self => {
|
|||
}
|
||||
}
|
||||
}
|
||||
}, options);
|
||||
}, myOptions);
|
||||
|
||||
const salesPerson = ticket.client().salesPersonUser();
|
||||
if (salesPerson) {
|
||||
|
@ -144,10 +151,10 @@ module.exports = Self => {
|
|||
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
|
||||
}
|
||||
|
||||
await tx.commit();
|
||||
} catch (error) {
|
||||
await tx.rollback();
|
||||
throw error;
|
||||
if (tx) await tx.commit();
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@ module.exports = Self => {
|
|||
{
|
||||
arg: 'data',
|
||||
description: 'Model instance data',
|
||||
type: 'Object',
|
||||
type: 'object',
|
||||
required: true,
|
||||
http: {source: 'body'}
|
||||
}
|
||||
|
@ -30,12 +30,30 @@ module.exports = Self => {
|
|||
}
|
||||
|
||||
});
|
||||
Self.updateEditableTicket = async(ctx, id, data) => {
|
||||
let ticketIsEditable = await Self.app.models.Ticket.isEditable(ctx, id);
|
||||
if (!ticketIsEditable)
|
||||
throw new UserError('This ticket can not be modified');
|
||||
Self.updateEditableTicket = async(ctx, id, data, options) => {
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
|
||||
let ticket = await Self.app.models.Ticket.findById(id);
|
||||
await ticket.updateAttributes(data);
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
try {
|
||||
const ticketIsEditable = await Self.app.models.Ticket.isEditable(ctx, id, myOptions);
|
||||
if (!ticketIsEditable)
|
||||
throw new UserError('This ticket can not be modified');
|
||||
|
||||
const ticket = await Self.app.models.Ticket.findById(id, null, myOptions);
|
||||
await ticket.updateAttributes(data, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4,40 +4,40 @@ module.exports = Self => {
|
|||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
description: 'The ticket id',
|
||||
http: {source: 'path'}
|
||||
}, {
|
||||
arg: 'warehouseId',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
description: 'The warehouse id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'companyId',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
description: 'The company id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'dmsTypeId',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
description: 'The dms type id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'reference',
|
||||
type: 'String',
|
||||
type: 'string',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'description',
|
||||
type: 'String',
|
||||
type: 'string',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'hasFile',
|
||||
type: 'Boolean',
|
||||
type: 'boolean',
|
||||
description: 'True if has an attached file',
|
||||
required: true
|
||||
}],
|
||||
returns: {
|
||||
type: 'Object',
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
|
@ -46,31 +46,38 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.uploadFile = async(ctx, id) => {
|
||||
Self.uploadFile = async(ctx, id, options) => {
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
const promises = [];
|
||||
const tx = await Self.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const uploadedFiles = await models.Dms.uploadFile(ctx, options);
|
||||
const uploadedFiles = await models.Dms.uploadFile(ctx, myOptions);
|
||||
uploadedFiles.forEach(dms => {
|
||||
const newTicketDms = models.TicketDms.create({
|
||||
ticketFk: id,
|
||||
dmsFk: dms.id
|
||||
}, options);
|
||||
}, myOptions);
|
||||
|
||||
promises.push(newTicketDms);
|
||||
});
|
||||
const resolvedPromises = await Promise.all(promises);
|
||||
|
||||
await tx.commit();
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return resolvedPromises;
|
||||
} catch (err) {
|
||||
await tx.rollback();
|
||||
throw err;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -35,7 +35,7 @@ module.exports = Self => {
|
|||
});
|
||||
|
||||
Self.getLanded = async(ctx, shipped, addressFk, agencyModeFk, warehouseFk, options) => {
|
||||
let myOptions = {};
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
@ -57,8 +57,7 @@ module.exports = Self => {
|
|||
agencyModeFk,
|
||||
warehouseFk,
|
||||
showExpired
|
||||
],
|
||||
myOptions
|
||||
]
|
||||
));
|
||||
|
||||
const rsIndex = stmts.push('SELECT * FROM tmp.zoneGetLanded') - 1;
|
||||
|
|
Loading…
Reference in New Issue