#7936 fineTunningInvoiceIn #3251
|
@ -4038,6 +4038,11 @@ INSERT IGNORE INTO vn.saySimpleConfig (url, defaultChannel)
|
|||
INSERT INTO vn.workerIrpf (workerFk,spouseNif, geographicMobilityDate)
|
||||
VALUES (1106,'26493101E','2019-09-20');
|
||||
|
||||
INSERT INTO vn.referenceRate (currencyFk, dated, value)
|
||||
VALUES (2, '2000-12-01', 1.0495),
|
||||
(2, '2001-01-01', 1.0531),
|
||||
(2, '2001-02-01', 7.6347);
|
||||
|
||||
INSERT IGNORE INTO vn.osrmConfig (id,url,tolerance)
|
||||
VALUES (1,'https://router.project-osrm.org', 0.002);
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ BEGIN
|
|||
/**
|
||||
* Traslada la info de contabilidad relacionada con las facturas recibidas
|
||||
*
|
||||
* @vInvoiceInFk Factura recibida
|
||||
* @vXDiarioFk Id tabla XDiario
|
||||
* @param vInvoiceInFk Factura recibida
|
||||
* @param vXDiarioFk Id tabla XDiario
|
||||
*/
|
||||
DECLARE vInvoiceInOriginalFk INT;
|
||||
DECLARE vInvoiceInOriginalFk INT;
|
||||
DECLARE vDone BOOL DEFAULT FALSE;
|
||||
DECLARE vBase DOUBLE;
|
||||
DECLARE vVat DOUBLE;
|
||||
|
@ -205,9 +205,9 @@ BEGIN
|
|||
WHERE correctingFk = vInvoiceInFk;
|
||||
|
||||
IF vInvoiceInOriginalFk THEN
|
||||
|
||||
UPDATE movContaIVA mci
|
||||
JOIN vn.invoiceInRefund iir ON iir.invoiceInRefundFk = vInvoiceInFk
|
||||
JOIN vn.invoiceInCorrection iic ON iic.correctingFk = vInvoiceInFk
|
||||
JOIN vn.siiTypeInvoiceIn st ON st.id = iic.siiTypeInvoiceInFk
|
||||
JOIN (SELECT issued,
|
||||
SUM(sub.taxableBase) taxableBase,
|
||||
SUM(ROUND((sub.taxableBase * sub.PorcentajeIva) / 100 , 2)) vat
|
||||
|
@ -216,7 +216,7 @@ BEGIN
|
|||
ti.PorcentajeIva
|
||||
FROM vn.invoiceIn i
|
||||
JOIN vn.invoiceInTax iit ON iit.invoiceInFk = i.id
|
||||
JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk
|
||||
JOIN TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk
|
||||
WHERE i.id = vInvoiceInOriginalFk
|
||||
GROUP BY ti.CodigoIva)sub
|
||||
)invoiceInOriginal
|
||||
|
@ -229,7 +229,6 @@ BEGIN
|
|||
mci.CuotaIvaOriginal = invoiceInOriginal.vat,
|
||||
mci.ClaveOperacionFactura = co.ClaveOperacionFactura_
|
||||
WHERE mci.id = vXDiarioFk;
|
||||
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -169,6 +169,7 @@ BEGIN
|
|||
UPDATE movContaIVA mci
|
||||
JOIN vn.invoiceOut i ON i.id = vInvoiceOutCorrectedFk
|
||||
JOIN vn.invoiceCorrection ic ON ic.correctedFk = vInvoiceOutCorrectedFk
|
||||
JOIN vn.siiTypeInvoiceOut st ON st.id = ic.siiTypeInvoiceOutFk
|
||||
JOIN (SELECT SUM(IF(IFNULL(e.vatFk, TRUE), iot.taxableBase, 0)) taxableBase,
|
||||
SUM(IF(IFNULL(e.vatFk, TRUE), iot.vat, 0)) vat,
|
||||
SUM(IF(IFNULL(e.vatFk, TRUE), 0, iot.vat)) equ
|
||||
|
@ -177,8 +178,8 @@ BEGIN
|
|||
WHERE iot.invoiceOutFk = vInvoiceOutCorrectedFk
|
||||
) tax
|
||||
JOIN ClavesOperacion co ON co.Descripcion = 'Factura rectificativa'
|
||||
SET mci.TipoRectificativa = 2,
|
||||
mci.ClaseAbonoRectificativas = 1,
|
||||
SET mci.TipoRectificativa = ic.cplusRectificationTypeFk,
|
||||
mci.ClaseAbonoRectificativas = REGEXP_REPLACE(st.`code`, '[^0-9]', ''),
|
||||
mci.FechaFacturaOriginal = i.issued,
|
||||
mci.FechaOperacion = i.issued,
|
||||
mci.BaseImponibleOriginal = tax.taxableBase,
|
||||
|
|
|
@ -43,7 +43,7 @@ BEGIN
|
|||
ii.cplusTaxBreakFk,
|
||||
ii.cplusSubjectOpFk,
|
||||
ii.siiTypeInvoiceInFk,
|
||||
ii.cplusRectificationTypeFk,
|
||||
ic.cplusRectificationTypeFk,
|
||||
ii.booked,
|
||||
IFNULL(a.isUeeMember, c.isUeeMember) isUeeMember,
|
||||
(c.id = cc.id) isSameCountry,
|
||||
|
@ -66,6 +66,7 @@ BEGIN
|
|||
e.name expenseName
|
||||
FROM invoiceIn ii
|
||||
JOIN supplier s ON s.id = ii.supplierFk
|
||||
LEFT JOIN invoiceInCorrection ic ON ic.correctingFk = ii.id
|
||||
LEFT JOIN province p ON p.id = s.provinceFk
|
||||
LEFT JOIN autonomy a ON a.id = p.autonomyFk
|
||||
JOIN country c ON c.id = s.countryFk
|
||||
|
|
|
@ -3,24 +3,30 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`invoiceIn_afterUpdate`
|
|||
AFTER UPDATE ON `invoiceIn`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
IF NEW.issued != OLD.issued
|
||||
OR NEW.currencyFk != OLD.currencyFk THEN
|
||||
DECLARE vIsEuro BOOL;
|
||||
|
||||
SELECT `code` = 'EUR' INTO vIsEuro
|
||||
jorgep marked this conversation as resolved
Outdated
|
||||
FROM currency
|
||||
WHERE id = NEW.currencyFk;
|
||||
|
||||
IF (NOT NEW.issued <=> OLD.issued
|
||||
OR NEW.currencyFk <> OLD.currencyFk) THEN
|
||||
|
||||
UPDATE invoiceInTax iit
|
||||
JOIN invoiceIn ii ON ii.id = iit.invoiceInFk
|
||||
LEFT JOIN referenceRate rr ON rr.dated = ii.issued
|
||||
AND rr.currencyFk = ii.currencyFk
|
||||
SET iit.taxableBase = IF(iit.foreignValue IS NULL, iit.taxableBase, iit.foreignValue / rr.value)
|
||||
SET iit.taxableBase = IF(vIsEuro, iit.taxableBase, iit.foreignValue / rr.value),
|
||||
iit.foreignValue = IF(vIsEuro, NULL, iit.foreignValue)
|
||||
WHERE ii.id = NEW.id;
|
||||
|
||||
UPDATE invoiceInDueDay iidd
|
||||
JOIN invoiceIn ii ON ii.id = iidd.invoiceInFk
|
||||
LEFT JOIN referenceRate rr ON rr.dated = ii.issued
|
||||
AND rr.currencyFk = ii.currencyFk
|
||||
SET iidd.amount = IF(iidd.foreignValue IS NULL, iidd.amount, iidd.foreignValue / rr.value)
|
||||
SET iidd.amount = IF(vIsEuro, iidd.amount, iidd.foreignValue / rr.value),
|
||||
iidd.foreignValue = IF(vIsEuro, NULL, iidd.foreignValue)
|
||||
WHERE ii.id = NEW.id;
|
||||
|
||||
END IF;
|
||||
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
USE vn;
|
||||
|
||||
DROP TRIGGER IF EXISTS invoiceIn_beforeUpdate;
|
||||
|
||||
UPDATE invoiceIn
|
||||
SET cplusRectificationTypeFk = NULL
|
||||
WHERE cplusRectificationTypeFk = 1;
|
||||
|
||||
DELETE IGNORE FROM cplusRectificationType WHERE id = 1;
|
||||
|
||||
UPDATE cplusRectificationType
|
||||
SET id = 1
|
||||
WHERE id = 3;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`invoiceIn_beforeUpdate`
|
||||
jgallego
commented
porque no lo has puesto en el propio archivo invoiceIn_beforeUpdate porque no lo has puesto en el propio archivo invoiceIn_beforeUpdate
jorgep
commented
Es necesario para poder hacer los updates de arriba, si no no se puede(el contenido del trigger no cambia). Hablado con Carlos Andrés. Es necesario para poder hacer los updates de arriba, si no no se puede(el contenido del trigger no cambia). Hablado con Carlos Andrés.
|
||||
BEFORE UPDATE ON `invoiceIn`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
DECLARE vWithholdingSageFk INT;
|
||||
|
||||
IF NOT (NEW.supplierRef <=> OLD.supplierRef) AND NOT util.checkPrintableChars(NEW.supplierRef) THEN
|
||||
CALL util.throw('The invoiceIn reference contains invalid characters');
|
||||
END IF;
|
||||
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
|
||||
IF (SELECT COUNT(*) FROM invoiceIn
|
||||
WHERE supplierRef = NEW.supplierRef
|
||||
AND supplierFk = NEW.supplierFk
|
||||
AND YEAR(issued) = YEAR(NEW.issued)
|
||||
AND id <> NEW.id
|
||||
) THEN
|
||||
CALL util.throw('reference duplicated');
|
||||
END IF;
|
||||
|
||||
IF NEW.supplierFk != OLD.supplierFk THEN
|
||||
CALL supplier_checkIsActive(NEW.supplierFk);
|
||||
SELECT withholdingSageFk INTO vWithholdingSageFk
|
||||
FROM supplier
|
||||
carlosap marked this conversation as resolved
Outdated
jgallego
commented
no se pone vn. es innecesario no se pone vn. es innecesario
|
||||
WHERE id = NEW.supplierFk;
|
||||
SET NEW.withholdingSageFk = vWithholdingSageFk;
|
||||
END IF;
|
||||
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId)
|
||||
VALUES('SiiTypeInvoiceIn', 'find', 'READ', 'ALLOW', 'ROLE', 'salesPerson');
|
||||
|
||||
DROP TABLE IF EXISTS vn.invoiceInCorrection;
|
||||
|
||||
CREATE TABLE `invoiceInCorrection` (
|
||||
`correctingFk` mediumint(8) unsigned NOT NULL COMMENT 'Factura rectificativa',
|
||||
`correctedFk` mediumint(8) unsigned NOT NULL COMMENT 'Factura rectificada',
|
||||
`cplusRectificationTypeFk` int(10) unsigned NOT NULL,
|
||||
`siiTypeInvoiceInFk` int(10) unsigned NOT NULL,
|
||||
`invoiceCorrectionTypeFk` int(11) NOT NULL DEFAULT 3,
|
||||
PRIMARY KEY (`correctingFk`),
|
||||
KEY `invoiceInCorrection_correctedFk` (`correctedFk`),
|
||||
KEY `invoiceInCorrection_cplusRectificationTypeFk` (`cplusRectificationTypeFk`),
|
||||
KEY `invoiceInCorrection_siiTypeInvoiceIn` (`siiTypeInvoiceInFk`),
|
||||
KEY `invoiceInCorrection_invoiceCorrectionTypeFk` (`invoiceCorrectionTypeFk`),
|
||||
CONSTRAINT `invoiceInCorrection_correctedFk` FOREIGN KEY (`correctedFk`) REFERENCES `invoiceIn` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `invoiceInCorrection_correctingFk` FOREIGN KEY (`correctingFk`) REFERENCES `invoiceIn` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `invoiceInCorrection_cplusRectificationTypeFk` FOREIGN KEY (`cplusRectificationTypeFk`) REFERENCES `cplusRectificationType` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `invoiceInCorrection_invoiceCorrectionTypeFk` FOREIGN KEY (`invoiceCorrectionTypeFk`) REFERENCES `invoiceCorrectionType` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `invoiceInCorrection_siiTypeInvoiceIn` FOREIGN KEY (`siiTypeInvoiceInFk`) REFERENCES `siiTypeInvoiceIn` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
|
@ -44,7 +44,7 @@ module.exports = Self => {
|
|||
correctingFk: clone.id,
|
||||
correctedFk: id,
|
||||
cplusRectificationTypeFk: invoiceType,
|
||||
siiTypeInvoiceOutFk: invoiceClass,
|
||||
siiTypeInvoiceInFk: invoiceClass,
|
||||
invoiceCorrectionTypeFk: invoiceReason
|
||||
}, myOptions);
|
||||
|
||||
|
|
|
@ -91,6 +91,10 @@ module.exports = Self => {
|
|||
{
|
||||
arg: 'supplierActivityFk',
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
arg: 'companyFk',
|
||||
type: 'number',
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
|
@ -161,8 +165,8 @@ module.exports = Self => {
|
|||
: {'ii.id': {nin: correcteds.map(x => x.correctingFk)}};
|
||||
case 'correctedFk':
|
||||
return {'ii.id': {inq: correctings.map(x => x.correctingFk)}};
|
||||
case 'supplierActivityFk':
|
||||
return {'s.supplierActivityFk': value};
|
||||
case 'companyFk':
|
||||
return {'ii.companyFk': value};
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -184,7 +188,9 @@ module.exports = Self => {
|
|||
s.name supplierName,
|
||||
s.account,
|
||||
SUM(iid.amount) amount,
|
||||
sub.code awbCode
|
||||
sub.code awbCode,
|
||||
c.code,
|
||||
MIN(iid.dueDated) dueDated
|
||||
FROM invoiceIn ii
|
||||
JOIN supplier s ON s.id = ii.supplierFk
|
||||
LEFT JOIN invoiceInDueDay iid ON iid.invoiceInFk = ii.id
|
||||
|
@ -199,7 +205,8 @@ module.exports = Self => {
|
|||
GROUP BY de.duaFk
|
||||
) sub ON sub.duaFk = d.id
|
||||
LEFT JOIN company co ON co.id = ii.companyFk
|
||||
LEFT JOIN dms dm ON dm.id = ii.docFk`
|
||||
LEFT JOIN dms dm ON dm.id = ii.docFk
|
||||
JOIN company c ON c.id = ii.companyFk`,
|
||||
);
|
||||
|
||||
const sqlWhere = conn.makeWhere(filter.where);
|
||||
|
|
|
@ -15,11 +15,11 @@ describe('invoiceIn corrective()', () => {
|
|||
await tx.rollback();
|
||||
});
|
||||
|
||||
it('La función corrective debería devolver un id cuando se ejecuta correctamente', async() => {
|
||||
it('should return an id when executed correctly', async() => {
|
||||
const originalId = 1;
|
||||
const invoiceReason = 3;
|
||||
const invoiceType = 2;
|
||||
const invoiceClass = 1;
|
||||
const invoiceClass = 8;
|
||||
const cloneId = await models.InvoiceIn.corrective(ctx,
|
||||
originalId, invoiceReason, invoiceType, invoiceClass, options);
|
||||
|
||||
|
@ -30,7 +30,7 @@ describe('invoiceIn corrective()', () => {
|
|||
}, options);
|
||||
|
||||
expect(correction.cplusRectificationTypeFk).toEqual(invoiceType);
|
||||
expect(correction.siiTypeInvoiceOutFk).toEqual(invoiceClass);
|
||||
expect(correction.siiTypeInvoiceInFk).toEqual(invoiceClass);
|
||||
expect(correction.invoiceCorrectionTypeFk).toEqual(invoiceReason);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -166,4 +166,21 @@ describe('InvoiceIn filter()', () => {
|
|||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return the invoice in matching companyFk', async() => {
|
||||
const tx = await models.InvoiceIn.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
|
||||
try {
|
||||
const company = await models.Company.findOne({}, options);
|
||||
const invoicesByCompany = await models.InvoiceIn.find({where: {companyFk: company.id}}, options);
|
||||
const filteredInvoices = await models.InvoiceIn.filter({args: {companyFk: company.id}}, {}, options);
|
||||
|
||||
expect(filteredInvoices.length).toEqual(invoicesByCompany.length);
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('invoiceIn', () => {
|
||||
let options;
|
||||
let tx;
|
||||
const invoiceId = 1;
|
||||
const supplierId = 791;
|
||||
const currencyId = 1;
|
||||
const companyId = 442;
|
||||
|
||||
beforeEach(async() => {
|
||||
tx = await models.InvoiceIn.beginTransaction({});
|
||||
options = {transaction: tx};
|
||||
});
|
||||
|
||||
afterEach(async() => {
|
||||
await tx.rollback();
|
||||
});
|
||||
|
||||
it('should allow insert for new instance', async() => {
|
||||
const newInvoice = {
|
||||
supplierFk: supplierId,
|
||||
issued: Date.vnNew(),
|
||||
operated: Date.vnNew(),
|
||||
currencyFk: currencyId,
|
||||
companyFk: companyId,
|
||||
isBooked: false
|
||||
};
|
||||
|
||||
const createdInvoice = await models.InvoiceIn.create(newInvoice, options);
|
||||
|
||||
expect(createdInvoice).toBeDefined();
|
||||
expect(createdInvoice.id).toBeDefined();
|
||||
});
|
||||
|
||||
it('should throw an error if trying to update a booked invoice', async() => {
|
||||
const invoice = await models.InvoiceIn.findById(invoiceId, null, options);
|
||||
await invoice.updateAttribute('isBooked', true, options);
|
||||
|
||||
let error;
|
||||
try {
|
||||
await invoice.updateAttribute('supplierFk', supplierId, options);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
|
||||
expect(error.message).toBe('InvoiceIn is already booked');
|
||||
});
|
||||
|
||||
it('should throw an error if trying to delete a booked invoice', async() => {
|
||||
const invoice = await models.InvoiceIn.findById(invoiceId, null, options);
|
||||
await invoice.updateAttribute('isBooked', true, options);
|
||||
|
||||
let error;
|
||||
try {
|
||||
await models.InvoiceIn.deleteById(invoiceId, options);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
|
||||
expect(error.message).toBe('InvoiceIn is already booked');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,74 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('invoiceInTax', () => {
|
||||
let options;
|
||||
let tx;
|
||||
const invoiceInId = 1;
|
||||
const invoiceInTaxId = 1;
|
||||
beforeEach(async() => {
|
||||
tx = await models.InvoiceInTax.beginTransaction({});
|
||||
options = {transaction: tx};
|
||||
});
|
||||
|
||||
afterEach(async() => {
|
||||
await tx.rollback();
|
||||
});
|
||||
|
||||
it('should throw an error if trying to save a tax from a booked invoice', async() => {
|
||||
const invoiceIn = await models.InvoiceIn.findById(invoiceInId, null, options);
|
||||
await invoiceIn.updateAttributes({isBooked: true}, options);
|
||||
const invoiceInTax = await models.InvoiceInTax.findById(invoiceInTaxId, null, options);
|
||||
let error;
|
||||
try {
|
||||
await invoiceInTax.updateAttribute('taxableBase', 100, options);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
|
||||
expect(error.message).toBe('InvoiceIn is already booked');
|
||||
});
|
||||
|
||||
it('should allow save if the invoice is not booked', async() => {
|
||||
const invoiceIn = await models.InvoiceIn.findById(invoiceInId, null, options);
|
||||
await invoiceIn.updateAttribute('isBooked', false, options);
|
||||
|
||||
const invoiceInTax = await models.InvoiceInTax.findById(invoiceInTaxId, null, options);
|
||||
await invoiceInTax.updateAttribute('taxableBase', 100, options);
|
||||
|
||||
const updatedInvoiceInTax = await models.InvoiceInTax.findById(invoiceInTaxId, null, options);
|
||||
|
||||
expect(updatedInvoiceInTax.taxableBase).toBe(100);
|
||||
});
|
||||
|
||||
it('should throw an error if trying to delete a tax from a booked invoice', async() => {
|
||||
const invoiceIn = await models.InvoiceIn.findById(invoiceInId, null, options);
|
||||
await invoiceIn.updateAttribute('isBooked', true, options);
|
||||
|
||||
let error;
|
||||
try {
|
||||
await models.InvoiceInTax.destroyById(invoiceInTaxId, options);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
|
||||
expect(error).toBeDefined();
|
||||
expect(error.message).toBe('InvoiceIn is already booked');
|
||||
});
|
||||
|
||||
it('should allow delete if the invoice is not booked', async() => {
|
||||
const invoiceIn = await models.InvoiceIn.findById(invoiceInId, null, options);
|
||||
await invoiceIn.updateAttribute('isBooked', false, options);
|
||||
|
||||
let error;
|
||||
try {
|
||||
await models.InvoiceInTax.destroyById(invoiceInTaxId, options);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
|
||||
const deletedInvoiceInTax = await models.InvoiceInTax.findById(invoiceInTaxId, null, options);
|
||||
|
||||
expect(error).toBeUndefined();
|
||||
expect(deletedInvoiceInTax).toBeNull();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,59 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
const invoiceInId = 1;
|
||||
const supplierId = 791;
|
||||
describe('invoiceIn updateInvoiceIn()', () => {
|
||||
const ctx = beforeAll.getCtx();
|
||||
let options;
|
||||
let tx;
|
||||
|
||||
beforeEach(async() => {
|
||||
options = {transaction: tx};
|
||||
tx = await models.Sale.beginTransaction({});
|
||||
options.transaction = tx;
|
||||
});
|
||||
|
||||
afterEach(async() => {
|
||||
await tx.rollback();
|
||||
});
|
||||
|
||||
it('should update the invoice', async() => {
|
||||
const invoiceBefore = await models.InvoiceIn.findById(invoiceInId, null, options);
|
||||
await update(ctx, options);
|
||||
const invoiceAfter = await models.InvoiceIn.findById(invoiceInId, null, options);
|
||||
|
||||
expect(invoiceAfter.supplierFk).not.toBe(invoiceBefore.supplierFk);
|
||||
expect(invoiceAfter.supplierFk).toBe(supplierId);
|
||||
});
|
||||
|
||||
it('should not update the invoice if is booked', async() => {
|
||||
let error;
|
||||
try {
|
||||
await models.InvoiceIn.toBook(ctx, invoiceInId, options);
|
||||
await update(ctx, options);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.message).toBe('InvoiceIn is already booked');
|
||||
});
|
||||
});
|
||||
|
||||
async function update(ctx, opts) {
|
||||
const supplierRef = 'mockRef';
|
||||
const currencyId = 1;
|
||||
await models.InvoiceIn.updateInvoiceIn(ctx,
|
||||
invoiceInId,
|
||||
supplierId,
|
||||
supplierRef,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
currencyId,
|
||||
undefined,
|
||||
undefined,
|
||||
opts);
|
||||
}
|
|
@ -37,7 +37,13 @@ module.exports = Self => {
|
|||
{
|
||||
relation: 'supplier',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
fields: ['id', 'name', 'isVies', 'countryFk'],
|
||||
include: [{
|
||||
relation: 'country',
|
||||
scope: {
|
||||
fields: ['id', 'code']
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -52,7 +52,8 @@ module.exports = Self => {
|
|||
accountingEntries = await models.Xdiario.count({ASIEN: asien}, myOptions);
|
||||
|
||||
await models.Xdiario.destroyAll({ASIEN: asien}, myOptions);
|
||||
await Self.updateAll({id: invoiceInId}, {isBooked: false}, myOptions);
|
||||
const invoiceIn = await Self.findById(invoiceInId, myOptions);
|
||||
await invoiceIn.updateAttribute('isBooked', false, myOptions);
|
||||
} else {
|
||||
const linkedBookEntry = await models.Xdiario.findOne({
|
||||
fields: ['ASIEN'],
|
||||
|
|
|
@ -82,7 +82,7 @@ module.exports = Self => {
|
|||
|
||||
try {
|
||||
const invoiceIn = await Self.findById(id, null, myOptions);
|
||||
invoiceIn.updateAttributes({supplierFk,
|
||||
await invoiceIn.updateAttributes({supplierFk,
|
||||
supplierRef,
|
||||
issued,
|
||||
operated,
|
||||
|
@ -94,6 +94,7 @@ module.exports = Self => {
|
|||
companyFk,
|
||||
withholdingSageFk
|
||||
}, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
return invoiceIn;
|
||||
} catch (e) {
|
||||
|
|
|
@ -28,11 +28,10 @@
|
|||
"model": "InvoiceCorrectionType",
|
||||
"foreignKey": "invoiceCorrectionTypeFk"
|
||||
},
|
||||
"siiTypeInvoiceOut": {
|
||||
"siiTypeInvoiceIn": {
|
||||
"type": "belongsTo",
|
||||
"model": "SiiTypeInvoiceOut",
|
||||
"foreignKey": "siiTypeInvoiceOutFk"
|
||||
"model": "SiiTypeInvoiceIn",
|
||||
"foreignKey": "siiTypeInvoiceInFk"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.observe('before save', async function(ctx) {
|
||||
if (ctx.isNewInstance) return;
|
||||
|
||||
const models = Self.app.models;
|
||||
const invoiceIn = await models.InvoiceIn.findById(ctx.currentInstance.invoiceInFk, null, ctx.options);
|
||||
if (invoiceIn.isBooked) throw new UserError('InvoiceIn is already booked');
|
||||
});
|
||||
|
||||
Self.observe('before delete', async function(ctx) {
|
||||
const models = Self.app.models;
|
||||
const invoiceInTax = await Self.findById(ctx.where.id, null, ctx.options);
|
||||
const invoiceIn = await models.InvoiceIn.findById(invoiceInTax.invoiceInFk, null, ctx.options);
|
||||
if (invoiceIn.isBooked) throw new UserError('InvoiceIn is already booked');
|
||||
});
|
||||
};
|
|
@ -22,12 +22,11 @@
|
|||
"type": "number"
|
||||
},
|
||||
"expenseFk": {
|
||||
"type": "number"
|
||||
"type": "string"
|
||||
},
|
||||
"created": {
|
||||
"type": "date"
|
||||
}
|
||||
|
||||
},
|
||||
"relations": {
|
||||
"invoiceIn": {
|
||||
|
@ -51,4 +50,4 @@
|
|||
"foreignKey": "transactionTypeSageFk"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,4 +19,25 @@ module.exports = Self => {
|
|||
return new UserError(`This invoice has a linked vehicle.`);
|
||||
return err;
|
||||
});
|
||||
|
||||
Self.observe('before save', async function(ctx) {
|
||||
if (ctx.isNewInstance) return;
|
||||
|
||||
const changes = ctx.data || ctx.instance;
|
||||
const orgData = ctx.currentInstance;
|
||||
let isNotEditable = orgData.isBooked || (!orgData.isBooked && changes.isBooked);
|
||||
|
||||
if (isNotEditable) {
|
||||
for (const [key, value] of Object.entries(changes)) {
|
||||
if (key !== 'isBooked' && value !== orgData[key])
|
||||
throw new UserError('InvoiceIn is already booked');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Self.observe('before delete', async function(ctx) {
|
||||
const invoiceIn = await Self.findById(ctx.where.id, null, ctx.options);
|
||||
if (invoiceIn.isBooked) throw new UserError('InvoiceIn is already booked');
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -43,5 +43,8 @@
|
|||
},
|
||||
"SiiTypeInvoiceOut": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"SiiTypeInvoiceIn": {
|
||||
"dataSource": "vn"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "SiiTypeInvoiceIn",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "siiTypeInvoiceIn"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "number",
|
||||
"description": "Identifier"
|
||||
},
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,9 +17,6 @@
|
|||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"code": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
SELECT (
code
= 'EUR') vIsEurodejalo así que es lo mismo pero es mas compacto