#6942 toUnbook #2135
|
@ -0,0 +1,24 @@
|
||||||
|
REVOKE UPDATE ON vn. invoiceIn FROM administrative, hrBoss, buyer, logistic;
|
||||||
|
GRANT UPDATE (id,
|
||||||
|
serialNumber,
|
||||||
|
serial,
|
||||||
|
supplierFk,
|
||||||
|
issued,
|
||||||
|
supplierRef,
|
||||||
|
currencyFk,
|
||||||
|
created,
|
||||||
|
companyFk,
|
||||||
|
docFk,
|
||||||
|
booked,
|
||||||
|
operated,
|
||||||
|
siiTypeInvoiceInFk,
|
||||||
|
cplusRectificationTypeFk,
|
||||||
|
cplusSubjectOpFk,
|
||||||
|
cplusTaxBreakFk,
|
||||||
|
siiTrascendencyInvoiceInFk,
|
||||||
|
bookEntried,
|
||||||
|
isVatDeductible,
|
||||||
|
withholdingSageFk,
|
||||||
|
expenseFkDeductible,
|
||||||
|
editorFk
|
||||||
|
) ON vn.invoiceIn TO administrative, hrBoss, buyer, logistic;
|
|
@ -0,0 +1,23 @@
|
||||||
|
UPDATE salix.ACL
|
||||||
|
SET accessType = 'READ'
|
||||||
|
WHERE principalId IN ('administrative','buyer')
|
||||||
|
AND model = 'invoiceIn'
|
||||||
|
AND property = '*';
|
||||||
|
|
||||||
|
INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId)
|
||||||
|
VALUES
|
||||||
|
('InvoiceIn', 'updateInvoiceIn', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'clone', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'corrective', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'exchangeRateUpdate', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'invoiceInEmail', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'toBook', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'toUnbook', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'updateInvoiceIn', 'WRITE', 'ALLOW', 'ROLE', 'buyer'),
|
||||||
|
('InvoiceIn', 'clone', 'WRITE', 'ALLOW', 'ROLE', 'buyer'),
|
||||||
|
('InvoiceIn', 'corrective', 'WRITE', 'ALLOW', 'ROLE', 'buyer'),
|
||||||
|
('InvoiceIn', 'exchangeRateUpdate', 'WRITE', 'ALLOW', 'ROLE', 'buyer'),
|
||||||
|
('InvoiceIn', 'invoiceInEmail', 'WRITE', 'ALLOW', 'ROLE', 'buyer'),
|
||||||
|
('InvoiceIn', 'toBook', 'WRITE', 'ALLOW', 'ROLE', 'buyer'),
|
||||||
|
('InvoiceIn', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'buyer');
|
|
@ -76,7 +76,16 @@
|
||||||
},
|
},
|
||||||
"enlazadoSage": {
|
"enlazadoSage": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
}
|
},
|
||||||
|
"enlazado": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
"type": "number",
|
||||||
|
"mysql": {
|
||||||
|
"columnName": "CLAVE"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
"company": {
|
"company": {
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
|
describe('invoiceIn toUnbook()', () => {
|
||||||
|
it('should check that invoiceIn is unbooked', async() => {
|
||||||
|
const userId = 1;
|
||||||
|
const ctx = {
|
||||||
|
req: {
|
||||||
|
|
||||||
|
accessToken: {userId: userId},
|
||||||
|
headers: {origin: 'http://localhost:5000'},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const invoiceInId = 1;
|
||||||
|
const tx = await models.InvoiceIn.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await models.InvoiceIn.toBook(ctx, invoiceInId, options);
|
||||||
|
const bookEntry = await models.InvoiceIn.toUnbook(ctx, invoiceInId, options);
|
||||||
|
const invoiceIn = await models.InvoiceIn.findById(invoiceInId, null, options);
|
||||||
|
|
||||||
|
expect(bookEntry.accountingEntries).toEqual(4);
|
||||||
|
expect(bookEntry.isLinked).toBeFalsy();
|
||||||
|
expect(invoiceIn.isBooked).toEqual(false);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,80 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('toUnbook', {
|
||||||
|
description: 'To unbook the invoiceIn',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: {
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The invoiceIn id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: '/:id/toUnbook',
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.toUnbook = async(ctx, invoiceInId, options) => {
|
||||||
|
let tx;
|
||||||
|
const models = Self.app.models;
|
||||||
|
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let isLinked;
|
||||||
|
let accountingEntries;
|
||||||
|
|
||||||
|
let bookEntry = await models.Xdiario.findOne({
|
||||||
|
fields: ['ASIEN'],
|
||||||
|
where: {
|
||||||
|
and: [
|
||||||
|
{key: invoiceInId},
|
||||||
|
{enlazado: false},
|
||||||
|
{enlazadoSage: false}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
jorgep marked this conversation as resolved
|
|||||||
|
let asien = bookEntry?.ASIEN;
|
||||||
|
if (asien) {
|
||||||
|
accountingEntries = await models.Xdiario.count({ASIEN: asien}, myOptions);
|
||||||
|
|
||||||
|
await models.Xdiario.destroyAll({ASIEN: asien}, myOptions);
|
||||||
|
await Self.updateAll({id: invoiceInId}, {isBooked: false}, myOptions);
|
||||||
|
} else {
|
||||||
|
const linkedBookEntry = await models.Xdiario.findOne({
|
||||||
|
fields: ['ASIEN'],
|
||||||
|
where: {
|
||||||
|
key: invoiceInId,
|
||||||
|
and: [{or: [{enlazado: true, enlazadoSage: true}]}]
|
||||||
|
}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
asien = linkedBookEntry?.ASIEN;
|
||||||
|
isLinked = true;
|
||||||
|
}
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return {
|
||||||
|
isLinked,
|
||||||
|
bookEntry: asien,
|
||||||
|
accountingEntries
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,104 @@
|
||||||
|
module.exports = Self => {
|
||||||
jorgep
commented
Se llama desde basic-data para actualizar los campos de la factura. Tras hablar con @alex se ha decidido usar any. Ya que hay parametros que pueden ser number| null o string| null ... y en loopback no hay manera de ponerle 2 tipos a un argumento. Se llama desde basic-data para actualizar los campos de la factura. Tras hablar con @alex se ha decidido usar any. Ya que hay parametros que pueden ser number| null o string| null ... y en loopback no hay manera de ponerle 2 tipos a un argumento.
|
|||||||
|
Self.remoteMethodCtx('updateInvoiceIn', {
|
||||||
jorgep marked this conversation as resolved
jgallego
commented
porque no usas el nativo? porque no usas el nativo?
jorgep
commented
Porque con el nativo no se puede evitar la modificación de 1 solo campo de una tabla. En este caso, queremos evitar la modificación de isBooked desde salix. Lo hablé con Juan y me dijo que creará un back. Porque con el nativo no se puede evitar la modificación de 1 solo campo de una tabla. En este caso, queremos evitar la modificación de isBooked desde salix. Lo hablé con Juan y me dijo que creará un back.
|
|||||||
|
description: 'To update the invoiceIn attributes',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The invoiceIn id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
}, {
|
||||||
|
arg: 'supplierFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
}, {
|
||||||
|
arg: 'supplierRef',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'issued',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'operated',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'deductibleExpenseFk',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'dmsFk',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'bookEntried',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'booked',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'currencyFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
}, {
|
||||||
|
arg: 'companyFk',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'withholdingSageFk',
|
||||||
|
type: 'any',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: '/:id/updateInvoiceIn',
|
||||||
|
verb: 'PATCH'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.updateInvoiceIn = async(ctx,
|
||||||
|
id,
|
||||||
|
supplierFk,
|
||||||
|
supplierRef,
|
||||||
|
issued,
|
||||||
|
operated,
|
||||||
|
deductibleExpenseFk,
|
||||||
|
dmsFk,
|
||||||
|
bookEntried,
|
||||||
|
booked,
|
||||||
|
currencyFk,
|
||||||
|
companyFk,
|
||||||
|
withholdingSageFk,
|
||||||
|
options
|
||||||
|
) => {
|
||||||
|
let tx;
|
||||||
|
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||||
|
|
||||||
|
if (typeof options == 'object') Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const invoiceIn = await Self.findById(id, null, myOptions);
|
||||||
|
invoiceIn.updateAttributes({supplierFk,
|
||||||
|
supplierRef,
|
||||||
|
issued,
|
||||||
|
operated,
|
||||||
|
deductibleExpenseFk,
|
||||||
|
dmsFk,
|
||||||
|
bookEntried,
|
||||||
|
booked,
|
||||||
|
currencyFk,
|
||||||
|
companyFk,
|
||||||
|
withholdingSageFk
|
||||||
|
}, myOptions);
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
return invoiceIn;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -11,6 +11,8 @@ module.exports = Self => {
|
||||||
require('../methods/invoice-in/getSerial')(Self);
|
require('../methods/invoice-in/getSerial')(Self);
|
||||||
require('../methods/invoice-in/corrective')(Self);
|
require('../methods/invoice-in/corrective')(Self);
|
||||||
require('../methods/invoice-in/exchangeRateUpdate')(Self);
|
require('../methods/invoice-in/exchangeRateUpdate')(Self);
|
||||||
|
require('../methods/invoice-in/toUnbook')(Self);
|
||||||
|
require('../methods/invoice-in/updateInvoiceIn')(Self);
|
||||||
|
|
||||||
Self.rewriteDbError(function(err) {
|
Self.rewriteDbError(function(err) {
|
||||||
if (err.code === 'ER_ROW_IS_REFERENCED_2' && err.sqlMessage.includes('vehicleInvoiceIn'))
|
if (err.code === 'ER_ROW_IS_REFERENCED_2' && err.sqlMessage.includes('vehicleInvoiceIn'))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<mg-ajax path="InvoiceIns/{{patch.params.id}}" options="vnPatch"></mg-ajax>
|
<mg-ajax path="InvoiceIns/{{patch.params.id}}/updateInvoiceIn" options="vnPatch"></mg-ajax>
|
||||||
<vn-watcher
|
<vn-watcher
|
||||||
vn-id="watcher"
|
vn-id="watcher"
|
||||||
data="$ctrl.invoiceIn"
|
data="$ctrl.invoiceIn"
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"id": true,
|
"id": true,
|
||||||
"type": "number",
|
"type": "string",
|
||||||
jorgep
commented
En la base de datos está como varchar En la base de datos está como varchar
|
|||||||
"description": "Identifier"
|
"description": "Identifier"
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
|
|
Loading…
Reference in New Issue
El numero de ocurrencias de bookEntry.ASIEN es medio-alto.
Propongo crear una variable representativa de este valor y reemplazar donde toque.
Otro enfoque puede ser que en el if, reemplazar bookEntry.ASIEN porque ya es true
Me parece bien.