Changes
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
parent
c270ec6207
commit
e7c1dc2210
|
@ -236,9 +236,9 @@ export default class Contextmenu {
|
||||||
* value to the clipboard
|
* value to the clipboard
|
||||||
*/
|
*/
|
||||||
copyValue() {
|
copyValue() {
|
||||||
console.log(this.field);
|
const cell = angular.element(this.cell);
|
||||||
if (navigator && navigator.clipboard)
|
if (navigator && navigator.clipboard)
|
||||||
navigator.clipboard.writeText(this.fieldValue);
|
navigator.clipboard.writeText(cell.text());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ Workers: Trabajadores
|
||||||
Routes: Rutas
|
Routes: Rutas
|
||||||
Locator: Localizador
|
Locator: Localizador
|
||||||
Invoices out: Facturas emitidas
|
Invoices out: Facturas emitidas
|
||||||
|
Invoices in: Fact. recibidas
|
||||||
Entries: Entradas
|
Entries: Entradas
|
||||||
Users: Usuarios
|
Users: Usuarios
|
||||||
Suppliers: Proveedores
|
Suppliers: Proveedores
|
||||||
|
|
|
@ -6,6 +6,7 @@ import './modules/zone/front/module.js';
|
||||||
import './modules/claim/front/module.js';
|
import './modules/claim/front/module.js';
|
||||||
import './modules/client/front/module.js';
|
import './modules/client/front/module.js';
|
||||||
import './modules/invoiceOut/front/module.js';
|
import './modules/invoiceOut/front/module.js';
|
||||||
|
import './modules/invoiceIn/front/module.js';
|
||||||
import './modules/item/front/module.js';
|
import './modules/item/front/module.js';
|
||||||
import './modules/order/front/module.js';
|
import './modules/order/front/module.js';
|
||||||
import './modules/route/front/module.js';
|
import './modules/route/front/module.js';
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
const fs = require('fs-extra');
|
|
||||||
|
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethod('download', {
|
|
||||||
description: 'Download an invoice PDF',
|
|
||||||
accessType: 'READ',
|
|
||||||
accepts: [
|
|
||||||
{
|
|
||||||
arg: 'id',
|
|
||||||
type: 'String',
|
|
||||||
description: 'The invoice id',
|
|
||||||
http: {source: 'path'}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
returns: [
|
|
||||||
{
|
|
||||||
arg: 'body',
|
|
||||||
type: 'file',
|
|
||||||
root: true
|
|
||||||
}, {
|
|
||||||
arg: 'Content-Type',
|
|
||||||
type: 'String',
|
|
||||||
http: {target: 'header'}
|
|
||||||
}, {
|
|
||||||
arg: 'Content-Disposition',
|
|
||||||
type: 'String',
|
|
||||||
http: {target: 'header'}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
http: {
|
|
||||||
path: `/:id/download`,
|
|
||||||
verb: 'GET'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.download = async function(id) {
|
|
||||||
let file;
|
|
||||||
let env = process.env.NODE_ENV;
|
|
||||||
let [invoice] = await Self.rawSql(`SELECT invoiceOut_getPath(?) path`, [id]);
|
|
||||||
|
|
||||||
if (env && env != 'development') {
|
|
||||||
file = {
|
|
||||||
path: `/var/lib/salix/pdfs/${invoice.path}`,
|
|
||||||
contentType: 'application/pdf',
|
|
||||||
name: `${id}.pdf`
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
file = {
|
|
||||||
path: `${process.cwd()}/README.md`,
|
|
||||||
contentType: 'text/plain',
|
|
||||||
name: `README.md`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
await fs.access(file.path);
|
|
||||||
let stream = fs.createReadStream(file.path);
|
|
||||||
return [stream, file.contentType, `filename="${file.name}"`];
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -140,7 +140,6 @@ module.exports = Self => {
|
||||||
let itemsIndex = stmts.push(stmt) - 1;
|
let itemsIndex = stmts.push(stmt) - 1;
|
||||||
|
|
||||||
let sql = ParameterizedSQL.join(stmts, ';');
|
let sql = ParameterizedSQL.join(stmts, ';');
|
||||||
console.log(sql.sql);
|
|
||||||
let result = await conn.executeStmt(sql);
|
let result = await conn.executeStmt(sql);
|
||||||
return itemsIndex === 0 ? result : result[itemsIndex];
|
return itemsIndex === 0 ? result : result[itemsIndex];
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
const app = require('vn-loopback/server/server');
|
|
||||||
|
|
||||||
describe('invoiceOut book()', () => {
|
|
||||||
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() => {
|
|
||||||
const originalInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
|
||||||
const bookedDate = originalInvoiceOut.booked;
|
|
||||||
const invoiceOutRef = originalInvoiceOut.ref;
|
|
||||||
|
|
||||||
await app.models.InvoiceOut.book(invoiceOutRef);
|
|
||||||
|
|
||||||
const updatedInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
|
||||||
|
|
||||||
expect(updatedInvoiceOut.booked).not.toEqual(bookedDate);
|
|
||||||
expect(updatedInvoiceOut.hasPdf).toBeFalsy();
|
|
||||||
|
|
||||||
// restores
|
|
||||||
await updatedInvoiceOut.updateAttributes({
|
|
||||||
booked: originalInvoiceOut.booked,
|
|
||||||
hasPdf: originalInvoiceOut.hasPdf,
|
|
||||||
amount: originalInvoiceOut.amount
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,38 +0,0 @@
|
||||||
const app = require('vn-loopback/server/server');
|
|
||||||
const LoopBackContext = require('loopback-context');
|
|
||||||
|
|
||||||
describe('invoiceOut delete()', () => {
|
|
||||||
const invoiceOutId = 2;
|
|
||||||
let originalInvoiceOut;
|
|
||||||
let originalTicket;
|
|
||||||
const userId = 106;
|
|
||||||
const activeCtx = {
|
|
||||||
accessToken: {userId: userId},
|
|
||||||
};
|
|
||||||
|
|
||||||
it('should check that there is one ticket in the target invoiceOut', async() => {
|
|
||||||
const invoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
|
||||||
const tickets = await app.models.Ticket.find({where: {refFk: invoiceOut.ref}});
|
|
||||||
|
|
||||||
expect(tickets.length).toEqual(1);
|
|
||||||
expect(tickets[0].id).toEqual(3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should delete the target invoiceOut then check the ticket doesn't have a refFk anymore`, async() => {
|
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
|
||||||
active: activeCtx
|
|
||||||
});
|
|
||||||
originalInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
|
||||||
await app.models.InvoiceOut.delete(invoiceOutId);
|
|
||||||
originalTicket = await app.models.Ticket.findById(3);
|
|
||||||
const deletedInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
|
||||||
|
|
||||||
expect(deletedInvoiceOut).toBeNull();
|
|
||||||
expect(originalTicket.refFk).toBeNull();
|
|
||||||
|
|
||||||
// restores
|
|
||||||
const restoredInvoiceOut = await app.models.InvoiceOut.create(originalInvoiceOut);
|
|
||||||
await restoredInvoiceOut.updateAttribute('ref', originalInvoiceOut.ref);
|
|
||||||
await originalTicket.updateAttribute('refFk', restoredInvoiceOut.ref);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,10 +0,0 @@
|
||||||
const app = require('vn-loopback/server/server');
|
|
||||||
|
|
||||||
describe('InvoiceOut download()', () => {
|
|
||||||
it('should return the downloaded fine name', async() => {
|
|
||||||
let result = await app.models.InvoiceOut.download(1);
|
|
||||||
|
|
||||||
expect(result[1]).toEqual('text/plain');
|
|
||||||
expect(result[2]).toEqual('filename="README.md"');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,109 +1,81 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('InvoiceOut filter()', () => {
|
fdescribe('InvoiceIn filter()', () => {
|
||||||
let today = new Date();
|
it('should return the invoice in matching supplier name', async() => {
|
||||||
today.setHours(2, 0, 0, 0);
|
|
||||||
|
|
||||||
it('should return the invoice out matching ref', async() => {
|
|
||||||
let ctx = {
|
let ctx = {
|
||||||
args: {
|
args: {
|
||||||
search: 'T4444444',
|
search: 'Plants SL',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
let result = await app.models.InvoiceIn.filter(ctx);
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
|
||||||
expect(result[0].ref).toEqual('T4444444');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return the invoice out matching clientFk', async() => {
|
|
||||||
let ctx = {
|
|
||||||
args: {
|
|
||||||
clientFk: 102,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
|
||||||
expect(result[0].ref).toEqual('T2222222');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return the invoice out matching hasPdf', async() => {
|
|
||||||
let ctx = {
|
|
||||||
args: {
|
|
||||||
hasPdf: true,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
|
||||||
|
|
||||||
expect(result.length).toEqual(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return the invoice out matching amount', async() => {
|
|
||||||
let ctx = {
|
|
||||||
args: {
|
|
||||||
amount: 121.36,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
|
||||||
expect(result[0].ref).toEqual('T2222222');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return the invoice out matching min and max', async() => {
|
|
||||||
let ctx = {
|
|
||||||
args: {
|
|
||||||
min: 0,
|
|
||||||
max: 100,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
|
||||||
|
|
||||||
expect(result.length).toEqual(3);
|
expect(result.length).toEqual(3);
|
||||||
|
expect(result[0].supplierName).toEqual('Plants SL');
|
||||||
});
|
});
|
||||||
|
|
||||||
// #1428 cuadrar formato de horas
|
it('should return the invoice in matching supplier reference', async() => {
|
||||||
xit('should return the invoice out matching issued', async() => {
|
|
||||||
let ctx = {
|
let ctx = {
|
||||||
args: {
|
args: {
|
||||||
issued: today,
|
supplierRef: '4233',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
let result = await app.models.InvoiceIn.filter(ctx);
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
expect(result.length).toEqual(1);
|
||||||
|
expect(result[0].supplierRef).toEqual('4233');
|
||||||
});
|
});
|
||||||
|
|
||||||
// #1428 cuadrar formato de horas
|
it('should return the invoice in matching the serial number', async() => {
|
||||||
xit('should return the invoice out matching created', async() => {
|
|
||||||
let ctx = {
|
let ctx = {
|
||||||
args: {
|
args: {
|
||||||
created: today,
|
serialNumber: '1002',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = await app.models.InvoiceOut.filter(ctx);
|
let result = await app.models.InvoiceIn.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);
|
expect(result.length).toEqual(1);
|
||||||
|
expect(result[0].serialNumber).toEqual(1002);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the invoice in matching the account', async() => {
|
||||||
|
let ctx = {
|
||||||
|
args: {
|
||||||
|
account: '4000020002',
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = await app.models.InvoiceIn.filter(ctx);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(4);
|
||||||
|
expect(result[0].account).toEqual('4000020002');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the invoice in matching the amount', async() => {
|
||||||
|
let ctx = {
|
||||||
|
args: {
|
||||||
|
amount: '64.23',
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = await app.models.InvoiceIn.filter(ctx);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
expect(result[0].amount).toEqual(64.23);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the booked invoice in', async() => {
|
||||||
|
let ctx = {
|
||||||
|
args: {
|
||||||
|
isBooked: true,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = await app.models.InvoiceIn.filter(ctx);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(3);
|
||||||
|
expect(result[0].isBooked).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
const app = require('vn-loopback/server/server');
|
|
||||||
|
|
||||||
describe('invoiceOut regenerate()', () => {
|
|
||||||
const invoiceReportFk = 30;
|
|
||||||
const invoiceOutId = 1;
|
|
||||||
|
|
||||||
it('should check that the invoice has a PDF and is not in print generation queue', async() => {
|
|
||||||
const invoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
|
||||||
const [queue] = await app.models.InvoiceOut.rawSql(`
|
|
||||||
SELECT COUNT(*) AS total
|
|
||||||
FROM vn.printServerQueue
|
|
||||||
WHERE reportFk = ?`, [invoiceReportFk]);
|
|
||||||
|
|
||||||
expect(invoiceOut.hasPdf).toBeTruthy();
|
|
||||||
expect(queue.total).toEqual(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should mark the invoice as doesn't have PDF and add it to a print queue`, async() => {
|
|
||||||
const ctx = {req: {accessToken: {userId: 5}}};
|
|
||||||
const invoiceOut = await app.models.InvoiceOut.regenerate(ctx, invoiceOutId);
|
|
||||||
const [queue] = await app.models.InvoiceOut.rawSql(`
|
|
||||||
SELECT COUNT(*) AS total
|
|
||||||
FROM vn.printServerQueue
|
|
||||||
WHERE reportFk = ?`, [invoiceReportFk]);
|
|
||||||
|
|
||||||
expect(invoiceOut.hasPdf).toBeFalsy();
|
|
||||||
expect(queue.total).toEqual(1);
|
|
||||||
|
|
||||||
// restores
|
|
||||||
const invoiceOutToRestore = await app.models.InvoiceOut.findById(invoiceOutId);
|
|
||||||
await invoiceOutToRestore.updateAttributes({hasPdf: true});
|
|
||||||
await app.models.InvoiceOut.rawSql(`
|
|
||||||
DELETE FROM vn.printServerQueue
|
|
||||||
WHERE reportFk = ?`, [invoiceReportFk]);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,33 +0,0 @@
|
||||||
const app = require('vn-loopback/server/server');
|
|
||||||
|
|
||||||
describe('invoiceOut summary()', () => {
|
|
||||||
it('should return a summary object containing data from one invoiceOut', async() => {
|
|
||||||
const result = await app.models.InvoiceOut.summary(1);
|
|
||||||
|
|
||||||
expect(result.invoiceOut.id).toEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should return a summary object containing data from it's tickets`, async() => {
|
|
||||||
const summary = await app.models.InvoiceOut.summary(1);
|
|
||||||
const tickets = summary.invoiceOut.tickets();
|
|
||||||
|
|
||||||
expect(summary.invoiceOut.ref).toEqual('T1111111');
|
|
||||||
expect(tickets.length).toEqual(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should return a summary object containing it's supplier country`, async() => {
|
|
||||||
const summary = await app.models.InvoiceOut.summary(1);
|
|
||||||
const supplier = summary.invoiceOut.supplier();
|
|
||||||
|
|
||||||
expect(summary.invoiceOut.ref).toEqual('T1111111');
|
|
||||||
expect(supplier.id).toEqual(442);
|
|
||||||
expect(supplier.countryFk).toEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should return a summary object containing idata from it's tax types`, async() => {
|
|
||||||
const summary = await app.models.InvoiceOut.summary(1);
|
|
||||||
|
|
||||||
expect(summary.invoiceOut.ref).toEqual('T1111111');
|
|
||||||
expect(summary.invoiceOut.taxesBreakdown.length).toEqual(2);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,111 +0,0 @@
|
||||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
|
||||||
|
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethod('summary', {
|
|
||||||
description: 'The invoiceOut summary',
|
|
||||||
accessType: 'READ',
|
|
||||||
accepts: [{
|
|
||||||
arg: 'id',
|
|
||||||
type: 'number',
|
|
||||||
required: true,
|
|
||||||
description: 'The invoiceOut id',
|
|
||||||
http: {source: 'path'}
|
|
||||||
}],
|
|
||||||
returns: {
|
|
||||||
type: 'object',
|
|
||||||
root: true
|
|
||||||
},
|
|
||||||
http: {
|
|
||||||
path: `/:id/summary`,
|
|
||||||
verb: 'GET'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.summary = async id => {
|
|
||||||
const conn = Self.dataSource.connector;
|
|
||||||
let summary = {};
|
|
||||||
|
|
||||||
const filter = {
|
|
||||||
fields: [
|
|
||||||
'id',
|
|
||||||
'ref',
|
|
||||||
'issued',
|
|
||||||
'dued',
|
|
||||||
'amount',
|
|
||||||
'created',
|
|
||||||
'booked',
|
|
||||||
'clientFk',
|
|
||||||
'companyFk',
|
|
||||||
'hasPdf'
|
|
||||||
],
|
|
||||||
where: {id: id},
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
relation: 'company',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'code']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
relation: 'supplier',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'countryFk']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
relation: 'client',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'socialName']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
relation: 'tickets'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
summary.invoiceOut = await Self.app.models.InvoiceOut.findOne(filter);
|
|
||||||
|
|
||||||
let stmts = [];
|
|
||||||
|
|
||||||
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticket');
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(`
|
|
||||||
CREATE TEMPORARY TABLE tmp.ticket
|
|
||||||
(INDEX (ticketFk)) ENGINE = MEMORY
|
|
||||||
SELECT id ticketFk FROM vn.ticket WHERE refFk=?`, [summary.invoiceOut.ref]);
|
|
||||||
stmts.push(stmt);
|
|
||||||
|
|
||||||
stmts.push('CALL ticketGetTotal()');
|
|
||||||
|
|
||||||
let ticketTotalsIndex = stmts.push('SELECT * FROM tmp.ticketTotal') - 1;
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(`
|
|
||||||
SELECT iot.* , pgc.*, IF(pe.equFk IS NULL, taxableBase, 0) AS Base, pgc.rate / 100 as vatPercent
|
|
||||||
FROM vn.invoiceOutTax iot
|
|
||||||
JOIN vn.pgc ON pgc.code = iot.pgcFk
|
|
||||||
LEFT JOIN vn.pgcEqu pe ON pe.equFk = pgc.code
|
|
||||||
WHERE invoiceOutFk = ?`, [summary.invoiceOut.id]);
|
|
||||||
let invoiceOutTaxesIndex = stmts.push(stmt) - 1;
|
|
||||||
|
|
||||||
stmts.push(
|
|
||||||
`DROP TEMPORARY TABLE
|
|
||||||
tmp.ticket,
|
|
||||||
tmp.ticketTotal`);
|
|
||||||
|
|
||||||
let sql = ParameterizedSQL.join(stmts, ';');
|
|
||||||
let result = await conn.executeStmt(sql);
|
|
||||||
|
|
||||||
totalMap = {};
|
|
||||||
for (ticketTotal of result[ticketTotalsIndex])
|
|
||||||
totalMap[ticketTotal.ticketFk] = ticketTotal.total;
|
|
||||||
|
|
||||||
summary.invoiceOut.tickets().forEach(ticket => {
|
|
||||||
ticket.total = totalMap[ticket.id];
|
|
||||||
});
|
|
||||||
|
|
||||||
summary.invoiceOut.taxesBreakdown = result[invoiceOutTaxesIndex];
|
|
||||||
|
|
||||||
return summary;
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,4 +1,3 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
require('../methods/invoice-in/filter')(Self);
|
require('../methods/invoice-in/filter')(Self);
|
||||||
require('../methods/invoice-in/summary')(Self);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<vn-portal slot="menu">
|
<vn-portal slot="menu">
|
||||||
<vn-invoice-out-descriptor invoice-out="$ctrl.invoiceOut"></vn-invoice-out-descriptor>
|
<vn-invoice-in-descriptor invoice-in="$ctrl.invoiceIn"></vn-invoice-out-descriptor>
|
||||||
<vn-left-menu source="card"></vn-left-menu>
|
<vn-left-menu source="card"></vn-left-menu>
|
||||||
</vn-portal>
|
</vn-portal>
|
||||||
<ui-view></ui-view>
|
<ui-view></ui-view>
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Controller extends ModuleCard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnInvoiceOutCard', {
|
ngModule.vnComponent('vnInvoiceInCard', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller
|
controller: Controller
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,33 +2,14 @@ import ngModule from '../module';
|
||||||
import Descriptor from 'salix/components/descriptor';
|
import Descriptor from 'salix/components/descriptor';
|
||||||
|
|
||||||
class Controller extends Descriptor {
|
class Controller extends Descriptor {
|
||||||
get invoiceOut() {
|
get invoiceIn() {
|
||||||
return this.entity;
|
return this.entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
set invoiceOut(value) {
|
set invoiceIn(value) {
|
||||||
this.entity = value;
|
this.entity = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteInvoiceOut() {
|
|
||||||
return this.$http.post(`InvoiceOuts/${this.id}/delete`)
|
|
||||||
.then(() => this.$state.go('invoiceOut.index'))
|
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('InvoiceOut deleted')));
|
|
||||||
}
|
|
||||||
|
|
||||||
bookInvoiceOut() {
|
|
||||||
return this.$http.post(`InvoiceOuts/${this.invoiceOut.ref}/book`)
|
|
||||||
.then(() => this.$state.reload())
|
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('InvoiceOut booked')));
|
|
||||||
}
|
|
||||||
|
|
||||||
get filter() {
|
|
||||||
if (this.invoiceOut)
|
|
||||||
return JSON.stringify({refFk: this.invoiceOut.ref});
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
loadData() {
|
loadData() {
|
||||||
const filter = {
|
const filter = {
|
||||||
include: [
|
include: [
|
||||||
|
@ -37,24 +18,19 @@ class Controller extends Descriptor {
|
||||||
scope: {
|
scope: {
|
||||||
fields: ['id', 'code']
|
fields: ['id', 'code']
|
||||||
}
|
}
|
||||||
}, {
|
|
||||||
relation: 'client',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'name']
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.getData(`InvoiceOuts/${this.id}`, {filter})
|
return this.getData(`InvoiceIns/${this.id}`, {filter})
|
||||||
.then(res => this.entity = res.data);
|
.then(res => this.entity = res.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnInvoiceOutDescriptor', {
|
ngModule.vnComponent('vnInvoiceInDescriptor', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller,
|
controller: Controller,
|
||||||
bindings: {
|
bindings: {
|
||||||
invoiceOut: '<'
|
invoiceIn: '<'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,6 @@ export * from './module';
|
||||||
import './main';
|
import './main';
|
||||||
import './index/';
|
import './index/';
|
||||||
import './search-panel';
|
import './search-panel';
|
||||||
import './summary';
|
|
||||||
import './card';
|
import './card';
|
||||||
import './descriptor';
|
import './descriptor';
|
||||||
import './descriptor-popover';
|
import './descriptor-popover';
|
||||||
|
|
|
@ -2,16 +2,6 @@ import ngModule from '../module';
|
||||||
import Section from 'salix/components/section';
|
import Section from 'salix/components/section';
|
||||||
|
|
||||||
export default class Controller extends Section {
|
export default class Controller extends Section {
|
||||||
/* preview(invoiceOut) {
|
|
||||||
this.selectedInvoiceOut = invoiceOut;
|
|
||||||
this.$.summary.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
openPdf(id) {
|
|
||||||
let url = `api/InvoiceOuts/${id}/download?access_token=${this.vnToken.token}`;
|
|
||||||
window.open(url, '_blank');
|
|
||||||
} */
|
|
||||||
|
|
||||||
exprBuilder(param, value) {
|
exprBuilder(param, value) {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'shipped':
|
case 'shipped':
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
<vn-card class="summary">
|
|
||||||
<h5>
|
|
||||||
<a ng-if="::$ctrl.summary.invoiceOut.id"
|
|
||||||
vn-tooltip="Go to the Invoice Out"
|
|
||||||
ui-sref="invoiceOut.card.summary({id: {{::$ctrl.summary.invoiceOut.id}}})"
|
|
||||||
name="goToSummary">
|
|
||||||
<vn-icon-button icon="launch"></vn-icon-button>
|
|
||||||
</a>
|
|
||||||
<span>{{$ctrl.summary.invoiceOut.ref}} - {{$ctrl.summary.invoiceOut.client.socialName}}</span>
|
|
||||||
</h5>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-one>
|
|
||||||
<vn-label-value label="Date"
|
|
||||||
value="{{$ctrl.summary.invoiceOut.issued | date: 'dd/MM/yyyy'}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value label="Due"
|
|
||||||
value="{{$ctrl.summary.invoiceOut.dued | date: 'dd/MM/yyyy'}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value label="Created"
|
|
||||||
value="{{$ctrl.summary.invoiceOut.created | date: 'dd/MM/yyyy'}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value label="Booked"
|
|
||||||
value="{{$ctrl.summary.invoiceOut.booked | date: 'dd/MM/yyyy'}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value label="Company"
|
|
||||||
value="{{$ctrl.summary.invoiceOut.company.code | dashIfEmpty}}">
|
|
||||||
</vn-label-value>
|
|
||||||
</vn-one>
|
|
||||||
<vn-two>
|
|
||||||
<h4 translate>Tax breakdown</h4>
|
|
||||||
<vn-table model="model">
|
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th>Type</vn-th>
|
|
||||||
<vn-th>Taxable base</vn-th>
|
|
||||||
<vn-th>Rate</vn-th>
|
|
||||||
<vn-th>Fee</vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr ng-repeat="tax in $ctrl.summary.invoiceOut.taxesBreakdown">
|
|
||||||
<vn-td>{{tax.name}}</vn-td>
|
|
||||||
<vn-td>{{tax.taxableBase | currency: 'EUR': 2}}</vn-td>
|
|
||||||
<vn-td>{{tax.rate}}%</vn-td>
|
|
||||||
<vn-td>{{tax.vat | currency: 'EUR': 2}}</vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
</vn-two>
|
|
||||||
<vn-auto>
|
|
||||||
<h4 translate>Ticket</h4>
|
|
||||||
<vn-table model="model">
|
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th number>Ticket id</vn-th>
|
|
||||||
<vn-th>Alias</vn-th>
|
|
||||||
<vn-th expand>Shipped</vn-th>
|
|
||||||
<vn-th number>Amount</vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr ng-repeat="ticket in $ctrl.summary.invoiceOut.tickets">
|
|
||||||
<vn-td number>
|
|
||||||
<span
|
|
||||||
ng-click="ticketDescriptor.show($event, ticket.id)"
|
|
||||||
class="link">
|
|
||||||
{{ticket.id}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td>
|
|
||||||
<span
|
|
||||||
ng-click="clientDescriptor.show($event, ticket.clientFk)"
|
|
||||||
class="link">
|
|
||||||
{{ticket.nickname}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td expand>{{ticket.shipped | date: 'dd/MM/yyyy' | dashIfEmpty}}</vn-td>
|
|
||||||
<vn-td number>{{ticket.total | currency: 'EUR': 2}}</vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
</vn-auto>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-ticket-descriptor-popover
|
|
||||||
vn-id="ticketDescriptor">
|
|
||||||
</vn-ticket-descriptor-popover>
|
|
||||||
<vn-client-descriptor-popover
|
|
||||||
vn-id="clientDescriptor">
|
|
||||||
</vn-client-descriptor-popover>
|
|
|
@ -1,28 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Summary from 'salix/components/summary';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends Summary {
|
|
||||||
set invoiceOut(value) {
|
|
||||||
this._invoiceOut = value;
|
|
||||||
if (value && value.id)
|
|
||||||
this.getSummary();
|
|
||||||
}
|
|
||||||
|
|
||||||
get invoiceOut() {
|
|
||||||
return this._invoiceOut;
|
|
||||||
}
|
|
||||||
|
|
||||||
getSummary() {
|
|
||||||
return this.$http.get(`InvoiceOuts/${this.invoiceOut.id}/summary`)
|
|
||||||
.then(res => this.summary = res.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnInvoiceOutSummary', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
invoiceOut: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,29 +0,0 @@
|
||||||
import './index.js';
|
|
||||||
|
|
||||||
describe('InvoiceOut', () => {
|
|
||||||
describe('Component summary', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
let $scope;
|
|
||||||
|
|
||||||
beforeEach(ngModule('invoiceOut'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_, $rootScope) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
const $element = angular.element('<vn-invoice-out-summary></vn-invoice-out-summary>');
|
|
||||||
controller = $componentController('vnInvoiceOutSummary', {$element, $scope});
|
|
||||||
controller.invoiceOut = {id: 1};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('getSummary()', () => {
|
|
||||||
it('should perform a query to set summary', () => {
|
|
||||||
$httpBackend.when('GET', `InvoiceOuts/1/summary`).respond(200, 'the data you are looking for');
|
|
||||||
controller.getSummary();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.summary).toEqual('the data you are looking for');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,6 +0,0 @@
|
||||||
@import "variables";
|
|
||||||
|
|
||||||
|
|
||||||
vn-invoice-out-summary .summary {
|
|
||||||
max-width: $width-lg;
|
|
||||||
}
|
|
Loading…
Reference in New Issue