clone invoiceIn from descriptor
This commit is contained in:
parent
6143992238
commit
abbce74100
|
@ -6,6 +6,9 @@
|
|||
"table": "sage.TiposRetencion"
|
||||
}
|
||||
},
|
||||
"log": {
|
||||
"showField": "withholding"
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "Number",
|
||||
|
|
|
@ -2339,6 +2339,14 @@ INSERT INTO `vn`.`duaInvoiceIn`(`id`, `duaFk`, `invoiceInFk`)
|
|||
(9, 9, 9),
|
||||
(10, 10, 10);
|
||||
|
||||
INSERT INTO `vn`.`invoiceInTax` (`invoiceInFk`, `taxCodeFk`, `taxableBase`, `expenceFk`, `foreignValue`, `taxTypeSageFk`, `transactionTypeSageFk`, `created`)
|
||||
VALUES
|
||||
(1, 4, 99.99, '2000000000', null, null, null, CURDATE()),
|
||||
(2, 4, 999.99, '2000000000', null, null, null, CURDATE()),
|
||||
(3, 4, 1000.50, '2000000000', null, null, null, CURDATE()),
|
||||
(4, 4, 0.50, '2000000000', null, null, null, CURDATE()),
|
||||
(5, 4, 150.50, '2000000000', null, null, null, CURDATE());
|
||||
|
||||
INSERT INTO `vn`.`ticketRecalc`(`ticketFk`)
|
||||
SELECT `id`
|
||||
FROM `vn`.`ticket` t
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
|
||||
const loggable = require('vn-loopback/util/log');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('clone', {
|
||||
description: 'Clone the invoiceIn and as many invoiceInTax and invoiceInDueDay referencing it',
|
||||
accessType: 'WRITE',
|
||||
accepts: {
|
||||
arg: 'id',
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'The invoiceIn id',
|
||||
http: {source: 'path'}
|
||||
},
|
||||
returns: {
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: '/:id/clone',
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.clone = async(ctx, id, options) => {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
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',
|
||||
]
|
||||
}, myOptions);
|
||||
const sourceInvoiceInTax = await models.InvoiceInTax.find({where: {invoiceInFk: id}}, myOptions);
|
||||
const sourceInvoiceInDueDay = await models.InvoiceInDueDay.find({where: {invoiceInFk: id}}, myOptions);
|
||||
|
||||
const issued = new Date(sourceInvoiceIn.issued);
|
||||
issued.setMonth(issued.getMonth() + 1);
|
||||
|
||||
const clone = await models.InvoiceIn.create({
|
||||
serial: sourceInvoiceIn.serial,
|
||||
supplierRef: sourceInvoiceIn.supplierRef,
|
||||
supplierFk: sourceInvoiceIn.supplierFk,
|
||||
issued: issued,
|
||||
currencyFk: sourceInvoiceIn.currencyFk,
|
||||
companyFk: sourceInvoiceIn.companyFk,
|
||||
isVatDeductible: sourceInvoiceIn.isVatDeductible,
|
||||
withholdingSageFk: sourceInvoiceIn.withholdingSageFk,
|
||||
deductibleExpenseFk: sourceInvoiceIn.deductibleExpenseFk,
|
||||
}, myOptions);
|
||||
|
||||
const oldProperties = await loggable.translateValues(Self, sourceInvoiceIn);
|
||||
const newProperties = await loggable.translateValues(Self, clone);
|
||||
await models.InvoiceInLog.create({
|
||||
originFk: clone.id,
|
||||
userFk: userId,
|
||||
action: 'insert',
|
||||
changedModel: 'InvoiceIn',
|
||||
changedModelId: clone.id,
|
||||
oldInstance: oldProperties,
|
||||
newInstance: newProperties
|
||||
}, myOptions);
|
||||
|
||||
const promises = [];
|
||||
|
||||
for (let tax of sourceInvoiceInTax) {
|
||||
promises.push(models.InvoiceInTax.create({
|
||||
invoiceInFk: clone.id,
|
||||
taxableBase: tax.taxableBase,
|
||||
expenceFk: tax.expenceFk,
|
||||
foreignValue: tax.foreignValue,
|
||||
taxTypeSageFk: tax.taxTypeSageFk,
|
||||
transactionTypeSageFk: tax.transactionTypeSageFk
|
||||
}, myOptions));
|
||||
}
|
||||
|
||||
for (let dueDay of sourceInvoiceInDueDay) {
|
||||
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));
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return clone;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('invoiceIn clone()', () => {
|
||||
it('should return the cloned invoiceIn and also clone invoiceInDueDays and invoiceInTaxes if there are any referencing the invoiceIn', async() => {
|
||||
const userId = 1;
|
||||
const ctx = {
|
||||
req: {
|
||||
|
||||
accessToken: {userId: userId},
|
||||
headers: {origin: 'http://localhost:5000'},
|
||||
}
|
||||
};
|
||||
|
||||
const tx = await models.InvoiceIn.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
|
||||
try {
|
||||
const clone = await models.InvoiceIn.clone(ctx, 1, options);
|
||||
|
||||
expect(clone.supplierRef).toEqual('1234');
|
||||
|
||||
const invoiceInTaxes = await models.InvoiceInTax.find({where: {invoiceInFk: clone.id}}, options);
|
||||
|
||||
expect(invoiceInTaxes.length).toEqual(1);
|
||||
|
||||
const invoiceInDueDays = await models.InvoiceInDueDay.find({where: {invoiceInFk: clone.id}}, options);
|
||||
|
||||
expect(invoiceInDueDays.length).toEqual(2);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
|
@ -2,6 +2,9 @@
|
|||
"InvoiceIn": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"InvoiceInTax": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"InvoiceInDueDay": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
"amount": {
|
||||
"type": "number"
|
||||
},
|
||||
"foreignValue": {
|
||||
"type": "number"
|
||||
},
|
||||
"created": {
|
||||
"type": "date"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"name": "InvoiceInTax",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "invoiceInTax"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "number",
|
||||
"description": "Identifier"
|
||||
},
|
||||
"invoiceInFk": {
|
||||
"type": "number"
|
||||
},
|
||||
"taxCodeFk": {
|
||||
"type": "number"
|
||||
},
|
||||
"taxableBase": {
|
||||
"type": "number"
|
||||
},
|
||||
"expenceFk": {
|
||||
"type": "string"
|
||||
},
|
||||
"foreignValue": {
|
||||
"type": "number"
|
||||
},
|
||||
"taxTypeSageFk": {
|
||||
"type": "number"
|
||||
},
|
||||
"transactionTypeSageFk": {
|
||||
"type": "number"
|
||||
},
|
||||
"created": {
|
||||
"type": "date"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
module.exports = Self => {
|
||||
require('../methods/invoice-in/filter')(Self);
|
||||
require('../methods/invoice-in/summary')(Self);
|
||||
require('../methods/invoice-in/clone')(Self);
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "Number",
|
||||
"type": "number",
|
||||
"description": "Identifier"
|
||||
},
|
||||
"serialNumber": {
|
||||
|
@ -36,6 +36,9 @@
|
|||
"booked": {
|
||||
"type": "date"
|
||||
},
|
||||
"isVatDeductible": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"operated": {
|
||||
"type": "date"
|
||||
},
|
||||
|
|
|
@ -8,6 +8,13 @@
|
|||
translate>
|
||||
Delete Invoice
|
||||
</vn-item>
|
||||
<vn-item
|
||||
ng-click="cloneConfirmation.show()"
|
||||
vn-acl="invoicing"
|
||||
name="cloneInvoice"
|
||||
translate>
|
||||
Clone Invoice
|
||||
</vn-item>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
|
@ -42,8 +49,16 @@
|
|||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-confirm vn-id="deleteConfirmation" on-accept="$ctrl.deleteInvoiceIn()"
|
||||
<vn-confirm
|
||||
vn-id="deleteConfirmation"
|
||||
on-accept="$ctrl.deleteInvoiceIn()"
|
||||
question="Are you sure you want to delete this invoice?">
|
||||
</vn-confirm>
|
||||
<vn-supplier-descriptor-popover vn-id="supplierDescriptor">
|
||||
<vn-confirm
|
||||
vn-id="cloneConfirmation"
|
||||
on-accept="$ctrl.cloneInvoiceIn()"
|
||||
question="Are you sure you want to clone this invoice?">
|
||||
</vn-confirm>
|
||||
<vn-supplier-descriptor-popover
|
||||
vn-id="supplierDescriptor">
|
||||
</vn-supplier-descriptor-popover>
|
||||
|
|
|
@ -30,6 +30,12 @@ class Controller extends Descriptor {
|
|||
.then(() => this.vnApp.showSuccess(this.$t('InvoiceIn deleted')));
|
||||
}
|
||||
|
||||
cloneInvoiceIn() {
|
||||
return this.$http.post(`InvoiceIns/${this.id}/clone`)
|
||||
.then(res => this.$state.go('invoiceIn.card.summary', {id: res.data.id}))
|
||||
.then(() => this.vnApp.showSuccess(this.$t('InvoiceIn cloned')));
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
include: [
|
||||
|
|
|
@ -2,4 +2,5 @@ InvoiceIn: Facturas recibidas
|
|||
Search invoices in by reference: Buscar facturas recibidas por referencia
|
||||
Entries list: Listado de entradas
|
||||
Invoice list: Listado de facturas recibidas
|
||||
InvoiceIn deleted: Factura eliminada
|
||||
InvoiceIn deleted: Factura eliminada
|
||||
InvoiceIn cloned: Factura clonada
|
|
@ -5,8 +5,10 @@ Invoice ticket list: Listado de tickets de la factura
|
|||
Show invoice PDF: Ver factura en PDF
|
||||
Send invoice PDF: Enviar factura en PDF
|
||||
Delete Invoice: Eliminar factura
|
||||
Clone Invoice: Clonar factura
|
||||
InvoiceOut deleted: Factura eliminada
|
||||
Are you sure you want to delete this invoice?: Estas seguro de eliminar esta factura?
|
||||
Are you sure you want to clone this invoice?: Estas seguro de clonar esta factura?
|
||||
Book invoice: Asentar factura
|
||||
InvoiceOut booked: Factura asentada
|
||||
Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura?
|
||||
|
|
Loading…
Reference in New Issue