add sale and canbeInvoice refactor + tests
This commit is contained in:
parent
4628c8ab6f
commit
870314277f
|
@ -32,64 +32,81 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.addSale = async(ctx, id, itemId, quantity) => {
|
||||
Self.addSale = async(ctx, id, itemId, quantity, options) => {
|
||||
const $t = ctx.req.__; // $translate
|
||||
const models = Self.app.models;
|
||||
let tx;
|
||||
const myOptions = {};
|
||||
|
||||
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);
|
||||
|
||||
const item = await models.Item.findById(itemId);
|
||||
const ticket = await models.Ticket.findById(id, {
|
||||
include: {
|
||||
relation: 'client',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'salesPersonUser',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
try {
|
||||
const isEditable = await models.Ticket.isEditable(ctx, id, myOptions);
|
||||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
const item = await models.Item.findById(itemId, null, myOptions);
|
||||
const ticket = await models.Ticket.findById(id, {
|
||||
include: {
|
||||
relation: 'client',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'salesPersonUser',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, myOptions);
|
||||
|
||||
const itemInfo = await models.Item.getVisibleAvailable(itemId, ticket.warehouseFk, ticket.shipped, myOptions);
|
||||
|
||||
const isPackaging = item.family == 'EMB';
|
||||
if (!isPackaging && itemInfo.available < quantity)
|
||||
throw new UserError(`This item is not available`);
|
||||
|
||||
const newSale = await models.Sale.create({
|
||||
ticketFk: id,
|
||||
itemFk: item.id,
|
||||
concept: item.name,
|
||||
quantity: quantity
|
||||
}, myOptions);
|
||||
|
||||
await Self.rawSql('CALL vn.sale_calculateComponent(?, NULL)', [newSale.id], myOptions);
|
||||
|
||||
const sale = await models.Sale.findById(newSale.id, {
|
||||
include: {
|
||||
relation: 'item'
|
||||
}
|
||||
}, myOptions);
|
||||
|
||||
const addition = `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity})`;
|
||||
|
||||
const salesPerson = ticket.client().salesPersonUser();
|
||||
if (salesPerson) {
|
||||
const origin = ctx.req.headers.origin;
|
||||
|
||||
const message = $t('Added sale to ticket', {
|
||||
ticketId: id,
|
||||
ticketUrl: `${origin}/#!/ticket/${id}/sale`,
|
||||
addition: addition
|
||||
});
|
||||
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
|
||||
}
|
||||
});
|
||||
|
||||
const res = await models.Item.getVisibleAvailable(itemId, ticket.warehouseFk, ticket.shipped);
|
||||
if (tx) await tx.commit();
|
||||
|
||||
const isPackaging = item.family == 'EMB';
|
||||
if (!isPackaging && res.available < quantity)
|
||||
throw new UserError(`This item is not available`);
|
||||
|
||||
const newSale = await models.Sale.create({
|
||||
ticketFk: id,
|
||||
itemFk: item.id,
|
||||
concept: item.name,
|
||||
quantity: quantity
|
||||
});
|
||||
|
||||
await Self.rawSql('CALL vn.sale_calculateComponent(?, NULL)', [newSale.id]);
|
||||
|
||||
const sale = await models.Sale.findById(newSale.id, {
|
||||
include: {
|
||||
relation: 'item'
|
||||
}
|
||||
});
|
||||
|
||||
const addition = `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity})`;
|
||||
|
||||
const salesPerson = ticket.client().salesPersonUser();
|
||||
if (salesPerson) {
|
||||
const origin = ctx.req.headers.origin;
|
||||
|
||||
const message = $t('Added sale to ticket', {
|
||||
ticketId: id,
|
||||
ticketUrl: `${origin}/#!/ticket/${id}/sale`,
|
||||
addition: addition
|
||||
});
|
||||
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
|
||||
return sale;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
|
||||
return sale;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -2,69 +2,87 @@ const app = require('vn-loopback/server/server');
|
|||
|
||||
describe('ticket addSale()', () => {
|
||||
const ticketId = 13;
|
||||
let newSale;
|
||||
|
||||
afterAll(async done => {
|
||||
const sale = await app.models.Sale.findById(newSale.id);
|
||||
await sale.destroy();
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should create a new sale for the ticket with id 13', async() => {
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const itemId = 4;
|
||||
const quantity = 10;
|
||||
newSale = await app.models.Ticket.addSale(ctx, ticketId, itemId, quantity);
|
||||
const tx = await app.models.Ticket.beginTransaction({});
|
||||
|
||||
expect(newSale.itemFk).toEqual(4);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const itemId = 4;
|
||||
const quantity = 10;
|
||||
const newSale = await app.models.Ticket.addSale(ctx, ticketId, itemId, quantity, options);
|
||||
|
||||
expect(newSale.itemFk).toEqual(4);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should not be able to add a sale if the item quantity is not available', async() => {
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const itemId = 11;
|
||||
const quantity = 10;
|
||||
const tx = await app.models.Ticket.beginTransaction({});
|
||||
|
||||
let error;
|
||||
await app.models.Ticket.addSale(ctx, ticketId, itemId, quantity).catch(e => {
|
||||
error = e;
|
||||
}).finally(() => {
|
||||
expect(error.message).toEqual(`This item is not available`);
|
||||
});
|
||||
|
||||
expect(error).toBeDefined();
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const itemId = 11;
|
||||
const quantity = 10;
|
||||
|
||||
await app.models.Ticket.addSale(ctx, ticketId, itemId, quantity, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(`This item is not available`);
|
||||
});
|
||||
|
||||
it('should not be able to add a sale if the ticket is not editable', async() => {
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const notEditableTicketId = 1;
|
||||
const itemId = 4;
|
||||
const quantity = 10;
|
||||
let error;
|
||||
await app.models.Ticket.addSale(ctx, notEditableTicketId, itemId, quantity).catch(e => {
|
||||
error = e;
|
||||
}).finally(() => {
|
||||
expect(error.message).toEqual(`The sales of this ticket can't be modified`);
|
||||
});
|
||||
const tx = await app.models.Ticket.beginTransaction({});
|
||||
|
||||
expect(error).toBeDefined();
|
||||
let error;
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const ctx = {
|
||||
req: {
|
||||
accessToken: {userId: 9},
|
||||
headers: {origin: 'localhost:5000'},
|
||||
__: () => {}
|
||||
}
|
||||
};
|
||||
const notEditableTicketId = 1;
|
||||
const itemId = 4;
|
||||
const quantity = 10;
|
||||
await app.models.Ticket.addSale(ctx, notEditableTicketId, itemId, quantity, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(`The sales of this ticket can't be modified`);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,7 +24,7 @@ describe('ticket canBeInvoiced()', () => {
|
|||
const options = {transaction: tx};
|
||||
|
||||
const ticket = await models.Ticket.findById(ticketId, null, options);
|
||||
await ticket.updateAttribute('refFk', 'T1234567', options);
|
||||
await ticket.updateAttribute('refFk', 'T1111111', options);
|
||||
|
||||
const canBeInvoiced = await models.Ticket.canBeInvoiced([ticketId], options);
|
||||
|
||||
|
@ -33,6 +33,7 @@ describe('ticket canBeInvoiced()', () => {
|
|||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -52,6 +53,7 @@ describe('ticket canBeInvoiced()', () => {
|
|||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -75,6 +77,7 @@ describe('ticket canBeInvoiced()', () => {
|
|||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue