Views migrated to vn schema, Node v8, Error handling, async-await, bugs solved
This commit is contained in:
parent
506d6e0688
commit
a3188b204f
|
@ -1,5 +1,4 @@
|
||||||
extends: [eslint:recommended, google, plugin:jasmine/recommended]
|
extends: [eslint:recommended, google, plugin:jasmine/recommended]
|
||||||
installedESLint: true
|
|
||||||
plugins:
|
plugins:
|
||||||
- jasmine
|
- jasmine
|
||||||
env:
|
env:
|
||||||
|
|
|
@ -2,25 +2,10 @@
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "Asociar",
|
|
||||||
"type": "node",
|
"type": "node",
|
||||||
"request": "attach",
|
"request": "attach",
|
||||||
"port": 5858,
|
"name": "Attach by Process ID",
|
||||||
"address": "localhost",
|
"processId": "${command:PickProcess}"
|
||||||
"restart": false,
|
|
||||||
"sourceMaps": false,
|
|
||||||
"outFiles": [],
|
|
||||||
"localRoot": "${workspaceRoot}",
|
|
||||||
"remoteRoot": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Asociar al proceso",
|
|
||||||
"type": "node",
|
|
||||||
"request": "attach",
|
|
||||||
"processId": "${command:PickProcess}",
|
|
||||||
"port": 5858,
|
|
||||||
"sourceMaps": false,
|
|
||||||
"outFiles": []
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@salix/auth",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.verdnatura.es/salix"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@salix/client",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.verdnatura.es/salix"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,7 +13,7 @@
|
||||||
<vn-check vn-one label="Default" field="$ctrl.address.isDefaultAddress"></vn-check>
|
<vn-check vn-one label="Default" field="$ctrl.address.isDefaultAddress"></vn-check>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-textfield vn-one label="Consignee" field="$ctrl.address.consignee" vn-focus></vn-textfield>
|
<vn-textfield vn-one label="Consignee" field="$ctrl.address.nickname" vn-focus></vn-textfield>
|
||||||
<vn-textfield vn-one label="Street address" field="$ctrl.address.street"></vn-textfield>
|
<vn-textfield vn-one label="Street address" field="$ctrl.address.street"></vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
|
|
|
@ -4,7 +4,7 @@ export default class Controller {
|
||||||
constructor($state) {
|
constructor($state) {
|
||||||
this.address = {
|
this.address = {
|
||||||
clientFk: parseInt($state.params.id),
|
clientFk: parseInt($state.params.id),
|
||||||
isEnabled: true
|
isActive: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ describe('Client', () => {
|
||||||
|
|
||||||
it('should define and set address property', () => {
|
it('should define and set address property', () => {
|
||||||
expect(controller.address.clientFk).toBe(1234);
|
expect(controller.address.clientFk).toBe(1234);
|
||||||
expect(controller.address.isEnabled).toBe(true);
|
expect(controller.address.isActive).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,14 +12,14 @@
|
||||||
<vn-title>Address</vn-title>
|
<vn-title>Address</vn-title>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-one>
|
<vn-one>
|
||||||
<vn-check label="Enabled" field="$ctrl.address.isEnabled"></vn-check>
|
<vn-check label="Enabled" field="$ctrl.address.isActive"></vn-check>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
<vn-one>
|
<vn-one>
|
||||||
<vn-check label="Is equalizated" field="$ctrl.address.isEqualizated" vn-acl="administrative"></vn-check>
|
<vn-check label="Is equalizated" field="$ctrl.address.isEqualizated" vn-acl="administrative"></vn-check>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-textfield vn-one label="Consignee" field="$ctrl.address.consignee" vn-focus></vn-textfield>
|
<vn-textfield vn-one label="Consignee" field="$ctrl.address.nickname" vn-focus></vn-textfield>
|
||||||
<vn-textfield vn-one label="Street" field="$ctrl.address.street"></vn-textfield>
|
<vn-textfield vn-one label="Street" field="$ctrl.address.street"></vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
|
@ -36,8 +36,8 @@
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
initial-data="$ctrl.address.defaultAgency"
|
initial-data="$ctrl.address.agency"
|
||||||
field="$ctrl.address.defaultAgencyFk"
|
field="$ctrl.address.agencyFk"
|
||||||
url="/client/api/AgencyModes"
|
url="/client/api/AgencyModes"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<mg-ajax path="/client/api/Clients/{{index.params.id}}/addressesList" options="mgIndex"></mg-ajax>
|
<mg-ajax path="/client/api/Clients/{{index.params.id}}/listAddresses" options="mgIndex"></mg-ajax>
|
||||||
<vn-vertical pad-medium>
|
<vn-vertical pad-medium>
|
||||||
<vn-card>
|
<vn-card>
|
||||||
<vn-vertical pad-large>
|
<vn-vertical pad-large>
|
||||||
|
@ -7,14 +7,14 @@
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal ng-repeat="i in index.model.items track by i.id" class="pad-medium-top" style="align-items: center;">
|
<vn-horizontal ng-repeat="i in index.model.items track by i.id" class="pad-medium-top" style="align-items: center;">
|
||||||
<vn-one border-radius class="pad-small border-solid"
|
<vn-one border-radius class="pad-small border-solid"
|
||||||
ng-class="{'bg-dark-item': i.isDefaultAddress,'bg-opacity-item': !i.isEnabled && !i.isDefaultAddress}">
|
ng-class="{'bg-dark-item': i.isDefaultAddress,'bg-opacity-item': !i.isActive && !i.isDefaultAddress}">
|
||||||
<vn-horizontal style="align-items: center;">
|
<vn-horizontal style="align-items: center;">
|
||||||
<vn-none pad-medium-h style="color:#FFA410;">
|
<vn-none pad-medium-h style="color:#FFA410;">
|
||||||
<i class="material-icons" ng-if="i.isDefaultAddress">star</i>
|
<i class="material-icons" ng-if="i.isDefaultAddress">star</i>
|
||||||
<i class="material-icons pointer" ng-if="!i.isDefaultAddress&&i.isEnabled" vn-tooltip="Set as default" tooltip-position="left" ng-click="$ctrl.setDefault(i.id)">star_border</i>
|
<i class="material-icons pointer" ng-if="!i.isDefaultAddress&&i.isActive" vn-tooltip="Set as default" tooltip-position="left" ng-click="$ctrl.setDefault(i.id)">star_border</i>
|
||||||
</vn-none>
|
</vn-none>
|
||||||
<vn-one>
|
<vn-one>
|
||||||
<div><b>{{::i.consignee}}</b></div>
|
<div><b>{{::i.nickname}}</b></div>
|
||||||
<div>{{::i.street}}</div>
|
<div>{{::i.street}}</div>
|
||||||
<div>{{::i.city}}, {{::i.province}}</div>
|
<div>{{::i.city}}, {{::i.province}}</div>
|
||||||
<div>{{::i.phone}}, {{::i.mobile}}</div>
|
<div>{{::i.phone}}, {{::i.mobile}}</div>
|
||||||
|
|
|
@ -6,9 +6,10 @@ class ClientAddresses {
|
||||||
this.$scope = $scope;
|
this.$scope = $scope;
|
||||||
}
|
}
|
||||||
setDefault(id) {
|
setDefault(id) {
|
||||||
this.$http.patch(`/client/api/Addresses/${id}`, {id: id, isDefaultAddress: true}).then(() => {
|
let params = {isDefaultAddress: true};
|
||||||
this.$scope.index.accept();
|
this.$http.patch(`/client/api/Addresses/${id}`, params).then(
|
||||||
});
|
() => this.$scope.index.accept()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClientAddresses.$inject = ['$http', '$scope'];
|
ClientAddresses.$inject = ['$http', '$scope'];
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
<vn-textfield vn-one
|
<vn-textfield vn-one
|
||||||
label="Email"
|
label="Email"
|
||||||
field="$ctrl.client.email"
|
field="$ctrl.client.email"
|
||||||
info="You can save multiple emails by chaining them using comma without spaces, example: user@domain.com,user2@domain.com the first email will be considered as the main"
|
info="You can save multiple emails by chaining them using comma without spaces, example: user@domain.com,user2@domain.com the first email will be considered as the main">
|
||||||
>
|
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
|
@ -30,10 +29,9 @@
|
||||||
url="/client/api/Clients/activeSalesPerson"
|
url="/client/api/Clients/activeSalesPerson"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
select-fields="surname"
|
select-fields="name"
|
||||||
label="Salesperson"
|
label="Salesperson"
|
||||||
filter-search="{where: {or: [{name: {regexp: 'search'}}, {surname: {regexp: 'search'}}]}}"
|
filter-search="{where: {or: [{name: {regexp: 'search'}}, {name: {regexp: 'search'}}]}}">
|
||||||
>
|
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
initial-data="$ctrl.client.contactChannel"
|
initial-data="$ctrl.client.contactChannel"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<mg-ajax path="/client/api/Clients/createUserProfile" options="vnPost"></mg-ajax>
|
<mg-ajax path="/client/api/Clients/createWithUser" options="vnPost"></mg-ajax>
|
||||||
<vn-watcher
|
<vn-watcher
|
||||||
vn-id="watcher"
|
vn-id="watcher"
|
||||||
data="$ctrl.client"
|
data="$ctrl.client"
|
||||||
|
@ -25,10 +25,10 @@
|
||||||
url="/client/api/Clients/activeSalesPerson"
|
url="/client/api/Clients/activeSalesPerson"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
select-fields="surname"
|
select-fields="name"
|
||||||
label="Salesperson"
|
label="Salesperson"
|
||||||
filter-search="{where: {or: [{name: {regexp: 'search'}}, {surname: {regexp: 'search'}}]}}"
|
filter-search="{where: {or: [{name: {regexp: 'search'}}, {name: {regexp: 'search'}}]}}">
|
||||||
></vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<vn-grid-header on-order="$ctrl.onOrder(field, order)">
|
<vn-grid-header on-order="$ctrl.onOrder(field, order)">
|
||||||
<vn-column-header vn-one pad-medium-h field="amount" text="Credit"></vn-column-header>
|
<vn-column-header vn-one pad-medium-h field="amount" text="Credit"></vn-column-header>
|
||||||
<vn-column-header vn-two pad-medium-h field="created" text="Since" default-order="ASC"></vn-column-header>
|
<vn-column-header vn-two pad-medium-h field="created" text="Since" default-order="ASC"></vn-column-header>
|
||||||
<vn-column-header vn-two pad-medium-h field="employee.name" text="Employee" order-locked></vn-column-header>
|
<vn-column-header vn-two pad-medium-h field="worker.firstName" text="Employee" order-locked></vn-column-header>
|
||||||
</vn-grid-header>
|
</vn-grid-header>
|
||||||
<vn-one class="list list-content">
|
<vn-one class="list list-content">
|
||||||
<vn-horizontal
|
<vn-horizontal
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
ng-repeat="credit in index.model.instances track by credit.id">
|
ng-repeat="credit in index.model.instances track by credit.id">
|
||||||
<vn-one pad-medium-h>{{::credit.amount | number:2}} €</vn-one>
|
<vn-one pad-medium-h>{{::credit.amount | number:2}} €</vn-one>
|
||||||
<vn-two pad-medium-h>{{::credit.created | date:'dd/MM/yyyy HH:mm' }}</vn-two>
|
<vn-two pad-medium-h>{{::credit.created | date:'dd/MM/yyyy HH:mm' }}</vn-two>
|
||||||
<vn-two pad-medium-h>{{::credit.employee.name}} {{::credit.employee.surname}}</vn-two>
|
<vn-two pad-medium-h>{{::credit.worker.firstName}} {{::credit.worker.name}}</vn-two>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
<vn-one class="text-center pad-small-v" ng-if="index.model.count === 0" translate>No results</vn-one>
|
<vn-one class="text-center pad-small-v" ng-if="index.model.count === 0" translate>No results</vn-one>
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
<vn-vertical pad-large>
|
<vn-vertical pad-large>
|
||||||
<vn-title>Fiscal data</vn-title>
|
<vn-title>Fiscal data</vn-title>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-textfield autofocus vn-two label="Social name" field="$ctrl.client.socialName" vn-acl="administrative"></vn-textfield>
|
<vn-textfield autofocus vn-two label="Social name" field="$ctrl.client.socialName" vn-acl="administrative"></vn-textfield>
|
||||||
<vn-textfield vn-one label="Tax number" field="$ctrl.client.fi" vn-acl="administrative"></vn-textfield>
|
<vn-textfield vn-one label="Tax number" field="$ctrl.client.fi" vn-acl="administrative"></vn-textfield>
|
||||||
<vn-check vn-one label="Is equalizated" field="$ctrl.client.isEqualizated" vn-acl="administrative"></vn-check>
|
<vn-check vn-one label="Is equalizated" field="$ctrl.client.isEqualizated" vn-acl="administrative"></vn-check>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-textfield vn-two label="Street" field="$ctrl.client.street" vn-focus vn-acl="administrative"></vn-textfield>
|
<vn-textfield vn-two label="Street" field="$ctrl.client.street" vn-focus vn-acl="administrative"></vn-textfield>
|
||||||
|
@ -27,18 +27,16 @@
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
label="Province"
|
label="Province"
|
||||||
vn-acl="administrative"
|
vn-acl="administrative">
|
||||||
>
|
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
initial-data="$ctrl.client.country"
|
initial-data="$ctrl.client.country"
|
||||||
field="$ctrl.client.countryFk"
|
field="$ctrl.client.countryFk"
|
||||||
url="/client/api/Countries"
|
url="/client/api/Countries"
|
||||||
show-field="name"
|
show-field="country"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
label="Country"
|
label="Country"
|
||||||
vn-acl="administrative"
|
vn-acl="administrative">
|
||||||
>
|
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal margin-small-bottom>
|
<vn-horizontal margin-small-bottom>
|
||||||
|
@ -64,17 +62,14 @@
|
||||||
</vn-one>
|
</vn-one>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
|
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
|
||||||
<vn-button-bar>
|
<vn-button-bar>
|
||||||
<vn-submit label="Save"></vn-submit>
|
<vn-submit label="Save"></vn-submit>
|
||||||
</vn-button-bar>
|
</vn-button-bar>
|
||||||
</form>
|
</form>
|
||||||
<vn-dialog
|
<vn-dialog
|
||||||
vn-id="propagate-isEqualizated"
|
vn-id="propagate-isEqualizated"
|
||||||
on-response="$ctrl.returnDialogEt(response)"
|
on-response="$ctrl.returnDialogEt(response)">
|
||||||
>
|
|
||||||
<tpl-body>
|
<tpl-body>
|
||||||
<vn-vertical>
|
<vn-vertical>
|
||||||
<vn-one text-center translate>You changes the equivalen
|
<vn-one text-center translate>You changes the equivalen
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<a ui-sref="clientCard.basicData({ id: {{$ctrl.client.id}} })" pad-medium border-solid-bottom>
|
<a ui-sref="clientCard.basicData({ id: {{::$ctrl.client.id}} })" pad-medium border-solid-bottom>
|
||||||
<div class="vn-item-client-name">{{$ctrl.client.name}}</div>
|
<div class="vn-item-client-name">{{::$ctrl.client.name}}</div>
|
||||||
<div><span translate>Client id</span>: <b>{{$ctrl.client.id}}</b></div>
|
<div><span translate>Client id</span>: <b>{{::$ctrl.client.id}}</b></div>
|
||||||
<div><span translate>Phone</span>: <b>{{$ctrl.client.phone | phone}}</b></div>
|
<div><span translate>Phone</span>: <b>{{::$ctrl.client.phone | phone}}</b></div>
|
||||||
<div><span translate>Town/City</span>: <b>{{$ctrl.client.city}}</b></div>
|
<div><span translate>Town/City</span>: <b>{{::$ctrl.client.city}}</b></div>
|
||||||
<div><span translate>Email</span>: <b>{{$ctrl.client.email}}</b></div>
|
<div><span translate>Email</span>: <b>{{::$ctrl.client.email}}</b></div>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
<vn-vertical pad-large>
|
<vn-vertical pad-large>
|
||||||
<vn-title>Notes</vn-title>
|
<vn-title>Notes</vn-title>
|
||||||
<vn-one
|
<vn-one
|
||||||
ng-repeat="n in $ctrl.observations"
|
ng-repeat="n in $ctrl.observations"
|
||||||
pad-small border-solid
|
pad-small border-solid
|
||||||
border-radius
|
border-radius
|
||||||
margin-small-bottom style="align-items: center;">
|
margin-small-bottom style="align-items: center;">
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-one >{{::n.employee.name}} {{::n.employee.surname}}</vn-one>
|
<vn-one >{{::n.worker.firstName}} {{::n.worker.name}}</vn-one>
|
||||||
<vn-auto>{{::n.created | date:'dd/MM/yyyy HH:mm'}}</vn-auto>
|
<vn-auto>{{::n.created | date:'dd/MM/yyyy HH:mm'}}</vn-auto>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
|
|
|
@ -16,7 +16,7 @@ export default class Controller {
|
||||||
|
|
||||||
isCustomer() {
|
isCustomer() {
|
||||||
if (this.client && this.client.id) {
|
if (this.client && this.client.id) {
|
||||||
this.$http.get(`/client/api/Clients/${this.client.id}/getRoleCustomer`).then(res => {
|
this.$http.get(`/client/api/Clients/${this.client.id}/hasCustomerRole`).then(res => {
|
||||||
this.canChangePassword = (res.data) ? res.data.isCustomer : false;
|
this.canChangePassword = (res.data) ? res.data.isCustomer : false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -37,8 +37,8 @@ describe('Component VnClientWebAccess', () => {
|
||||||
controller.client = {id: '1234'};
|
controller.client = {id: '1234'};
|
||||||
controller.isCustomer();
|
controller.isCustomer();
|
||||||
|
|
||||||
$httpBackend.when('GET', `/client/api/Clients/${controller.client.id}/getRoleCustomer`).respond('ok');
|
$httpBackend.when('GET', `/client/api/Clients/${controller.client.id}/hasCustomerRole`).respond('ok');
|
||||||
$httpBackend.expectGET(`/client/api/Clients/${controller.client.id}/getRoleCustomer`);
|
$httpBackend.expectGET(`/client/api/Clients/${controller.client.id}/hasCustomerRole`);
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@salix/core",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.verdnatura.es/salix"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,5 +18,5 @@
|
||||||
item-width="$ctrl.width"
|
item-width="$ctrl.width"
|
||||||
multiple="$ctrl.multiple"
|
multiple="$ctrl.multiple"
|
||||||
parent = "$ctrl.element"
|
parent = "$ctrl.element"
|
||||||
><vn-item ng-transclude="tplItem">{{$parent.item.name}}</vn-item></vn-drop-down>
|
><vn-item ng-transclude="tplItem">{{$parent.item[$ctrl.showField]}}</vn-item></vn-drop-down>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
|
@ -2,7 +2,6 @@ import {module} from '../module';
|
||||||
import Component from '../lib/component';
|
import Component from '../lib/component';
|
||||||
import copyObject from '../lib/copy';
|
import copyObject from '../lib/copy';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
import { log } from 'util';
|
|
||||||
|
|
||||||
class Autocomplete extends Component {
|
class Autocomplete extends Component {
|
||||||
constructor($element, $scope, $http, $timeout, $filter) {
|
constructor($element, $scope, $http, $timeout, $filter) {
|
||||||
|
@ -20,9 +19,8 @@ class Autocomplete extends Component {
|
||||||
this._field = null;
|
this._field = null;
|
||||||
this._preLoad = false;
|
this._preLoad = false;
|
||||||
this.maxRow = 10;
|
this.maxRow = 10;
|
||||||
this.showField = this.showField || 'name';
|
this.showField = 'name';
|
||||||
this.valueField = this.valueField || 'id';
|
this.valueField = 'id';
|
||||||
this.order = this.order || 'name ASC';
|
|
||||||
this.items = copyObject(this.data) || [];
|
this.items = copyObject(this.data) || [];
|
||||||
this.displayValueMultiCheck = [];
|
this.displayValueMultiCheck = [];
|
||||||
this._multiField = [];
|
this._multiField = [];
|
||||||
|
@ -195,6 +193,10 @@ class Autocomplete extends Component {
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getOrder() {
|
||||||
|
return this.order ? this.order : `${this.showField} ASC`;
|
||||||
|
}
|
||||||
|
|
||||||
findItems(search) {
|
findItems(search) {
|
||||||
if (this.url && search && !this.finding) {
|
if (this.url && search && !this.finding) {
|
||||||
this.maxRow = false;
|
this.maxRow = false;
|
||||||
|
@ -208,7 +210,7 @@ class Autocomplete extends Component {
|
||||||
Object.assign(filter.where, this.filter.where);
|
Object.assign(filter.where, this.filter.where);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filter.order = this.order;
|
filter.order = this.getOrder();
|
||||||
let json = JSON.stringify(filter);
|
let json = JSON.stringify(filter);
|
||||||
this.finding = true;
|
this.finding = true;
|
||||||
this.$http.get(`${this.url}?filter=${json}`).then(
|
this.$http.get(`${this.url}?filter=${json}`).then(
|
||||||
|
@ -252,7 +254,7 @@ class Autocomplete extends Component {
|
||||||
filter.skip = this.items.length;
|
filter.skip = this.items.length;
|
||||||
}
|
}
|
||||||
filter.limit = this.maxRow;
|
filter.limit = this.maxRow;
|
||||||
filter.order = this.order;
|
filter.order = this.getOrder();
|
||||||
}
|
}
|
||||||
if (this.filter) {
|
if (this.filter) {
|
||||||
Object.assign(filter, this.filter);
|
Object.assign(filter, this.filter);
|
||||||
|
|
|
@ -163,8 +163,8 @@ describe('Component vnAutocomplete', () => {
|
||||||
let controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout});
|
let controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout});
|
||||||
controller.url = 'test.com';
|
controller.url = 'test.com';
|
||||||
let search = 'The Joker';
|
let search = 'The Joker';
|
||||||
controller.filterSearch = "{where: {surname: {regexp: 'search'}}}";
|
controller.filterSearch = "{where: {name: {regexp: 'search'}}}";
|
||||||
let json = JSON.stringify({where: {surname: {regexp: search}}, order: controller.order});
|
let json = JSON.stringify({where: {name: {regexp: search}}, order: controller.order});
|
||||||
$httpBackend.whenGET(`${controller.url}?filter=${json}`).respond([{id: 3, name: 'The Joker'}]);
|
$httpBackend.whenGET(`${controller.url}?filter=${json}`).respond([{id: 3, name: 'The Joker'}]);
|
||||||
$httpBackend.expectGET(`${controller.url}?filter=${json}`);
|
$httpBackend.expectGET(`${controller.url}?filter=${json}`);
|
||||||
controller.findItems(search);
|
controller.findItems(search);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<vn-icon-button icon="textsms" ng-click="$ctrl.doAction('addComment')"></vn-icon-button>
|
<vn-icon-button icon="textsms" ng-click="$ctrl.doAction('addComment')"></vn-icon-button>
|
||||||
</vn-none>
|
</vn-none>
|
||||||
<vn-none margin-medium-right>
|
<vn-none margin-medium-right>
|
||||||
<vn-icon-menu icon="person" url="/client/api/Clients/employeeList" selected="$ctrl.actionWorker"></vn-icon-menu>
|
<vn-icon-menu icon="person" url="/client/api/Clients/listWorkers" selected="$ctrl.actionWorker"></vn-icon-menu>
|
||||||
</vn-none>
|
</vn-none>
|
||||||
<vn-none margin-medium-right>
|
<vn-none margin-medium-right>
|
||||||
<vn-icon-menu icon="query_builder" items="$ctrl.parent.sharedData.hourItems" selected="$ctrl.actionHours"></vn-icon-menu>
|
<vn-icon-menu icon="query_builder" items="$ctrl.parent.sharedData.hourItems" selected="$ctrl.actionHours"></vn-icon-menu>
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
<vn-watcher
|
<vn-watcher
|
||||||
vn-id="watcher"
|
vn-id="watcher"
|
||||||
data="$ctrl.route"
|
data="$ctrl.route"
|
||||||
form="form"
|
form="form">
|
||||||
>
|
|
||||||
</vn-watcher>
|
</vn-watcher>
|
||||||
<form name="form" pad-medium>
|
<form name="form" pad-medium>
|
||||||
<vn-card>
|
<vn-card>
|
||||||
<vn-vertical pad-large>
|
<vn-vertical pad-large>
|
||||||
<vn-title>Logistic data</vn-title>
|
<vn-title>Logistic data</vn-title>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-date-picker vn-one label="Start Hour" model="$ctrl.route.startHour" ini-options="{enableTime: true, noCalendar: true, enableSeconds: false, dateFormat: 'H:i'}"></vn-date-picker>
|
<vn-date-picker vn-one label="Start Hour" model="$ctrl.route.startHour" ini-options="{enableTime: true, noCalendar: true, enableSeconds: false, dateFormat: 'H:i'}"></vn-date-picker>
|
||||||
<vn-date-picker vn-one label="End Hour" model="$ctrl.route.endHour" ini-options="{enableTime: true, noCalendar: true, enableSeconds: false, dateFormat: 'H:i'}"></vn-date-picker>
|
<vn-date-picker vn-one label="End Hour" model="$ctrl.route.endHour" ini-options="{enableTime: true, noCalendar: true, enableSeconds: false, dateFormat: 'H:i'}"></vn-date-picker>
|
||||||
<vn-textfield vn-one label="Start Km" model="$ctrl.route.starKm"></vn-textfield>
|
<vn-textfield vn-one label="Start Km" model="$ctrl.route.starKm"></vn-textfield>
|
||||||
<vn-textfield vn-one label="End Km" model="$ctrl.route.endKm"></vn-textfield>
|
<vn-textfield vn-one label="End Km" model="$ctrl.route.endKm"></vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-textfield vn-one label="Packages" model="$ctrl.route.packages"></vn-textfield>
|
<vn-textfield vn-one label="Packages" model="$ctrl.route.packages"></vn-textfield>
|
||||||
<vn-textfield vn-one label="M3" model="$ctrl.route.m3"></vn-textfield>
|
<vn-textfield vn-one label="M3" model="$ctrl.route.m3"></vn-textfield>
|
||||||
<vn-one></vn-one>
|
<vn-one></vn-one>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
<vn-button-bar>
|
<vn-button-bar>
|
||||||
|
|
|
@ -10,12 +10,10 @@
|
||||||
order="printingOrder ASC"
|
order="printingOrder ASC"
|
||||||
></vn-autocomplete>
|
></vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-textfield vn-one label="Postcode" model="$ctrl.filter.postcode"></vn-textfield>
|
<vn-textfield vn-one label="Postcode" model="$ctrl.filter.postcode"></vn-textfield>
|
||||||
<vn-textfield vn-one label="Route_Id" model="$ctrl.filter.id"></vn-textfield>
|
<vn-textfield vn-one label="Route_Id" model="$ctrl.filter.id"></vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
||||||
<vn-horizontal margin-large-top>
|
<vn-horizontal margin-large-top>
|
||||||
<vn-submit label="Search"></vn-submit>
|
<vn-submit label="Search"></vn-submit>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@salix/salix",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "http://git.verdnatura.es:/salix"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,7 +4,7 @@
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: vn-font;
|
font-family: vn-font;
|
||||||
src: url(./fonts/Roboto.ttf);
|
src: url(./fonts/Roboto-Regular.ttf);
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: vn-font-bold;
|
font-family: vn-font-bold;
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@salix/vendor",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.verdnatura.es/salix"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,8 +8,6 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ./services
|
context: ./services
|
||||||
dockerfile: /auth/Dockerfile
|
dockerfile: /auth/Dockerfile
|
||||||
expose:
|
|
||||||
- "3000"
|
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
|
|
||||||
|
@ -21,8 +19,6 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ./services
|
context: ./services
|
||||||
dockerfile: /salix/Dockerfile
|
dockerfile: /salix/Dockerfile
|
||||||
expose:
|
|
||||||
- "3001"
|
|
||||||
ports:
|
ports:
|
||||||
- "3001:3001"
|
- "3001:3001"
|
||||||
|
|
||||||
|
@ -34,8 +30,6 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ./services
|
context: ./services
|
||||||
dockerfile: /client/Dockerfile
|
dockerfile: /client/Dockerfile
|
||||||
expose:
|
|
||||||
- "3002"
|
|
||||||
ports:
|
ports:
|
||||||
- "3002:3002"
|
- "3002:3002"
|
||||||
|
|
||||||
|
@ -46,8 +40,6 @@ services:
|
||||||
image: "mailer:${TAG}"
|
image: "mailer:${TAG}"
|
||||||
build:
|
build:
|
||||||
context: ./services/mailer
|
context: ./services/mailer
|
||||||
expose:
|
|
||||||
- "3003"
|
|
||||||
ports:
|
ports:
|
||||||
- "3003:3003"
|
- "3003:3003"
|
||||||
|
|
||||||
|
@ -59,8 +51,6 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ./services
|
context: ./services
|
||||||
dockerfile: /production/Dockerfile
|
dockerfile: /production/Dockerfile
|
||||||
expose:
|
|
||||||
- "3004"
|
|
||||||
ports:
|
ports:
|
||||||
- "3004:3004"
|
- "3004:3004"
|
||||||
|
|
||||||
|
@ -72,8 +62,6 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ./services
|
context: ./services
|
||||||
dockerfile: /route/Dockerfile
|
dockerfile: /route/Dockerfile
|
||||||
expose:
|
|
||||||
- "3005"
|
|
||||||
ports:
|
ports:
|
||||||
- "3005:3005"
|
- "3005:3005"
|
||||||
print:
|
print:
|
||||||
|
@ -84,8 +72,6 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ./services
|
context: ./services
|
||||||
dockerfile: /print/Dockerfile
|
dockerfile: /print/Dockerfile
|
||||||
expose:
|
|
||||||
- "3006"
|
|
||||||
ports:
|
ports:
|
||||||
- "3006:3006"
|
- "3006:3006"
|
||||||
item:
|
item:
|
||||||
|
@ -96,8 +82,6 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ./services
|
context: ./services
|
||||||
dockerfile: /item/Dockerfile
|
dockerfile: /item/Dockerfile
|
||||||
expose:
|
|
||||||
- "3007"
|
|
||||||
ports:
|
ports:
|
||||||
- "3007:3007"
|
- "3007:3007"
|
||||||
nginx:
|
nginx:
|
||||||
|
@ -106,8 +90,6 @@ services:
|
||||||
privileged: true
|
privileged: true
|
||||||
build:
|
build:
|
||||||
context: ./services/nginx
|
context: ./services/nginx
|
||||||
expose:
|
|
||||||
- "80"
|
|
||||||
ports:
|
ports:
|
||||||
- "80:80"
|
- "80:80"
|
||||||
mem_limit: 200m
|
mem_limit: 200m
|
||||||
|
|
|
@ -87,7 +87,7 @@ export default {
|
||||||
addressesButton: `${components.vnMenuItem}[ui-sref="clientCard.addresses.list"]`,
|
addressesButton: `${components.vnMenuItem}[ui-sref="clientCard.addresses.list"]`,
|
||||||
createAddress: `${components.vnFloatButton}`,
|
createAddress: `${components.vnFloatButton}`,
|
||||||
defaultCheckboxInput: `${components.vnCheck}[label='Default'] > label > input`,
|
defaultCheckboxInput: `${components.vnCheck}[label='Default'] > label > input`,
|
||||||
consigneeInput: `${components.vnTextfield}[name="consignee"]`,
|
consigneeInput: `${components.vnTextfield}[name="nickname"]`,
|
||||||
streetAddressInput: `${components.vnTextfield}[name="street"]`,
|
streetAddressInput: `${components.vnTextfield}[name="street"]`,
|
||||||
postcodeInput: `${components.vnTextfield}[name="postcode"]`,
|
postcodeInput: `${components.vnTextfield}[name="postcode"]`,
|
||||||
cityInput: `${components.vnTextfield}[name="city"]`,
|
cityInput: `${components.vnTextfield}[name="city"]`,
|
||||||
|
|
|
@ -250,8 +250,8 @@ describe('Edit addresses path', () => {
|
||||||
nightmare
|
nightmare
|
||||||
.waitForSnackbarReset()
|
.waitForSnackbarReset()
|
||||||
.waitToClick(selectors.addresses.addressesButton)
|
.waitToClick(selectors.addresses.addressesButton)
|
||||||
.wait(selectors.addresses.defaultAddress)
|
.wait(selectors.addresses.isDefaultAddress)
|
||||||
.getInnerText(selectors.addresses.defaultAddress)
|
.getInnerText(selectors.addresses.isDefaultAddress)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
expect(result).toContain('320 Park Avenue New York');
|
expect(result).toContain('320 Park Avenue New York');
|
||||||
done();
|
done();
|
||||||
|
@ -263,8 +263,8 @@ describe('Edit addresses path', () => {
|
||||||
nightmare
|
nightmare
|
||||||
.waitForSnackbarReset()
|
.waitForSnackbarReset()
|
||||||
.waitToClick(selectors.addresses.secondMakeDefaultStar)
|
.waitToClick(selectors.addresses.secondMakeDefaultStar)
|
||||||
.waitForTextInElement(selectors.addresses.defaultAddress, 'Somewhere in Thailand')
|
.waitForTextInElement(selectors.addresses.isDefaultAddress, 'Somewhere in Thailand')
|
||||||
.getInnerText(selectors.addresses.defaultAddress)
|
.getInnerText(selectors.addresses.isDefaultAddress)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
expect(result).toContain('Somewhere in Thailand');
|
expect(result).toContain('Somewhere in Thailand');
|
||||||
done();
|
done();
|
||||||
|
@ -274,7 +274,7 @@ describe('Edit addresses path', () => {
|
||||||
|
|
||||||
it(`should click on the edit icon of the default address`, done => {
|
it(`should click on the edit icon of the default address`, done => {
|
||||||
nightmare
|
nightmare
|
||||||
.waitForTextInElement(selectors.addresses.defaultAddress, 'Somewhere in Thailand')
|
.waitForTextInElement(selectors.addresses.isDefaultAddress, 'Somewhere in Thailand')
|
||||||
.waitToClick(selectors.addresses.firstEditButton)
|
.waitToClick(selectors.addresses.firstEditButton)
|
||||||
.waitForURL('/edit')
|
.waitForURL('/edit')
|
||||||
.url()
|
.url()
|
||||||
|
|
84
gulpfile.js
84
gulpfile.js
|
@ -1,5 +1,5 @@
|
||||||
var gulp = require('gulp');
|
var gulp = require('gulp');
|
||||||
const jasmine = require('gulp-jasmine');
|
var jasmine = require('gulp-jasmine');
|
||||||
var gutil = require('gulp-util');
|
var gutil = require('gulp-util');
|
||||||
var wrap = require('gulp-wrap');
|
var wrap = require('gulp-wrap');
|
||||||
var concat = require('gulp-concat');
|
var concat = require('gulp-concat');
|
||||||
|
@ -12,55 +12,62 @@ var del = require('del');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var webpack = require('webpack');
|
var webpack = require('webpack');
|
||||||
var WebpackDevServer = require('webpack-dev-server');
|
var WebpackDevServer = require('webpack-dev-server');
|
||||||
|
|
||||||
var exec = require('child_process').exec;
|
var exec = require('child_process').exec;
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
|
|
||||||
var srcDir = './client';
|
var srcDir = './client';
|
||||||
var buildDir = './services/nginx/static';
|
var buildDir = './services/nginx/static';
|
||||||
var langs = ['es', 'en'];
|
var langs = ['es', 'en'];
|
||||||
|
|
||||||
var modules = require('./client/modules.json');
|
var modules = require('./client/modules.json');
|
||||||
|
|
||||||
var webpackConfig = require('./webpack.config.js');
|
var webpackConfig = require('./webpack.config.js');
|
||||||
|
|
||||||
// Main tasks
|
// Main tasks
|
||||||
|
|
||||||
gulp.task('default', function() {
|
gulp.task('default', () => {
|
||||||
return gulp.start('services', 'client');
|
return gulp.start('services', 'client');
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('build', ['clean'], function() {
|
gulp.task('build', ['clean'], () => {
|
||||||
return gulp.start('routes', 'locales', 'webpack');
|
return gulp.start('routes', 'locales', 'webpack');
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('client', ['clean'], function() {
|
gulp.task('client', ['clean'], () => {
|
||||||
return gulp.start('watch', 'routes', 'locales', 'webpack-dev-server');
|
return gulp.start('watch', 'routes', 'locales', 'webpack-dev-server');
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('nginxRestart', callback => {
|
gulp.task('services', ['nginx'], () => {
|
||||||
let isWindows = /^win/.test(process.platform);
|
|
||||||
let command = isWindows ? '.\\dev.cmd' : './dev.sh';
|
|
||||||
exec(command, (err, stdout, stderr) => {
|
|
||||||
console.log(stdout);
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('services', () => {
|
|
||||||
process.env.NODE_ENV = gutil.env.env || 'development';
|
process.env.NODE_ENV = gutil.env.env || 'development';
|
||||||
const pathServices = './services/';
|
const servicesPath = './services/';
|
||||||
const services = fs.readdirSync(pathServices);
|
const services = fs.readdirSync(servicesPath);
|
||||||
services.splice(services.indexOf('loopback'), 1);
|
services.splice(services.indexOf('loopback'), 1);
|
||||||
return services.forEach(service => {
|
return services.forEach(service => {
|
||||||
const serviceJs = pathServices.concat(service, '/server/server.js');
|
const serviceJs = servicesPath.concat(service, '/server/server.js');
|
||||||
if (fs.existsSync(serviceJs))
|
if (fs.existsSync(serviceJs))
|
||||||
require(serviceJs).start();
|
require(serviceJs).start();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('clientDev', callback => {
|
gulp.task('clean', function() {
|
||||||
runSequence('nginxRestart', 'client', callback);
|
return del([`${buildDir}/*`, `!${buildDir}/templates`, `!${buildDir}/images`], {force: true});
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('install', () => {
|
||||||
|
const servicesPath = './services/';
|
||||||
|
const jsonFile = [];
|
||||||
|
const services = fs.readdirSync(servicesPath);
|
||||||
|
services.push('..');
|
||||||
|
services.forEach(service => {
|
||||||
|
jsonFile.push(servicesPath.concat(service, '/package.json'));
|
||||||
|
});
|
||||||
|
return gulp.src(jsonFile)
|
||||||
|
.pipe(print(filepath => {
|
||||||
|
return `Installing packages in ${filepath}`;
|
||||||
|
}))
|
||||||
|
.pipe(install({
|
||||||
|
npm: ['--no-package-lock']
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('servicesDev', callback => {
|
gulp.task('servicesDev', callback => {
|
||||||
|
@ -78,25 +85,16 @@ gulp.task('servicesDev', callback => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('clean', function() {
|
// Nginx
|
||||||
return del([`${buildDir}/*`, `!${buildDir}/templates`, `!${buildDir}/images`], {force: true});
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('install', () => {
|
gulp.task('nginx', callback => {
|
||||||
const pathServices = './services/';
|
let isWindows = /^win/.test(process.platform);
|
||||||
const fileJson = [];
|
let command = isWindows ? 'start.cmd' : 'start.sh';
|
||||||
const services = fs.readdirSync(pathServices);
|
command = `./services/nginx/${command}`;
|
||||||
services.push('..');
|
exec(command, (err, stdout, stderr) => {
|
||||||
services.forEach(service => {
|
console.log(stdout);
|
||||||
fileJson.push(pathServices.concat(service, '/package.json'));
|
callback(err);
|
||||||
});
|
});
|
||||||
return gulp.src(fileJson)
|
|
||||||
.pipe(print(filepath => {
|
|
||||||
return `Installing packages in ${filepath}`;
|
|
||||||
}))
|
|
||||||
.pipe(install({
|
|
||||||
npm: ['--no-package-lock']
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Webpack
|
// Webpack
|
||||||
|
@ -171,17 +169,20 @@ gulp.task('routes', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Watch
|
// Watch
|
||||||
|
|
||||||
gulp.task('watch', function() {
|
gulp.task('watch', function() {
|
||||||
gulp.watch(routeFiles, ['routes']);
|
gulp.watch(routeFiles, ['routes']);
|
||||||
gulp.watch(localeFiles, ['locales']);
|
gulp.watch(localeFiles, ['locales']);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Server side unit tests
|
// Services tests
|
||||||
|
|
||||||
gulp.task('test', callback => {
|
gulp.task('test', callback => {
|
||||||
return require('./services_tests').start();
|
return require('./services_tests').start();
|
||||||
});
|
});
|
||||||
|
|
||||||
// e2e tests
|
// E2E tests
|
||||||
|
|
||||||
gulp.task('e2e', callback => {
|
gulp.task('e2e', callback => {
|
||||||
runSequence('docker', 'waitForMySQL', 'endToEndTests', callback);
|
runSequence('docker', 'waitForMySQL', 'endToEndTests', callback);
|
||||||
});
|
});
|
||||||
|
@ -212,7 +213,8 @@ gulp.task('endToEndTests', callback => {
|
||||||
.pipe(jasmine({reporter: 'none'}));
|
.pipe(jasmine({reporter: 'none'}));
|
||||||
});
|
});
|
||||||
|
|
||||||
// docker dblocal
|
// Docker
|
||||||
|
|
||||||
gulp.task('docker', callback => {
|
gulp.task('docker', callback => {
|
||||||
runSequence('deleteDockerDb', 'deleteDockerImageDb', 'buildDockerDb', 'runDockerDb', callback);
|
runSequence('deleteDockerDb', 'deleteDockerImageDb', 'buildDockerDb', 'runDockerDb', callback);
|
||||||
});
|
});
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -62,7 +62,7 @@
|
||||||
"merge-stream": "^1.0.1",
|
"merge-stream": "^1.0.1",
|
||||||
"mysql": "^2.15.0",
|
"mysql": "^2.15.0",
|
||||||
"nightmare": "^2.10.0",
|
"nightmare": "^2.10.0",
|
||||||
"node-sass": "^3.11.0",
|
"node-sass": "^3.13.1",
|
||||||
"raw-loader": "*",
|
"raw-loader": "*",
|
||||||
"run-sequence": "^2.2.0",
|
"run-sequence": "^2.2.0",
|
||||||
"sass-loader": "^4.0.2",
|
"sass-loader": "^4.0.2",
|
||||||
|
|
|
@ -22,6 +22,6 @@
|
||||||
"dataSource": "salix"
|
"dataSource": "salix"
|
||||||
},
|
},
|
||||||
"Account": {
|
"Account": {
|
||||||
"dataSource": "salix"
|
"dataSource": "account"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,64 +0,0 @@
|
||||||
var request = require('request');
|
|
||||||
var app = require('../../../server/server');
|
|
||||||
|
|
||||||
module.exports = function(Client) {
|
|
||||||
Client.remoteMethod('activate', {
|
|
||||||
description: 'Activate or deactive client',
|
|
||||||
accepts: [
|
|
||||||
{
|
|
||||||
arg: 'id',
|
|
||||||
type: 'number',
|
|
||||||
required: true,
|
|
||||||
description: 'Model id',
|
|
||||||
http: {source: 'path'}
|
|
||||||
}, {
|
|
||||||
arg: 'context',
|
|
||||||
type: 'object',
|
|
||||||
http: function(ctx) {
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
returns: {
|
|
||||||
arg: 'active',
|
|
||||||
type: 'boolean'
|
|
||||||
},
|
|
||||||
http: {
|
|
||||||
verb: 'put',
|
|
||||||
path: '/:id/activate'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Client.activate = function(id, ctx, cb) {
|
|
||||||
Client.findById(id, function(err, client) {
|
|
||||||
if (!err) {
|
|
||||||
Client.update({id: client.id}, {active: !client.active});
|
|
||||||
|
|
||||||
let filter = {where: {clientFk: client.id}, fields: ['started', 'ended']};
|
|
||||||
|
|
||||||
app.models.CreditClassification.findOne(filter, function(error, data) {
|
|
||||||
if (error)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let currentDate = new Date();
|
|
||||||
|
|
||||||
if (data && client.active && (data.ended >= currentDate || data.ended == null)) {
|
|
||||||
let referer = ctx.req.headers.referer;
|
|
||||||
var options = {
|
|
||||||
url: `${referer}/mailer/notification/client-deactivate/${client.id}`,
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'content-type': 'application/json',
|
|
||||||
'Authorization': ctx.req.headers.authorization
|
|
||||||
},
|
|
||||||
json: {}
|
|
||||||
};
|
|
||||||
request(options);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cb(null, !client.active);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,147 +0,0 @@
|
||||||
var app = require('../../../server/server');
|
|
||||||
|
|
||||||
module.exports = function(Client) {
|
|
||||||
var CREDIT_CARD = 5;
|
|
||||||
var models = app.models;
|
|
||||||
|
|
||||||
Client.observe('before save', function(ctx, next) {
|
|
||||||
if (ctx.currentInstance) {
|
|
||||||
let dataChange = Object.assign({}, ctx.data);
|
|
||||||
let userId = ctx.options.accessToken.userId;
|
|
||||||
|
|
||||||
Object.assign(ctx.data, doIfNullSalesPerson(ctx.currentInstance));
|
|
||||||
|
|
||||||
if (!ctx.data.dueDay)
|
|
||||||
ctx.data.dueDay = 5;
|
|
||||||
|
|
||||||
if (dataChange.hasOwnProperty('equalizationTax') && !canMarkEqualizationTax(ctx.data))
|
|
||||||
next(generateErrorEqualizationTax());
|
|
||||||
else if (dataChange.hasOwnProperty('credit'))
|
|
||||||
canChangeCredit(dataChange, userId, next);
|
|
||||||
else
|
|
||||||
next();
|
|
||||||
} else if (ctx.where && ctx.where.id) {
|
|
||||||
Client.findById(ctx.where.id, (_, instance) => {
|
|
||||||
Object.assign(ctx.data, doIfNullSalesPerson(instance));
|
|
||||||
|
|
||||||
if (instance
|
|
||||||
&& instance.payMethodFk != ctx.data.payMethodFk
|
|
||||||
&& instance.dueDay == ctx.data.dueDay)
|
|
||||||
ctx.data.dueDay = 5;
|
|
||||||
|
|
||||||
if (instance.fi && ctx.data.equalizationTax && !canMarkEqualizationTax(instance)) {
|
|
||||||
next(generateErrorEqualizationTax());
|
|
||||||
} else if (instance.equalizationTax !== undefined && instance.equalizationTax && ctx.data.fi && canMarkEqualizationTax(ctx.data)) {
|
|
||||||
next(generateErrorEqualizationTax());
|
|
||||||
} else {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// newInstance
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function doIfNullSalesPerson(instance) {
|
|
||||||
var data = {};
|
|
||||||
if (instance.salesPerson === null) {
|
|
||||||
data.credit = 0;
|
|
||||||
data.discount = 0;
|
|
||||||
data.payMethodFk = CREDIT_CARD;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
function canMarkEqualizationTax(instance) {
|
|
||||||
var firstLetter = (instance && instance.fi) ? instance.fi.toUpperCase().charAt(0) : '';
|
|
||||||
if (firstLetter == "A" || firstLetter == "B")
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateErrorEqualizationTax() {
|
|
||||||
var error = new Error();
|
|
||||||
error.message = "No se puede marcar el recargo de equivalencia";
|
|
||||||
error.status = 500;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateErrorCredit() {
|
|
||||||
var error = new Error();
|
|
||||||
error.message = "No tienes privilegios para modificar el crédito";
|
|
||||||
error.status = 500;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
function canChangeCredit(data, userId, done) {
|
|
||||||
let filter = {
|
|
||||||
fields: ['roleFk'],
|
|
||||||
where: {
|
|
||||||
maxAmount: {gt: data.credit}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
models.ClientCreditLimit.find(filter,
|
|
||||||
(_, res) => limitCb(_, res));
|
|
||||||
|
|
||||||
function limitCb(_, instances) {
|
|
||||||
let requiredRoles = [];
|
|
||||||
for (instance of instances)
|
|
||||||
requiredRoles.push(instance.roleFk);
|
|
||||||
|
|
||||||
let where = {
|
|
||||||
roleId: {inq: requiredRoles},
|
|
||||||
principalType: 'USER',
|
|
||||||
principalId: userId
|
|
||||||
};
|
|
||||||
models.RoleMapping.count(where,
|
|
||||||
(_, res) => roleCb(_, res));
|
|
||||||
}
|
|
||||||
function roleCb(_, count) {
|
|
||||||
// si el usuario no tiene alguno de los roles no continua
|
|
||||||
if (count <= 0) {
|
|
||||||
done(generateErrorCredit());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// si tiene el rol hay que validar que el último movimiento no fuese crédito 0 insertado por gerencia
|
|
||||||
validate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si se puso a 0 por gerencia, solo gerencia puede aumentarlo
|
|
||||||
function validate() {
|
|
||||||
let query = 'SELECT * FROM ClientCredit WHERE clientFk = ? ORDER BY created DESC LIMIT 1';
|
|
||||||
Client.dataSource.connector.execute(query, [data.id],
|
|
||||||
(_, res) => maxCb(_, res));
|
|
||||||
}
|
|
||||||
|
|
||||||
function maxCb(_, instances) {
|
|
||||||
if (!instances || instances.length !== 1 || instances[0].employeeFk == userId || instances[0].amount > 0) {
|
|
||||||
done();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// el ultimo registro tiene valor 0, hay que comprobar que no fue editado por un gerente
|
|
||||||
let sql = `SELECT count(distinct r.id) as hasManagerRole
|
|
||||||
FROM ClientCredit cc
|
|
||||||
JOIN Employee em ON (em.id = cc.employeeFk)
|
|
||||||
JOIN Account ac ON (ac.id = em.userFk)
|
|
||||||
JOIN RoleMapping rm ON (rm.principalId = ac.id)
|
|
||||||
JOIN Role r on (r.id = rm.roleId)
|
|
||||||
WHERE rm.principalType = 'USER'
|
|
||||||
AND cc.employeeFk = ?
|
|
||||||
AND r.\`name\` = 'manager'`;
|
|
||||||
|
|
||||||
Client.dataSource.connector.execute(sql, [instances[0].employeeFk], (_, res) => clientCreditCb(_, res));
|
|
||||||
}
|
|
||||||
|
|
||||||
function clientCreditCb(_, instance) {
|
|
||||||
if (!instance || (instance.length && instance[0].hasManagerRole > 0)) {
|
|
||||||
done(generateErrorCredit());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"relation": "salesPerson",
|
|
||||||
"scope": {
|
|
||||||
"fields": ["id", "name", "surname"]
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"relation": "contactChannel",
|
|
||||||
"scope": {
|
|
||||||
"fields": ["id", "name"]
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"relation": "province",
|
|
||||||
"scope": {
|
|
||||||
"fields": ["id", "name"]
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"relation": "country",
|
|
||||||
"scope": {
|
|
||||||
"fields": ["id", "name"]
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"relation": "payMethod",
|
|
||||||
"scope": {
|
|
||||||
"fields": ["id", "name"]
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"relation": "account",
|
|
||||||
"scope": {
|
|
||||||
"fields": ["id", "name", "active"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -1,42 +0,0 @@
|
||||||
module.exports = function(Client) {
|
|
||||||
Client.remoteMethod('employeeList', {
|
|
||||||
description: 'List employee',
|
|
||||||
accessType: 'READ',
|
|
||||||
returns: {
|
|
||||||
arg: 'data',
|
|
||||||
type: 'Employee',
|
|
||||||
root: true
|
|
||||||
},
|
|
||||||
http: {
|
|
||||||
path: `/employeeList`,
|
|
||||||
verb: 'get'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let getEmployees = listEmployees => {
|
|
||||||
let employees = [];
|
|
||||||
listEmployees.forEach(function(e) {
|
|
||||||
employees.push({id: e.id, name: e.name});
|
|
||||||
}, this);
|
|
||||||
return employees;
|
|
||||||
};
|
|
||||||
|
|
||||||
Client.employeeList = function(callback) {
|
|
||||||
let query = `SELECT em.id, CASE em.surname WHEN NULL THEN em.name ELSE concat(em.name, " ", em.surname) END \`name\`
|
|
||||||
FROM salix.Employee em
|
|
||||||
JOIN salix.Account ac ON em.userFk = ac.id
|
|
||||||
JOIN salix.RoleMapping rm on ac.id=rm.principalId
|
|
||||||
JOIN salix.Role rl on rm.roleId = rl.id
|
|
||||||
WHERE ac.active
|
|
||||||
and rl.\`name\`='employee'
|
|
||||||
ORDER BY em.name ASC`;
|
|
||||||
|
|
||||||
Client.rawSql(query, [], callback)
|
|
||||||
.then(response => {
|
|
||||||
callback(null, getEmployees(response));
|
|
||||||
})
|
|
||||||
.catch(reject => {
|
|
||||||
callback(reject, null);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,45 +0,0 @@
|
||||||
module.exports = Client => {
|
|
||||||
Client.remoteMethod('getRoleCustomer', {
|
|
||||||
description: 'devuelve true/false si es Customer el client',
|
|
||||||
accessType: 'READ',
|
|
||||||
accepts: [
|
|
||||||
{
|
|
||||||
arg: 'id',
|
|
||||||
type: 'string',
|
|
||||||
required: true,
|
|
||||||
description: 'Model id',
|
|
||||||
http: {source: 'path'}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
arg: 'filter',
|
|
||||||
type: 'object',
|
|
||||||
required: true,
|
|
||||||
description: 'Filter defining where',
|
|
||||||
http: function(context) {
|
|
||||||
return context.req.query;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
returns: {
|
|
||||||
arg: 'data',
|
|
||||||
type: 'boolean',
|
|
||||||
root: true
|
|
||||||
},
|
|
||||||
http: {
|
|
||||||
path: `/:id/getRoleCustomer`,
|
|
||||||
verb: 'get'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Client.getRoleCustomer = (id, context, callback) => {
|
|
||||||
let query = `SELECT count(*) isCustomer FROM salix.Account ac JOIN salix.Role r ON r.id = ac.roleFK WHERE r.\`name\`='customer' AND ac.id IN (?)`;
|
|
||||||
const params = [id];
|
|
||||||
Client.rawSql(query, params, callback)
|
|
||||||
.then(response => {
|
|
||||||
callback(null, response[0]);
|
|
||||||
})
|
|
||||||
.catch(reject => {
|
|
||||||
callback(reject, null);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,6 +1,6 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethod('sumAmount', {
|
Self.remoteMethod('sumAmount', {
|
||||||
description: 'returns sum greuge.ammount from client',
|
description: 'Returns the sum of greuge for a client',
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'id',
|
arg: 'id',
|
||||||
|
@ -19,16 +19,13 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.sumAmount = (clientFk, callback) => {
|
Self.sumAmount = (clientFk, callback) => {
|
||||||
let query = `SELECT sum(amount) as sumAmount FROM vn.greuge WHERE clientFk = ?`;
|
let query = `SELECT SUM(amount) AS sumAmount FROM vn.greuge WHERE clientFk = ?`;
|
||||||
Self.rawSql(query, [clientFk], callback).then(response => {
|
Self.rawSql(query, [clientFk])
|
||||||
if (response.length) {
|
.then(response => {
|
||||||
callback(null, response[0].sumAmount);
|
callback(null, response.length ? response[0].sumAmount : 0);
|
||||||
} else {
|
})
|
||||||
callback(null, 0);
|
.catch(err => {
|
||||||
}
|
callback(err);
|
||||||
})
|
});
|
||||||
.catch(reject => {
|
|
||||||
callback(reject, null);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
};
|
};
|
|
@ -1,75 +0,0 @@
|
||||||
module.exports = function(Self) {
|
|
||||||
Self.validate('default', isEnabled, {message: 'No se puede poner predeterminado un consignatario desactivado'});
|
|
||||||
function isEnabled(err) {
|
|
||||||
if (!this.isEnabled && this.isDefaultAddress) err();
|
|
||||||
}
|
|
||||||
|
|
||||||
Self.beforeRemote('create', function(ctx, modelInstance, next) {
|
|
||||||
var data = ctx.req.body;
|
|
||||||
create(data, next);
|
|
||||||
});
|
|
||||||
|
|
||||||
function create(data, next) {
|
|
||||||
if (data.isDefaultAddress) {
|
|
||||||
removeAllDefault(data, next);
|
|
||||||
} else {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Self.beforeRemote('prototype.patchAttributes', function(ctx, modelInstance, next) {
|
|
||||||
let newData = ctx.req.body;
|
|
||||||
newData.id = ctx.req.params.id;
|
|
||||||
getAddress(ctx, newData, next);
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.beforeRemote('findById', function(ctx, modelInstance, next) {
|
|
||||||
ctx.args.filter = {
|
|
||||||
include: [{
|
|
||||||
relation: "province",
|
|
||||||
scope: {
|
|
||||||
fields: ["id", "name"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
relation: "defaultAgency",
|
|
||||||
scope: {
|
|
||||||
fields: ["id", "name"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
function getAddress(ctx, newData, next) {
|
|
||||||
Self.findOne({where: {id: newData.id}}, (_, oldData) => {
|
|
||||||
if (oldData)
|
|
||||||
callbackGetAddress(ctx, newData, oldData, next);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function callbackGetAddress(ctx, newData, oldData, next) {
|
|
||||||
if (newData.isDefaultAddress) {
|
|
||||||
removeAllDefault(oldData, next);
|
|
||||||
} else if (oldData.isDefaultAddress && newData.hasOwnProperty('isDefaultAddress') && !newData.isDefaultAddress) {
|
|
||||||
next(generateErrorDefaultAddress());
|
|
||||||
} else
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeAllDefault(client, next) {
|
|
||||||
if (client && client.clientFk)
|
|
||||||
Self.updateAll({clientFk: client.clientFk, isDefaultAddress: {neq: 0}}, {isDefaultAddress: false}, next);
|
|
||||||
else
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateErrorDefaultAddress() {
|
|
||||||
var error = new Error();
|
|
||||||
error.message = "No se puede desmarcar el consignatario predeterminado";
|
|
||||||
error.status = 500;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "AgencyMode",
|
"name": "AgencyMode",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "agencyMode"
|
||||||
|
}
|
||||||
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
|
@ -20,7 +25,7 @@
|
||||||
"inflation": {
|
"inflation": {
|
||||||
"type": "Number"
|
"type": "Number"
|
||||||
},
|
},
|
||||||
"sendMailTo": {
|
"reportMail": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,9 +10,9 @@ module.exports = function(Self) {
|
||||||
limit: params.size,
|
limit: params.size,
|
||||||
order: params.order || 'created DESC',
|
order: params.order || 'created DESC',
|
||||||
include: {
|
include: {
|
||||||
relation: "employee",
|
relation: "worker",
|
||||||
scope: {
|
scope: {
|
||||||
fields: ["id", "name", "surname"]
|
fields: ["id", "firstName", "name"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,10 +27,10 @@
|
||||||
"model": "Client",
|
"model": "Client",
|
||||||
"foreignKey": "clientFk"
|
"foreignKey": "clientFk"
|
||||||
},
|
},
|
||||||
"employee": {
|
"worker": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Employee",
|
"model": "Worker",
|
||||||
"foreignKey": "employeeFk"
|
"foreignKey": "workerFk"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,13 +8,11 @@ module.exports = function(Self) {
|
||||||
ctx.instance.created = Date();
|
ctx.instance.created = Date();
|
||||||
let token = ctx.options.accessToken;
|
let token = ctx.options.accessToken;
|
||||||
let userId = token && token.userId;
|
let userId = token && token.userId;
|
||||||
let app = require('../../server/server');
|
|
||||||
let Employee = app.models.Employee;
|
Self.app.models.Worker.findOne({where: {userFk: userId}}, (err, user) => {
|
||||||
Employee.findOne({where: {userFk: userId}}, (err, user) => {
|
if (err) return next(err);
|
||||||
if (user) {
|
ctx.instance.workerFk = user.id;
|
||||||
ctx.instance.employeeFk = user.id;
|
next();
|
||||||
next();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
"name": "ClientObservation",
|
"name": "ClientObservation",
|
||||||
"description": "Notas de los clientes.",
|
"description": "Notas de los clientes.",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "clientObservation"
|
||||||
|
}
|
||||||
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
|
@ -21,10 +26,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
"employee": {
|
"worker": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Employee",
|
"model": "Worker",
|
||||||
"foreignKey": "employeeFk"
|
"foreignKey": "workerFk"
|
||||||
},
|
},
|
||||||
"client": {
|
"client": {
|
||||||
"type": "hasOne",
|
"type": "hasOne",
|
||||||
|
@ -33,6 +38,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scope": {
|
"scope": {
|
||||||
"include": "employee"
|
"include": "worker"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
var app = require('../../server/server');
|
|
||||||
|
|
||||||
module.exports = function(Self) {
|
|
||||||
var models = app.models;
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
|
|
||||||
require('../methods/client/activate.js')(Self);
|
|
||||||
require('../methods/client/addresses.js')(Self);
|
|
||||||
require('../methods/client/before-save.js')(Self);
|
|
||||||
require('../methods/client/card.js')(Self);
|
|
||||||
require('../methods/client/create.js')(Self);
|
|
||||||
require('../methods/client/employee.js')(Self);
|
|
||||||
require('../methods/client/filter.js')(Self);
|
|
||||||
require('../methods/client/roles.js')(Self);
|
|
||||||
require('../methods/client/salesperson.js')(Self);
|
|
||||||
require('../methods/client/addressesPropagateRe.js')(Self);
|
|
||||||
|
|
||||||
// Validations
|
|
||||||
|
|
||||||
Self.validatesUniquenessOf('fi', {
|
|
||||||
message: 'El NIF/CIF debe ser único'
|
|
||||||
});
|
|
||||||
Self.validatesUniquenessOf('socialName', {
|
|
||||||
message: 'La razón social debe ser única'
|
|
||||||
});
|
|
||||||
Self.validatesFormatOf('postcode', {
|
|
||||||
message: 'El código postal solo debe contener números',
|
|
||||||
allowNull: true,
|
|
||||||
allowBlank: true,
|
|
||||||
with: /^\d+$/
|
|
||||||
});
|
|
||||||
Self.validatesFormatOf('email', {
|
|
||||||
message: 'Correo electrónico inválido',
|
|
||||||
allowNull: true,
|
|
||||||
allowBlank: true,
|
|
||||||
with: /^[\w|.|-]+@\w[\w|.|-]*\w(,[\w|.|-]+@\w[\w|.|-]*\w)*$/
|
|
||||||
});
|
|
||||||
Self.validatesLengthOf('postcode', {
|
|
||||||
allowNull: true,
|
|
||||||
allowBlank: true,
|
|
||||||
min: 3, max: 10
|
|
||||||
});
|
|
||||||
|
|
||||||
var validateIban = require('../validations/validateIban');
|
|
||||||
Self.validateBinded('iban', validateIban, {
|
|
||||||
message: 'El iban no tiene el formato correcto'
|
|
||||||
});
|
|
||||||
|
|
||||||
let validateDni = require('../validations/validateDni');
|
|
||||||
Self.validateBinded('fi', validateDni, {
|
|
||||||
message: 'DNI Incorrecto'
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.validate('payMethod', hasSalesMan, {
|
|
||||||
message: 'No se puede cambiar la forma de pago si no hay comercial asignado'
|
|
||||||
});
|
|
||||||
function hasSalesMan(err) {
|
|
||||||
if (this.payMethod && !this.salesPerson)
|
|
||||||
err();
|
|
||||||
}
|
|
||||||
Self.validateAsync('payMethodFk', hasIban, {
|
|
||||||
message: 'El método de pago seleccionado requiere que se especifique el IBAN'
|
|
||||||
});
|
|
||||||
|
|
||||||
function hasIban(err, done) {
|
|
||||||
models.PayMethod.findById(this.payMethodFk, (_, instance) => {
|
|
||||||
if (instance && instance.ibanRequired && !this.iban)
|
|
||||||
err();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "company",
|
"table": "company"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "greugeType",
|
"table": "greugeType"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
module.exports = function(Self) {
|
module.exports = function(Self) {
|
||||||
require('../methods/greuge/filter.js')(Self);
|
require('../methods/greuge/filter.js')(Self);
|
||||||
require('../methods/greuge/total.js')(Self);
|
require('../methods/greuge/sumAmount.js')(Self);
|
||||||
|
|
||||||
Self.validatesLengthOf('description', {
|
Self.validatesLengthOf('description', {
|
||||||
max: 45,
|
max: 45,
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "greuge",
|
"table": "greuge"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "mandate",
|
"table": "mandate"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "mandateType",
|
"table": "mandateType"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
"dataSource": "salix"
|
"dataSource": "salix"
|
||||||
},
|
},
|
||||||
"Account": {
|
"Account": {
|
||||||
"dataSource": "salix"
|
"dataSource": "account"
|
||||||
},
|
},
|
||||||
"Client": {
|
"Client": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
|
@ -31,34 +31,34 @@
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"ClientCreditLimit": {
|
"ClientCreditLimit": {
|
||||||
"dataSource": "salix"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"ClientObservation": {
|
"ClientObservation": {
|
||||||
"dataSource": "salix"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"PayMethod": {
|
"PayMethod": {
|
||||||
"dataSource": "salix"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"Address": {
|
"Address": {
|
||||||
"dataSource": "salix"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"AgencyMode": {
|
"AgencyMode": {
|
||||||
"dataSource": "salix"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"Province": {
|
"Province": {
|
||||||
"dataSource": "salix"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"Country": {
|
"Country": {
|
||||||
"dataSource": "salix"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"ContactChannel": {
|
"ContactChannel": {
|
||||||
"dataSource": "salix"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"Employee": {
|
"Worker": {
|
||||||
"dataSource": "salix"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"CreditClassification": {
|
"CreditClassification": {
|
||||||
"dataSource": "salix"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"Greuge": {
|
"Greuge": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
|
|
|
@ -3,15 +3,7 @@ FROM mysql:5.6.37
|
||||||
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
|
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
|
||||||
ENV TZ GMT-1
|
ENV TZ GMT-1
|
||||||
|
|
||||||
COPY localDB01StructureAccount.sql /docker-entrypoint-initdb.d
|
COPY *.sql /docker-entrypoint-initdb.d/
|
||||||
COPY localDB02StructureVn2008.sql /docker-entrypoint-initdb.d
|
|
||||||
COPY localDB03StructureVn.sql /docker-entrypoint-initdb.d
|
|
||||||
COPY localDB04StructureOthersDB.sql /docker-entrypoint-initdb.d
|
|
||||||
COPY localDB05StructureUtil.sql /docker-entrypoint-initdb.d
|
|
||||||
COPY localDB06ViewsVn.sql /docker-entrypoint-initdb.d
|
|
||||||
COPY localDB07OthersViews.sql /docker-entrypoint-initdb.d
|
|
||||||
COPY localDB08Views2008.sql /docker-entrypoint-initdb.d
|
|
||||||
COPY localDB09Inserts.sql /docker-entrypoint-initdb.d
|
|
||||||
|
|
||||||
RUN chmod -R 755 /docker-entrypoint-initdb.d
|
RUN chmod -R 755 /docker-entrypoint-initdb.d
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "expence",
|
"table": "expence"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "ink",
|
"table": "ink"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "intrastat",
|
"table": "intrastat"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "itemType",
|
"table": "itemType"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "item",
|
"table": "item"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "origin",
|
"table": "origin"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "producer",
|
"table": "producer"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "taxClass",
|
"table": "taxClass"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "taxCode",
|
"table": "taxCode"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "taxType",
|
"table": "taxType"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
exports.UserError = class extends Error {
|
||||||
|
constructor(message) {
|
||||||
|
super(message);
|
||||||
|
this.statusCode = 400;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.getFinalState = function(ctx) {
|
||||||
|
if (ctx.isNewInstance)
|
||||||
|
return ctx.instance;
|
||||||
|
if (ctx.currentInstance)
|
||||||
|
return Object.assign({},
|
||||||
|
ctx.currentInstance.__data,
|
||||||
|
ctx.data || ctx.instance
|
||||||
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.isMultiple = function(ctx) {
|
||||||
|
return !ctx.isNewInstance && !ctx.currentInstance;
|
||||||
|
};
|
|
@ -1,3 +0,0 @@
|
||||||
module.exports = function(Self) {
|
|
||||||
Self.defineScope({where: {isManaged: {neq: 0}}});
|
|
||||||
};
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
var request = require('request');
|
||||||
|
|
||||||
|
module.exports = function(Self) {
|
||||||
|
Self.remoteMethod('activate', {
|
||||||
|
description: 'Activate or deactive client',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'Model id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
}, {
|
||||||
|
arg: 'context',
|
||||||
|
type: 'object',
|
||||||
|
http: function(ctx) {
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
arg: 'active',
|
||||||
|
type: 'boolean'
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
verb: 'put',
|
||||||
|
path: '/:id/activate'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.activate = function(id, ctx, cb) {
|
||||||
|
Self.findById(id, function(err, client) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
|
||||||
|
Self.update({id: client.id}, {active: !client.active});
|
||||||
|
|
||||||
|
let filter = {where: {clientFk: client.id}, fields: ['started', 'ended']};
|
||||||
|
|
||||||
|
Self.app.models.CreditClassification.findOne(filter, function(error, data) {
|
||||||
|
if (error) return;
|
||||||
|
|
||||||
|
let currentDate = new Date();
|
||||||
|
|
||||||
|
if (data && client.active && (data.ended >= currentDate || data.ended == null)) {
|
||||||
|
let referer = ctx.req.headers.referer;
|
||||||
|
var options = {
|
||||||
|
url: `${referer}/mailer/notification/client-deactivate/${client.id}`,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: ctx.req.headers.authorization
|
||||||
|
},
|
||||||
|
json: {}
|
||||||
|
};
|
||||||
|
request(options);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cb(null, !client.active);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,6 +1,6 @@
|
||||||
module.exports = Client => {
|
module.exports = Client => {
|
||||||
Client.remoteMethod('activeSalesPerson', {
|
Client.remoteMethod('activeSalesPerson', {
|
||||||
description: 'returns actives employees with salesperson role',
|
description: 'Returns actives workers with salesperson role',
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'filter',
|
arg: 'filter',
|
||||||
|
@ -11,7 +11,7 @@ module.exports = Client => {
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
arg: 'data',
|
arg: 'data',
|
||||||
type: 'Employee',
|
type: 'Worker',
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
|
@ -25,21 +25,19 @@ module.exports = Client => {
|
||||||
let limit = filter.limit || 10;
|
let limit = filter.limit || 10;
|
||||||
let where = getCondition(filter.where, limit, skip);
|
let where = getCondition(filter.where, limit, skip);
|
||||||
|
|
||||||
let query = `SELECT em.id, em.name, em.surname
|
let query =
|
||||||
FROM salix.Employee em
|
`SELECT em.id, em.firstName, em.name
|
||||||
JOIN salix.Account ac ON em.userFk = ac.id
|
FROM worker em
|
||||||
JOIN salix.Role r ON r.id = ac.roleFK
|
JOIN account.user ac ON em.userFk = ac.id
|
||||||
WHERE ac.active AND r.\`name\`='salesPerson' ${where.sql}
|
JOIN account.role r ON r.id = ac.role
|
||||||
ORDER BY em.name ASC
|
WHERE ac.active AND r.\`name\` = 'salesPerson' ${where.sql}
|
||||||
LIMIT ? OFFSET ?`;
|
ORDER BY em.name ASC
|
||||||
|
LIMIT ? OFFSET ?`;
|
||||||
|
|
||||||
Client.rawSql(query, where.params, callback)
|
Client.rawSql(query, where.params).then(
|
||||||
.then(response => {
|
response => callback(null, formatSalesPerson(response)),
|
||||||
callback(null, formatSalesPerson(response));
|
err => callback(err)
|
||||||
})
|
);
|
||||||
.catch(reject => {
|
|
||||||
callback(reject, null);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function getCondition(where, limit, skip) {
|
function getCondition(where, limit, skip) {
|
||||||
|
@ -48,7 +46,7 @@ module.exports = Client => {
|
||||||
params: []
|
params: []
|
||||||
};
|
};
|
||||||
if (where && where.or) {
|
if (where && where.or) {
|
||||||
out.sql = `AND (em.name regexp ? OR em.surname regexp ?)`;
|
out.sql = `AND (em.firstName regexp ? OR em.name regexp ?)`;
|
||||||
where.or.forEach(val => {
|
where.or.forEach(val => {
|
||||||
Object.keys(val).forEach(key => {
|
Object.keys(val).forEach(key => {
|
||||||
out.params.push(val[key].regexp);
|
out.params.push(val[key].regexp);
|
||||||
|
@ -66,7 +64,7 @@ module.exports = Client => {
|
||||||
response.forEach(person => {
|
response.forEach(person => {
|
||||||
results.push({
|
results.push({
|
||||||
id: person.id,
|
id: person.id,
|
||||||
name: `${person.name} ${person.surname}`
|
name: `${person.firstName} ${person.name}`
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
module.exports = function(Client) {
|
||||||
|
Client.remoteMethod('addressesPropagateRe', {
|
||||||
|
description: 'Change property isEqualizated in all client addresses',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
description: 'Client id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'data',
|
||||||
|
type: 'Object',
|
||||||
|
required: true,
|
||||||
|
description: 'data with new value',
|
||||||
|
http: {source: 'body'}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
arg: 'data',
|
||||||
|
type: 'boolean',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/:id/addressesPropagateRe`,
|
||||||
|
verb: 'patch'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Client.addressesPropagateRe = (id, data, callback) => {
|
||||||
|
if (data.hasOwnProperty('isEqualizated')) {
|
||||||
|
Client.app.models.Address.updateAll({clientFk: id}, data, (err, info) => {
|
||||||
|
if (err)
|
||||||
|
return callback(err, null);
|
||||||
|
callback(null, true);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback(null, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
module.exports = function(Self) {
|
||||||
|
Self.remoteMethod('card', {
|
||||||
|
description: 'Get client basic data',
|
||||||
|
accepts: {
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The client id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
returns: {
|
||||||
|
arg: 'data',
|
||||||
|
type: 'Object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
verb: 'GET',
|
||||||
|
path: '/:id/card'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.card = function(id, cb) {
|
||||||
|
let filter = {
|
||||||
|
where: {
|
||||||
|
id: id
|
||||||
|
},
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'salesPerson',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'firstName', 'name']
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
relation: 'contactChannel',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name']
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
relation: 'province',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name']
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
relation: 'country',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'country']
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
relation: 'payMethod',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name']
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
relation: 'account',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name', 'active']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
Self.findOne(filter, function(err, card) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
|
||||||
|
let formatedCard = JSON.parse(JSON.stringify(card));
|
||||||
|
|
||||||
|
if (formatedCard.salesPersonFk)
|
||||||
|
formatedCard.salesPerson = {
|
||||||
|
id: card.salesPerson().id,
|
||||||
|
name: `${card.salesPerson().firstName} ${card.salesPerson().name}`
|
||||||
|
};
|
||||||
|
|
||||||
|
cb(null, formatedCard);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,60 @@
|
||||||
|
let md5 = require('md5');
|
||||||
|
|
||||||
|
module.exports = function(Self) {
|
||||||
|
Self.remoteMethod('createWithUser', {
|
||||||
|
description: 'Creates both client and its web account',
|
||||||
|
accepts: {
|
||||||
|
arg: 'data',
|
||||||
|
type: 'object',
|
||||||
|
http: {source: 'body'}
|
||||||
|
},
|
||||||
|
returns: {
|
||||||
|
root: true,
|
||||||
|
type: 'boolean'
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
verb: 'post',
|
||||||
|
path: '/createWithUser'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.createWithUser = (data, callback) => {
|
||||||
|
let firstEmail = data.email ? data.email.split(',')[0] : null;
|
||||||
|
let user = {
|
||||||
|
name: data.userName,
|
||||||
|
email: firstEmail,
|
||||||
|
password: md5(parseInt(Math.random() * 100000000000000))
|
||||||
|
};
|
||||||
|
let Account = Self.app.models.Account;
|
||||||
|
|
||||||
|
Account.beginTransaction({}, (error, transaction) => {
|
||||||
|
if (error) return callback(error);
|
||||||
|
|
||||||
|
Account.create(user, {transaction}, (error, account) => {
|
||||||
|
if (error) {
|
||||||
|
transaction.rollback();
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
let client = {
|
||||||
|
name: data.name,
|
||||||
|
fi: data.fi,
|
||||||
|
socialName: data.socialName,
|
||||||
|
id: account.id,
|
||||||
|
email: data.email,
|
||||||
|
salesPersonFk: data.salesPersonFk
|
||||||
|
};
|
||||||
|
|
||||||
|
Self.create(client, {transaction}, (error, newClient) => {
|
||||||
|
if (error) {
|
||||||
|
transaction.rollback();
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
callback(null, newClient);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,45 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('hasCustomerRole', {
|
||||||
|
description: 'Comprueba si un usuario tiene el rol de cliente',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
description: 'The user id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
}, {
|
||||||
|
arg: 'context',
|
||||||
|
type: 'object',
|
||||||
|
required: true,
|
||||||
|
description: 'Filter defining where',
|
||||||
|
http: function(context) {
|
||||||
|
return context.req.query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
type: 'boolean',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/:id/hasCustomerRole`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.hasCustomerRole = (id, context, callback) => {
|
||||||
|
let query =
|
||||||
|
`SELECT COUNT(*) > 0 isCustomer
|
||||||
|
FROM salix.Account A
|
||||||
|
JOIN salix.Role r ON r.id = A.roleFK
|
||||||
|
WHERE r.name = 'customer'
|
||||||
|
AND A.id IN (?)`;
|
||||||
|
|
||||||
|
Self.rawSql(query, [id]).then(
|
||||||
|
instances => callback(null, instances[0]),
|
||||||
|
err => callback(err)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,70 @@
|
||||||
|
module.exports = function(Client) {
|
||||||
|
Client.remoteMethod('listAddresses', {
|
||||||
|
description: 'List items using a filter',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
description: 'Model id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'filter',
|
||||||
|
type: 'object',
|
||||||
|
required: true,
|
||||||
|
description: 'Filter defining where',
|
||||||
|
http: function(ctx) {
|
||||||
|
return ctx.req.query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
arg: 'data',
|
||||||
|
type: ['Address'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/:id/listAddresses`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Client.listAddresses = function(id, params, callback) {
|
||||||
|
let filter = {
|
||||||
|
where: {
|
||||||
|
clientFk: id
|
||||||
|
},
|
||||||
|
skip: (params.page - 1) * params.size,
|
||||||
|
limit: params.size,
|
||||||
|
order: ['isDefaultAddress DESC', 'isActive DESC']
|
||||||
|
};
|
||||||
|
|
||||||
|
let total = null;
|
||||||
|
let items = null;
|
||||||
|
|
||||||
|
function response(type, value) {
|
||||||
|
if (type === 'total') {
|
||||||
|
total = value;
|
||||||
|
} else {
|
||||||
|
items = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total !== null && items !== null) {
|
||||||
|
callback(null, {total: total, items: items});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Client.app.models.Address.find(filter, function(err, instances) {
|
||||||
|
if (err) return callback(err);
|
||||||
|
response('find', instances);
|
||||||
|
});
|
||||||
|
|
||||||
|
Client.app.models.Address.count(filter.where, function(err, total) {
|
||||||
|
if (err) return callback(err);
|
||||||
|
response('total', total);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,30 @@
|
||||||
|
module.exports = function(Self) {
|
||||||
|
Self.remoteMethod('listWorkers', {
|
||||||
|
description: 'List workers',
|
||||||
|
accessType: 'READ',
|
||||||
|
returns: {
|
||||||
|
arg: 'data',
|
||||||
|
type: 'Worker',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/listWorkers`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.listWorkers = function() {
|
||||||
|
let query =
|
||||||
|
`SELECT w.id,
|
||||||
|
CONCAT(w.firstName, IFNULL(CONCAT(" ", w.name), "")) \`name\`
|
||||||
|
FROM worker w
|
||||||
|
JOIN account.user u ON w.userFk = u.id
|
||||||
|
JOIN account.roleRole rr ON rr.role = u.role
|
||||||
|
JOIN account.role r ON r.id = rr.inheritsFrom
|
||||||
|
WHERE u.active
|
||||||
|
AND r.\`name\` = 'employee'
|
||||||
|
ORDER BY w.name ASC`;
|
||||||
|
|
||||||
|
return Self.rawSql(query);
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,3 +0,0 @@
|
||||||
module.exports = function(Self) {
|
|
||||||
Self.defineScope({where: {isManaged: {neq: 0}}});
|
|
||||||
};
|
|
|
@ -1,6 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "Account",
|
"name": "Account",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "user"
|
||||||
|
}
|
||||||
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
var UserError = require('../helpers').UserError;
|
||||||
|
var getFinalState = require('../helpers').getFinalState;
|
||||||
|
var isMultiple = require('../helpers').isMultiple;
|
||||||
|
|
||||||
|
module.exports = function(Self) {
|
||||||
|
Self.validate('isDefaultAddress', isActive,
|
||||||
|
{message: 'No se puede poner predeterminado un consignatario desactivado'}
|
||||||
|
);
|
||||||
|
function isActive(err) {
|
||||||
|
if (!this.isActive && this.isDefaultAddress) err();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self.beforeRemote('findById', function(ctx, modelInstance, next) {
|
||||||
|
ctx.args.filter = {
|
||||||
|
include: [{
|
||||||
|
relation: 'province',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name']
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
relation: 'agency',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name']
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
|
||||||
|
Self.observe('before save', async function(ctx) {
|
||||||
|
if (isMultiple(ctx)) return;
|
||||||
|
|
||||||
|
let changes = ctx.data || ctx.instance;
|
||||||
|
let finalState = getFinalState(ctx);
|
||||||
|
|
||||||
|
if (changes.isActive == false && finalState.isDefaultAddress)
|
||||||
|
throw new UserError('No se puede desmarcar el consignatario predeterminado');
|
||||||
|
|
||||||
|
if (changes.isDefaultAddress == true) {
|
||||||
|
let filter = {
|
||||||
|
clientFk: finalState.clientFk,
|
||||||
|
isDefaultAddress: {neq: false}
|
||||||
|
};
|
||||||
|
await Self.updateAll(filter, {isDefaultAddress: false});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
|
@ -1,13 +1,18 @@
|
||||||
{
|
{
|
||||||
"name": "Address",
|
"name": "Address",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "address"
|
||||||
|
}
|
||||||
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"id": true,
|
"id": true,
|
||||||
"description": "Identifier"
|
"description": "Identifier"
|
||||||
},
|
},
|
||||||
"consignee": {
|
"nickname": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
@ -19,7 +24,7 @@
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
"postcode": {
|
"postalCode": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"phone": {
|
"phone": {
|
||||||
|
@ -28,7 +33,7 @@
|
||||||
"mobile": {
|
"mobile": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"isEnabled": {
|
"isActive": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"isDefaultAddress": {
|
"isDefaultAddress": {
|
||||||
|
@ -56,10 +61,10 @@
|
||||||
"model": "Client",
|
"model": "Client",
|
||||||
"foreignKey": "clientFk"
|
"foreignKey": "clientFk"
|
||||||
},
|
},
|
||||||
"defaultAgency": {
|
"agency": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "AgencyMode",
|
"model": "AgencyMode",
|
||||||
"foreignKey": "defaultAgencyFk"
|
"foreignKey": "agencyFk"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
module.exports = function(Self) {
|
module.exports = function(Self) {
|
||||||
require('../methods/agency/list.js')(Self);
|
Self.defineScope({where: {isManaged: {neq: 0}}});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "Agency",
|
"name": "Agency",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "agency"
|
||||||
|
}
|
||||||
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"id": true,
|
"id": true,
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "ClientCreditLimit",
|
"name": "ClientCreditLimit",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "clientCreditLimit"
|
||||||
|
}
|
||||||
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "Number",
|
"type": "Number",
|
|
@ -0,0 +1,160 @@
|
||||||
|
var UserError = require('../helpers').UserError;
|
||||||
|
var getFinalState = require('../helpers').getFinalState;
|
||||||
|
var isMultiple = require('../helpers').isMultiple;
|
||||||
|
|
||||||
|
module.exports = function(Self) {
|
||||||
|
// Methods
|
||||||
|
|
||||||
|
require('../methods/client/activate')(Self);
|
||||||
|
require('../methods/client/listAddresses')(Self);
|
||||||
|
require('../methods/client/card')(Self);
|
||||||
|
require('../methods/client/createWithUser')(Self);
|
||||||
|
require('../methods/client/listWorkers')(Self);
|
||||||
|
require('../methods/client/filter')(Self);
|
||||||
|
require('../methods/client/hasCustomerRole')(Self);
|
||||||
|
require('../methods/client/activeSalesPerson')(Self);
|
||||||
|
require('../methods/client/addressesPropagateRe')(Self);
|
||||||
|
|
||||||
|
// Validations
|
||||||
|
|
||||||
|
Self.validatesUniquenessOf('fi', {
|
||||||
|
message: 'El NIF/CIF debe ser único'
|
||||||
|
});
|
||||||
|
Self.validatesUniquenessOf('socialName', {
|
||||||
|
message: 'La razón social debe ser única'
|
||||||
|
});
|
||||||
|
Self.validatesFormatOf('postcode', {
|
||||||
|
message: 'El código postal solo debe contener números',
|
||||||
|
allowNull: true,
|
||||||
|
allowBlank: true,
|
||||||
|
with: /^\d+$/
|
||||||
|
});
|
||||||
|
Self.validatesFormatOf('email', {
|
||||||
|
message: 'Correo electrónico inválido',
|
||||||
|
allowNull: true,
|
||||||
|
allowBlank: true,
|
||||||
|
with: /^[\w|.|-]+@\w[\w|.|-]*\w(,[\w|.|-]+@\w[\w|.|-]*\w)*$/
|
||||||
|
});
|
||||||
|
Self.validatesLengthOf('postcode', {
|
||||||
|
allowNull: true,
|
||||||
|
allowBlank: true,
|
||||||
|
min: 3, max: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
var validateIban = require('../validations/validateIban');
|
||||||
|
Self.validateBinded('iban', validateIban, {
|
||||||
|
message: 'El iban no tiene el formato correcto'
|
||||||
|
});
|
||||||
|
|
||||||
|
let validateDni = require('../validations/validateDni');
|
||||||
|
Self.validateBinded('fi', validateDni, {
|
||||||
|
message: 'DNI Incorrecto'
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.validate('payMethod', hasSalesMan, {
|
||||||
|
message: 'No se puede cambiar la forma de pago si no hay comercial asignado'
|
||||||
|
});
|
||||||
|
function hasSalesMan(err) {
|
||||||
|
if (this.payMethod && !this.salesPerson)
|
||||||
|
err();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self.validateAsync('payMethodFk', hasIban, {
|
||||||
|
message: 'El método de pago seleccionado requiere que se especifique el IBAN'
|
||||||
|
});
|
||||||
|
function hasIban(err, done) {
|
||||||
|
Self.app.models.PayMethod.findById(this.payMethodFk, (_, instance) => {
|
||||||
|
if (instance && instance.ibanRequired && !this.iban)
|
||||||
|
err();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
|
||||||
|
Self.observe('before save', async function(ctx) {
|
||||||
|
let changes = ctx.data || ctx.instance;
|
||||||
|
let finalState = getFinalState(ctx);
|
||||||
|
|
||||||
|
if (changes.salesPerson === null) {
|
||||||
|
changes.credit = 0;
|
||||||
|
changes.discount = 0;
|
||||||
|
changes.payMethodFk = 5; // Credit card
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.payMethodFk !== undefined && changes.dueDay === undefined)
|
||||||
|
changes.dueDay = 5;
|
||||||
|
|
||||||
|
if (isMultiple(ctx)) return;
|
||||||
|
|
||||||
|
if (changes.isEqualizated || changes.fi !== undefined) {
|
||||||
|
let fiLetter = finalState.fi && finalState.fi.toUpperCase().charAt(0);
|
||||||
|
let canMarkEqualizationTax = fiLetter != 'A' && fiLetter != 'B';
|
||||||
|
|
||||||
|
if (finalState.isEqualizated && !canMarkEqualizationTax)
|
||||||
|
throw new UserError('No se puede marcar el recargo de equivalencia');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.credit !== undefined)
|
||||||
|
try {
|
||||||
|
await validateCreditChange(ctx, finalState);
|
||||||
|
} catch (e) {
|
||||||
|
throw new UserError('No tienes privilegios para modificar el crédito');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function validateCreditChange(ctx, finalState) {
|
||||||
|
let models = Self.app.models;
|
||||||
|
let userId = ctx.options.accessToken.userId;
|
||||||
|
let filter = {
|
||||||
|
fields: ['roleFk'],
|
||||||
|
where: {
|
||||||
|
maxAmount: {gt: ctx.data.credit}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let limits = await models.ClientCreditLimit.find(filter);
|
||||||
|
|
||||||
|
if (limits.length == 0)
|
||||||
|
throw new Error('Credit limits not found');
|
||||||
|
|
||||||
|
// Si el usuario no tiene alguno de los roles no continua
|
||||||
|
|
||||||
|
let requiredRoles = [];
|
||||||
|
for (limit of limits)
|
||||||
|
requiredRoles.push(limit.roleFk);
|
||||||
|
|
||||||
|
let where = {
|
||||||
|
roleId: {inq: requiredRoles},
|
||||||
|
principalType: 'USER',
|
||||||
|
principalId: userId
|
||||||
|
};
|
||||||
|
let count = await models.RoleMapping.count(where);
|
||||||
|
|
||||||
|
if (count <= 0)
|
||||||
|
throw new Error('The role cannot set this credit amount');
|
||||||
|
|
||||||
|
// Si se puso a 0 por gerencia, solo gerencia puede aumentarlo
|
||||||
|
|
||||||
|
let query = 'SELECT * FROM clientCredit WHERE clientFk = ? ORDER BY created DESC LIMIT 1';
|
||||||
|
let instances = await Self.rawSql(query, [finalState.id]);
|
||||||
|
|
||||||
|
if (instances.length !== 1 || instances[0].workerFk == userId || instances[0].amount > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
query = `SELECT COUNT(distinct r.id) > 0 as hasManagerRole
|
||||||
|
FROM clientCredit cc
|
||||||
|
JOIN worker em ON em.id = cc.workerFk
|
||||||
|
JOIN account.user ac ON ac.id = em.userFk
|
||||||
|
JOIN salix.RoleMapping rm ON rm.principalId = ac.id
|
||||||
|
JOIN account.role r on r.id = rm.roleId
|
||||||
|
WHERE rm.principalType = 'USER'
|
||||||
|
AND cc.workerFk = ?
|
||||||
|
AND r.name = 'manager'`;
|
||||||
|
|
||||||
|
let instance = await Self.rawSql(query, [instances[0].workerFk]);
|
||||||
|
|
||||||
|
if (instance[0].hasManagerRole > 0)
|
||||||
|
throw new Error('Only manager can change the credit');
|
||||||
|
}
|
||||||
|
};
|
|
@ -3,8 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "client",
|
"table": "client"
|
||||||
"database": "vn"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -121,7 +120,7 @@
|
||||||
},
|
},
|
||||||
"salesPerson": {
|
"salesPerson": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Employee",
|
"model": "Worker",
|
||||||
"foreignKey": "salesPersonFk"
|
"foreignKey": "salesPersonFk"
|
||||||
},
|
},
|
||||||
"province":{
|
"province":{
|
|
@ -1,6 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "ContactChannel",
|
"name": "ContactChannel",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "contactChannel"
|
||||||
|
}
|
||||||
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "Number",
|
"type": "Number",
|
|
@ -1,19 +1,21 @@
|
||||||
{
|
{
|
||||||
"name": "Country",
|
"name": "Country",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "country"
|
||||||
|
}
|
||||||
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"id": true,
|
"id": true,
|
||||||
"description": "Identifier"
|
"description": "Identifier"
|
||||||
},
|
},
|
||||||
"name": {
|
"country": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
"inCee": {
|
|
||||||
"type": "Number"
|
|
||||||
},
|
|
||||||
"code": {
|
"code": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
|
@ -23,11 +25,6 @@
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Currency",
|
"model": "Currency",
|
||||||
"foreignKey": "currencyFk"
|
"foreignKey": "currencyFk"
|
||||||
},
|
|
||||||
"realCountry": {
|
|
||||||
"type": "belongsTo",
|
|
||||||
"model": "Country",
|
|
||||||
"foreignKey": "realCountryFk"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"acls": [
|
"acls": [
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
"name": "CreditClassification",
|
"name": "CreditClassification",
|
||||||
"description": "Clientes clasificados.",
|
"description": "Clientes clasificados.",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "creditClassification"
|
||||||
|
}
|
||||||
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"id": true,
|
"id": true,
|
|
@ -1,6 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "PayMethod",
|
"name": "PayMethod",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "payMethod"
|
||||||
|
}
|
||||||
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "Number",
|
"type": "Number",
|
|
@ -1,6 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "Province",
|
"name": "Province",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "province"
|
||||||
|
}
|
||||||
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue