3002-backend_transactions #679
|
@ -54,7 +54,8 @@ module.exports = Self => {
|
||||||
arg: 'from',
|
arg: 'from',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
description: `The from date filter`
|
description: `The from date filter`
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
arg: 'to',
|
arg: 'to',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
description: `The to date filter`
|
description: `The to date filter`
|
||||||
|
@ -90,16 +91,21 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.filter = async(ctx, filter) => {
|
Self.filter = async(ctx, filter, options) => {
|
||||||
const conn = Self.dataSource.connector;
|
const conn = Self.dataSource.connector;
|
||||||
const args = ctx.args;
|
const args = ctx.args;
|
||||||
|
|
||||||
|
let myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
if (args && args.to) {
|
if (args && args.to) {
|
||||||
const dateTo = args.to;
|
const dateTo = args.to;
|
||||||
dateTo.setHours(23, 59, 0, 0);
|
dateTo.setHours(23, 59, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let where = buildFilter(ctx.args, (param, value) => {
|
const where = buildFilter(ctx.args, (param, value) => {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'search':
|
case 'search':
|
||||||
return /^\d+$/.test(value)
|
return /^\d+$/.test(value)
|
||||||
|
@ -127,10 +133,9 @@ module.exports = Self => {
|
||||||
|
|
||||||
filter = mergeFilters(filter, {where});
|
filter = mergeFilters(filter, {where});
|
||||||
|
|
||||||
let stmts = [];
|
const stmts = [];
|
||||||
let stmt;
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(
|
const stmt = new ParameterizedSQL(
|
||||||
`SELECT
|
`SELECT
|
||||||
ii.id,
|
ii.id,
|
||||||
ii.serialNumber,
|
ii.serialNumber,
|
||||||
|
@ -169,10 +174,11 @@ module.exports = Self => {
|
||||||
|
|
||||||
stmt.merge(conn.makePagination(filter));
|
stmt.merge(conn.makePagination(filter));
|
||||||
|
|
||||||
let itemsIndex = stmts.push(stmt) - 1;
|
const itemsIndex = stmts.push(stmt) - 1;
|
||||||
|
|
||||||
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||||||
|
const result = await conn.executeStmt(sql, myOptions);
|
||||||
|
|
||||||
let sql = ParameterizedSQL.join(stmts, ';');
|
|
||||||
let result = await conn.executeStmt(sql);
|
|
||||||
return itemsIndex === 0 ? result : result[itemsIndex];
|
return itemsIndex === 0 ? result : result[itemsIndex];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,86 +2,150 @@ const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('InvoiceIn filter()', () => {
|
describe('InvoiceIn filter()', () => {
|
||||||
it('should return the invoice in matching supplier name', async() => {
|
it('should return the invoice in matching supplier name', async() => {
|
||||||
let ctx = {
|
const tx = await app.models.Entry.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ctx = {
|
||||||
args: {
|
args: {
|
||||||
search: 'Plants SL',
|
search: 'Plants SL',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceIn.filter(ctx);
|
const result = await app.models.InvoiceIn.filter(ctx, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(5);
|
expect(result.length).toEqual(5);
|
||||||
expect(result[0].supplierName).toEqual('Plants SL');
|
expect(result[0].supplierName).toEqual('Plants SL');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the invoice in matching supplier reference', async() => {
|
it('should return the invoice in matching supplier reference', async() => {
|
||||||
let ctx = {
|
const tx = await app.models.Entry.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ctx = {
|
||||||
args: {
|
args: {
|
||||||
supplierRef: '1241',
|
supplierRef: '1241',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceIn.filter(ctx);
|
const result = await app.models.InvoiceIn.filter(ctx, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
expect(result.length).toEqual(1);
|
||||||
expect(result[0].supplierRef).toEqual('1241');
|
expect(result[0].supplierRef).toEqual('1241');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the invoice in matching the serial number', async() => {
|
it('should return the invoice in matching the serial number', async() => {
|
||||||
let ctx = {
|
const tx = await app.models.Entry.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ctx = {
|
||||||
args: {
|
args: {
|
||||||
serialNumber: '1002',
|
serialNumber: '1002',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceIn.filter(ctx);
|
const result = await app.models.InvoiceIn.filter(ctx, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
expect(result.length).toEqual(1);
|
||||||
expect(result[0].serialNumber).toEqual(1002);
|
expect(result[0].serialNumber).toEqual(1002);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the invoice in matching the account', async() => {
|
it('should return the invoice in matching the account', async() => {
|
||||||
let ctx = {
|
const tx = await app.models.Entry.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ctx = {
|
||||||
args: {
|
args: {
|
||||||
account: '4000020002',
|
account: '4000020002',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceIn.filter(ctx);
|
const result = await app.models.InvoiceIn.filter(ctx, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(5);
|
expect(result.length).toEqual(5);
|
||||||
expect(result[0].account).toEqual('4000020002');
|
expect(result[0].account).toEqual('4000020002');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the invoice in matching the awb code', async() => {
|
it('should return the invoice in matching the awb code', async() => {
|
||||||
let ctx = {
|
const tx = await app.models.Entry.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ctx = {
|
||||||
args: {
|
args: {
|
||||||
awbCode: '07546491432',
|
awbCode: '07546491432',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceIn.filter(ctx);
|
const result = await app.models.InvoiceIn.filter(ctx, {}, options);
|
||||||
const firstRow = result[0];
|
const firstRow = result[0];
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
expect(result.length).toEqual(1);
|
||||||
expect(firstRow.id).toEqual(7);
|
expect(firstRow.id).toEqual(7);
|
||||||
expect(firstRow.awbCode).toEqual('07546491432');
|
expect(firstRow.awbCode).toEqual('07546491432');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the invoice in matching the amount', async() => {
|
it('should return the invoice in matching the amount', async() => {
|
||||||
let ctx = {
|
const tx = await app.models.Entry.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ctx = {
|
||||||
args: {
|
args: {
|
||||||
amount: '64.23',
|
amount: '64.23',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceIn.filter(ctx);
|
const result = await app.models.InvoiceIn.filter(ctx, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
expect(result.length).toEqual(1);
|
||||||
expect(result[0].amount).toEqual(64.23);
|
expect(result[0].amount).toEqual(64.23);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the invoice in matching "from" and "to"', async() => {
|
it('should return the invoice in matching "from" and "to"', async() => {
|
||||||
|
const tx = await app.models.Entry.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
const from = new Date();
|
const from = new Date();
|
||||||
const to = new Date();
|
const to = new Date();
|
||||||
from.setHours(0, 0, 0, 0);
|
from.setHours(0, 0, 0, 0);
|
||||||
|
@ -91,21 +155,37 @@ describe('InvoiceIn filter()', () => {
|
||||||
args: {from, to}
|
args: {from, to}
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = await app.models.InvoiceIn.filter(ctx);
|
const result = await app.models.InvoiceIn.filter(ctx, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(6);
|
expect(result.length).toEqual(6);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the booked invoice in', async() => {
|
it('should return the booked invoice in', async() => {
|
||||||
let ctx = {
|
const tx = await app.models.Entry.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ctx = {
|
||||||
args: {
|
args: {
|
||||||
isBooked: true,
|
isBooked: true,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceIn.filter(ctx);
|
const result = await app.models.InvoiceIn.filter(ctx, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(6);
|
expect(result.length).toEqual(6);
|
||||||
expect(result[0].isBooked).toBeTruthy();
|
expect(result[0].isBooked).toBeTruthy();
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,8 +2,18 @@ const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('invoiceIn summary()', () => {
|
describe('invoiceIn summary()', () => {
|
||||||
it('should return a summary object containing data from one invoiceIn', async() => {
|
it('should return a summary object containing data from one invoiceIn', async() => {
|
||||||
const summary = await app.models.InvoiceIn.summary(1);
|
const tx = await app.models.Entry.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const summary = await app.models.InvoiceIn.summary(1, options);
|
||||||
|
|
||||||
expect(summary.supplierRef).toEqual('1234');
|
expect(summary.supplierRef).toEqual('1234');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,7 +19,12 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.summary = async id => {
|
Self.summary = async(id, options) => {
|
||||||
|
let myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const filter = {
|
const filter = {
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
|
@ -55,6 +60,6 @@ module.exports = Self => {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
return Self.app.models.InvoiceIn.findById(id, filter);
|
return Self.app.models.InvoiceIn.findById(id, filter, myOptions);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,21 +20,45 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.book = async ref => {
|
Self.book = async(ref, options) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
let tx;
|
||||||
|
let myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
const ticketAddress = await models.Ticket.findOne({
|
const ticketAddress = await models.Ticket.findOne({
|
||||||
where: {invoiceOut: ref}
|
where: {invoiceOut: ref}
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
const invoiceCompany = await models.InvoiceOut.findOne({
|
const invoiceCompany = await models.InvoiceOut.findOne({
|
||||||
where: {ref: ref}
|
where: {ref: ref}
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
let query = 'SELECT vn.addressTaxArea(?, ?) AS code';
|
let query = 'SELECT vn.addressTaxArea(?, ?) AS code';
|
||||||
|
|
||||||
const [taxArea] = await Self.rawSql(query, [
|
const [taxArea] = await Self.rawSql(query, [
|
||||||
ticketAddress.address,
|
ticketAddress.address,
|
||||||
invoiceCompany.company
|
invoiceCompany.company
|
||||||
]);
|
], myOptions);
|
||||||
|
|
||||||
query = 'CALL vn.invoiceOutAgain(?, ?)';
|
query = 'CALL vn.invoiceOutAgain(?, ?)';
|
||||||
return Self.rawSql(query, [ref, taxArea.code]);
|
|
||||||
|
const result = Self.rawSql(query, [ref, taxArea.code], myOptions);
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,22 +34,22 @@ module.exports = Self => {
|
||||||
throw new UserError(`Action not allowed on the test environment`);
|
throw new UserError(`Action not allowed on the test environment`);
|
||||||
|
|
||||||
let tx;
|
let tx;
|
||||||
let newOptions = {};
|
let myOptions = {};
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(newOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
if (!newOptions.transaction) {
|
if (!myOptions.transaction) {
|
||||||
tx = await Self.beginTransaction({});
|
tx = await Self.beginTransaction({});
|
||||||
newOptions.transaction = tx;
|
myOptions.transaction = tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
let fileSrc;
|
let fileSrc;
|
||||||
try {
|
try {
|
||||||
const invoiceOut = await Self.findById(id, null, newOptions);
|
const invoiceOut = await Self.findById(id, null, myOptions);
|
||||||
await invoiceOut.updateAttributes({
|
await invoiceOut.updateAttributes({
|
||||||
hasPdf: true
|
hasPdf: true
|
||||||
}, newOptions);
|
}, myOptions);
|
||||||
|
|
||||||
const response = got.stream(`${origin}/api/report/invoice`, {
|
const response = got.stream(`${origin}/api/report/invoice`, {
|
||||||
query: {
|
query: {
|
||||||
|
|
|
@ -20,25 +20,37 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.delete = async id => {
|
Self.delete = async(id, options) => {
|
||||||
const transaction = await Self.beginTransaction({});
|
let tx;
|
||||||
try {
|
let myOptions = {};
|
||||||
let options = {transaction: transaction};
|
|
||||||
|
|
||||||
let invoiceOut = await Self.findById(id);
|
if (typeof options == 'object')
|
||||||
let tickets = await Self.app.models.Ticket.find({where: {refFk: invoiceOut.ref}});
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const invoiceOut = await Self.findById(id, {}, myOptions);
|
||||||
|
const tickets = await Self.app.models.Ticket.find({where: {refFk: invoiceOut.ref}}, myOptions);
|
||||||
|
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
|
||||||
tickets.forEach(ticket => {
|
tickets.forEach(ticket => {
|
||||||
promises.push(ticket.updateAttribute('refFk', null, options));
|
promises.push(ticket.updateAttribute('refFk', null, myOptions));
|
||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all(promises);
|
await Promise.all(promises, myOptions);
|
||||||
await invoiceOut.destroy(options);
|
|
||||||
await transaction.commit();
|
await invoiceOut.destroy(myOptions);
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
return tickets;
|
return tickets;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await transaction.rollback();
|
if (tx) await tx.rollback();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -85,10 +85,14 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.filter = async(ctx, filter) => {
|
Self.filter = async(ctx, filter, options) => {
|
||||||
let conn = Self.dataSource.connector;
|
const conn = Self.dataSource.connector;
|
||||||
|
let myOptions = {};
|
||||||
|
|
||||||
let where = buildFilter(ctx.args, (param, value) => {
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
const where = buildFilter(ctx.args, (param, value) => {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'search':
|
case 'search':
|
||||||
return {'i.ref': {like: `%${value}%`}};
|
return {'i.ref': {like: `%${value}%`}};
|
||||||
|
@ -115,10 +119,9 @@ module.exports = Self => {
|
||||||
|
|
||||||
filter = mergeFilters(filter, {where});
|
filter = mergeFilters(filter, {where});
|
||||||
|
|
||||||
let stmts = [];
|
const stmts = [];
|
||||||
let stmt;
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(
|
const stmt = new ParameterizedSQL(
|
||||||
`SELECT
|
`SELECT
|
||||||
i.id,
|
i.id,
|
||||||
i.ref,
|
i.ref,
|
||||||
|
@ -136,10 +139,12 @@ module.exports = Self => {
|
||||||
);
|
);
|
||||||
|
|
||||||
stmt.merge(conn.makeSuffix(filter));
|
stmt.merge(conn.makeSuffix(filter));
|
||||||
let itemsIndex = stmts.push(stmt) - 1;
|
|
||||||
|
|
||||||
let sql = ParameterizedSQL.join(stmts, ';');
|
const itemsIndex = stmts.push(stmt) - 1;
|
||||||
let result = await conn.executeStmt(sql);
|
|
||||||
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||||||
|
const result = await conn.executeStmt(sql, myOptions);
|
||||||
|
|
||||||
return itemsIndex === 0 ? result : result[itemsIndex];
|
return itemsIndex === 0 ? result : result[itemsIndex];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,30 +3,26 @@ const app = require('vn-loopback/server/server');
|
||||||
describe('invoiceOut book()', () => {
|
describe('invoiceOut book()', () => {
|
||||||
const invoiceOutId = 5;
|
const invoiceOutId = 5;
|
||||||
|
|
||||||
it('should check that invoice out booked is untainted', async() => {
|
|
||||||
const invoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
|
||||||
|
|
||||||
expect(invoiceOut.booked).toBeDefined();
|
|
||||||
expect(invoiceOut.hasPdf).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update the booked property', async() => {
|
it('should update the booked property', async() => {
|
||||||
const originalInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
const tx = await app.models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const originalInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId, {}, options);
|
||||||
const bookedDate = originalInvoiceOut.booked;
|
const bookedDate = originalInvoiceOut.booked;
|
||||||
const invoiceOutRef = originalInvoiceOut.ref;
|
const invoiceOutRef = originalInvoiceOut.ref;
|
||||||
|
|
||||||
await app.models.InvoiceOut.book(invoiceOutRef);
|
await app.models.InvoiceOut.book(invoiceOutRef, options);
|
||||||
|
|
||||||
const updatedInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
const updatedInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId, {}, options);
|
||||||
|
|
||||||
expect(updatedInvoiceOut.booked).not.toEqual(bookedDate);
|
expect(updatedInvoiceOut.booked).not.toEqual(bookedDate);
|
||||||
expect(updatedInvoiceOut.hasPdf).toBeFalsy();
|
expect(updatedInvoiceOut.hasPdf).toBeFalsy();
|
||||||
|
|
||||||
// restores
|
await tx.rollback();
|
||||||
await updatedInvoiceOut.updateAttributes({
|
} catch (e) {
|
||||||
booked: originalInvoiceOut.booked,
|
await tx.rollback();
|
||||||
hasPdf: originalInvoiceOut.hasPdf,
|
throw e;
|
||||||
amount: originalInvoiceOut.amount
|
}
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,36 +3,51 @@ const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('invoiceOut delete()', () => {
|
describe('invoiceOut delete()', () => {
|
||||||
const invoiceOutId = 2;
|
const invoiceOutId = 2;
|
||||||
let originalInvoiceOut;
|
|
||||||
let originalTicket;
|
|
||||||
const userId = 1106;
|
const userId = 1106;
|
||||||
const activeCtx = {
|
const activeCtx = {
|
||||||
accessToken: {userId: userId},
|
accessToken: {userId: userId},
|
||||||
};
|
};
|
||||||
|
|
||||||
it('should check that there is one ticket in the target invoiceOut', async() => {
|
it('should check that there is one ticket in the target invoiceOut', async() => {
|
||||||
const invoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
const tx = await app.models.InvoiceOut.beginTransaction({});
|
||||||
const tickets = await app.models.Ticket.find({where: {refFk: invoiceOut.ref}});
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const invoiceOut = await app.models.InvoiceOut.findById(invoiceOutId, {}, options);
|
||||||
|
const tickets = await app.models.Ticket.find({where: {refFk: invoiceOut.ref}}, options);
|
||||||
|
|
||||||
expect(tickets.length).toEqual(1);
|
expect(tickets.length).toEqual(1);
|
||||||
expect(tickets[0].id).toEqual(3);
|
expect(tickets[0].id).toEqual(3);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should delete the target invoiceOut then check the ticket doesn't have a refFk anymore`, async() => {
|
it(`should delete the target invoiceOut then check the ticket doesn't have a refFk anymore`, async() => {
|
||||||
|
const tx = await app.models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
active: activeCtx
|
active: activeCtx
|
||||||
});
|
});
|
||||||
originalInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
|
||||||
await app.models.InvoiceOut.delete(invoiceOutId);
|
await app.models.InvoiceOut.delete(invoiceOutId, options);
|
||||||
originalTicket = await app.models.Ticket.findById(3);
|
|
||||||
const deletedInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
const originalTicket = await app.models.Ticket.findById(3, {}, options);
|
||||||
|
|
||||||
|
const deletedInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId, {}, options);
|
||||||
|
|
||||||
expect(deletedInvoiceOut).toBeNull();
|
expect(deletedInvoiceOut).toBeNull();
|
||||||
expect(originalTicket.refFk).toBeNull();
|
expect(originalTicket.refFk).toBeNull();
|
||||||
|
|
||||||
// restores
|
await tx.rollback();
|
||||||
const restoredInvoiceOut = await app.models.InvoiceOut.create(originalInvoiceOut);
|
} catch (e) {
|
||||||
await restoredInvoiceOut.updateAttribute('ref', originalInvoiceOut.ref);
|
await tx.rollback();
|
||||||
await originalTicket.updateAttribute('refFk', restoredInvoiceOut.ref);
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,57 +5,101 @@ describe('InvoiceOut filter()', () => {
|
||||||
today.setHours(2, 0, 0, 0);
|
today.setHours(2, 0, 0, 0);
|
||||||
|
|
||||||
it('should return the invoice out matching ref', async() => {
|
it('should return the invoice out matching ref', async() => {
|
||||||
let ctx = {
|
const tx = await app.models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ctx = {
|
||||||
args: {
|
args: {
|
||||||
search: 'T4444444',
|
search: 'T4444444',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
const result = await app.models.InvoiceOut.filter(ctx, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
expect(result.length).toEqual(1);
|
||||||
expect(result[0].ref).toEqual('T4444444');
|
expect(result[0].ref).toEqual('T4444444');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the invoice out matching clientFk', async() => {
|
it('should return the invoice out matching clientFk', async() => {
|
||||||
let ctx = {
|
const tx = await app.models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ctx = {
|
||||||
args: {
|
args: {
|
||||||
clientFk: 1102,
|
clientFk: 1102,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
const result = await app.models.InvoiceOut.filter(ctx, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
expect(result.length).toEqual(1);
|
||||||
expect(result[0].ref).toEqual('T2222222');
|
expect(result[0].ref).toEqual('T2222222');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the invoice out matching hasPdf', async() => {
|
it('should return the invoice out matching hasPdf', async() => {
|
||||||
let ctx = {
|
const tx = await app.models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ctx = {
|
||||||
args: {
|
args: {
|
||||||
hasPdf: true,
|
hasPdf: true,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
const result = await app.models.InvoiceOut.filter(ctx, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(5);
|
expect(result.length).toEqual(5);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the invoice out matching amount', async() => {
|
it('should return the invoice out matching amount', async() => {
|
||||||
let ctx = {
|
const tx = await app.models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ctx = {
|
||||||
args: {
|
args: {
|
||||||
amount: 121.36,
|
amount: 121.36,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
const result = await app.models.InvoiceOut.filter(ctx, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
expect(result.length).toEqual(1);
|
||||||
expect(result[0].ref).toEqual('T2222222');
|
expect(result[0].ref).toEqual('T2222222');
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the invoice out matching min and max', async() => {
|
it('should return the invoice out matching min and max', async() => {
|
||||||
|
const tx = await app.models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
let ctx = {
|
let ctx = {
|
||||||
args: {
|
args: {
|
||||||
min: 0,
|
min: 0,
|
||||||
|
@ -63,47 +107,14 @@ describe('InvoiceOut filter()', () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
let result = await app.models.InvoiceOut.filter(ctx, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(3);
|
expect(result.length).toEqual(3);
|
||||||
});
|
|
||||||
|
|
||||||
// #1428 cuadrar formato de horas
|
await tx.rollback();
|
||||||
xit('should return the invoice out matching issued', async() => {
|
} catch (e) {
|
||||||
let ctx = {
|
await tx.rollback();
|
||||||
args: {
|
throw e;
|
||||||
issued: today,
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
// #1428 cuadrar formato de horas
|
|
||||||
xit('should return the invoice out matching created', async() => {
|
|
||||||
let ctx = {
|
|
||||||
args: {
|
|
||||||
created: today,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
|
||||||
|
|
||||||
expect(result.length).toEqual(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
// #1428 cuadrar formato de horas
|
|
||||||
xit('should return the invoice out matching dued', async() => {
|
|
||||||
let ctx = {
|
|
||||||
args: {
|
|
||||||
dued: today
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,8 +3,18 @@ const app = require('vn-loopback/server/server');
|
||||||
describe('entry getTickets()', () => {
|
describe('entry getTickets()', () => {
|
||||||
const invoiceOutId = 4;
|
const invoiceOutId = 4;
|
||||||
it('should get the ticket of an invoiceOut', async() => {
|
it('should get the ticket of an invoiceOut', async() => {
|
||||||
const result = await app.models.InvoiceOut.getTickets(invoiceOutId);
|
const tx = await app.models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await app.models.InvoiceOut.getTickets(invoiceOutId, {}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
expect(result.length).toEqual(1);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,24 +2,54 @@ const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('invoiceOut summary()', () => {
|
describe('invoiceOut summary()', () => {
|
||||||
it('should return a summary object containing data from one invoiceOut', async() => {
|
it('should return a summary object containing data from one invoiceOut', async() => {
|
||||||
const result = await app.models.InvoiceOut.summary(1);
|
const tx = await app.models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await app.models.InvoiceOut.summary(1, options);
|
||||||
|
|
||||||
expect(result.invoiceOut.id).toEqual(1);
|
expect(result.invoiceOut.id).toEqual(1);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should return a summary object containing it's supplier country`, async() => {
|
it(`should return a summary object containing it's supplier country`, async() => {
|
||||||
const summary = await app.models.InvoiceOut.summary(1);
|
const tx = await app.models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const summary = await app.models.InvoiceOut.summary(1, options);
|
||||||
const supplier = summary.invoiceOut.supplier();
|
const supplier = summary.invoiceOut.supplier();
|
||||||
|
|
||||||
expect(summary.invoiceOut.ref).toEqual('T1111111');
|
expect(summary.invoiceOut.ref).toEqual('T1111111');
|
||||||
expect(supplier.id).toEqual(442);
|
expect(supplier.id).toEqual(442);
|
||||||
expect(supplier.countryFk).toEqual(1);
|
expect(supplier.countryFk).toEqual(1);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should return a summary object containing idata from it's tax types`, async() => {
|
it(`should return a summary object containing idata from it's tax types`, async() => {
|
||||||
const summary = await app.models.InvoiceOut.summary(1);
|
const tx = await app.models.InvoiceOut.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const summary = await app.models.InvoiceOut.summary(1, options);
|
||||||
|
|
||||||
expect(summary.invoiceOut.ref).toEqual('T1111111');
|
expect(summary.invoiceOut.ref).toEqual('T1111111');
|
||||||
expect(summary.invoiceOut.taxesBreakdown.length).toEqual(2);
|
expect(summary.invoiceOut.taxesBreakdown.length).toEqual(2);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,8 +19,12 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.summary = async id => {
|
Self.summary = async(id, options) => {
|
||||||
let summary = {};
|
let summary = {};
|
||||||
|
let myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const filter = {
|
const filter = {
|
||||||
fields: [
|
fields: [
|
||||||
|
@ -58,14 +62,14 @@ module.exports = Self => {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
summary.invoiceOut = await Self.app.models.InvoiceOut.findOne(filter);
|
summary.invoiceOut = await Self.app.models.InvoiceOut.findOne(filter, myOptions);
|
||||||
|
|
||||||
const invoiceOutTaxes = await Self.rawSql(`
|
const invoiceOutTaxes = await Self.rawSql(`
|
||||||
SELECT iot.* , pgc.*, IF(pe.equFk IS NULL, taxableBase, 0) AS Base, pgc.rate / 100 as vatPercent
|
SELECT iot.* , pgc.*, IF(pe.equFk IS NULL, taxableBase, 0) AS Base, pgc.rate / 100 as vatPercent
|
||||||
FROM vn.invoiceOutTax iot
|
FROM vn.invoiceOutTax iot
|
||||||
JOIN vn.pgc ON pgc.code = iot.pgcFk
|
JOIN vn.pgc ON pgc.code = iot.pgcFk
|
||||||
LEFT JOIN vn.pgcEqu pe ON pe.equFk = pgc.code
|
LEFT JOIN vn.pgcEqu pe ON pe.equFk = pgc.code
|
||||||
WHERE invoiceOutFk = ?`, [summary.invoiceOut.id]);
|
WHERE invoiceOutFk = ?`, [summary.invoiceOut.id], myOptions);
|
||||||
|
|
||||||
summary.invoiceOut.taxesBreakdown = invoiceOutTaxes;
|
summary.invoiceOut.taxesBreakdown = invoiceOutTaxes;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue