#1300-1301 client.risk

This commit is contained in:
Carlos Jimenez Ruiz 2019-04-05 13:20:34 +02:00
parent 5ae58f1d70
commit 837a7b08cc
12 changed files with 228 additions and 52 deletions

View File

@ -25,6 +25,7 @@ input[type=reset]::-moz-focus-inner {
a, .link {
color: $color-font-link;
text-decoration: none;
outline: 0
}
.link {
cursor: pointer;

View File

@ -36,13 +36,15 @@ module.exports = Self => {
r.payed,
c.code company,
r.created,
NULL ref,
r.invoiceFk ref,
NULL debit,
r.amountPaid credit,
r.bankFk,
u.nickname userNickname,
u.id userId,
r.clientFk,
FALSE pdf
FALSE pdf,
FALSE isInvoice
FROM vn.receipt r
LEFT JOIN vn.worker w ON w.id = r.workerFk
LEFT JOIN account.user u ON u.id = w.userFk
@ -60,11 +62,14 @@ module.exports = Self => {
NULL,
NULL,
NULL,
NULL,
i.clientFk,
i.pdf
i.pdf,
TRUE isInvoice
FROM vn.invoiceOut i
JOIN vn.company c ON c.id = i.companyFk
WHERE i.clientFk = ? AND i.companyFk = ?
ORDER BY payed DESC, created DESC
) t
ORDER BY payed DESC, created DESC`, [
params.clientFk,

View File

@ -1,7 +1,7 @@
const app = require('vn-loopback/server/server');
describe('receipt filter()', () => {
it('should call the filter method', async () => {
it('should return the receipts', async() => {
let filter = {limit: 20};
let params = {
clientFk: 101,

View File

@ -3,15 +3,13 @@
url="/client/api/receipts/filter"
params="$ctrl.params"
limit="20"
data="$ctrl.risks"
auto-load="true">
data="$ctrl.balances">
</vn-crud-model>
<vn-crud-model
vn-id="riskModel"
url="/client/api/ClientRisks"
filter="$ctrl.filter"
data="riskTotal"
auto-load="true">
data="$ctrl.riskTotal">
</vn-crud-model>
<vn-vertical>
<vn-card pad-large>
@ -20,6 +18,7 @@
</vn-one>
<vn-one>
<vn-autocomplete vn-one
vn-id="company"
field="$ctrl.companyFk"
on-change="$ctrl.setOrder(value)"
url="/client/api/Companies"
@ -29,9 +28,9 @@
</vn-autocomplete>
</vn-one>
<vn-one>
<div class="totalBox" ng-if="riskTotal.length">
<div class="totalBox" ng-if="$ctrl.riskTotal.length">
<h6 translate>Total by company</h6>
<vn-auto ng-repeat="riskByCompany in riskTotal">
<vn-auto ng-repeat="riskByCompany in $ctrl.riskTotal">
<vn-label-value
label="{{riskByCompany.company.code}}"
value="{{riskByCompany.amount | currency: 'EUR':2}}">
@ -44,7 +43,7 @@
<vn-table model="model">
<vn-thead>
<vn-tr>
<vn-th>Date</vn-th>
<vn-th default-order>Date</vn-th>
<vn-th>Creation date</vn-th>
<vn-th>Employee</vn-th>
<vn-th>Reference</vn-th>
@ -57,27 +56,37 @@
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="risk in $ctrl.risks">
<vn-td>{{::risk.payed | dateTime:'dd/MM/yyyy'}}</vn-td>
<vn-td>{{::risk.created | dateTime:'dd/MM/yyyy HH:mm'}}</vn-td>
<vn-td>{{::risk.userNickname}}</vn-td>
<vn-tr ng-repeat="balance in $ctrl.balances">
<vn-td>{{::balance.payed | dateTime:'dd/MM/yyyy'}}</vn-td>
<vn-td>{{::balance.created | dateTime:'dd/MM/yyyy HH:mm'}}</vn-td>
<vn-td>
<span ng-show="risk.ref" translate>BILL</span> {{::risk.ref}}
<span
class="link"
ng-click="$ctrl.showWorkerDescriptor($event, balance.userId)">
{{::balance.userNickname}}
</span>
</vn-td>
<vn-td number>{{::risk.bankFk}}</vn-td>
<vn-td number>{{::risk.debit | currency: 'EUR':2}}</vn-td>
<vn-td number>{{::risk.credit | currency: 'EUR':2}}</vn-td>
<vn-td number>{{risk.balance | currency: 'EUR':2}}</vn-td>
<vn-td>
<span
ng-class="{'link': balance.isInvoice}"
ng-click="$ctrl.showInvoiceOutDescriptor($event, balance)"
ng-show="balance.ref">{{balance.isInvoice ? 'BILL' : balance.ref | translate: {ref: balance.ref} }}
</span>
</vn-td>
<vn-td number>{{::balance.bankFk}}</vn-td>
<vn-td number>{{::balance.debit | currency: 'EUR':2}}</vn-td>
<vn-td number>{{::balance.credit | currency: 'EUR':2}}</vn-td>
<vn-td number>{{balance.balance | currency: 'EUR':2}}</vn-td>
<vn-td center>
<vn-check
field="risk.isConciliate"
field="balance.isConciliate"
disabled="true">
</vn-check>
</vn-td>
<vn-td center>
<a ng-show="risk.pdf"
<a ng-show="balance.pdf"
target="_blank"
href="api/InvoiceOuts/{{::risk.id}}/download?access_token={{::$ctrl.accessToken}}">
href="api/InvoiceOuts/{{::balance.id}}/download?access_token={{::$ctrl.accessToken}}">
<vn-icon-button
icon="cloud_download"
title="Download PDF">
@ -103,4 +112,14 @@
</vn-float-button>
<vn-client-risk-create vn-id="riskCreateDialog">
</vn-client-risk-create>
</vn-client-risk-create>
<vn-worker-descriptor-popover
vn-id="workerDescriptor"
user-id="$ctrl.selectedWorker">
</vn-worker-descriptor-popover>
<vn-invoice-out-descriptor-popover
vn-id="invoiceOutDescriptor"
invoice-out-id="$ctrl.selectedInvoiceOut">
</vn-invoice-out-descriptor-popover>

View File

@ -2,7 +2,8 @@ import ngModule from '../../module';
import './style.scss';
class Controller {
constructor($stateParams, $translate, $scope, vnToken) {
constructor($stateParams, $translate, $scope, vnToken, $http) {
this.$http = $http;
this.$ = $scope;
this.$stateParams = $stateParams;
this.$translate = $translate;
@ -38,26 +39,46 @@ class Controller {
this.$.riskModel.refresh();
}
set risks(value) {
if (value) {
for (let i = this.$.model.data.length - 1; i >= 0; i--) {
let row = this.$.model.data[i];
let tot;
if (i != this.$.model.data.length - 1)
row.balance = (row.credit - row.debit) + (this.$.model.data[i + 1].balance);
else
row.balance = row.credit - row.debit;
set balances(value) {
this._balances = value;
tot = tot + row.balance;
if (!value) return;
const params = {filter: this.filter};
this.$http.get(`/client/api/ClientRisks`, {params}).then(response => {
if (response.data) {
this.riskTotal = response.data;
this.getBalances();
}
this._risks = this.$.model.data;
}
});
}
get risks() {
return this._risks;
get balances() {
return this._balances;
}
getCurrentBalance() {
const selectedCompany = this.$.company.selection;
const currentBalance = this.riskTotal.find(balance => {
return balance.companyFk === selectedCompany.id;
});
return currentBalance.amount;
}
getBalances() {
this.balances.forEach((balance, index) => {
if (index === 0)
balance.balance = this.getCurrentBalance();
if (index > 0) {
let previousBalance = this.balances[index - 1];
balance.balance = previousBalance.balance - (previousBalance.debit - previousBalance.credit);
}
});
}
openCreateDialog() {
this.$.riskCreateDialog.companyFk = this.companyFk;
this.$.riskCreateDialog.onResponse = () => {
@ -69,9 +90,32 @@ class Controller {
onDownload() {
alert('Not implemented yet');
}
showWorkerDescriptor(event, userId) {
if (event.defaultPrevented) return;
event.preventDefault();
event.stopPropagation();
this.selectedWorker = userId;
this.$.workerDescriptor.parent = event.target;
this.$.workerDescriptor.show();
}
showInvoiceOutDescriptor(event, balance) {
if (!balance.isInvoice) return;
if (event.defaultPrevented) return;
event.preventDefault();
event.stopPropagation();
this.selectedInvoiceOut = balance.id;
this.$.invoiceOutDescriptor.parent = event.target;
this.$.invoiceOutDescriptor.show();
}
}
Controller.$inject = ['$stateParams', '$translate', '$scope', 'vnToken'];
Controller.$inject = ['$stateParams', '$translate', '$scope', 'vnToken', '$http'];
ngModule.component('vnClientRiskIndex', {
template: require('./index.html'),

View File

@ -4,29 +4,40 @@ describe('Client', () => {
describe('Component vnClientRiskIndex', () => {
let $componentController;
let $scope;
let $httpBackend;
let $httpParamSerializer;
let controller;
beforeEach(ngModule('client'));
beforeEach(angular.mock.inject((_$componentController_, $rootScope) => {
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
$componentController = _$componentController_;
$httpBackend = _$httpBackend_;
$httpParamSerializer = _$httpParamSerializer_;
$scope = $rootScope.$new();
controller = $componentController('vnClientRiskIndex', {$scope});
}));
describe('risks() setter', () => {
describe('balances() setter', () => {
it('should calculate the balance for each line from the oldest date to the newest', () => {
let risks = [
controller.getCurrentBalance = jasmine.createSpy(controller, 'getCurrentBalance').and.returnValue(1000);
let balances = [
{credit: -100, debit: 0},
{credit: 0, debit: 300},
{credit: 100, debit: 0},
{credit: 100, debit: 0},
{credit: 0, debit: 300}
{credit: 0, debit: -300}
];
controller.$.model = {data: risks};
controller.risks = risks;
const params = {filter: controller.filter};
let serializedParams = $httpParamSerializer(params);
$httpBackend.when('GET', `/client/api/ClientRisks?${serializedParams}`).respond(balances);
$httpBackend.expect('GET', `/client/api/ClientRisks?${serializedParams}`);
controller.balances = balances;
$httpBackend.flush();
expect(controller.risks[0].balance).toEqual(-100);
expect(controller.risks[1].balance).toEqual(-200);
expect(controller.risks[2].balance).toEqual(-300);
expect(controller.balances[0].balance).toEqual(1000);
expect(controller.balances[1].balance).toEqual(900);
expect(controller.balances[2].balance).toEqual(600);
expect(controller.balances[3].balance).toEqual(700);
});
});
});

View File

@ -8,4 +8,4 @@ Havings: Haber
Balance: Balance
Total by company: Total por empresa
Download PDF: Descargar PDF
BILL: N/FRA
BILL: N/FRA {{ref}}

View File

@ -3,7 +3,7 @@
"name": "Clients",
"icon": "icon-person",
"validations" : true,
"dependencies": ["worker"],
"dependencies": ["worker", "invoiceOut"],
"menu": [
{"state": "client.card.basicData", "icon": "settings"},
{"state": "client.card.fiscalData", "icon": "account_balance"},

View File

@ -0,0 +1,12 @@
<vn-popover vn-id="popover">
<vn-spinner
ng-if="$ctrl.invoiceOut == null"
style="padding: 1em;"
enable="true">
</vn-spinner>
<vn-invoice-out-descriptor
ng-if="$ctrl.invoiceOut"
invoice-out="$ctrl.invoiceOut"
quicklinks="$ctrl.quicklinks">
</vn-invoice-out-descriptor>
</vn-popover>

View File

@ -0,0 +1,72 @@
import ngModule from '../module';
import Component from 'core/lib/component';
import './style.scss';
class Controller extends Component {
constructor($element, $scope, $http, $timeout, $q) {
super($element, $scope);
this.$timeout = $timeout;
this.$http = $http;
this.$q = $q;
this.worker = null;
}
set invoiceOutId(id) {
if (id == this._invoiceOutId) return;
this._invoiceOutId = id;
this.invoiceOut = null;
this.loadData();
}
get invoiceOutId() {
return this._invoiceOutId;
}
set quicklinks(value = {}) {
this._quicklinks = Object.assign(value, this._quicklinks);
}
get quicklinks() {
return this._quicklinks;
}
show() {
this.$.popover.parent = this.parent;
this.$.popover.show();
}
loadData() {
let query = `api/InvoiceOuts/findOne`;
let filter = {
where: {
id: this._invoiceOutId
},
include: [
{
relation: 'company',
scope: {
fields: ['id', 'code']
}
}
]
};
this.$http.get(query, {params: {filter}}).then(res => {
this.invoiceOut = res.data;
this.$.$applyAsync(() => {
this.$.popover.relocate();
});
});
}
}
Controller.$inject = ['$element', '$scope', '$http', '$timeout', '$q'];
ngModule.component('vnInvoiceOutDescriptorPopover', {
template: require('./index.html'),
controller: Controller,
bindings: {
invoiceOutId: '<',
quicklinks: '<'
}
});

View File

@ -0,0 +1,11 @@
vn-ticket-descriptor-popover {
vn-ticket-descriptor {
display: block;
width: 16em;
max-height: 28em;
& > vn-card {
margin: 0!important;
}
}
}

View File

@ -5,3 +5,4 @@ import './search-panel';
import './summary';
import './card';
import './descriptor';
import './descriptor-popover';