diff --git a/modules/ticket/back/methods/ticket/addSale.js b/modules/ticket/back/methods/ticket/addSale.js index dc45e5de9..0956e8772 100644 --- a/modules/ticket/back/methods/ticket/addSale.js +++ b/modules/ticket/back/methods/ticket/addSale.js @@ -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; }; }; diff --git a/modules/ticket/back/methods/ticket/specs/addSale.spec.js b/modules/ticket/back/methods/ticket/specs/addSale.spec.js index 9f6da7ed2..2df19b675 100644 --- a/modules/ticket/back/methods/ticket/specs/addSale.spec.js +++ b/modules/ticket/back/methods/ticket/specs/addSale.spec.js @@ -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`); }); }); diff --git a/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js b/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js index 77da98b26..0420c9697 100644 --- a/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js +++ b/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js @@ -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; } });