module.exports = Self => { Self.remoteMethodCtx('clone', { description: 'Clone the invoiceIn and as many invoiceInTax and invoiceInDueDay referencing it', accessType: 'WRITE', accepts: [{ arg: 'id', type: 'number', required: true, description: 'The invoiceIn id', http: {source: 'path'} }, { arg: 'isRectification', type: 'boolean', description: 'Clone quantities in negative and clone Intrastat' }], returns: { type: 'object', root: true }, http: { path: '/:id/clone', verb: 'POST' } }); Self.clone = async(ctx, id, isRectification, options) => { const models = Self.app.models; let tx; const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); if (!myOptions.transaction) { tx = await Self.beginTransaction({}); myOptions.transaction = tx; } try { const sourceInvoiceIn = await Self.findById(id, { fields: [ 'id', 'serial', 'supplierRef', 'supplierFk', 'issued', 'currencyFk', 'companyFk', 'isVatDeductible', 'withholdingSageFk', 'deductibleExpenseFk', ], include: [ { relation: 'invoiceInTax', }, { relation: 'invoiceInDueDay', }, { relation: 'invoiceInIntrastat' } ], }, myOptions); const invoiceInTax = sourceInvoiceIn.invoiceInTax(); const invoiceInDueDay = sourceInvoiceIn.invoiceInDueDay(); const invoiceInIntrastat = sourceInvoiceIn.invoiceInIntrastat(); const issued = new Date(sourceInvoiceIn.issued); issued.setMonth(issued.getMonth() + 1); const totalCorrections = await models.InvoiceInCorrection.count({correctedFk: id}, myOptions); const clonedRef = sourceInvoiceIn.supplierRef + `(${totalCorrections + 2})`; const clone = await models.InvoiceIn.create({ serial: sourceInvoiceIn.serial, supplierRef: clonedRef, supplierFk: sourceInvoiceIn.supplierFk, issued: issued, currencyFk: sourceInvoiceIn.currencyFk, companyFk: sourceInvoiceIn.companyFk, isVatDeductible: sourceInvoiceIn.isVatDeductible, withholdingSageFk: sourceInvoiceIn.withholdingSageFk, deductibleExpenseFk: sourceInvoiceIn.deductibleExpenseFk, }, myOptions); const promises = []; for (let tax of invoiceInTax) { promises.push(models.InvoiceInTax.create({ invoiceInFk: clone.id, taxableBase: isRectification ? -tax.taxableBase : tax.taxableBase, expenseFk: tax.expenseFk, foreignValue: isRectification ? -tax.foreignValue : tax.foreignValue, taxTypeSageFk: tax.taxTypeSageFk, transactionTypeSageFk: tax.transactionTypeSageFk }, myOptions)); } if (!isRectification) { for (let dueDay of invoiceInDueDay) { const dueDated = dueDay.dueDated; dueDated.setMonth(dueDated.getMonth() + 1); promises.push(models.InvoiceInDueDay.create({ invoiceInFk: clone.id, dueDated: dueDated, bankFk: dueDay.bankFk, amount: dueDay.amount, foreignValue: dueDated.foreignValue, }, myOptions)); } } else { for (let intrastat of invoiceInIntrastat) { promises.push(models.InvoiceInIntrastat.create({ invoiceInFk: clone.id, net: -intrastat.net, intrastatFk: intrastat.intrastatFk, amount: -intrastat.amount, stems: -intrastat.stems, country: intrastat.countryFk, dated: Date.vnNew(), statisticalValue: intrastat.statisticalValue }, myOptions)); } } await Promise.all(promises); if (tx) await tx.commit(); return clone; } catch (e) { if (tx) await tx.rollback(); throw e; } }; };