salix/modules/ticket/back/methods/ticket/invoiceTickets.js

102 lines
3.2 KiB
JavaScript

const UserError = require('vn-loopback/util/user-error');
module.exports = function(Self) {
Self.remoteMethodCtx('invoiceTickets', {
description: 'Make out an invoice from one or more tickets',
accessType: 'WRITE',
accepts: [
{
arg: 'ticketsIds',
description: 'The tickets id',
type: ['number'],
required: true
},
{
arg: 'invoiceCorrection',
description: 'The invoice correction',
type: 'object',
}
],
returns: {
type: ['object'],
root: true
},
http: {
path: `/invoiceTickets`,
verb: 'POST'
}
});
Self.invoiceTickets = async(ctx, ticketsIds, invoiceCorrection, options) => {
const models = Self.app.models;
const date = Date.vnNew();
date.setHours(0, 0, 0, 0);
const myOptions = {userId: ctx.req.accessToken.userId};
let tx;
if (typeof options === 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
let invoicesIds = [];
try {
const tickets = await models.Ticket.find({
fields: ['id', 'clientFk', 'companyFk', 'addressFk'],
where: {
id: {inq: ticketsIds}
}
}, myOptions);
const [firstTicket] = tickets;
const clientId = firstTicket.clientFk;
const companyId = firstTicket.companyFk;
const isSameClient = tickets.every(ticket => ticket.clientFk === clientId);
if (!isSameClient)
throw new UserError(`You can't invoice tickets from multiple clients`);
const {hasToInvoiceByAddress} = await models.Client.findById(clientId, {
fields: ['hasToInvoiceByAddress']
}, myOptions);
let ticketsByAddress = hasToInvoiceByAddress
? Object.values(tickets.reduce((group, {id, addressFk}) => {
group[addressFk] = group[addressFk] ?? [];
group[addressFk].push(id);
return group;
}, {}))
: [ticketsIds];
for (const ticketIds of ticketsByAddress)
invoicesIds.push(await createInvoice(ctx, companyId, ticketIds, invoiceCorrection, myOptions));
tx && await tx.commit();
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
return invoicesIds;
};
async function createInvoice(ctx, companyId, ticketsIds, invoiceCorrection, myOptions) {
const models = Self.app.models;
await models.Ticket.rawSql(`
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketToInvoice
(PRIMARY KEY (id))
ENGINE = MEMORY
SELECT id
FROM vn.ticket
WHERE id IN (?)
`, [ticketsIds], myOptions);
return models.Ticket.makeInvoice(ctx, 'quick', companyId, Date.vnNew(), invoiceCorrection, myOptions);
}
};