Merge pull request '5128-client.credit-management' (!1459) from 5128-client.credit-management into dev
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Reviewed-on: #1459 Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
This commit is contained in:
commit
75432b8823
|
@ -0,0 +1,3 @@
|
||||||
|
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||||
|
VALUES ('ClientInforma', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('ClientInforma', '*', 'WRITE', 'ALLOW', 'ROLE', 'financial');
|
|
@ -0,0 +1,16 @@
|
||||||
|
ALTER TABLE `vn`.`client` ADD rating INT UNSIGNED DEFAULT NULL NULL COMMENT 'información proporcionada por Informa';
|
||||||
|
ALTER TABLE `vn`.`client` ADD recommendedCredit INT UNSIGNED DEFAULT NULL NULL COMMENT 'información proporcionada por Informa';
|
||||||
|
|
||||||
|
CREATE TABLE `vn`.`clientInforma` (
|
||||||
|
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`clientFk` int(11) NOT NULL,
|
||||||
|
`rating` int(10) unsigned DEFAULT NULL,
|
||||||
|
`recommendedCredit` int(10) unsigned DEFAULT NULL,
|
||||||
|
`workerFk` int(10) unsigned NOT NULL,
|
||||||
|
`created` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `informaWorkers_fk_idx` (`workerFk`),
|
||||||
|
KEY `informaClientFk` (`clientFk`),
|
||||||
|
CONSTRAINT `informa_ClienteFk` FOREIGN KEY (`clientFk`) REFERENCES `client` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT `informa_workers_fk` FOREIGN KEY (`workerFk`) REFERENCES `worker` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='información proporcionada por Informa, se actualiza desde el hook de client (salix)';
|
|
@ -0,0 +1,64 @@
|
||||||
|
DELETE FROM `salix`.`ACL` WHERE id=7;
|
||||||
|
|
||||||
|
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
||||||
|
VALUES
|
||||||
|
('Client', 'setRating', 'WRITE', 'ALLOW', 'ROLE', 'financial');
|
||||||
|
|
||||||
|
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
||||||
|
VALUES
|
||||||
|
('Client', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'addressesPropagateRe', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'canBeInvoiced', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'canCreateTicket', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'consumption', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'createAddress', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'createWithUser', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'extendedListFilter', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'getAverageInvoiced', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'getCard', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'getDebt', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'getMana', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'transactions', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'hasCustomerRole', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'isValidClient', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'lastActiveTickets', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'sendSms', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'setPassword', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'summary', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'updateAddress', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'updateFiscalData', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'updateUser', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'uploadFile', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'campaignMetricsPdf', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'campaignMetricsEmail', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'clientWelcomeHtml', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'clientWelcomeEmail', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'printerSetupHtml', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'printerSetupEmail', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'sepaCoreEmail', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'letterDebtorPdf', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'letterDebtorStHtml', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'letterDebtorStEmail', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'letterDebtorNdHtml', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'letterDebtorNdEmail', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'clientDebtStatementPdf', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'clientDebtStatementHtml', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'clientDebtStatementEmail', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'creditRequestPdf', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'creditRequestHtml', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'creditRequestEmail', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'incotermsAuthorizationPdf', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'incotermsAuthorizationHtml', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'incotermsAuthorizationEmail', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'consumptionSendQueued', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'filter', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'getClientOrSupplierReference', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'upsert', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'create', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'replaceById', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'updateAttributes', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'updateAttributes', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'deleteById', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'replaceOrCreate', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'updateAll', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Client', 'upsertWithWhere', '*', 'ALLOW', 'ROLE', 'employee');
|
|
@ -156,14 +156,14 @@ let actions = {
|
||||||
await this.waitForSpinnerLoad();
|
await this.waitForSpinnerLoad();
|
||||||
},
|
},
|
||||||
|
|
||||||
accessToSection: async function(state) {
|
accessToSection: async function(state, name = 'Others') {
|
||||||
await this.waitForSelector('vn-left-menu');
|
await this.waitForSelector('vn-left-menu');
|
||||||
let nested = await this.evaluate(state => {
|
let nested = await this.evaluate(state => {
|
||||||
return document.querySelector(`vn-left-menu li li > a[ui-sref="${state}"]`) != null;
|
return document.querySelector(`vn-left-menu li li > a[ui-sref="${state}"]`) != null;
|
||||||
}, state);
|
}, state);
|
||||||
|
|
||||||
if (nested) {
|
if (nested) {
|
||||||
let selector = 'vn-left-menu vn-item-section > vn-icon[icon=keyboard_arrow_down]';
|
let selector = `vn-left-menu li[name="${name}"]`;
|
||||||
await this.evaluate(selector => {
|
await this.evaluate(selector => {
|
||||||
document.querySelector(selector).scrollIntoViewIfNeeded();
|
document.querySelector(selector).scrollIntoViewIfNeeded();
|
||||||
}, selector);
|
}, selector);
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('setRating', {
|
||||||
|
description: 'Change rating and recommendedCredit of a client',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The user id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'rating',
|
||||||
|
type: 'number'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'recommendedCredit',
|
||||||
|
type: 'number'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
http: {
|
||||||
|
path: `/:id/setRating`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.setRating = async function(ctx, id, rating, recommendedCredit, options) {
|
||||||
|
let tx;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const client = await Self.findById(id, null, myOptions);
|
||||||
|
const clientUpdated = await client.updateAttributes({
|
||||||
|
rating: rating,
|
||||||
|
recommendedCredit: recommendedCredit
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return clientUpdated;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,43 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
|
describe('Client setRating()', () => {
|
||||||
|
const financialId = 73;
|
||||||
|
const activeCtx = {
|
||||||
|
accessToken: {userId: financialId},
|
||||||
|
http: {
|
||||||
|
req: {
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const ctx = {req: activeCtx};
|
||||||
|
|
||||||
|
beforeAll(async() => {
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should change rating and recommendedCredit', async() => {
|
||||||
|
const tx = await models.Ticket.beginTransaction({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const clientId = 1101;
|
||||||
|
const newRating = 10;
|
||||||
|
const newRecommendedCredit = 20;
|
||||||
|
|
||||||
|
const updatedClient = await models.Client.setRating(ctx, clientId, newRating, newRecommendedCredit, options);
|
||||||
|
|
||||||
|
expect(updatedClient.rating).toEqual(newRating);
|
||||||
|
expect(updatedClient.recommendedCredit).toEqual(newRecommendedCredit);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -32,6 +32,9 @@
|
||||||
"ClientConsumptionQueue": {
|
"ClientConsumptionQueue": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"ClientInforma": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"ClientLog": {
|
"ClientLog": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"name": "ClientInforma",
|
||||||
|
"base": "Loggable",
|
||||||
|
"log": {
|
||||||
|
"model":"ClientLog",
|
||||||
|
"relation": "client",
|
||||||
|
"showField": "clientFk"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "clientInforma"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"rating": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"recommendedCredit": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"created": {
|
||||||
|
"type": "date"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"worker": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Worker",
|
||||||
|
"foreignKey": "workerFk"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Client",
|
||||||
|
"foreignKey": "clientFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,4 +47,5 @@ module.exports = Self => {
|
||||||
require('../methods/client/consumptionSendQueued')(Self);
|
require('../methods/client/consumptionSendQueued')(Self);
|
||||||
require('../methods/client/filter')(Self);
|
require('../methods/client/filter')(Self);
|
||||||
require('../methods/client/getClientOrSupplierReference')(Self);
|
require('../methods/client/getClientOrSupplierReference')(Self);
|
||||||
|
require('../methods/client/setRating')(Self);
|
||||||
};
|
};
|
||||||
|
|
|
@ -280,6 +280,10 @@ module.exports = Self => {
|
||||||
if (changes.credit !== undefined)
|
if (changes.credit !== undefined)
|
||||||
await Self.changeCredit(ctx, finalState, changes);
|
await Self.changeCredit(ctx, finalState, changes);
|
||||||
|
|
||||||
|
// Credit management changes
|
||||||
|
if (orgData?.rating != changes.rating || orgData?.recommendedCredit != changes.recommendedCredit)
|
||||||
|
await Self.changeCreditManagement(ctx, finalState, changes);
|
||||||
|
|
||||||
const oldInstance = {};
|
const oldInstance = {};
|
||||||
if (!ctx.isNewInstance) {
|
if (!ctx.isNewInstance) {
|
||||||
const newProps = Object.keys(changes);
|
const newProps = Object.keys(changes);
|
||||||
|
@ -441,6 +445,19 @@ module.exports = Self => {
|
||||||
}, ctx.options);
|
}, ctx.options);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Self.changeCreditManagement = async function changeCreditManagement(ctx, finalState, changes) {
|
||||||
|
const models = Self.app.models;
|
||||||
|
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||||
|
const userId = loopBackContext.active.accessToken.userId;
|
||||||
|
|
||||||
|
await models.ClientInforma.create({
|
||||||
|
clientFk: finalState.id,
|
||||||
|
rating: changes.rating,
|
||||||
|
recommendedCredit: changes.recommendedCredit,
|
||||||
|
workerFk: userId
|
||||||
|
}, ctx.options);
|
||||||
|
};
|
||||||
|
|
||||||
const app = require('vn-loopback/server/server');
|
const app = require('vn-loopback/server/server');
|
||||||
app.on('started', function() {
|
app.on('started', function() {
|
||||||
const VnUser = app.models.VnUser;
|
const VnUser = app.models.VnUser;
|
||||||
|
|
|
@ -141,6 +141,12 @@
|
||||||
},
|
},
|
||||||
"hasElectronicInvoice": {
|
"hasElectronicInvoice": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"rating": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"recommendedCredit": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
<mg-ajax path="Clients/{{post.params.id}}/setRating" options="vnPost"></mg-ajax>
|
||||||
|
<vn-watcher
|
||||||
|
vn-id="watcher"
|
||||||
|
url="Clients"
|
||||||
|
data="$ctrl.client"
|
||||||
|
id-value="$ctrl.$params.id"
|
||||||
|
insert-mode="true"
|
||||||
|
form="form"
|
||||||
|
save="post">
|
||||||
|
</vn-watcher>
|
||||||
|
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
||||||
|
<vn-card class="vn-pa-lg">
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-input-number
|
||||||
|
vn-one
|
||||||
|
label="Rating"
|
||||||
|
ng-model="$ctrl.client.rating"
|
||||||
|
vn-focus
|
||||||
|
rule>
|
||||||
|
</vn-input-number>
|
||||||
|
<vn-input-number
|
||||||
|
vn-one
|
||||||
|
label="Recommended credit"
|
||||||
|
ng-model="$ctrl.client.recommendedCredit"
|
||||||
|
rule>
|
||||||
|
</vn-input-number>
|
||||||
|
</vn-horizontal>
|
||||||
|
</vn-card>
|
||||||
|
<vn-button-bar>
|
||||||
|
<vn-submit
|
||||||
|
disabled="!watcher.dataChanged()"
|
||||||
|
label="Save">
|
||||||
|
</vn-submit>
|
||||||
|
</vn-button-bar>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<vn-crud-model
|
||||||
|
vn-id="model"
|
||||||
|
url="ClientInformas"
|
||||||
|
filter="$ctrl.filter"
|
||||||
|
link="{clientFk: $ctrl.$params.id}"
|
||||||
|
limit="20"
|
||||||
|
data="clientInformas"
|
||||||
|
order="created DESC"
|
||||||
|
auto-load="true">
|
||||||
|
</vn-crud-model>
|
||||||
|
<vn-data-viewer
|
||||||
|
model="model"
|
||||||
|
class="vn-w-md">
|
||||||
|
<vn-card>
|
||||||
|
<vn-table model="model" class="vn-mt-lg">
|
||||||
|
<vn-thead>
|
||||||
|
<vn-tr>
|
||||||
|
<vn-th shrink-date field="created">Since</vn-th>
|
||||||
|
<vn-th field="workerFk">Employee</vn-th>
|
||||||
|
<vn-th field="rating" number>Rating</vn-th>
|
||||||
|
<vn-th field="recommendedCredit" number>Recommended credit</vn-th>
|
||||||
|
</vn-tr>
|
||||||
|
</vn-thead>
|
||||||
|
<vn-tbody>
|
||||||
|
<vn-tr ng-repeat="clientInforma in clientInformas">
|
||||||
|
<vn-td shrink-datetime>{{::clientInforma.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>
|
||||||
|
<vn-td shrink>
|
||||||
|
<span
|
||||||
|
ng-click="workerDescriptor.show($event, clientInforma.workerFk)"
|
||||||
|
class="link">
|
||||||
|
{{::clientInforma.worker.user.nickname}}
|
||||||
|
</span>
|
||||||
|
</vn-td>
|
||||||
|
<vn-td number>{{::clientInforma.rating}}</vn-td>
|
||||||
|
<vn-td number>{{::clientInforma.recommendedCredit}}</vn-td>
|
||||||
|
</vn-tr>
|
||||||
|
</vn-tbody>
|
||||||
|
</vn-table>
|
||||||
|
</vn-card>
|
||||||
|
</vn-data-viewer>
|
||||||
|
<vn-worker-descriptor-popover
|
||||||
|
vn-id="workerDescriptor">
|
||||||
|
</vn-worker-descriptor-popover>
|
|
@ -0,0 +1,32 @@
|
||||||
|
import ngModule from '../module';
|
||||||
|
import Section from 'salix/components/section';
|
||||||
|
|
||||||
|
export default class Controller extends Section {
|
||||||
|
constructor($element, $) {
|
||||||
|
super($element, $);
|
||||||
|
|
||||||
|
this.filter = {
|
||||||
|
include: [{
|
||||||
|
relation: 'worker',
|
||||||
|
scope: {
|
||||||
|
fields: ['userFk'],
|
||||||
|
include: {
|
||||||
|
relation: 'user',
|
||||||
|
scope: {
|
||||||
|
fields: ['nickname']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
onSubmit() {
|
||||||
|
this.$.watcher.submit()
|
||||||
|
.then(() => this.$state.reload());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngModule.vnComponent('vnClientCreditManagement', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: Controller
|
||||||
|
});
|
|
@ -0,0 +1,2 @@
|
||||||
|
Recommended credit: Crédito recomendado
|
||||||
|
Rating: Clasificación
|
|
@ -47,3 +47,5 @@ import './defaulter';
|
||||||
import './notification';
|
import './notification';
|
||||||
import './unpaid';
|
import './unpaid';
|
||||||
import './extended-list';
|
import './extended-list';
|
||||||
|
import './credit-management';
|
||||||
|
|
||||||
|
|
|
@ -64,4 +64,6 @@ Compensation Account: Cuenta para compensar
|
||||||
Amount to return: Cantidad a devolver
|
Amount to return: Cantidad a devolver
|
||||||
Delivered amount: Cantidad entregada
|
Delivered amount: Cantidad entregada
|
||||||
Unpaid: Impagado
|
Unpaid: Impagado
|
||||||
|
Credit management: Gestión de crédito
|
||||||
|
Credit opinion: Opinión de crédito
|
||||||
There is no zona: No hay zona
|
There is no zona: No hay zona
|
|
@ -23,6 +23,14 @@
|
||||||
{"state": "client.card.recovery.index", "icon": "icon-recovery"},
|
{"state": "client.card.recovery.index", "icon": "icon-recovery"},
|
||||||
{"state": "client.card.webAccess", "icon": "cloud"},
|
{"state": "client.card.webAccess", "icon": "cloud"},
|
||||||
{"state": "client.card.log", "icon": "history"},
|
{"state": "client.card.log", "icon": "history"},
|
||||||
|
{
|
||||||
|
"description": "Credit management",
|
||||||
|
"icon": "monetization_on",
|
||||||
|
"childs": [
|
||||||
|
{"state": "client.card.creditInsurance.index", "icon": "icon-solunion"},
|
||||||
|
{"state": "client.card.creditManagement", "icon": "contact_support"}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "Others",
|
"description": "Others",
|
||||||
"icon": "more",
|
"icon": "more",
|
||||||
|
@ -30,7 +38,6 @@
|
||||||
{"state": "client.card.sample.index", "icon": "mail"},
|
{"state": "client.card.sample.index", "icon": "mail"},
|
||||||
{"state": "client.card.consumption", "icon": "show_chart"},
|
{"state": "client.card.consumption", "icon": "show_chart"},
|
||||||
{"state": "client.card.mandate", "icon": "pan_tool"},
|
{"state": "client.card.mandate", "icon": "pan_tool"},
|
||||||
{"state": "client.card.creditInsurance.index", "icon": "icon-solunion"},
|
|
||||||
{"state": "client.card.contact", "icon": "contact_phone"},
|
{"state": "client.card.contact", "icon": "contact_phone"},
|
||||||
{"state": "client.card.webPayment", "icon": "icon-onlinepayment"},
|
{"state": "client.card.webPayment", "icon": "icon-onlinepayment"},
|
||||||
{"state": "client.card.dms.index", "icon": "cloud_upload"},
|
{"state": "client.card.dms.index", "icon": "cloud_upload"},
|
||||||
|
@ -416,7 +423,8 @@
|
||||||
"state": "client.notification",
|
"state": "client.notification",
|
||||||
"component": "vn-client-notification",
|
"component": "vn-client-notification",
|
||||||
"description": "Notifications"
|
"description": "Notifications"
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"url": "/unpaid",
|
"url": "/unpaid",
|
||||||
"state": "client.card.unpaid",
|
"state": "client.card.unpaid",
|
||||||
"component": "vn-client-unpaid",
|
"component": "vn-client-unpaid",
|
||||||
|
@ -428,6 +436,13 @@
|
||||||
"state": "client.extendedList",
|
"state": "client.extendedList",
|
||||||
"component": "vn-client-extended-list",
|
"component": "vn-client-extended-list",
|
||||||
"description": "Extended list"
|
"description": "Extended list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/credit-management",
|
||||||
|
"state": "client.card.creditManagement",
|
||||||
|
"component": "vn-client-credit-management",
|
||||||
|
"acl": ["financial"],
|
||||||
|
"description": "Credit opinion"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
</head>
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="ticketsModel"
|
vn-id="ticketsModel"
|
||||||
url="Tickets"
|
url="Tickets"
|
||||||
|
@ -253,7 +256,11 @@
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
<vn-one>
|
<vn-one>
|
||||||
<h4 translate>Financial information</h4>
|
<h4 ng-show="$ctrl.isEmployee">
|
||||||
|
<a href="https://grafana.verdnatura.es/d/40buzE4Vk/comportamiento-pagos-clientes?orgId=1&var-clientFk={{::$ctrl.client.id}}">
|
||||||
|
<span class="grafana" translate vn-tooltip="Go to grafana">Billing data</span>
|
||||||
|
</a>
|
||||||
|
</h4>
|
||||||
<vn-label-value label="Risk"
|
<vn-label-value label="Risk"
|
||||||
value="{{$ctrl.summary.debt.debt | currency: 'EUR':2}}"
|
value="{{$ctrl.summary.debt.debt | currency: 'EUR':2}}"
|
||||||
ng-class="{alert: $ctrl.summary.debt.debt > $ctrl.summary.credit}"
|
ng-class="{alert: $ctrl.summary.debt.debt > $ctrl.summary.credit}"
|
||||||
|
@ -282,6 +289,10 @@
|
||||||
ng-if="$ctrl.summary.recovery.started"
|
ng-if="$ctrl.summary.recovery.started"
|
||||||
value="{{$ctrl.summary.recovery.started | date:'dd/MM/yyyy'}}">
|
value="{{$ctrl.summary.recovery.started | date:'dd/MM/yyyy'}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
|
<vn-label-value label="Rating"
|
||||||
|
value="{{$ctrl.summary.rating}}"
|
||||||
|
info="Value from 1 to 20. The higher the better value">
|
||||||
|
</vn-label-value>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
|
|
|
@ -20,3 +20,6 @@ Invoices minus payments: Facturas menos recibos
|
||||||
Deviated invoices minus payments: Facturas fuera de plazo menos recibos
|
Deviated invoices minus payments: Facturas fuera de plazo menos recibos
|
||||||
Go to the client: Ir al cliente
|
Go to the client: Ir al cliente
|
||||||
Latest tickets: Últimos tickets
|
Latest tickets: Últimos tickets
|
||||||
|
Rating: Clasificación
|
||||||
|
Value from 1 to 20. The higher the better value: Valor del 1 al 20. Cuanto más alto mejor valoración
|
||||||
|
Go to grafana: Ir a grafana
|
||||||
|
|
|
@ -6,4 +6,9 @@ vn-client-summary .summary {
|
||||||
.alert span {
|
.alert span {
|
||||||
color: $color-alert !important
|
color: $color-alert !important
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vn-horizontal h4 .grafana:after {
|
||||||
|
content: 'contact_support';
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue