#1263 invoiceOut.summary

This commit is contained in:
Carlos Jimenez Ruiz 2019-03-28 11:55:23 +01:00
parent b24a6a6255
commit a14ba28629
26 changed files with 630 additions and 127 deletions

View File

@ -398,6 +398,18 @@ UPDATE `vn`.`invoiceOut` SET ref = 'T3333333' WHERE id = 3;
UPDATE `vn`.`invoiceOut` SET ref = 'T4444444' WHERE id = 4; UPDATE `vn`.`invoiceOut` SET ref = 'T4444444' WHERE id = 4;
UPDATE `vn`.`invoiceOut` SET ref = 'A1111111' WHERE id = 5; UPDATE `vn`.`invoiceOut` SET ref = 'A1111111' WHERE id = 5;
INSERT INTO `vn`.`invoiceOutTax` (`invoiceOutFk`, `taxableBase`, `vat`, `pgcFk`)
VALUES
(1, 100, 10, 4722000010),
(1, 200, 21, 4722000021),
(2, 100, 10, 4722000010),
(2, 200, 21, 4722000021),
(3, 100, 10, 4722000010),
(3, 200, 21, 4722000021),
(4, 100, 10, 4722000010),
(4, 200, 21, 4722000021),
(5, 100, 10, 4722000010),
(5, 200, 21, 4722000021);
INSERT INTO `vn`.`ticket`(`id`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `created`) INSERT INTO `vn`.`ticket`(`id`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `created`)
VALUES VALUES

View File

@ -7,15 +7,15 @@ export default function moduleImport(moduleName) {
//); //);
switch(moduleName) { switch(moduleName) {
case 'client' : return import('client/front'); case 'client' : return import('client/front');
case 'item' : return import('item/front'); case 'item' : return import('item/front');
case 'ticket' : return import('ticket/front'); case 'ticket' : return import('ticket/front');
case 'order' : return import('order/front'); case 'order' : return import('order/front');
case 'claim' : return import('claim/front'); case 'claim' : return import('claim/front');
case 'agency' : return import('agency/front'); case 'agency' : return import('agency/front');
case 'travel' : return import('travel/front'); case 'travel' : return import('travel/front');
case 'worker' : return import('worker/front'); case 'worker' : return import('worker/front');
case 'invoiceOut' : return import('invoiceOut/front'); case 'invoiceOut' : return import('invoiceOut/front');
case 'route' : return import('route/front'); case 'route' : return import('route/front');
} }
} }

View File

@ -50,9 +50,6 @@
"GreugeType": { "GreugeType": {
"dataSource": "vn" "dataSource": "vn"
}, },
"InvoiceOut": {
"dataSource": "vn"
},
"Mandate": { "Mandate": {
"dataSource": "vn" "dataSource": "vn"
}, },

View File

@ -1,3 +0,0 @@
module.exports = function(Self) {
require('../methods/invoice-out/download')(Self);
};

View File

@ -1,58 +0,0 @@
{
"name": "InvoiceOut",
"base": "VnModel",
"options": {
"mysql": {
"table": "invoiceOut"
}
},
"properties": {
"id": {
"id": true,
"type": "Number",
"description": "Identifier"
},
"ref": {
"id": true,
"type": "String",
"required": true
},
"serial": {
"type": "String"
},
"issued": {
"type": "date"
},
"amount": {
"type": "Number"
},
"created": {
"type": "date"
},
"dued": {
"type": "date"
},
"booked": {
"type": "date"
},
"hasPdf": {
"type": "Number",
"mysql": {
"columnName": "pdf"
}
}
},
"relations": {
"client": {
"type": "belongsTo",
"model": "Client",
"foreignKey": "clientFk"
},
"company": {
"type": "belongsTo",
"model": "Company",
"foreignKey": "companyFk",
"required": true
}
}
}

View File

@ -0,0 +1,31 @@
const app = require('vn-loopback/server/server');
describe('invoiceOut summary()', () => {
it('should return a summary object containing data from one invoiceOut', async() => {
let 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() => {
let result = await app.models.InvoiceOut.summary(1);
expect(result.invoiceOut.ref).toEqual('T1111111');
expect(result.invoiceOut.tickets().length).toEqual(1);
});
it(`should return a summary object containing it's supplier country`, async() => {
let result = await app.models.InvoiceOut.summary(1);
expect(result.invoiceOut.ref).toEqual('T1111111');
expect(result.invoiceOut.supplier().id).toEqual(442);
expect(result.invoiceOut.supplier().countryFk).toEqual(1);
});
it(`should return a summary object containing idata from it's tax types`, async() => {
let result = await app.models.InvoiceOut.summary(1);
expect(result.invoiceOut.ref).toEqual('T1111111');
expect(result.invoiceOut.taxesBreakdown.length).toEqual(2);
});
});

View File

@ -0,0 +1,114 @@
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 tc.description as type, SUM(ROUND(s.quantity * s.price * (100 - s.discount) / 100,2)) AS base
FROM vn.sale s
JOIN vn.ticket t ON t.id = s.ticketFk
LEFT JOIN vn.itemTaxCountry itc ON itc.itemFk = s.itemFk
JOIN vn.country c ON c.id = itc.countryFK AND c.id = ?
LEFT JOIN vn.taxClass tc ON tc.id = itc.taxClassFk
WHERE t.refFk = ?
GROUP BY type`, [summary.invoiceOut.supplier().countryFk, summary.invoiceOut.ref]);
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;
};
};

View File

@ -0,0 +1,5 @@
{
"InvoiceOut": {
"dataSource": "vn"
}
}

View File

@ -0,0 +1,4 @@
module.exports = Self => {
require('../methods/invoiceOut/summary')(Self);
require('../methods/invoiceOut/download')(Self);
};

View File

@ -0,0 +1,71 @@
{
"name": "InvoiceOut",
"base": "VnModel",
"options": {
"mysql": {
"table": "invoiceOut"
}
},
"properties": {
"id": {
"id": true,
"type": "Number",
"description": "Identifier"
},
"ref": {
"type": "String",
"required": true
},
"serial": {
"type": "String"
},
"issued": {
"type": "date"
},
"amount": {
"type": "Number"
},
"created": {
"type": "date"
},
"dued": {
"type": "date"
},
"booked": {
"type": "date"
},
"hasPdf": {
"type": "Number",
"mysql": {
"columnName": "pdf"
}
}
},
"relations": {
"client": {
"type": "belongsTo",
"model": "Client",
"foreignKey": "clientFk"
},
"company": {
"type": "belongsTo",
"model": "Company",
"foreignKey": "companyFk",
"required": true
},
"supplier": {
"type": "belongsTo",
"model": "Supplier",
"foreignKey": "companyFk",
"required": true
},
"tickets": {
"type": "hasMany",
"model": "Ticket",
"foreignKey": "refFk",
"primaryKey": "ref"
}
}
}

View File

@ -14,15 +14,13 @@ export default class Controller {
'clientFk', 'clientFk',
'companyFk' 'companyFk'
], ],
where: {id: $stateParams.id},
include: [ include: [
{ {
relation: 'company', relation: 'company',
scope: { scope: {
fields: ['id', 'code'] fields: ['id', 'code']
} }
}, }, {
{
relation: 'client', relation: 'client',
scope: { scope: {
fields: ['id', 'socialName'] fields: ['id', 'socialName']
@ -37,10 +35,9 @@ export default class Controller {
} }
getCard() { getCard() {
let json = encodeURIComponent(JSON.stringify(this.filter)); const params = {filter: this.filter};
this.$http.get(`/client/api/InvoiceOuts?filter=${json}`).then(response => { this.$http.get(`/api/InvoiceOuts/${this.$stateParams.id}`, {params}).then(response => {
this.invoiceOut = response.data[0]; this.invoiceOut = response.data;
console.log(response.data[0]);
}); });
} }

View File

@ -2,5 +2,6 @@ export * from './module';
import './index/'; import './index/';
import './search-panel'; import './search-panel';
import './summary';
import './card'; import './card';
import './descriptor'; import './descriptor';

View File

@ -3,7 +3,7 @@
url="/api/InvoiceOuts" url="/api/InvoiceOuts"
filter="::$ctrl.filter" filter="::$ctrl.filter"
limit="20" limit="20"
data="invoices" data="invoicesOut"
order="id ASC" order="id ASC"
auto-load="false"> auto-load="false">
</vn-crud-model> </vn-crud-model>
@ -35,26 +35,26 @@
</vn-tr> </vn-tr>
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
<a ng-repeat="invoice in invoices" <a ng-repeat="invoiceOut in invoicesOut"
class="clickable vn-tr searchResult" class="clickable vn-tr searchResult"
ui-sref="invoice.card.summary({id: {{::invoice.id}}})"> ui-sref="invoiceOut.card.summary({id: {{::invoiceOut.id}}})">
<vn-td>{{::invoice.ref | dashIfEmpty}}</vn-td> <vn-td>{{::invoiceOut.ref | dashIfEmpty}}</vn-td>
<vn-td>{{::invoice.issued | dateTime:'dd/MM/yyyy' | dashIfEmpty}}</vn-td> <vn-td>{{::invoiceOut.issued | dateTime:'dd/MM/yyyy' | dashIfEmpty}}</vn-td>
<vn-td number>{{::invoice.amount | currency: 'EUR': 2 | dashIfEmpty}}</vn-td> <vn-td number>{{::invoiceOut.amount | currency: 'EUR': 2 | dashIfEmpty}}</vn-td>
<vn-td> <vn-td>
<span <span
class="link" class="link"
ng-click="$ctrl.showClientDescriptor($event, invoice.clientFk)"> ng-click="$ctrl.showClientDescriptor($event, invoiceOut.clientFk)">
{{::invoice.client.name | dashIfEmpty}} {{::invoiceOut.client.name | dashIfEmpty}}
</span> </span>
</vn-td> </vn-td>
<vn-td>{{::invoice.created | dateTime:'dd/MM/yyyy' | dashIfEmpty}}</vn-td> <vn-td>{{::invoiceOut.created | dateTime:'dd/MM/yyyy' | dashIfEmpty}}</vn-td>
<vn-td>{{::invoice.company.code | dashIfEmpty}}</vn-td> <vn-td>{{::invoiceOut.company.code | dashIfEmpty}}</vn-td>
<vn-td>{{::invoice.dued | dateTime:'dd/MM/yyyy' | dashIfEmpty}}</vn-td> <vn-td>{{::invoiceOut.dued | dateTime:'dd/MM/yyyy' | dashIfEmpty}}</vn-td>
<vn-td> <vn-td>
<vn-icon-button <vn-icon-button
ng-show="invoice.hasPdf" ng-show="invoiceOut.hasPdf"
ng-click="$ctrl.openPdf(invoice.id)" ng-click="$ctrl.openPdf(invoiceOut.id, $event)"
icon="cloud_download" icon="cloud_download"
title="Download PDF" title="Download PDF"
vn-tooltip="Download PDF"> vn-tooltip="Download PDF">
@ -62,7 +62,7 @@
</vn-td> </vn-td>
<vn-td> <vn-td>
<vn-icon-button <vn-icon-button
ng-click="$ctrl.preview($event, invoice)" ng-click="$ctrl.preview($event, invoiceOut)"
vn-tooltip="Preview" vn-tooltip="Preview"
icon="desktop_windows"> icon="desktop_windows">
</vn-icon-button> </vn-icon-button>
@ -77,7 +77,7 @@
vn-id="summary" vn-id="summary"
class="dialog-summary"> class="dialog-summary">
<tpl-body> <tpl-body>
<vn-invoice-summary invoice="$ctrl.selectedTicket"></vn-invoice-summary> <vn-invoice-out-summary invoice-out="$ctrl.selectedInvoiceOut"></vn-invoice-out-summary>
</tpl-body> </tpl-body>
</vn-dialog> </vn-dialog>
<vn-client-descriptor-popover vn-id="clientDescriptor"></vn-client-descriptor-popover> <vn-client-descriptor-popover vn-id="clientDescriptor"></vn-client-descriptor-popover>

View File

@ -4,7 +4,7 @@ export default class Controller {
constructor($scope, vnToken) { constructor($scope, vnToken) {
this.accessToken = vnToken.token; this.accessToken = vnToken.token;
this.$ = $scope; this.$ = $scope;
this.ticketSelected = null; this.selectedInvoiceOut = null;
this.filter = { this.filter = {
include: [ include: [
@ -51,9 +51,9 @@ export default class Controller {
event.stopImmediatePropagation(); event.stopImmediatePropagation();
} }
preview(event, claim) { preview(event, invoiceOut) {
this.claimSelected = claim; this.selectedInvoiceOut = invoiceOut;
this.$.dialogSummaryClaim.show(); this.$.summary.show();
event.preventDefault(); event.preventDefault();
event.stopImmediatePropagation(); event.stopImmediatePropagation();
} }
@ -62,9 +62,11 @@ export default class Controller {
this.$.popover.relocate(); this.$.popover.relocate();
} }
openPdf(id) { openPdf(id, event) {
let url = `api/InvoiceOuts/${id}/download?access_token=${this.accessToken}`; let url = `api/InvoiceOuts/${id}/download?access_token=${this.accessToken}`;
window.open(url, '_blank'); window.open(url, '_blank');
event.preventDefault();
event.stopImmediatePropagation();
} }
} }

View File

@ -3,10 +3,10 @@
"name": "Invoices out", "name": "Invoices out",
"icon": "icon-invoices1", "icon": "icon-invoices1",
"validations" : true, "validations" : true,
"dependencies": ["client"], "dependencies": ["client", "ticket"],
"routes": [ "routes": [
{ {
"url": "/invoiceOut", "url": "/invoice-out",
"state": "invoiceOut", "state": "invoiceOut",
"abstract": true, "abstract": true,
"component": "ui-view", "component": "ui-view",
@ -17,12 +17,21 @@
"url": "/index?q", "url": "/index?q",
"state": "invoiceOut.index", "state": "invoiceOut.index",
"component": "vn-invoice-out-index", "component": "vn-invoice-out-index",
"description": "Invoices out" "description": "Invoice out"
},
{
"url": "/summary",
"state": "invoiceOut.card.summary",
"component": "vn-invoice-out-summary",
"description": "Summary",
"params": {
"invoice-out": "$ctrl.invoiceOut"
}
}, },
{ {
"url": "/:id", "url": "/:id",
"state": "invoiceOut.card", "state": "invoiceOut.card",
"abstract": false, "abstract": true,
"component": "vn-invoice-out-card" "component": "vn-invoice-out-card"
} }
] ]

View File

@ -0,0 +1,74 @@
<vn-card class="summary">
<h5>{{$ctrl.summary.invoiceOut.ref}} - {{$ctrl.summary.invoiceOut.client.socialName}}</h5>
<vn-horizontal>
<vn-one>
<vn-label-value label="Date"
value="{{$ctrl.summary.invoiceOut.issued | dateTime: 'dd/MM/yyyy'}}">
</vn-label-value>
<vn-label-value label="Due"
value="{{$ctrl.summary.invoiceOut.dued | dateTime: 'dd/MM/yyyy'}}">
</vn-label-value>
<vn-label-value label="Created"
value="{{$ctrl.summary.invoiceOut.created | dateTime: 'dd/MM/yyyy'}}">
</vn-label-value>
<vn-label-value label="Booked"
value="{{$ctrl.summary.invoiceOut.booked | dateTime: 'dd/MM/yyyy'}}">
</vn-label-value>
</vn-one>
<vn-one>
<vn-label-value label="Company"
value="{{$ctrl.summary.invoiceOut.company.code | dashIfEmpty}}">
</vn-label-value>
<vn-icon-button
ng-show="$ctrl.summary.invoiceOut.hasPdf"
ng-click="$ctrl.openPdf(invoiceOut.id, $event)"
icon="cloud_download"
title="Download PDF"
vn-tooltip="Download PDF">
</vn-icon-button>
</vn-one>
<vn-one>
<vn-label-value ng-repeat="tax in $ctrl.summary.invoiceOut.taxesBreakdown"
label="{{tax.type}}"
value="{{tax.base | currency: 'EUR': 2}}">
</vn-label-value>
</vn-one>
<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 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="$ctrl.showTicketDescriptor($event, ticket.id)"
class="link">
{{ticket.id | zeroFill:6}}
</span>
</vn-td>
<vn-td>
<span
ng-click="$ctrl.showClientDescriptor($event, ticket.clientFk)"
class="link">
{{ticket.nickname}}
</span>
</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>

View File

@ -0,0 +1,66 @@
import ngModule from '../module';
import './style.scss';
class Controller {
constructor($scope, $http, vnToken) {
this.accessToken = vnToken.token;
this.$http = $http;
this.$ = $scope;
}
set invoiceOut(value) {
this._invoiceOut = value;
if (value && value.id)
this.getSummary();
}
get invoiceOut() {
return this._invoiceOut;
}
openPdf(id, event) {
let url = `api/InvoiceOuts/${id}/download?access_token=${this.accessToken}`;
window.open(url, '_blank');
event.preventDefault();
event.stopImmediatePropagation();
}
getSummary() {
this.$http.get(`/api/InvoiceOuts/${this.invoiceOut.id}/summary`).then(response => {
this.summary = response.data;
});
}
showClientDescriptor(event, clientFk) {
this.$.clientDescriptor.clientFk = clientFk;
this.$.clientDescriptor.parent = event.target;
this.$.clientDescriptor.show();
event.preventDefault();
event.stopImmediatePropagation();
}
showTicketDescriptor(event, ticketFk) {
this.$.ticketDescriptor.ticketFk = ticketFk;
this.$.ticketDescriptor.parent = event.target;
this.$.ticketDescriptor.show();
event.preventDefault();
event.stopImmediatePropagation();
}
preview(event, invoiceOut) {
this.selectedInvoiceOut = invoiceOut;
this.$.invoiceOutSummaryDialog.show();
event.preventDefault();
event.stopImmediatePropagation();
}
}
Controller.$inject = ['$scope', '$http', 'vnToken'];
ngModule.component('vnInvoiceOutSummary', {
template: require('./index.html'),
controller: Controller,
bindings: {
invoiceOut: '<'
}
});

View File

@ -0,0 +1,41 @@
import './index.js';
describe('Route', () => {
describe('Component summary', () => {
let controller;
let $httpBackend;
beforeEach(ngModule('route'));
beforeEach(angular.mock.inject(($componentController, _$httpBackend_) => {
$httpBackend = _$httpBackend_;
controller = $componentController('vnRouteSummary');
controller.route = {id: 1};
}));
describe('getSummary()', () => {
it('should perform a query to set summary', () => {
$httpBackend.when('GET', `/api/Routes/1/summary`).respond(200, 24);
$httpBackend.expect('GET', `/api/Routes/1/summary`);
controller.getSummary();
$httpBackend.flush();
expect(controller.summary).toEqual(24);
});
});
describe('sumPackages()', () => {
it('should calculate the packages total', () => {
controller.summary = {
tickets: [
{packages: 3},
{packages: 1}
]
};
controller.sumPackages();
expect(controller.packagesTotal).toEqual(4);
});
});
});
});

View File

@ -0,0 +1,15 @@
Driver: Conductor
Vehicle: Vehículo
Packages: Bultos
Starting time: H. Inicio
Finishing time: H. Fin
Km Start: Km de inicio
Km End: Km de fin
PC: CP
Date: Fecha
Created: Creada
Due: Vencimiento
Booked: Asentado
General VAT: IVA general
Reduced VAT: IVA reducido

View File

@ -0,0 +1,10 @@
@import "variables";
vn-route-summary .summary {
max-width: $width-large;
vn-icon[icon=insert_drive_file]{
color: $color-font-secondary;
}
}

View File

@ -64,5 +64,8 @@
}, },
"TaxType": { "TaxType": {
"dataSource": "vn" "dataSource": "vn"
},
"Supplier": {
"dataSource": "vn"
} }
} }

View File

@ -0,0 +1,78 @@
{
"name": "Supplier",
"base": "VnModel",
"options": {
"mysql": {
"table": "supplier"
}
},
"properties": {
"id": {
"type": "Number",
"id": true,
"description": "Identifier"
},
"name": {
"type": "String"
},
"account": {
"type": "Number"
},
"countryFk": {
"type": "Number"
},
"nif": {
"type": "String"
},
"isFarmer": {
"type": "Boolean"
},
"phone": {
"type": "Number"
},
"retAccount": {
"type": "Number"
},
"commision": {
"type": "Boolean"
},
"created": {
"type": "Date"
},
"poscodeFk": {
"type": "Number"
},
"isActive": {
"type": "Boolean"
},
"street": {
"type": "String"
},
"city": {
"type": "String"
},
"provinceFk": {
"type": "Number"
},
"postCode": {
"type": "Number"
},
"payMethodFk": {
"type": "Number"
},
"payDemFk": {
"type": "Number"
},
"nickname": {
"type": "String"
}
},
"acls": [
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
}
]
}

View File

@ -34,7 +34,6 @@ module.exports = Self => {
subtotal += service.price * service.quantity; subtotal += service.price * service.quantity;
}); });
return Math.round(subtotal * 100) / 100; return Math.round(subtotal * 100) / 100;
}; };
}; };

View File

@ -65,7 +65,8 @@
"invoiceOut": { "invoiceOut": {
"type": "belongsTo", "type": "belongsTo",
"model": "InvoiceOut", "model": "InvoiceOut",
"foreignKey": "refFk" "foreignKey": "refFk",
"primaryKey": "ref"
}, },
"address": { "address": {
"type": "belongsTo", "type": "belongsTo",

74
package-lock.json generated
View File

@ -5180,7 +5180,8 @@
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@ -5201,12 +5202,14 @@
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@ -5221,17 +5224,20 @@
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@ -5348,7 +5354,8 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@ -5360,6 +5367,7 @@
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@ -5374,6 +5382,7 @@
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
@ -5381,12 +5390,14 @@
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.2.4", "version": "2.2.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.1", "safe-buffer": "^5.1.1",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@ -5405,6 +5416,7 @@
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
@ -5485,7 +5497,8 @@
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
@ -5497,6 +5510,7 @@
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@ -5582,7 +5596,8 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.1", "version": "5.1.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@ -5618,6 +5633,7 @@
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@ -5637,6 +5653,7 @@
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@ -5680,12 +5697,14 @@
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.2", "version": "3.0.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
} }
} }
}, },
@ -10748,7 +10767,8 @@
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@ -10791,7 +10811,8 @@
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
@ -10802,7 +10823,8 @@
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@ -10919,7 +10941,8 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@ -10931,6 +10954,7 @@
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@ -10953,12 +10977,14 @@
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.3.5", "version": "2.3.5",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@ -10977,6 +11003,7 @@
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
@ -11057,7 +11084,8 @@
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
@ -11069,6 +11097,7 @@
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@ -11154,7 +11183,8 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@ -11190,6 +11220,7 @@
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@ -11209,6 +11240,7 @@
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@ -11252,12 +11284,14 @@
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.3", "version": "3.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
} }
} }
}, },