refactor(sale): ticket.sale endpoints now use transactions
This commit is contained in:
parent
e690febc7f
commit
392c4dcba3
|
@ -26,54 +26,73 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.deleteSales = async(ctx, sales, ticketId) => {
|
Self.deleteSales = async(ctx, sales, ticketId, options) => {
|
||||||
const $t = ctx.req.__; // $translate
|
const $t = ctx.req.__; // $translate
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
const canEditSales = await models.Sale.canEdit(ctx, sales);
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const ticket = await models.Ticket.findById(ticketId, {
|
if (!myOptions.transaction) {
|
||||||
include: {
|
tx = await Self.beginTransaction({});
|
||||||
relation: 'client',
|
myOptions.transaction = tx;
|
||||||
scope: {
|
}
|
||||||
include: {
|
|
||||||
relation: 'salesPersonUser',
|
try {
|
||||||
scope: {
|
const canEditSales = await models.Sale.canEdit(ctx, sales, myOptions);
|
||||||
fields: ['id', 'name']
|
|
||||||
|
const ticket = await models.Ticket.findById(ticketId, {
|
||||||
|
include: {
|
||||||
|
relation: 'client',
|
||||||
|
scope: {
|
||||||
|
include: {
|
||||||
|
relation: 'salesPersonUser',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
const isTicketEditable = await models.Ticket.isEditable(ctx, ticketId, myOptions);
|
||||||
|
if (!isTicketEditable)
|
||||||
|
throw new UserError(`The sales of this ticket can't be modified`);
|
||||||
|
|
||||||
|
if (!canEditSales)
|
||||||
|
throw new UserError(`Sale(s) blocked, please contact production`);
|
||||||
|
|
||||||
|
const promises = [];
|
||||||
|
let deletions = '';
|
||||||
|
for (let sale of sales) {
|
||||||
|
const deletedSale = models.Sale.destroyById(sale.id, myOptions);
|
||||||
|
deletions += `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity})`;
|
||||||
|
|
||||||
|
promises.push(deletedSale);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
const isTicketEditable = await models.Ticket.isEditable(ctx, ticketId);
|
const salesPerson = ticket.client().salesPersonUser();
|
||||||
if (!isTicketEditable)
|
if (salesPerson) {
|
||||||
throw new UserError(`The sales of this ticket can't be modified`);
|
const origin = ctx.req.headers.origin;
|
||||||
|
|
||||||
if (!canEditSales)
|
const message = $t('Deleted sales from ticket', {
|
||||||
throw new UserError(`Sale(s) blocked, please contact production`);
|
ticketId: ticketId,
|
||||||
|
ticketUrl: `${origin}/#!/ticket/${ticketId}/sale`,
|
||||||
|
deletions: deletions
|
||||||
|
});
|
||||||
|
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions);
|
||||||
|
}
|
||||||
|
|
||||||
const promises = [];
|
const deletedSales = await Promise.all(promises);
|
||||||
let deletions = '';
|
|
||||||
for (let sale of sales) {
|
|
||||||
const deletedSale = models.Sale.destroyById(sale.id);
|
|
||||||
deletions += `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity})`;
|
|
||||||
|
|
||||||
promises.push(deletedSale);
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return deletedSales;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
const salesPerson = ticket.client().salesPersonUser();
|
|
||||||
if (salesPerson) {
|
|
||||||
const origin = ctx.req.headers.origin;
|
|
||||||
|
|
||||||
const message = $t('Deleted sales from ticket', {
|
|
||||||
ticketId: ticketId,
|
|
||||||
ticketUrl: `${origin}/#!/ticket/${ticketId}/sale`,
|
|
||||||
deletions: deletions
|
|
||||||
});
|
|
||||||
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.all(promises);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,26 +18,32 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getClaimableFromTicket = async ticketFk => {
|
Self.getClaimableFromTicket = async(ticketFk, options) => {
|
||||||
let query = `SELECT
|
const myOptions = {};
|
||||||
s.id AS saleFk,
|
|
||||||
t.id AS ticketFk,
|
|
||||||
t.landed,
|
|
||||||
s.concept,
|
|
||||||
s.itemFk,
|
|
||||||
s.quantity,
|
|
||||||
s.price,
|
|
||||||
s.discount,
|
|
||||||
t.nickname
|
|
||||||
FROM vn.ticket t
|
|
||||||
INNER JOIN vn.sale s ON s.ticketFk = t.id
|
|
||||||
LEFT JOIN vn.claimBeginning cb ON cb.saleFk = s.id
|
|
||||||
|
|
||||||
WHERE (t.landed) >= TIMESTAMPADD(DAY, -7, CURDATE())
|
if (typeof options == 'object')
|
||||||
AND t.id = ? AND cb.id IS NULL
|
Object.assign(myOptions, options);
|
||||||
ORDER BY t.landed DESC, t.id DESC`;
|
|
||||||
|
|
||||||
let claimableSales = await Self.rawSql(query, [ticketFk]);
|
const query = `
|
||||||
|
SELECT
|
||||||
|
s.id AS saleFk,
|
||||||
|
t.id AS ticketFk,
|
||||||
|
t.landed,
|
||||||
|
s.concept,
|
||||||
|
s.itemFk,
|
||||||
|
s.quantity,
|
||||||
|
s.price,
|
||||||
|
s.discount,
|
||||||
|
t.nickname
|
||||||
|
FROM vn.ticket t
|
||||||
|
INNER JOIN vn.sale s ON s.ticketFk = t.id
|
||||||
|
LEFT JOIN vn.claimBeginning cb ON cb.saleFk = s.id
|
||||||
|
|
||||||
|
WHERE (t.landed) >= TIMESTAMPADD(DAY, -7, CURDATE())
|
||||||
|
AND t.id = ? AND cb.id IS NULL
|
||||||
|
ORDER BY t.landed DESC, t.id DESC`;
|
||||||
|
|
||||||
|
const claimableSales = await Self.rawSql(query, [ticketFk], myOptions);
|
||||||
|
|
||||||
return claimableSales;
|
return claimableSales;
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,20 +20,39 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.recalculatePrice = async(ctx, id) => {
|
Self.recalculatePrice = async(ctx, id, options) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
const sale = await Self.findById(id);
|
if (typeof options == 'object')
|
||||||
const isEditable = await models.Ticket.isEditable(ctx, sale.ticketFk);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
if (!isEditable)
|
if (!myOptions.transaction) {
|
||||||
throw new UserError(`The sales of this ticket can't be modified`);
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
const canEditSale = await models.Sale.canEdit(ctx, [id]);
|
try {
|
||||||
|
const sale = await Self.findById(id, null, myOptions);
|
||||||
|
const isEditable = await models.Ticket.isEditable(ctx, sale.ticketFk, myOptions);
|
||||||
|
|
||||||
if (!canEditSale)
|
if (!isEditable)
|
||||||
throw new UserError(`Sale(s) blocked, please contact production`);
|
throw new UserError(`The sales of this ticket can't be modified`);
|
||||||
|
|
||||||
return Self.rawSql('CALL vn.sale_calculateComponent(?, null)', [id]);
|
const canEditSale = await models.Sale.canEdit(ctx, [id], myOptions);
|
||||||
|
|
||||||
|
if (!canEditSale)
|
||||||
|
throw new UserError(`Sale(s) blocked, please contact production`);
|
||||||
|
|
||||||
|
const recalculation = await Self.rawSql('CALL vn.sale_calculateComponent(?, null)', [id], myOptions);
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return recalculation;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,63 +34,80 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.reserve = async(ctx, ticketId, sales, reserved) => {
|
Self.reserve = async(ctx, ticketId, sales, reserved, options) => {
|
||||||
const $t = ctx.req.__; // $translate
|
const $t = ctx.req.__; // $translate
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
const isTicketEditable = await models.Ticket.isEditable(ctx, ticketId);
|
if (typeof options == 'object')
|
||||||
if (!isTicketEditable)
|
Object.assign(myOptions, options);
|
||||||
throw new UserError(`The sales of this ticket can't be modified`);
|
|
||||||
|
|
||||||
const canEditSale = await models.Sale.canEdit(ctx, sales);
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
if (!canEditSale)
|
myOptions.transaction = tx;
|
||||||
throw new UserError(`Sale(s) blocked, please contact production`);
|
|
||||||
|
|
||||||
let changesMade = '';
|
|
||||||
const promises = [];
|
|
||||||
|
|
||||||
for (let sale of sales) {
|
|
||||||
if (sale.reserved != reserved) {
|
|
||||||
const oldState = sale.reserved ? 'reserved' : 'regular';
|
|
||||||
const newState = reserved ? 'reserved' : 'regular';
|
|
||||||
|
|
||||||
const reservedSale = models.Sale.update({id: sale.id}, {reserved: reserved});
|
|
||||||
|
|
||||||
promises.push(reservedSale);
|
|
||||||
|
|
||||||
changesMade += `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity}) ${$t('State')}: ${$t(oldState)} ➔ *${$t(newState)}*`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await Promise.all(promises);
|
try {
|
||||||
|
const isTicketEditable = await models.Ticket.isEditable(ctx, ticketId, myOptions);
|
||||||
|
if (!isTicketEditable)
|
||||||
|
throw new UserError(`The sales of this ticket can't be modified`);
|
||||||
|
|
||||||
const ticket = await models.Ticket.findById(ticketId, {
|
const canEditSale = await models.Sale.canEdit(ctx, sales, myOptions);
|
||||||
include: {
|
|
||||||
relation: 'client',
|
if (!canEditSale)
|
||||||
scope: {
|
throw new UserError(`Sale(s) blocked, please contact production`);
|
||||||
include: {
|
|
||||||
relation: 'salesPersonUser',
|
let changesMade = '';
|
||||||
scope: {
|
const promises = [];
|
||||||
fields: ['id', 'name']
|
|
||||||
|
for (let sale of sales) {
|
||||||
|
if (sale.reserved != reserved) {
|
||||||
|
const oldState = sale.reserved ? 'reserved' : 'regular';
|
||||||
|
const newState = reserved ? 'reserved' : 'regular';
|
||||||
|
|
||||||
|
const reservedSale = models.Sale.updateAll({id: sale.id}, {reserved: reserved}, myOptions);
|
||||||
|
|
||||||
|
promises.push(reservedSale);
|
||||||
|
|
||||||
|
changesMade += `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity}) ${$t('State')}: ${$t(oldState)} ➔ *${$t(newState)}*`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await Promise.all(promises);
|
||||||
|
|
||||||
|
const ticket = await models.Ticket.findById(ticketId, {
|
||||||
|
include: {
|
||||||
|
relation: 'client',
|
||||||
|
scope: {
|
||||||
|
include: {
|
||||||
|
relation: 'salesPersonUser',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
const salesPerson = ticket.client().salesPersonUser();
|
||||||
|
if (salesPerson) {
|
||||||
|
const origin = ctx.req.headers.origin;
|
||||||
|
|
||||||
|
const message = $t('Changed sale reserved state', {
|
||||||
|
ticketId: ticketId,
|
||||||
|
ticketUrl: `${origin}/#!/ticket/${ticketId}/sale`,
|
||||||
|
changes: changesMade
|
||||||
|
});
|
||||||
|
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
const salesPerson = ticket.client().salesPersonUser();
|
if (tx) await tx.commit();
|
||||||
if (salesPerson) {
|
|
||||||
const origin = ctx.req.headers.origin;
|
|
||||||
|
|
||||||
const message = $t('Changed sale reserved state', {
|
return result;
|
||||||
ticketId: ticketId,
|
} catch (e) {
|
||||||
ticketUrl: `${origin}/#!/ticket/${ticketId}/sale`,
|
if (tx) await tx.rollback();
|
||||||
changes: changesMade
|
throw e;
|
||||||
});
|
|
||||||
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,36 +1,69 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('sale canEdit()', () => {
|
describe('sale canEdit()', () => {
|
||||||
it('should return true if the role is production regardless of the saleTrackings', async() => {
|
it('should return true if the role is production regardless of the saleTrackings', async() => {
|
||||||
const productionUserID = 49;
|
const tx = await models.Sale.beginTransaction({});
|
||||||
let ctx = {req: {accessToken: {userId: productionUserID}}};
|
|
||||||
|
|
||||||
const sales = [{id: 3}];
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const result = await app.models.Sale.canEdit(ctx, sales);
|
const productionUserID = 49;
|
||||||
|
const ctx = {req: {accessToken: {userId: productionUserID}}};
|
||||||
|
|
||||||
expect(result).toEqual(true);
|
const sales = [{id: 3}];
|
||||||
|
|
||||||
|
const result = await models.Sale.canEdit(ctx, sales, options);
|
||||||
|
|
||||||
|
expect(result).toEqual(true);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true if the role is not production and none of the sales has saleTracking', async() => {
|
it('should return true if the role is not production and none of the sales has saleTracking', async() => {
|
||||||
const salesPersonUserID = 18;
|
const tx = await models.Sale.beginTransaction({});
|
||||||
let ctx = {req: {accessToken: {userId: salesPersonUserID}}};
|
|
||||||
|
|
||||||
const sales = [{id: 10}];
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const result = await app.models.Sale.canEdit(ctx, sales);
|
const salesPersonUserID = 18;
|
||||||
|
const ctx = {req: {accessToken: {userId: salesPersonUserID}}};
|
||||||
|
|
||||||
expect(result).toEqual(true);
|
const sales = [{id: 10}];
|
||||||
|
|
||||||
|
const result = await models.Sale.canEdit(ctx, sales, options);
|
||||||
|
|
||||||
|
expect(result).toEqual(true);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false if any of the sales has a saleTracking record', async() => {
|
it('should return false if any of the sales has a saleTracking record', async() => {
|
||||||
const salesPersonUserID = 18;
|
const tx = await models.Sale.beginTransaction({});
|
||||||
let ctx = {req: {accessToken: {userId: salesPersonUserID}}};
|
|
||||||
|
|
||||||
const sales = [{id: 3}];
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const result = await app.models.Sale.canEdit(ctx, sales);
|
const salesPersonUserID = 18;
|
||||||
|
const ctx = {req: {accessToken: {userId: salesPersonUserID}}};
|
||||||
|
|
||||||
expect(result).toEqual(false);
|
const sales = [{id: 3}];
|
||||||
|
|
||||||
|
const result = await models.Sale.canEdit(ctx, sales, options);
|
||||||
|
|
||||||
|
expect(result).toEqual(false);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,38 +1,29 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('sale deleteSales()', () => {
|
describe('sale deleteSales()', () => {
|
||||||
let sale;
|
|
||||||
let newSale;
|
|
||||||
|
|
||||||
beforeAll(async done => {
|
|
||||||
try {
|
|
||||||
sale = await app.models.Sale.findOne({where: {id: 9}});
|
|
||||||
sale.id = null;
|
|
||||||
newSale = await app.models.Sale.create(sale);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an error if the ticket of the given sales is not editable', async() => {
|
it('should throw an error if the ticket of the given sales is not editable', async() => {
|
||||||
let ctx = {
|
const tx = await models.Sale.beginTransaction({});
|
||||||
req: {
|
|
||||||
accessToken: {userId: 9},
|
|
||||||
headers: {origin: 'localhost:5000'},
|
|
||||||
__: () => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let error;
|
let error;
|
||||||
|
|
||||||
const sales = [{id: 1, instance: 0}, {id: 2, instance: 1}];
|
|
||||||
const ticketId = 2;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await app.models.Sale.deleteSales(ctx, sales, ticketId);
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const ctx = {
|
||||||
|
req: {
|
||||||
|
accessToken: {userId: 9},
|
||||||
|
headers: {origin: 'localhost:5000'},
|
||||||
|
__: () => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const sales = [{id: 1, instance: 0}, {id: 2, instance: 1}];
|
||||||
|
const ticketId = 2;
|
||||||
|
|
||||||
|
await models.Sale.deleteSales(ctx, sales, ticketId, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,19 +31,33 @@ describe('sale deleteSales()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delete the sale', async() => {
|
it('should delete the sale', async() => {
|
||||||
let ctx = {
|
const tx = await models.Sale.beginTransaction({});
|
||||||
req: {
|
|
||||||
accessToken: {userId: 9},
|
|
||||||
headers: {origin: 'localhost:5000'},
|
|
||||||
__: () => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const sales = [{id: newSale.id, instance: 0}];
|
try {
|
||||||
const ticketId = 16;
|
const options = {transaction: tx};
|
||||||
|
|
||||||
let res = await app.models.Sale.deleteSales(ctx, sales, ticketId);
|
const ctx = {
|
||||||
|
req: {
|
||||||
|
accessToken: {userId: 9},
|
||||||
|
headers: {origin: 'localhost:5000'},
|
||||||
|
__: () => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const sale = await models.Sale.findOne({where: {id: 9}}, options);
|
||||||
|
sale.id = null;
|
||||||
|
const newSale = await models.Sale.create(sale, options);
|
||||||
|
|
||||||
expect(res).toEqual([{count: 1}]);
|
const sales = [{id: newSale.id, instance: 0}];
|
||||||
|
const ticketId = 16;
|
||||||
|
|
||||||
|
const deletions = await models.Sale.deleteSales(ctx, sales, ticketId, options);
|
||||||
|
|
||||||
|
expect(deletions).toEqual([{count: 1}]);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('sale getClaimableFromTicket()', () => {
|
describe('sale getClaimableFromTicket()', () => {
|
||||||
it('should return the claimable sales of a given ticket', async() => {
|
it('should return the claimable sales of a given ticket', async() => {
|
||||||
let claimableFromTicket = await app.models.Sale.getClaimableFromTicket(16);
|
const tx = await models.Sale.beginTransaction({});
|
||||||
|
|
||||||
expect(claimableFromTicket[0].concept).toBe('Ranged weapon longbow 2m');
|
try {
|
||||||
expect(claimableFromTicket.length).toBe(3);
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const claimableFromTicket = await models.Sale.getClaimableFromTicket(16, options);
|
||||||
|
|
||||||
|
expect(claimableFromTicket[0].concept).toBe('Ranged weapon longbow 2m');
|
||||||
|
expect(claimableFromTicket.length).toBe(3);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
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('sale recalculatePrice()', () => {
|
describe('sale recalculatePrice()', () => {
|
||||||
const saleId = 7;
|
const saleId = 7;
|
||||||
|
|
||||||
it('should update the sale price', async() => {
|
it('should update the sale price', async() => {
|
||||||
const ctx = {req: {accessToken: {userId: 9}}};
|
const tx = await models.Sale.beginTransaction({});
|
||||||
const response = await app.models.Sale.recalculatePrice(ctx, saleId);
|
|
||||||
|
|
||||||
expect(response.affectedRows).toBeDefined();
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const ctx = {req: {accessToken: {userId: 9}}};
|
||||||
|
const response = await models.Sale.recalculatePrice(ctx, saleId, 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() => {
|
it('should throw an error if the ticket is not editable', async() => {
|
||||||
const ctx = {req: {accessToken: {userId: 9}}};
|
const tx = await models.Sale.beginTransaction({});
|
||||||
const immutableSaleId = 1;
|
|
||||||
await app.models.Sale.recalculatePrice(ctx, immutableSaleId)
|
|
||||||
.catch(response => {
|
|
||||||
expect(response).toEqual(new Error(`The sales of this ticket can't be modified`));
|
|
||||||
error = response;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(error).toBeDefined();
|
let error;
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const ctx = {req: {accessToken: {userId: 9}}};
|
||||||
|
const immutableSaleId = 1;
|
||||||
|
await models.Sale.recalculatePrice(ctx, immutableSaleId, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toEqual(new Error(`The sales of this ticket can't be modified`));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('sale reserve()', () => {
|
describe('sale reserve()', () => {
|
||||||
const ctx = {
|
const ctx = {
|
||||||
|
@ -9,51 +9,54 @@ describe('sale reserve()', () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
afterAll(async done => {
|
|
||||||
let ctx = {req: {accessToken: {userId: 9}}};
|
|
||||||
let params = {
|
|
||||||
sales: [
|
|
||||||
{id: 7},
|
|
||||||
{id: 8}],
|
|
||||||
ticketFk: 11,
|
|
||||||
reserved: false
|
|
||||||
};
|
|
||||||
|
|
||||||
await app.models.Sale.reserve(ctx, params);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an error if the ticket can not be modified', async() => {
|
it('should throw an error if the ticket can not be modified', async() => {
|
||||||
|
const tx = await models.Sale.beginTransaction({});
|
||||||
|
|
||||||
let error;
|
let error;
|
||||||
const ticketId = 2;
|
try {
|
||||||
const sales = [{id: 5}];
|
const options = {transaction: tx};
|
||||||
const reserved = false;
|
|
||||||
|
|
||||||
await app.models.Sale.reserve(ctx, ticketId, sales, reserved)
|
const ticketId = 2;
|
||||||
.catch(response => {
|
const sales = [{id: 5}];
|
||||||
expect(response).toEqual(new Error(`The sales of this ticket can't be modified`));
|
const reserved = false;
|
||||||
error = response;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(error).toBeDefined();
|
await models.Sale.reserve(ctx, ticketId, sales, reserved, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toEqual(new Error(`The sales of this ticket can't be modified`));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the given sales of a ticket to reserved', async() => {
|
it('should update the given sales of a ticket to reserved', async() => {
|
||||||
originalTicketSales = await app.models.Ticket.getSales(11);
|
const tx = await models.Sale.beginTransaction({});
|
||||||
|
|
||||||
expect(originalTicketSales[0].reserved).toEqual(false);
|
try {
|
||||||
expect(originalTicketSales[1].reserved).toEqual(false);
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const ticketId = 11;
|
originalTicketSales = await models.Ticket.getSales(11, options);
|
||||||
const sales = [{id: 7}, {id: 8}];
|
|
||||||
const reserved = true;
|
|
||||||
|
|
||||||
await app.models.Sale.reserve(ctx, ticketId, sales, reserved);
|
expect(originalTicketSales[0].reserved).toEqual(false);
|
||||||
|
expect(originalTicketSales[1].reserved).toEqual(false);
|
||||||
|
|
||||||
const reservedTicketSales = await app.models.Ticket.getSales(ticketId);
|
const ticketId = 11;
|
||||||
|
const sales = [{id: 7}, {id: 8}];
|
||||||
|
const reserved = true;
|
||||||
|
|
||||||
expect(reservedTicketSales[0].reserved).toEqual(true);
|
await models.Sale.reserve(ctx, ticketId, sales, reserved, options);
|
||||||
expect(reservedTicketSales[1].reserved).toEqual(true);
|
|
||||||
|
const reservedTicketSales = await models.Ticket.getSales(ticketId, options);
|
||||||
|
|
||||||
|
expect(reservedTicketSales[0].reserved).toEqual(true);
|
||||||
|
expect(reservedTicketSales[1].reserved).toEqual(true);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,40 +1,45 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('sale updateConcept()', () => {
|
describe('sale updateConcept()', () => {
|
||||||
const ctx = {req: {accessToken: {userId: 9}}};
|
const ctx = {req: {accessToken: {userId: 9}}};
|
||||||
const saleId = 1;
|
const saleId = 1;
|
||||||
let originalSale;
|
|
||||||
|
|
||||||
beforeAll(async done => {
|
|
||||||
originalSale = await app.models.Sale.findById(saleId);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async done => {
|
|
||||||
await originalSale.save();
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw if ID was undefined', async() => {
|
it('should throw if ID was undefined', async() => {
|
||||||
let err;
|
const tx = await models.Sale.beginTransaction({});
|
||||||
const newConcept = 'I am he new concept';
|
|
||||||
|
|
||||||
|
let error;
|
||||||
try {
|
try {
|
||||||
await app.models.Sale.updateConcept(ctx, undefined, newConcept);
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const newConcept = 'not going to heppen';
|
||||||
|
|
||||||
|
await models.Sale.updateConcept(ctx, undefined, newConcept, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
err = e;
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(err).toBeDefined();
|
expect(error).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the sale concept', async() => {
|
it('should update the sale concept', async() => {
|
||||||
const newConcept = 'I am the new concept';
|
const tx = await models.Sale.beginTransaction({});
|
||||||
|
|
||||||
let response = await app.models.Sale.updateConcept(ctx, saleId, newConcept);
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
expect(response.concept).toEqual(newConcept);
|
const newConcept = 'I am the new concept';
|
||||||
|
|
||||||
|
let response = await models.Sale.updateConcept(ctx, saleId, newConcept, options);
|
||||||
|
|
||||||
|
expect(response.concept).toEqual(newConcept);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,104 +1,100 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('sale updatePrice()', () => {
|
describe('sale updatePrice()', () => {
|
||||||
let originalSale;
|
const ctx = {
|
||||||
let originalSalesPersonMana;
|
req: {
|
||||||
let createdSaleComponent;
|
accessToken: {userId: 18},
|
||||||
let saleId = 7;
|
headers: {origin: 'localhost:5000'},
|
||||||
let manaComponentId;
|
__: () => {}
|
||||||
|
}
|
||||||
beforeAll(async done => {
|
};
|
||||||
let component = await app.models.Component.findOne({where: {code: 'mana'}});
|
const saleId = 7;
|
||||||
manaComponentId = component.id;
|
|
||||||
originalSale = await app.models.Sale.findById(saleId);
|
|
||||||
originalSalesPersonMana = await app.models.WorkerMana.findById(18);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an error if the ticket is not editable', async() => {
|
it('should throw an error if the ticket is not editable', async() => {
|
||||||
const ctx = {
|
const tx = await models.Sale.beginTransaction({});
|
||||||
req: {
|
|
||||||
accessToken: {userId: 18},
|
|
||||||
headers: {origin: 'localhost:5000'},
|
|
||||||
__: () => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let immutableSaleId = 1;
|
|
||||||
let price = 5;
|
|
||||||
|
|
||||||
await app.models.Sale.updatePrice(ctx, immutableSaleId, price)
|
try {
|
||||||
.catch(response => {
|
const options = {transaction: tx};
|
||||||
expect(response).toEqual(new Error(`The sales of this ticket can't be modified`));
|
|
||||||
error = response;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(error).toBeDefined();
|
const immutableSaleId = 1;
|
||||||
|
const price = 5;
|
||||||
|
|
||||||
|
await models.Sale.updatePrice(ctx, immutableSaleId, price, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toEqual(new Error(`The sales of this ticket can't be modified`));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 0 if the price is an empty string', async() => {
|
it('should return 0 if the price is an empty string', async() => {
|
||||||
const ctx = {
|
const tx = await models.Sale.beginTransaction({});
|
||||||
req: {
|
|
||||||
accessToken: {userId: 18},
|
|
||||||
headers: {origin: 'localhost:5000'},
|
|
||||||
__: () => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let price = '';
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
await app.models.Sale.updatePrice(ctx, saleId, price);
|
const price = '';
|
||||||
let updatedSale = await app.models.Sale.findById(saleId);
|
|
||||||
|
|
||||||
expect(updatedSale.price).toEqual(0);
|
await models.Sale.updatePrice(ctx, saleId, price, options);
|
||||||
|
const updatedSale = await models.Sale.findById(saleId, null, options);
|
||||||
|
|
||||||
// restores
|
expect(updatedSale.price).toEqual(0);
|
||||||
await originalSale.updateAttributes(originalSale);
|
|
||||||
await app.models.SaleComponent.updateAll({componentFk: manaComponentId, saleFk: saleId}, {value: 0});
|
await tx.rollback();
|
||||||
await originalSalesPersonMana.updateAttributes(originalSalesPersonMana);
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should now set price as a number in a string', async() => {
|
it('should now set price as a number in a string', async() => {
|
||||||
const ctx = {
|
const tx = await models.Sale.beginTransaction({});
|
||||||
req: {
|
|
||||||
accessToken: {userId: 18},
|
|
||||||
headers: {origin: 'localhost:5000'},
|
|
||||||
__: () => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let price = '8';
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
await app.models.Sale.updatePrice(ctx, saleId, price);
|
const price = '8';
|
||||||
let updatedSale = await app.models.Sale.findById(saleId);
|
|
||||||
|
|
||||||
expect(updatedSale.price).toEqual(8);
|
await models.Sale.updatePrice(ctx, saleId, price, options);
|
||||||
|
const updatedSale = await models.Sale.findById(saleId, null, options);
|
||||||
|
|
||||||
// restores
|
expect(updatedSale.price).toEqual(8);
|
||||||
await originalSale.updateAttributes(originalSale);
|
|
||||||
await app.models.SaleComponent.updateAll({componentFk: manaComponentId, saleFk: saleId}, {value: 0});
|
await tx.rollback();
|
||||||
await originalSalesPersonMana.updateAttributes(originalSalesPersonMana);
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// #2736 sale updatePrice() returns inconsistent values
|
it('should set price as a decimal number and check the sale has the mana component changing the salesPersonMana', async() => {
|
||||||
xit('should set price as a decimal number and check the sale has the mana component changing the salesPersonMana', async() => {
|
const tx = await models.Sale.beginTransaction({});
|
||||||
let ctx = {req: {accessToken: {userId: 18}}};
|
|
||||||
let price = 5.4;
|
|
||||||
|
|
||||||
await app.models.Sale.updatePrice(ctx, saleId, price);
|
try {
|
||||||
let updatedSale = await app.models.Sale.findById(saleId);
|
const options = {transaction: tx};
|
||||||
createdSaleComponent = await app.models.SaleComponent.findOne({where: {saleFk: saleId, componentFk: manaComponentId}});
|
|
||||||
|
|
||||||
expect(updatedSale.price).toBe(price);
|
const price = 5.4;
|
||||||
expect(createdSaleComponent.value).toEqual(-2.04);
|
const originalSalesPersonMana = await models.WorkerMana.findById(18, null, options);
|
||||||
|
const manaComponent = await models.Component.findOne({where: {code: 'mana'}}, options);
|
||||||
|
|
||||||
let updatedSalesPersonMana = await app.models.WorkerMana.findById(18);
|
await models.Sale.updatePrice(ctx, saleId, price, options);
|
||||||
|
const updatedSale = await models.Sale.findById(saleId, null, options);
|
||||||
|
createdSaleComponent = await models.SaleComponent.findOne({where: {saleFk: saleId, componentFk: manaComponent.id}}, options);
|
||||||
|
|
||||||
expect(updatedSalesPersonMana.amount).not.toEqual(originalSalesPersonMana.amount);
|
expect(updatedSale.price).toBe(price);
|
||||||
|
expect(createdSaleComponent.value).toEqual(-2.04);
|
||||||
|
|
||||||
// restores
|
const updatedSalesPersonMana = await models.WorkerMana.findById(18, null, options);
|
||||||
await originalSale.updateAttributes(originalSale);
|
|
||||||
await app.models.SaleComponent.updateAll({componentFk: manaComponentId, saleFk: saleId}, {value: 0});
|
expect(updatedSalesPersonMana.amount).not.toEqual(originalSalesPersonMana.amount);
|
||||||
await originalSalesPersonMana.updateAttributes(originalSalesPersonMana);
|
|
||||||
|
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;
|
||||||
|
|
||||||
describe('sale updateQuantity()', () => {
|
describe('sale updateQuantity()', () => {
|
||||||
const ctx = {
|
const ctx = {
|
||||||
|
@ -10,44 +10,61 @@ describe('sale updateQuantity()', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
it('should throw an error if the quantity is not a number', async() => {
|
it('should throw an error if the quantity is not a number', async() => {
|
||||||
|
const tx = await models.Sale.beginTransaction({});
|
||||||
|
|
||||||
let error;
|
let error;
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
await app.models.Sale.updateQuantity(ctx, 1, 'wrong quantity!')
|
await models.Sale.updateQuantity(ctx, 1, 'wrong quantity!', options);
|
||||||
.catch(response => {
|
|
||||||
expect(response).toEqual(new Error('The value should be a number'));
|
|
||||||
error = response;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(error).toBeDefined();
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toEqual(new Error('The value should be a number'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if the quantity is greater than it should be', async() => {
|
it('should throw an error if the quantity is greater than it should be', async() => {
|
||||||
|
const tx = await models.Sale.beginTransaction({});
|
||||||
|
|
||||||
let error;
|
let error;
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
await app.models.Sale.updateQuantity(ctx, 1, 99)
|
await models.Sale.updateQuantity(ctx, 1, 99, options);
|
||||||
.catch(response => {
|
|
||||||
expect(response).toEqual(new Error('The new quantity should be smaller than the old one'));
|
|
||||||
error = response;
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(error).toBeDefined();
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toEqual(new Error('The new quantity should be smaller than the old one'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the quantity of a given sale current line', async() => {
|
it('should update the quantity of a given sale current line', async() => {
|
||||||
let originalLineData = await app.models.Sale.findOne({where: {id: 1}, fields: ['quantity']});
|
const tx = await models.Sale.beginTransaction({});
|
||||||
|
|
||||||
expect(originalLineData.quantity).toEqual(5);
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
await app.models.Sale.updateQuantity(ctx, 1, 4);
|
const originalLine = await models.Sale.findOne({where: {id: 1}, fields: ['quantity']}, options);
|
||||||
|
|
||||||
let modifiedLineData = await app.models.Sale.findOne({where: {id: 1}, fields: ['quantity']});
|
expect(originalLine.quantity).toEqual(5);
|
||||||
|
|
||||||
expect(modifiedLineData.quantity).toEqual(4);
|
await models.Sale.updateQuantity(ctx, 1, 4, options);
|
||||||
|
|
||||||
await app.models.Sale.update({id: 1}, {quantity: 5});
|
const modifiedLine = await models.Sale.findOne({where: {id: 1}, fields: ['quantity']}, options);
|
||||||
|
|
||||||
let resetLineDataValues = await app.models.Sale.findOne({where: {id: 1}, fields: ['quantity']});
|
expect(modifiedLine.quantity).toEqual(4);
|
||||||
|
|
||||||
expect(resetLineDataValues.quantity).toEqual(5);
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,15 +24,35 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.updateConcept = async(ctx, id, newConcept) => {
|
Self.updateConcept = async(ctx, id, newConcept, options) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const currentLine = await models.Sale.findById(id);
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
const canEditSale = await models.Sale.canEdit(ctx, [id]);
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
if (!canEditSale)
|
if (!myOptions.transaction) {
|
||||||
throw new UserError(`Sale(s) blocked, please contact production`);
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
return await currentLine.updateAttributes({concept: newConcept});
|
try {
|
||||||
|
const currentLine = await models.Sale.findById(id, null, myOptions);
|
||||||
|
|
||||||
|
const canEditSale = await models.Sale.canEdit(ctx, [id], myOptions);
|
||||||
|
|
||||||
|
if (!canEditSale)
|
||||||
|
throw new UserError(`Sale(s) blocked, please contact production`);
|
||||||
|
|
||||||
|
const line = await currentLine.updateAttributes({concept: newConcept}, myOptions);
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return line;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,14 +28,21 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.updatePrice = async(ctx, id, newPrice) => {
|
Self.updatePrice = async(ctx, id, newPrice, options) => {
|
||||||
const $t = ctx.req.__; // $translate
|
const $t = ctx.req.__; // $translate
|
||||||
const models = Self.app.models;
|
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 {
|
try {
|
||||||
const options = {transaction: tx};
|
|
||||||
|
|
||||||
const filter = {
|
const filter = {
|
||||||
include: {
|
include: {
|
||||||
relation: 'ticket',
|
relation: 'ticket',
|
||||||
|
@ -57,22 +64,22 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sale = await models.Sale.findById(id, filter, options);
|
const sale = await models.Sale.findById(id, filter, myOptions);
|
||||||
|
|
||||||
const isEditable = await models.Ticket.isEditable(ctx, sale.ticketFk);
|
const isEditable = await models.Ticket.isEditable(ctx, sale.ticketFk, 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 canEditSale = await models.Sale.canEdit(ctx, [id]);
|
const canEditSale = await models.Sale.canEdit(ctx, [id], myOptions);
|
||||||
|
|
||||||
if (!canEditSale)
|
if (!canEditSale)
|
||||||
throw new UserError(`Sale(s) blocked, please contact production`);
|
throw new UserError(`Sale(s) blocked, please contact production`);
|
||||||
|
|
||||||
const oldPrice = sale.price;
|
const oldPrice = sale.price;
|
||||||
const userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
const usesMana = await models.WorkerMana.findOne({where: {workerFk: userId}, fields: 'amount'}, options);
|
const usesMana = await models.WorkerMana.findOne({where: {workerFk: userId}, fields: 'amount'}, myOptions);
|
||||||
const componentCode = usesMana ? 'mana' : 'buyerDiscount';
|
const componentCode = usesMana ? 'mana' : 'buyerDiscount';
|
||||||
const discount = await models.Component.findOne({where: {code: componentCode}}, options);
|
const discount = await models.Component.findOne({where: {code: componentCode}}, myOptions);
|
||||||
const componentId = discount.id;
|
const componentId = discount.id;
|
||||||
const componentValue = newPrice - sale.price;
|
const componentValue = newPrice - sale.price;
|
||||||
|
|
||||||
|
@ -80,23 +87,23 @@ module.exports = Self => {
|
||||||
componentFk: componentId,
|
componentFk: componentId,
|
||||||
saleFk: id
|
saleFk: id
|
||||||
};
|
};
|
||||||
const saleComponent = await models.SaleComponent.findOne({where}, options);
|
const saleComponent = await models.SaleComponent.findOne({where}, myOptions);
|
||||||
|
|
||||||
if (saleComponent) {
|
if (saleComponent) {
|
||||||
await models.SaleComponent.updateAll(where, {
|
await models.SaleComponent.updateAll(where, {
|
||||||
value: saleComponent.value + componentValue
|
value: saleComponent.value + componentValue
|
||||||
}, options);
|
}, myOptions);
|
||||||
} else {
|
} else {
|
||||||
await models.SaleComponent.create({
|
await models.SaleComponent.create({
|
||||||
saleFk: id,
|
saleFk: id,
|
||||||
componentFk: componentId,
|
componentFk: componentId,
|
||||||
value: componentValue
|
value: componentValue
|
||||||
}, options);
|
}, myOptions);
|
||||||
}
|
}
|
||||||
await sale.updateAttributes({price: newPrice}, options);
|
await sale.updateAttributes({price: newPrice}, myOptions);
|
||||||
|
|
||||||
query = `CALL vn.manaSpellersRequery(?)`;
|
query = `CALL vn.manaSpellersRequery(?)`;
|
||||||
await Self.rawSql(query, [userId], options);
|
await Self.rawSql(query, [userId], myOptions);
|
||||||
|
|
||||||
const salesPerson = sale.ticket().client().salesPersonUser();
|
const salesPerson = sale.ticket().client().salesPersonUser();
|
||||||
if (salesPerson) {
|
if (salesPerson) {
|
||||||
|
@ -111,14 +118,14 @@ module.exports = Self => {
|
||||||
ticketUrl: `${origin}/#!/ticket/${sale.ticket().id}/sale`,
|
ticketUrl: `${origin}/#!/ticket/${sale.ticket().id}/sale`,
|
||||||
itemUrl: `${origin}/#!/item/${sale.itemFk}/summary`
|
itemUrl: `${origin}/#!/item/${sale.itemFk}/summary`
|
||||||
});
|
});
|
||||||
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
|
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
await tx.commit();
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
return sale;
|
return sale;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await tx.rollback();
|
if (tx) await tx.rollback();
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,60 +26,77 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.updateQuantity = async(ctx, id, newQuantity) => {
|
Self.updateQuantity = async(ctx, id, newQuantity, options) => {
|
||||||
const $t = ctx.req.__; // $translate
|
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
const $t = ctx.req.__; // $translate
|
||||||
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
const canEditSale = await models.Sale.canEdit(ctx, [id]);
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
if (!canEditSale)
|
if (!myOptions.transaction) {
|
||||||
throw new UserError(`Sale(s) blocked, please contact production`);
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
if (isNaN(newQuantity))
|
try {
|
||||||
throw new UserError(`The value should be a number`);
|
const canEditSale = await models.Sale.canEdit(ctx, [id], myOptions);
|
||||||
|
|
||||||
const filter = {
|
if (!canEditSale)
|
||||||
include: {
|
throw new UserError(`Sale(s) blocked, please contact production`);
|
||||||
relation: 'ticket',
|
|
||||||
scope: {
|
if (isNaN(newQuantity))
|
||||||
include: {
|
throw new UserError(`The value should be a number`);
|
||||||
relation: 'client',
|
|
||||||
scope: {
|
const filter = {
|
||||||
include: {
|
include: {
|
||||||
relation: 'salesPersonUser',
|
relation: 'ticket',
|
||||||
scope: {
|
scope: {
|
||||||
fields: ['id', 'name']
|
include: {
|
||||||
|
relation: 'client',
|
||||||
|
scope: {
|
||||||
|
include: {
|
||||||
|
relation: 'salesPersonUser',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const sale = await models.Sale.findById(id, filter, myOptions);
|
||||||
|
|
||||||
|
if (newQuantity > sale.quantity)
|
||||||
|
throw new UserError('The new quantity should be smaller than the old one');
|
||||||
|
|
||||||
|
const oldQuantity = sale.quantity;
|
||||||
|
const result = await sale.updateAttributes({quantity: newQuantity}, myOptions);
|
||||||
|
|
||||||
|
const salesPerson = sale.ticket().client().salesPersonUser();
|
||||||
|
if (salesPerson) {
|
||||||
|
const origin = ctx.req.headers.origin;
|
||||||
|
const message = $t('Changed sale quantity', {
|
||||||
|
ticketId: sale.ticket().id,
|
||||||
|
itemId: sale.itemFk,
|
||||||
|
concept: sale.concept,
|
||||||
|
oldQuantity: oldQuantity,
|
||||||
|
newQuantity: newQuantity,
|
||||||
|
ticketUrl: `${origin}/#!/ticket/${sale.ticket().id}/sale`,
|
||||||
|
itemUrl: `${origin}/#!/item/${sale.itemFk}/summary`
|
||||||
|
});
|
||||||
|
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const sale = await models.Sale.findById(id, filter);
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
if (newQuantity > sale.quantity)
|
return result;
|
||||||
throw new UserError('The new quantity should be smaller than the old one');
|
} catch (error) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
const oldQuantity = sale.quantity;
|
throw error;
|
||||||
const result = await sale.updateAttributes({quantity: newQuantity});
|
|
||||||
|
|
||||||
const salesPerson = sale.ticket().client().salesPersonUser();
|
|
||||||
if (salesPerson) {
|
|
||||||
const origin = ctx.req.headers.origin;
|
|
||||||
const message = $t('Changed sale quantity', {
|
|
||||||
ticketId: sale.ticket().id,
|
|
||||||
itemId: sale.itemFk,
|
|
||||||
concept: sale.concept,
|
|
||||||
oldQuantity: oldQuantity,
|
|
||||||
newQuantity: newQuantity,
|
|
||||||
ticketUrl: `${origin}/#!/ticket/${sale.ticket().id}/sale`,
|
|
||||||
itemUrl: `${origin}/#!/item/${sale.itemFk}/summary`
|
|
||||||
});
|
|
||||||
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue