Merge branch 'dev' of http://git.verdnatura.es/salix into dev
This commit is contained in:
commit
fa385cd9d6
|
@ -88,7 +88,12 @@
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
<vn-button-bar>
|
<vn-button-bar>
|
||||||
<vn-submit label="Regularizar" vn-acl="administrative, salesAssistant"></vn-submit>
|
{{$ctrl.resolvedStateText}}
|
||||||
|
<vn-button
|
||||||
|
label="Regularize"
|
||||||
|
ng-click="$ctrl.regularize()"
|
||||||
|
disabled="$ctrl.claim.claimStateFk == $ctrl.resolvedState">
|
||||||
|
</vn-button>
|
||||||
</vn-button-bar>
|
</vn-button-bar>
|
||||||
<!-- WIP
|
<!-- WIP
|
||||||
<a ng-click="$ctrl.openAddSalesDialog()" vn-tooltip="New item" vn-bind="+" fixed-bottom-right>
|
<a ng-click="$ctrl.openAddSalesDialog()" vn-tooltip="New item" vn-bind="+" fixed-bottom-right>
|
||||||
|
|
|
@ -22,6 +22,7 @@ class Controller {
|
||||||
{relation: 'claimBeggining'}
|
{relation: 'claimBeggining'}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
this.resolvedState = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
openAddSalesDialog() {
|
openAddSalesDialog() {
|
||||||
|
@ -118,6 +119,15 @@ class Controller {
|
||||||
this.$.model.refresh();
|
this.$.model.refresh();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
regularize() {
|
||||||
|
let data = {claimFk: this.$stateParams.id};
|
||||||
|
let query = `/claim/api/Claims/regularizeClaim`;
|
||||||
|
this.$http.post(query, data).then(() => {
|
||||||
|
this.card.reload();
|
||||||
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.$inject = ['$stateParams', '$scope', '$http', '$translate', 'vnApp'];
|
Controller.$inject = ['$stateParams', '$scope', '$http', '$translate', 'vnApp'];
|
||||||
|
@ -127,5 +137,8 @@ ngModule.component('vnClaimAction', {
|
||||||
controller: Controller,
|
controller: Controller,
|
||||||
bindings: {
|
bindings: {
|
||||||
claim: '<'
|
claim: '<'
|
||||||
|
},
|
||||||
|
require: {
|
||||||
|
card: '^vnClaimCard'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -31,6 +31,7 @@ describe('claim', () => {
|
||||||
hide: () => {},
|
hide: () => {},
|
||||||
show: () => {}
|
show: () => {}
|
||||||
};
|
};
|
||||||
|
controller.card = {reload: () => {}};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('openAddSalesDialog()', () => {
|
describe('openAddSalesDialog()', () => {
|
||||||
|
@ -135,7 +136,7 @@ describe('claim', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('importTicketLines()', () => {
|
describe('importTicketLines()', () => {
|
||||||
it('should perform a post quer', () => {
|
it('should perform a post query', () => {
|
||||||
spyOn(controller.$.model, 'refresh');
|
spyOn(controller.$.model, 'refresh');
|
||||||
spyOn(controller.vnApp, 'showSuccess');
|
spyOn(controller.vnApp, 'showSuccess');
|
||||||
spyOn(controller.$.lastTicketsPopover, 'hide');
|
spyOn(controller.$.lastTicketsPopover, 'hide');
|
||||||
|
@ -149,5 +150,20 @@ describe('claim', () => {
|
||||||
expect(controller.$.lastTicketsPopover.hide).toHaveBeenCalledWith();
|
expect(controller.$.lastTicketsPopover.hide).toHaveBeenCalledWith();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('regularize()', () => {
|
||||||
|
it('should perform a post query and reload the claim card', () => {
|
||||||
|
spyOn(controller.card, 'reload');
|
||||||
|
spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
|
||||||
|
let data = {claimFk: $state.params.id};
|
||||||
|
$httpBackend.expect('POST', `/claim/api/Claims/regularizeClaim`, data).respond({});
|
||||||
|
controller.regularize();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.card.reload).toHaveBeenCalledWith();
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,4 +4,5 @@ Total claimed: Total Reclamado
|
||||||
Import claim: Importar reclamacion
|
Import claim: Importar reclamacion
|
||||||
Imports claim details: Importa detalles de la reclamacion
|
Imports claim details: Importa detalles de la reclamacion
|
||||||
Import ticket: Importar ticket
|
Import ticket: Importar ticket
|
||||||
Imports ticket lines: Importa las lineas de un ticket
|
Imports ticket lines: Importa las lineas de un ticket
|
||||||
|
Regularize: Regularizar
|
|
@ -2,12 +2,9 @@ import ngModule from '../module';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
class Controller {
|
class Controller {
|
||||||
constructor($state, $scope, $http, $translate, vnApp) {
|
constructor($state, $scope) {
|
||||||
this.$state = $state;
|
this.$state = $state;
|
||||||
this.$ = $scope;
|
this.$ = $scope;
|
||||||
this.$http = $http;
|
|
||||||
this.$translate = $translate;
|
|
||||||
this.vnApp = vnApp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
|
@ -19,7 +16,7 @@ class Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.$inject = ['$state', '$scope', '$http', '$translate', 'vnApp'];
|
Controller.$inject = ['$state', '$scope'];
|
||||||
|
|
||||||
ngModule.component('vnClaimDevelopment', {
|
ngModule.component('vnClaimDevelopment', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
|
|
|
@ -5,4 +5,5 @@ Before: Antes
|
||||||
After: Despues
|
After: Despues
|
||||||
update: Actualizar
|
update: Actualizar
|
||||||
Create: Crear
|
Create: Crear
|
||||||
History: Historial
|
History: Historial
|
||||||
|
insert: Crear
|
|
@ -126,7 +126,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"url" : "/diary?warehouseFk",
|
"url" : "/diary?warehouseFk&ticketFk",
|
||||||
"state": "item.card.diary",
|
"state": "item.card.diary",
|
||||||
"component": "vn-item-diary",
|
"component": "vn-item-diary",
|
||||||
"description": "Diary",
|
"description": "Diary",
|
||||||
|
|
|
@ -16,15 +16,14 @@
|
||||||
value-field="id"
|
value-field="id"
|
||||||
initial-data="$ctrl.warehouseFk"
|
initial-data="$ctrl.warehouseFk"
|
||||||
field="$ctrl.warehouseFk"
|
field="$ctrl.warehouseFk"
|
||||||
label="Select warehouse"
|
label="Select warehouse">
|
||||||
on-change="$ctrl.onChange(value)">
|
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-table model="model">
|
<vn-table model="model">
|
||||||
<vn-thead>
|
<vn-thead>
|
||||||
<vn-tr>
|
<vn-tr>
|
||||||
<vn-th>Date</vn-th>
|
<vn-th>Date</vn-th>
|
||||||
<vn-th number>Id</vn-th>
|
<vn-th number order="DESC">Id</vn-th>
|
||||||
<vn-th>State</vn-th>
|
<vn-th>State</vn-th>
|
||||||
<vn-th>Reference</vn-th>
|
<vn-th>Reference</vn-th>
|
||||||
<vn-th>Client</vn-th>
|
<vn-th>Client</vn-th>
|
||||||
|
@ -34,9 +33,9 @@
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-thead>
|
</vn-thead>
|
||||||
<vn-tbody>
|
<vn-tbody>
|
||||||
<vn-tr ng-class="::{'warning': $ctrl.isToday(sale.date)}"
|
<vn-tr ng-class="::{'warning': $ctrl.isToday(sale.date), 'isIn': sale.in, 'balanceNegative': sale.balance < 0}"
|
||||||
ng-repeat="sale in sales" vn-repeat-last on-last="$ctrl.scrollToActive()">
|
ng-repeat="sale in sales" vn-repeat-last on-last="$ctrl.scrollToLine()">
|
||||||
<vn-td>{{::sale.date | date:'dd/MM/yyyy HH:mm' }}</vn-td>
|
<vn-td>{{::sale.date | date:'dd/MM/yyyy' }}</vn-td>
|
||||||
<vn-td number>
|
<vn-td number>
|
||||||
<span ng-class="::{'link pointer': sale.isTicket}"
|
<span ng-class="::{'link pointer': sale.isTicket}"
|
||||||
ng-click="$ctrl.showDescriptor($event, sale)">
|
ng-click="$ctrl.showDescriptor($event, sale)">
|
||||||
|
@ -45,16 +44,17 @@
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td>{{::sale.stateName | dashIfEmpty}}</vn-td>
|
<vn-td>{{::sale.stateName | dashIfEmpty}}</vn-td>
|
||||||
<vn-td>{{::sale.reference | dashIfEmpty}}</vn-td>
|
<vn-td>{{::sale.reference | dashIfEmpty}}</vn-td>
|
||||||
<vn-td>
|
<vn-td class="truncate">
|
||||||
<span ng-class="::{'link pointer': sale.isTicket}"
|
<span
|
||||||
|
ng-class="::{'link pointer': sale.isTicket}"
|
||||||
ng-click="$ctrl.showClientDescriptor($event, sale)">
|
ng-click="$ctrl.showClientDescriptor($event, sale)">
|
||||||
{{::sale.name | dashIfEmpty}}
|
{{::sale.name | dashIfEmpty}}
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td number>{{::sale.in | dashIfEmpty}}</vn-td>
|
<vn-td number class="in">{{::sale.in | dashIfEmpty}}</vn-td>
|
||||||
<vn-td number>{{::sale.out | dashIfEmpty}}</vn-td>
|
<vn-td number>{{::sale.out | dashIfEmpty}}</vn-td>
|
||||||
<vn-td number>
|
<vn-td number class="balance">
|
||||||
<span class="balance">
|
<span class="balanceSpan">
|
||||||
{{::sale.balance | dashIfEmpty}}
|
{{::sale.balance | dashIfEmpty}}
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
|
|
|
@ -27,6 +27,9 @@ class Controller {
|
||||||
this.warehouseFk = this.$stateParams.warehouseFk;
|
this.warehouseFk = this.$stateParams.warehouseFk;
|
||||||
else if (value)
|
else if (value)
|
||||||
this.warehouseFk = value.itemType.warehouseFk;
|
this.warehouseFk = value.itemType.warehouseFk;
|
||||||
|
|
||||||
|
if (this.$stateParams.ticketFk)
|
||||||
|
this.ticketFk = this.$stateParams.ticketFk;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,16 +77,33 @@ class Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollToActive() {
|
get givenTicketIndex() {
|
||||||
|
let lines = this.$scope.model.data;
|
||||||
|
|
||||||
|
for (let i = lines.length - 1; i > 0; i--) {
|
||||||
|
let line = lines[i];
|
||||||
|
|
||||||
|
if (line.origin == this.ticketFk)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToLine() {
|
||||||
let body = this.$window.document.body;
|
let body = this.$window.document.body;
|
||||||
let lineIndex = this.onPreparationLineIndex;
|
|
||||||
|
let lineIndex;
|
||||||
|
if (this.ticketFk)
|
||||||
|
lineIndex = this.givenTicketIndex;
|
||||||
|
else
|
||||||
|
lineIndex = this.onPreparationLineIndex;
|
||||||
|
|
||||||
let lines = body.querySelector('vn-tbody').children;
|
let lines = body.querySelector('vn-tbody').children;
|
||||||
|
|
||||||
if (!lineIndex || !lines.length) return;
|
if (!lineIndex || !lines.length) return;
|
||||||
|
|
||||||
let onPreparationLine = lines[lineIndex];
|
let onPreparationLine = lines[lineIndex];
|
||||||
|
|
||||||
let balance = onPreparationLine.querySelector('.balance');
|
let balance = onPreparationLine.querySelector('.balanceSpan');
|
||||||
balance.classList.add('counter');
|
balance.classList.add('counter');
|
||||||
balance.title = this.$translate.instant('Visible quantity');
|
balance.title = this.$translate.instant('Visible quantity');
|
||||||
|
|
||||||
|
@ -92,6 +112,7 @@ class Controller {
|
||||||
let offsetTop = onPreparationLine.offsetTop - headerHeight;
|
let offsetTop = onPreparationLine.offsetTop - headerHeight;
|
||||||
|
|
||||||
body.querySelector('ui-view').scrollTop = offsetTop;
|
body.querySelector('ui-view').scrollTop = offsetTop;
|
||||||
|
this.ticketFk = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -98,6 +98,22 @@ describe('Item', () => {
|
||||||
expect(controller.item.id).toEqual(1);
|
expect(controller.item.id).toEqual(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('givenTicketIndex() setter', () => {
|
||||||
|
it(`should return the index position of the line of a given ticket fk`, () => {
|
||||||
|
controller.$scope.model = {data: [
|
||||||
|
{name: 'My item 1', origin: 1, alertLevel: 3, isPicked: true, date: '2018-05-02'},
|
||||||
|
{name: 'My item 3', origin: 2, alertLevel: 1, isPicked: true, date: '2018-05-03'},
|
||||||
|
{name: 'My item 4', origin: 3, alertLevel: 1, isPicked: false, date: '2018-05-03'}]
|
||||||
|
};
|
||||||
|
controller.ticketFk = 2;
|
||||||
|
|
||||||
|
let index = controller.givenTicketIndex;
|
||||||
|
|
||||||
|
expect(controller.$scope.model.data[index].origin).toEqual(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,34 @@
|
||||||
|
@import 'colors';
|
||||||
|
|
||||||
vn-item-diary {
|
vn-item-diary {
|
||||||
|
& > vn-vertical {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
vn-card {
|
||||||
|
margin: auto;
|
||||||
|
max-width: 880px;
|
||||||
|
}
|
||||||
& vn-horizontal {
|
& vn-horizontal {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
& vn-autocomplete > div{
|
& vn-autocomplete > div{
|
||||||
width: 400px;
|
width: 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.balanceNegative .balance {
|
||||||
|
background-color: $main-01;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.isIn .in {
|
||||||
|
background-color: $main-02;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.truncate {
|
||||||
|
max-width: 250px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -4,3 +4,4 @@ import './main-menu/main-menu';
|
||||||
import './left-menu/left-menu';
|
import './left-menu/left-menu';
|
||||||
import './left-menu/menu-item';
|
import './left-menu/menu-item';
|
||||||
import './topbar/topbar';
|
import './topbar/topbar';
|
||||||
|
import './user-configuration-popover'
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<div style="position: fixed; top: 0; right: 0; padding: .8em 1.5em; z-index: 10;">
|
<div style="position: fixed; top: 0; right: 0; padding: .8em 1.5em; z-index: 10;">
|
||||||
<div
|
<div
|
||||||
id="user">
|
ng-click="$ctrl.openUserConfiguration($event)"
|
||||||
|
id="user"
|
||||||
|
class="unselectable">
|
||||||
<h6>{{currentUserName}}</h6>
|
<h6>{{currentUserName}}</h6>
|
||||||
</div>
|
</div>
|
||||||
<a href="/salix/version-notes.html"
|
<a href="/salix/version-notes.html"
|
||||||
|
@ -47,6 +49,7 @@
|
||||||
translate-attr="{title: 'Logout'}"
|
translate-attr="{title: 'Logout'}"
|
||||||
ng-click="$ctrl.onLogoutClick()">
|
ng-click="$ctrl.onLogoutClick()">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
TODO: Keep it commented until they are functional
|
TODO: Keep it commented until they are functional
|
||||||
|
|
||||||
|
@ -54,3 +57,8 @@
|
||||||
<vn-icon icon="account_circle" translate-attr="{title: 'Profile'}"></vn-icon>
|
<vn-icon icon="account_circle" translate-attr="{title: 'Profile'}"></vn-icon>
|
||||||
-->
|
-->
|
||||||
</div>
|
</div>
|
||||||
|
<vn-popover vn-id="popover">
|
||||||
|
<vn-user-configuration-popover>
|
||||||
|
|
||||||
|
</vn-user-configuration-popover>
|
||||||
|
</vn-popover>
|
|
@ -34,6 +34,11 @@ export default class MainMenu {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openUserConfiguration(event) {
|
||||||
|
this.$.popover.parent = event.target;
|
||||||
|
this.$.popover.show();
|
||||||
|
}
|
||||||
|
|
||||||
onLogoutClick() {
|
onLogoutClick() {
|
||||||
this.$window.location = '/logout';
|
this.$window.location = '/logout';
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
<vn-crud-model
|
||||||
|
url="/api/Banks"
|
||||||
|
data="banks"
|
||||||
|
order="bank">
|
||||||
|
</vn-crud-model>
|
||||||
|
<vn-crud-model
|
||||||
|
url="/api/Warehouses"
|
||||||
|
data="warehouses"
|
||||||
|
order="name">
|
||||||
|
</vn-crud-model>
|
||||||
|
<vn-crud-model
|
||||||
|
url="/api/Companies"
|
||||||
|
data="companies"
|
||||||
|
order="code">
|
||||||
|
</vn-crud-model>
|
||||||
|
<vn-vertical class="body">
|
||||||
|
<form name="form" ng-submit="$ctrl.onSubmit()">
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
label="Local warehouse"
|
||||||
|
id="localWarehouse"
|
||||||
|
field="$ctrl.localWarehouse"
|
||||||
|
data="warehouses"
|
||||||
|
select-fields="['id','name']"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
label="Local bank"
|
||||||
|
id="localBank"
|
||||||
|
field="$ctrl.localBank"
|
||||||
|
data="banks"
|
||||||
|
select-fields="['id','bank']"
|
||||||
|
show-field="bank"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
label="Local company"
|
||||||
|
id="localCompany"
|
||||||
|
field="$ctrl.localCompany"
|
||||||
|
data="companies"
|
||||||
|
select-fields="['id','code']"
|
||||||
|
show-field="code"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
label="User warehouse"
|
||||||
|
id="userWarehouse"
|
||||||
|
field="$ctrl.warehouseFk"
|
||||||
|
data="warehouses"
|
||||||
|
select-fields="['id', 'name']"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
label="User company"
|
||||||
|
id="userCompany"
|
||||||
|
field="$ctrl.companyFk"
|
||||||
|
data="companies"
|
||||||
|
select-fields="['id', 'code']"
|
||||||
|
show-field="code"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
</form>
|
||||||
|
</vn-vertical>
|
|
@ -0,0 +1,90 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
constructor($scope, $http, $state, vnApp, $translate) {
|
||||||
|
this.$scope = $scope;
|
||||||
|
this.$http = $http;
|
||||||
|
this.$state = $state;
|
||||||
|
this.vnApp = vnApp;
|
||||||
|
this.$translate = $translate;
|
||||||
|
this.getUserConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
set localBank(value) {
|
||||||
|
window.localStorage.localBank = value;
|
||||||
|
this.showOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
get localBank() {
|
||||||
|
return parseInt(window.localStorage.localBank);
|
||||||
|
}
|
||||||
|
|
||||||
|
set localWarehouse(value) {
|
||||||
|
window.localStorage.localWarehouse = value;
|
||||||
|
this.showOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
get localWarehouse() {
|
||||||
|
return parseInt(window.localStorage.localWarehouse);
|
||||||
|
}
|
||||||
|
|
||||||
|
set localCompany(value) {
|
||||||
|
window.localStorage.localCompany = value;
|
||||||
|
this.showOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
get localCompany() {
|
||||||
|
return parseInt(window.localStorage.localCompany);
|
||||||
|
}
|
||||||
|
|
||||||
|
set warehouseFk(value) {
|
||||||
|
this.warehouse = value;
|
||||||
|
this.setUserConfig('warehouseFk');
|
||||||
|
}
|
||||||
|
|
||||||
|
get warehouseFk() {
|
||||||
|
return this.warehouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
set companyFk(value) {
|
||||||
|
this.company = value;
|
||||||
|
this.setUserConfig('companyFk');
|
||||||
|
}
|
||||||
|
|
||||||
|
get companyFk() {
|
||||||
|
return this.company;
|
||||||
|
}
|
||||||
|
|
||||||
|
showOk() {
|
||||||
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserConfig() {
|
||||||
|
this.$http.get('/api/UserConfigs/getUserConfig')
|
||||||
|
.then(res => {
|
||||||
|
if (res.data && res.data.warehouseFk)
|
||||||
|
this.warehouse = res.data.warehouseFk;
|
||||||
|
|
||||||
|
if (res.data && res.data.companyFk)
|
||||||
|
this.company = res.data.companyFk;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setUserConfig(property) {
|
||||||
|
let params = {};
|
||||||
|
params[property] = this[property];
|
||||||
|
|
||||||
|
this.$http.post('/api/UserConfigs/setUserConfig', params)
|
||||||
|
.then(() => {
|
||||||
|
this.showOk();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.$inject = ['$scope', '$http', '$state', 'vnApp', '$translate'];
|
||||||
|
|
||||||
|
ngModule.component('vnUserConfigurationPopover', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: Controller
|
||||||
|
});
|
|
@ -0,0 +1,97 @@
|
||||||
|
import './index.js';
|
||||||
|
|
||||||
|
describe('Salix', () => {
|
||||||
|
describe('Component vnUserConfigurationPopover', () => {
|
||||||
|
let $componentController;
|
||||||
|
let controller;
|
||||||
|
let $httpBackend;
|
||||||
|
let $scope;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
angular.mock.module('salix');
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(angular.mock.inject((_$componentController_, _$httpBackend_, $rootScope) => {
|
||||||
|
$componentController = _$componentController_;
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||||
|
$scope = $rootScope.$new();
|
||||||
|
controller = $componentController('vnUserConfigurationPopover', {$scope: $scope, $translate: null});
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('localBank() setter', () => {
|
||||||
|
it('should set window.localStorage.localBank and call showOk', () => {
|
||||||
|
spyOn(controller, 'showOk')
|
||||||
|
controller.localBank = 4;
|
||||||
|
|
||||||
|
expect(window.localStorage.localBank).toBe('4');
|
||||||
|
expect(controller.showOk).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('localWarehouse() setter', () => {
|
||||||
|
it('should set window.localStorage.localWarehouse and call showOk', () => {
|
||||||
|
spyOn(controller, 'showOk')
|
||||||
|
controller.localWarehouse = 4;
|
||||||
|
|
||||||
|
expect(window.localStorage.localWarehouse).toBe('4');
|
||||||
|
expect(controller.showOk).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('localCompany() setter', () => {
|
||||||
|
it('should set window.localStorage.localCompany and call showOk', () => {
|
||||||
|
spyOn(controller, 'showOk')
|
||||||
|
controller.localCompany = 4;
|
||||||
|
|
||||||
|
expect(window.localStorage.localCompany).toBe('4');
|
||||||
|
expect(controller.showOk).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('warehouseFk() setter', () => {
|
||||||
|
it('should set warehouse and call setUserConfig', () => {
|
||||||
|
spyOn(controller, 'setUserConfig')
|
||||||
|
controller.warehouseFk = 4;
|
||||||
|
|
||||||
|
expect(controller.warehouse).toBe(4);
|
||||||
|
expect(controller.setUserConfig).toHaveBeenCalledWith('warehouseFk');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('companyFk() setter', () => {
|
||||||
|
it('should set company and call setUserConfig', () => {
|
||||||
|
spyOn(controller, 'setUserConfig')
|
||||||
|
controller.companyFk = 4;
|
||||||
|
|
||||||
|
expect(controller.company).toBe(4);
|
||||||
|
expect(controller.setUserConfig).toHaveBeenCalledWith('companyFk');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getUserConfig()', () => {
|
||||||
|
it('should make a query, set company and not set warehouse if its not in the response', () => {
|
||||||
|
$httpBackend.when('GET', `/api/UserConfigs/getUserConfig`).respond({response: {companyFk: 2}});
|
||||||
|
$httpBackend.expect('GET', `/api/UserConfigs/getUserConfig`);
|
||||||
|
controller.getUserConfig();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.warehouse).toBeUndefined();
|
||||||
|
expect(controller.company).toEqual(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setUserConfig()', () => {
|
||||||
|
it('should make a query with the property given and call showOk', () => {
|
||||||
|
spyOn(controller, 'showOk');
|
||||||
|
controller.company = 1;
|
||||||
|
$httpBackend.when('POST', `/api/UserConfigs/setUserConfig`, {companyFk: 1}).respond(200);
|
||||||
|
$httpBackend.expect('POST', `/api/UserConfigs/setUserConfig`, {companyFk: 1});
|
||||||
|
controller.setUserConfig('companyFk');
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.showOk).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,12 @@
|
||||||
|
@import 'colors';
|
||||||
|
|
||||||
|
vn-user-configuration-popover {
|
||||||
|
color: $main-font-color;
|
||||||
|
& > vn-vertical {
|
||||||
|
min-width: 250px;
|
||||||
|
}
|
||||||
|
.body {
|
||||||
|
padding: 16px 16px 6px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -93,7 +93,8 @@ class Controller {
|
||||||
icon: 'icon-transaction',
|
icon: 'icon-transaction',
|
||||||
state: `item.card.diary({
|
state: `item.card.diary({
|
||||||
id: ${itemFk},
|
id: ${itemFk},
|
||||||
q: '{"warehouseFk": ${this.ticket.warehouseFk}}'
|
warehouseFk: ${this.ticket.warehouseFk},
|
||||||
|
ticketFk: ${this.ticket.id}
|
||||||
})`,
|
})`,
|
||||||
tooltip: 'Item diary'
|
tooltip: 'Item diary'
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
<span
|
<span
|
||||||
ng-class="{'link pointer':expedition.itemFk}"
|
ng-class="{'link pointer':expedition.itemFk}"
|
||||||
ng-click="$ctrl.showDescriptor($event, expedition.itemFk)">
|
ng-click="$ctrl.showDescriptor($event, expedition.itemFk)">
|
||||||
{{expedition.itemFk}}
|
{{("000000"+expedition.itemFk).slice(-6)}}
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td>{{::expedition.namePackage}}</vn-td>
|
<vn-td>{{::expedition.namePackage}}</vn-td>
|
||||||
|
|
|
@ -27,7 +27,8 @@ class Controller {
|
||||||
icon: 'icon-transaction',
|
icon: 'icon-transaction',
|
||||||
state: `item.card.diary({
|
state: `item.card.diary({
|
||||||
id: ${itemFk},
|
id: ${itemFk},
|
||||||
q: '{"warehouseFk": ${this.ticket.warehouseFk}}'
|
warehouseFk: ${this.ticket.warehouseFk},
|
||||||
|
ticketFk: ${this.ticket.id}
|
||||||
})`,
|
})`,
|
||||||
tooltip: 'Item diary'
|
tooltip: 'Item diary'
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,4 +73,4 @@ Tracking: Revisión
|
||||||
Sale checked: Control clientes
|
Sale checked: Control clientes
|
||||||
Components: Componentes
|
Components: Componentes
|
||||||
Sale tracking: Líneas preparadas
|
Sale tracking: Líneas preparadas
|
||||||
Pictures: Imágenes
|
Pictures: Fotos
|
||||||
|
|
|
@ -39,7 +39,8 @@ class Controller {
|
||||||
icon: 'icon-transaction',
|
icon: 'icon-transaction',
|
||||||
state: `item.card.diary({
|
state: `item.card.diary({
|
||||||
id: ${itemFk},
|
id: ${itemFk},
|
||||||
q: '{"warehouseFk": ${this.ticket.warehouseFk}}'
|
warehouseFk: ${this.ticket.warehouseFk},
|
||||||
|
ticketFk: ${this.ticket.id}
|
||||||
})`,
|
})`,
|
||||||
tooltip: 'Item diary'
|
tooltip: 'Item diary'
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,8 @@ class Controller {
|
||||||
icon: 'icon-transaction',
|
icon: 'icon-transaction',
|
||||||
state: `item.card.diary({
|
state: `item.card.diary({
|
||||||
id: ${itemFk},
|
id: ${itemFk},
|
||||||
q: '{"warehouseFk": ${this.ticket.warehouseFk}}'
|
warehouseFk: ${this.ticket.warehouseFk},
|
||||||
|
ticketFk: ${this.ticket.id}
|
||||||
})`,
|
})`,
|
||||||
tooltip: 'Item diary'
|
tooltip: 'Item diary'
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,8 @@ class Controller {
|
||||||
icon: 'icon-transaction',
|
icon: 'icon-transaction',
|
||||||
state: `item.card.diary({
|
state: `item.card.diary({
|
||||||
id: ${itemFk},
|
id: ${itemFk},
|
||||||
q: '{"warehouseFk": ${this.ticket.warehouseFk}}'
|
warehouseFk: ${this.ticket.warehouseFk},
|
||||||
|
ticketFk: ${this.ticket.id}
|
||||||
})`,
|
})`,
|
||||||
tooltip: 'Item diary'
|
tooltip: 'Item diary'
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,8 @@ class Controller {
|
||||||
icon: 'icon-transaction',
|
icon: 'icon-transaction',
|
||||||
state: `item.card.diary({
|
state: `item.card.diary({
|
||||||
id: ${itemFk},
|
id: ${itemFk},
|
||||||
q: '{"warehouseFk": ${this.ticket.warehouseFk}}'
|
warehouseFk: ${this.ticket.warehouseFk},
|
||||||
|
ticketFk: ${this.ticket.id}
|
||||||
})`,
|
})`,
|
||||||
tooltip: 'Item diary'
|
tooltip: 'Item diary'
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,8 @@ class Controller {
|
||||||
icon: 'icon-transaction',
|
icon: 'icon-transaction',
|
||||||
state: `item.card.diary({
|
state: `item.card.diary({
|
||||||
id: ${itemFk},
|
id: ${itemFk},
|
||||||
q: '{"warehouseFk": ${this.ticket.warehouseFk}}'
|
warehouseFk: ${this.ticket.warehouseFk},
|
||||||
|
ticketFk: ${this.ticket.id}
|
||||||
})`,
|
})`,
|
||||||
tooltip: 'Item diary'
|
tooltip: 'Item diary'
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,6 @@ describe('Client lock verified data path', () => {
|
||||||
return nightmare
|
return nightmare
|
||||||
.wait(selectors.clientFiscalData.verifiedDataCheckboxInput)
|
.wait(selectors.clientFiscalData.verifiedDataCheckboxInput)
|
||||||
.evaluate(selector => {
|
.evaluate(selector => {
|
||||||
console.log(document.querySelector(selector));
|
|
||||||
return document.querySelector(selector).disabled;
|
return document.querySelector(selector).disabled;
|
||||||
}, selectors.clientFiscalData.verifiedDataCheckbox)
|
}, selectors.clientFiscalData.verifiedDataCheckbox)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('regularizeClaim', {
|
||||||
|
description: 'Imports lines from claimBeginning to a new ticket with specific shipped, landed dates, agency and company',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'params',
|
||||||
|
type: 'object',
|
||||||
|
http: {source: 'body'}
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: ['Object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/regularizeClaim`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.regularizeClaim = async (ctx, params) => {
|
||||||
|
const userId = ctx.req.accessToken.userId;
|
||||||
|
const models = Self.app.models;
|
||||||
|
const resolvedState = 3;
|
||||||
|
|
||||||
|
const claimEnds = await models.ClaimEnd.find({
|
||||||
|
include: {
|
||||||
|
relation: 'claimDestination',
|
||||||
|
fields: ['addressFk']
|
||||||
|
},
|
||||||
|
where: {claimFk: params.claimFk}
|
||||||
|
});
|
||||||
|
|
||||||
|
let transaction = await Self.beginTransaction({});
|
||||||
|
try {
|
||||||
|
for (let i = 0; i < claimEnds.length; i++) {
|
||||||
|
const claimEnd = claimEnds[i];
|
||||||
|
const destination = claimEnd.claimDestination();
|
||||||
|
const addressFk = destination && destination.addressFk;
|
||||||
|
|
||||||
|
if (!addressFk)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let sale = await getSale(claimEnd.saleFk);
|
||||||
|
let ticketFk = await getTicketId({
|
||||||
|
addressFk: addressFk,
|
||||||
|
companyFk: sale.ticket().companyFk,
|
||||||
|
warehouseFk: sale.ticket().warehouseFk
|
||||||
|
}, transaction);
|
||||||
|
|
||||||
|
let address = await models.Address.findOne({
|
||||||
|
where: {id: addressFk}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!ticketFk) {
|
||||||
|
ticketFk = await createTicket({
|
||||||
|
clientFk: address.clientFk,
|
||||||
|
addressFk: addressFk,
|
||||||
|
warehouseFk: sale.ticket().warehouseFk,
|
||||||
|
companyFk: sale.ticket().companyFk,
|
||||||
|
userId: userId
|
||||||
|
}, transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
await models.Sale.create({
|
||||||
|
ticketFk: ticketFk,
|
||||||
|
itemFk: sale.itemFk,
|
||||||
|
concept: sale.concept,
|
||||||
|
quantity: -sale.quantity,
|
||||||
|
price: sale.price,
|
||||||
|
discount: 100
|
||||||
|
}, {transaction: transaction});
|
||||||
|
|
||||||
|
await sendMessage(ctx, {
|
||||||
|
itemFk: sale.itemFk,
|
||||||
|
ticketFk: sale.ticketFk,
|
||||||
|
workerFk: sale.item().itemType().workerFk,
|
||||||
|
quantity: sale.quantity,
|
||||||
|
concept: sale.concept,
|
||||||
|
nickname: address.nickname
|
||||||
|
}, transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
let claim = await Self.findById(params.claimFk);
|
||||||
|
claim = await claim.updateAttributes({
|
||||||
|
claimStateFk: resolvedState
|
||||||
|
}, {transaction: transaction});
|
||||||
|
|
||||||
|
await transaction.commit();
|
||||||
|
|
||||||
|
return claim;
|
||||||
|
} catch (e) {
|
||||||
|
await transaction.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function getSale(saleFk) {
|
||||||
|
return await Self.app.models.Sale.findOne({
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'ticket',
|
||||||
|
scope: {fields: ['warehouseFk', 'companyFk']}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relation: 'item',
|
||||||
|
scope: {
|
||||||
|
fields: ['typeFk'],
|
||||||
|
include: {
|
||||||
|
relation: 'itemType',
|
||||||
|
scope: {fields: ['workerFk']}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
where: {id: saleFk}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getTicketId(params, transaction) {
|
||||||
|
const currentDate = new Date();
|
||||||
|
currentDate.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
let ticket = await Self.app.models.Ticket.findOne({
|
||||||
|
where: {
|
||||||
|
addressFk: params.addressFk,
|
||||||
|
companyFk: params.companyFk,
|
||||||
|
warehouseFk: params.warehouseFk,
|
||||||
|
shipped: currentDate,
|
||||||
|
landed: currentDate
|
||||||
|
}
|
||||||
|
}, {transaction: transaction});
|
||||||
|
|
||||||
|
return ticket && ticket.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createTicket(params, transaction) {
|
||||||
|
return await Self.app.models.Ticket.new({
|
||||||
|
shipped: new Date(),
|
||||||
|
landed: new Date(),
|
||||||
|
clientFk: params.clientFk,
|
||||||
|
warehouseFk: params.warehouseFk,
|
||||||
|
companyFk: params.companyFk,
|
||||||
|
addressFk: params.addressFk,
|
||||||
|
userId: params.userId
|
||||||
|
}, {transaction: transaction});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendMessage(ctx, params, transaction) {
|
||||||
|
const message = `Envio ${params.quantity} unidades de "${params.concept}" (#${params.itemFk}) a `
|
||||||
|
+ `"${params.nickname}" provenientes del ticket #${params.ticketFk}`;
|
||||||
|
|
||||||
|
await Self.app.models.Message.send(ctx, {
|
||||||
|
recipientFk: params.workerFk,
|
||||||
|
message: message
|
||||||
|
}, {transaction: transaction});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,45 @@
|
||||||
|
const app = require(`${servicesDir}/claim/server/server`);
|
||||||
|
|
||||||
|
describe('regularizeClaim()', () => {
|
||||||
|
const claimFk = 1;
|
||||||
|
const pendentState = 1;
|
||||||
|
const resolvedState = 3;
|
||||||
|
const trashDestination = 2;
|
||||||
|
const trashAddress = 12;
|
||||||
|
let claimEnds = [];
|
||||||
|
let trashTicket;
|
||||||
|
|
||||||
|
afterAll(async() => {
|
||||||
|
let claim = await app.models.Claim.findById(claimFk);
|
||||||
|
await claim.updateAttributes({claimStateFk: pendentState});
|
||||||
|
await app.models.Ticket.destroyById(trashTicket.id);
|
||||||
|
|
||||||
|
claimEnds.forEach(async line => {
|
||||||
|
await line.destroy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should change claim state to resolved', async() => {
|
||||||
|
let ctx = {req: {accessToken: {userId: 18}}};
|
||||||
|
let params = {claimFk: claimFk};
|
||||||
|
|
||||||
|
claimEnds = await app.models.ClaimEnd.importTicketSales(ctx, {
|
||||||
|
claimFk: claimFk,
|
||||||
|
ticketFk: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
claimEnds.forEach(async claimEnd => {
|
||||||
|
claimEnd.updateAttributes({claimDestinationFk: trashDestination});
|
||||||
|
});
|
||||||
|
|
||||||
|
let claimBefore = await app.models.Claim.findById(params.claimFk);
|
||||||
|
await app.models.Claim.regularizeClaim(ctx, params);
|
||||||
|
let claimAfter = await app.models.Claim.findById(params.claimFk);
|
||||||
|
|
||||||
|
trashTicket = await app.models.Ticket.findOne({where: {addressFk: 12}});
|
||||||
|
|
||||||
|
expect(trashTicket.addressFk).toEqual(trashAddress);
|
||||||
|
expect(claimBefore.claimStateFk).toEqual(pendentState);
|
||||||
|
expect(claimAfter.claimStateFk).toEqual(resolvedState);
|
||||||
|
});
|
||||||
|
});
|
|
@ -18,6 +18,13 @@
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"relations": {
|
||||||
|
"address": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Address",
|
||||||
|
"foreignKey": "addressFk"
|
||||||
|
}
|
||||||
|
},
|
||||||
"acls": [
|
"acls": [
|
||||||
{
|
{
|
||||||
"accessType": "READ",
|
"accessType": "READ",
|
||||||
|
|
|
@ -2,4 +2,5 @@ module.exports = Self => {
|
||||||
require('../methods/claim/getSummary')(Self);
|
require('../methods/claim/getSummary')(Self);
|
||||||
require('../methods/claim/createFromSales')(Self);
|
require('../methods/claim/createFromSales')(Self);
|
||||||
require('../methods/claim/updateClaim')(Self);
|
require('../methods/claim/updateClaim')(Self);
|
||||||
|
require('../methods/claim/regularizeClaim')(Self);
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,13 +71,15 @@ module.exports = function(Self) {
|
||||||
let customer = insurance.classification().customer();
|
let customer = insurance.classification().customer();
|
||||||
|
|
||||||
if (!customer.salesPerson()) return;
|
if (!customer.salesPerson()) return;
|
||||||
let salesPerson = customer.salesPerson().user().name;
|
let salesPersonId = customer.salesPerson().user().id;
|
||||||
let grade = data.grade ? `(Grado ${data.grade})` : '(Sin grado)';
|
let grade = data.grade ? `(Grado ${data.grade})` : '(Sin grado)';
|
||||||
let message = {
|
let params = {
|
||||||
message: `He cambiado el crédito asegurado del cliente "${customer.name}" a ${data.credit} € ${grade}`
|
recipientFk: salesPersonId,
|
||||||
|
message: `He cambiado el crédito asegurado del `
|
||||||
|
+ `cliente "${customer.name}" a ${data.credit} € ${grade}`
|
||||||
};
|
};
|
||||||
|
|
||||||
Self.app.models.Message.send(salesPerson, message, ctx);
|
Self.app.models.Message.send(ctx, params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update from transaction misses ctx accessToken.
|
// Update from transaction misses ctx accessToken.
|
||||||
|
|
|
@ -4,7 +4,10 @@ VALUES
|
||||||
(105, 'ItemBarcode', '*', 'WRITE', 'ALLOW', 'ROLE', 'marketingBoss'),
|
(105, 'ItemBarcode', '*', 'WRITE', 'ALLOW', 'ROLE', 'marketingBoss'),
|
||||||
(106, 'ItemBotanical', '*', 'WRITE', 'ALLOW', 'ROLE', 'marketingBoss'),
|
(106, 'ItemBotanical', '*', 'WRITE', 'ALLOW', 'ROLE', 'marketingBoss'),
|
||||||
(107, 'ItemNiche', '*', 'WRITE', 'ALLOW', 'ROLE', 'marketingBoss'),
|
(107, 'ItemNiche', '*', 'WRITE', 'ALLOW', 'ROLE', 'marketingBoss'),
|
||||||
(108, 'ItemPlacement', '*', 'WRITE', 'ALLOW', 'ROLE', 'marketingBoss');
|
(108, 'ItemPlacement', '*', 'WRITE', 'ALLOW', 'ROLE', 'marketingBoss'),
|
||||||
|
(109, 'UserConfig', '*', '*', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
(110, 'Bank', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
|
||||||
|
|
||||||
|
|
||||||
UPDATE salix.ACL
|
UPDATE salix.ACL
|
||||||
SET model='ItemTag', property='*', accessType='WRITE', permission='ALLOW', principalType='ROLE', principalId='marketingBoss'
|
SET model='ItemTag', property='*', accessType='WRITE', permission='ALLOW', principalType='ROLE', principalId='marketingBoss'
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
USE `vn`;
|
||||||
|
DROP procedure IF EXISTS `itemDiary`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
USE `vn`$$
|
||||||
|
CREATE DEFINER=`root`@`%` PROCEDURE `itemDiary`(IN vItemId INT, IN vWarehouse INT)
|
||||||
|
BEGIN
|
||||||
|
DECLARE vDateInventory DATETIME;
|
||||||
|
DECLARE vCurdate DATE DEFAULT CURDATE();
|
||||||
|
DECLARE vDayEnd DATETIME DEFAULT util.dayEnd(vCurdate);
|
||||||
|
-- traduccion: date, alertLevel, origin, reference, name, In, Out, Balance
|
||||||
|
SELECT Fechainventario INTO vDateInventory FROM vn2008.tblContadores;
|
||||||
|
SET @a = 0;
|
||||||
|
SELECT sql_no_cache DATE(date) AS date,
|
||||||
|
alertLevel,
|
||||||
|
stateName,
|
||||||
|
origin,
|
||||||
|
reference,
|
||||||
|
clientFk,
|
||||||
|
name,
|
||||||
|
`in`,
|
||||||
|
`out`,
|
||||||
|
@a := @a + IFNULL(`in`,0) - IFNULL(`out`,0) as balance,
|
||||||
|
isPicked,
|
||||||
|
isTicket
|
||||||
|
FROM
|
||||||
|
( SELECT tr.landed as date,
|
||||||
|
b.quantity as `in`,
|
||||||
|
NULL as `out`,
|
||||||
|
IF(tr.isReceived != FALSE,3, IF(tr.isDelivered,1,0)) as alertLevel,
|
||||||
|
st.name AS stateName,
|
||||||
|
s.name as name,
|
||||||
|
e.ref as reference,
|
||||||
|
e.id as origin,
|
||||||
|
s.id as clientFk,
|
||||||
|
TRUE isPicked,
|
||||||
|
FALSE AS isTicket
|
||||||
|
FROM vn.buy b
|
||||||
|
JOIN vn.entry e ON e.id = b.entryFk
|
||||||
|
JOIN vn.travel tr ON tr.id = e.travelFk
|
||||||
|
JOIN vn.supplier s ON s.id = e.supplierFk
|
||||||
|
JOIN vn.alertLevel al ON al.alertLevel =
|
||||||
|
CASE
|
||||||
|
WHEN tr.isReceived != FALSE THEN 3
|
||||||
|
WHEN tr.isDelivered THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END
|
||||||
|
JOIN vn.state st ON st.code = al.code
|
||||||
|
WHERE tr.landed >= vDateInventory
|
||||||
|
AND vWarehouse = tr.warehouseInFk
|
||||||
|
AND b.itemFk = vItemId
|
||||||
|
AND e.isInventory = 0
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT tr.shipped as date,
|
||||||
|
NULL as `in`,
|
||||||
|
b.quantity as `out`,
|
||||||
|
IF(tr.isReceived != FALSE,3, IF(tr.isDelivered,1,0)) as alertLevel,
|
||||||
|
st.name AS stateName,
|
||||||
|
s.name as name,
|
||||||
|
e.ref as reference,
|
||||||
|
e.id as origin,
|
||||||
|
s.id as clientFk,
|
||||||
|
TRUE isPicked,
|
||||||
|
FALSE AS isTicket
|
||||||
|
FROM vn.buy b
|
||||||
|
JOIN vn.entry e ON e.id = b.entryFk
|
||||||
|
JOIN vn.travel tr ON tr.id = e.travelFk
|
||||||
|
JOIN vn.warehouse w ON w.id = tr.warehouseOutFk
|
||||||
|
JOIN vn.supplier s ON s.id = e.supplierFk
|
||||||
|
JOIN vn.alertLevel al ON al.alertLevel =
|
||||||
|
CASE
|
||||||
|
WHEN tr.isReceived != FALSE THEN 3
|
||||||
|
WHEN tr.isDelivered THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END
|
||||||
|
JOIN vn.state st ON st.code = al.code
|
||||||
|
WHERE tr.shipped >= vDateInventory
|
||||||
|
AND vWarehouse =tr.warehouseOutFk
|
||||||
|
AND s.id <> 4
|
||||||
|
AND b.itemFk = vItemId
|
||||||
|
AND e.isInventory = 0
|
||||||
|
AND w.isFeedStock = 0
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT t.shipped as date,
|
||||||
|
NULL as `in`,
|
||||||
|
s.quantity as `out`,
|
||||||
|
al.alertLevel as alertLevel,
|
||||||
|
st.name AS stateName,
|
||||||
|
t.nickname as name,
|
||||||
|
t.refFk as reference,
|
||||||
|
t.id as origin,
|
||||||
|
t.clientFk,
|
||||||
|
TRUE as isPicked, -- stk.id as isPicked
|
||||||
|
TRUE as isTicket
|
||||||
|
FROM vn.sale s
|
||||||
|
JOIN vn.ticket t ON t.id = s.ticketFk
|
||||||
|
LEFT JOIN vn.ticketState ts ON ts.ticket = t.id
|
||||||
|
JOIN vn.client c ON c.id = t.clientFk
|
||||||
|
JOIN vn.alertLevel al ON al.alertLevel =
|
||||||
|
CASE
|
||||||
|
WHEN t.shipped < vCurdate THEN 3
|
||||||
|
WHEN t.shipped > vDayEnd THEN 0
|
||||||
|
ELSE IFNULL(ts.alertLevel, 0)
|
||||||
|
END
|
||||||
|
JOIN vn.state st ON st.code = al.code
|
||||||
|
-- LEFT JOIN vn.saleTracking stk ON stk.saleFk = s.id AND stk.stateFk = 14
|
||||||
|
WHERE t.shipped >= vDateInventory
|
||||||
|
AND s.itemFk = vItemId
|
||||||
|
AND vWarehouse =t.warehouseFk
|
||||||
|
) AS itemDiary
|
||||||
|
ORDER BY date DESC, alertLevel DESC, isPicked DESC, `in` DESC, `out` DESC;
|
||||||
|
END$$
|
||||||
|
|
||||||
|
DELIMITER ;
|
||||||
|
|
|
@ -483,7 +483,7 @@ INSERT INTO `vn`.`taxCode`(`id`, `dated`, `code`, `taxTypeFk`, `rate`, `equaliza
|
||||||
VALUES
|
VALUES
|
||||||
(1 , CURDATE(), '1111111111', 1, 7.0 , 0.0, 'R', 1, 1, CURDATE(), 1),
|
(1 , CURDATE(), '1111111111', 1, 7.0 , 0.0, 'R', 1, 1, CURDATE(), 1),
|
||||||
(2 , CURDATE(), '2222222222', 2, 16.0, 0.0, 'G', 2, 1, CURDATE(), 1),
|
(2 , CURDATE(), '2222222222', 2, 16.0, 0.0, 'G', 2, 1, CURDATE(), 1),
|
||||||
(21 , CURDATE(), '3333333333', 1, 18.0, 0.0, 'R', 3, 1, CURDATE(), 1),
|
(21 , CURDATE(), '3333333333', 1, 7.0, 0.0, 'R', 3, 1, CURDATE(), 1),
|
||||||
(108, CURDATE(), '4444444444', 2, 8.0 , 0.0, 'R', 4, 1, CURDATE(), 1);
|
(108, CURDATE(), '4444444444', 2, 8.0 , 0.0, 'R', 4, 1, CURDATE(), 1);
|
||||||
|
|
||||||
INSERT INTO `vn`.`taxClass`(`id`, `description`, `code`)
|
INSERT INTO `vn`.`taxClass`(`id`, `description`, `code`)
|
||||||
|
@ -928,4 +928,7 @@ INSERT INTO `vn`.`orderTicket`(`orderFk`, `ticketFk`)
|
||||||
(18, 18),
|
(18, 18),
|
||||||
(19, 19),
|
(19, 19),
|
||||||
(20, 20),
|
(20, 20),
|
||||||
(21, 21);
|
(21, 21);
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`userConfig` (`userFk`, `warehouseFk`, `companyFk`)
|
||||||
|
VALUES (9, 1, 442);
|
||||||
|
|
|
@ -51,5 +51,6 @@
|
||||||
"You don't have enough privileges to change that field": "No tienes permisos para cambiar ese campo",
|
"You don't have enough privileges to change that field": "No tienes permisos para cambiar ese campo",
|
||||||
"Warehouse cannot be blank": "El almacén no puede quedar en blanco",
|
"Warehouse cannot be blank": "El almacén no puede quedar en blanco",
|
||||||
"Agency cannot be blank": "La agencia no puede quedar en blanco",
|
"Agency cannot be blank": "La agencia no puede quedar en blanco",
|
||||||
"You don't have enough privileges to do that": "No tienes permisos para para hacer esto"
|
"You don't have enough privileges to do that": "No tienes permisos para para hacer esto",
|
||||||
|
"This address doesn't exist": "This address doesn't exist"
|
||||||
}
|
}
|
|
@ -1,18 +1,12 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethod('send', {
|
Self.remoteMethodCtx('send', {
|
||||||
description: 'Send message to user',
|
description: 'Send message to user',
|
||||||
accessType: 'WRITE',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'recipient',
|
|
||||||
type: 'string',
|
|
||||||
required: true,
|
|
||||||
description: 'The user/alias name',
|
|
||||||
http: {source: 'path'}
|
|
||||||
}, {
|
|
||||||
arg: 'data',
|
arg: 'data',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'Message data',
|
description: 'recipientFk, message',
|
||||||
http: {source: 'body'}
|
http: {source: 'body'}
|
||||||
}, {
|
}, {
|
||||||
arg: 'context',
|
arg: 'context',
|
||||||
|
@ -31,10 +25,23 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.send = async(recipient, data, ctx) => {
|
Self.send = async(ctx, data, transaction) => {
|
||||||
let query = `SELECT vn.messageSendWithUser(?, ?, ?) AS sent`;
|
const userId = ctx.req.accessToken.userId;
|
||||||
let [result] = await Self.rawSql(query, [ctx.req.accessToken.userId, recipient, data.message]);
|
const models = Self.app.models;
|
||||||
|
const sender = await models.Account.findById(userId, transaction);
|
||||||
|
const recipient = await models.Account.findById(data.recipientFk, transaction);
|
||||||
|
|
||||||
return result;
|
await Self.create({
|
||||||
|
sender: sender.name,
|
||||||
|
recipient: recipient.name,
|
||||||
|
message: data.message
|
||||||
|
}, transaction);
|
||||||
|
|
||||||
|
return await models.MessageInbox.create({
|
||||||
|
sender: sender.name,
|
||||||
|
recipient: recipient.name,
|
||||||
|
finalRecipient: recipient.name,
|
||||||
|
message: data.message
|
||||||
|
}, transaction);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,9 +3,12 @@ const app = require(`${servicesDir}/client/server/server`);
|
||||||
describe('message send()', () => {
|
describe('message send()', () => {
|
||||||
it('should call the send method and return the response', async() => {
|
it('should call the send method and return the response', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 1}}};
|
let ctx = {req: {accessToken: {userId: 1}}};
|
||||||
await app.models.Message.send('salesPerson', {message: 'I changed something'}, ctx)
|
let params = {
|
||||||
.then(response => {
|
recipientFk: 1,
|
||||||
expect(response.sent).toEqual(1);
|
message: 'I changed something'
|
||||||
});
|
};
|
||||||
|
let response = await app.models.Message.send(ctx, params, {transaction: 'You'});
|
||||||
|
|
||||||
|
expect(response.message).toEqual(params.message);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
module.exports = function(Self) {
|
||||||
|
Self.remoteMethodCtx('getUserConfig', {
|
||||||
|
description: 'returns the information from UserConfig model for the active user',
|
||||||
|
accepts: [],
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/getUserConfig`,
|
||||||
|
verb: 'get'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.getUserConfig = async ctx => {
|
||||||
|
let token = ctx.req.accessToken;
|
||||||
|
let currentUserId = token && token.userId;
|
||||||
|
|
||||||
|
return await Self.findOne({userFk: currentUserId});
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,28 @@
|
||||||
|
module.exports = function(Self) {
|
||||||
|
Self.remoteMethodCtx('setUserConfig', {
|
||||||
|
description: 'Change worker of tickets state',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'params',
|
||||||
|
type: 'object',
|
||||||
|
required: true,
|
||||||
|
description: 'warehouseFk, companyFk',
|
||||||
|
http: {source: 'body'}
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
arg: 'response',
|
||||||
|
type: 'object'
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/setUserConfig`,
|
||||||
|
verb: 'post'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.setUserConfig = async(ctx, params) => {
|
||||||
|
let token = ctx.req.accessToken;
|
||||||
|
let currentUserId = token && token.userId;
|
||||||
|
params.userFk = currentUserId;
|
||||||
|
|
||||||
|
return await Self.app.models.UserConfig.upsertWithWhere({userFk: currentUserId}, params);
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"name": "Bank",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "bank"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"bank": {
|
||||||
|
"type": "string",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"account": {
|
||||||
|
"type": "string",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"cash": {
|
||||||
|
"type": "string",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"entityFk": {
|
||||||
|
"type": "string",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"isActive": {
|
||||||
|
"type": "string",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"currencyFk": {
|
||||||
|
"type": "string",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,8 +17,7 @@
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
"userFk": {
|
"userFk": {
|
||||||
"type": "Number",
|
"type": "Number"
|
||||||
"required": true
|
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"type": "String",
|
"type": "String",
|
||||||
|
|
|
@ -127,7 +127,7 @@ module.exports = function(Self) {
|
||||||
|
|
||||||
|
|
||||||
let userFk;
|
let userFk;
|
||||||
if (!loopBackContext) userFk = process.env.NODE_ENV ? 1765 : 111;
|
if (!loopBackContext) userFk = null;
|
||||||
else userFk = loopBackContext.active.accessToken.userId;
|
else userFk = loopBackContext.active.accessToken.userId;
|
||||||
|
|
||||||
let action = setActionType(ctx);
|
let action = setActionType(ctx);
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
{
|
||||||
|
"name": "MessageInbox",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "messageInbox"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"sender": {
|
||||||
|
"type": "String",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"recipient": {
|
||||||
|
"type": "String",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"finalRecipient": {
|
||||||
|
"type": "String",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"remitter": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "User",
|
||||||
|
"foreignKey": "sender"
|
||||||
|
},
|
||||||
|
"receptor": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "User",
|
||||||
|
"foreignKey": "recipient"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
require('../methods/userConfig/setUserConfig')(Self);
|
||||||
|
require('../methods/userConfig/getUserConfig')(Self);
|
||||||
|
};
|
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
"name": "UserConfig",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "userConfig",
|
||||||
|
"database": "vn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"userFk": {
|
||||||
|
"id": true,
|
||||||
|
"type": "Number",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"warehouseFk": {
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"companyFk": {
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"created": {
|
||||||
|
"type": "Date"
|
||||||
|
},
|
||||||
|
"updated": {
|
||||||
|
"type": "Date"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"warehouse": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Warehouse",
|
||||||
|
"foreignKey": "warehouseFk"
|
||||||
|
},
|
||||||
|
"company": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Company",
|
||||||
|
"foreignKey": "companyFk"
|
||||||
|
},
|
||||||
|
"account": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Account",
|
||||||
|
"foreignKey": "userFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,6 +42,9 @@
|
||||||
"AgencyMode": {
|
"AgencyMode": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"Bank": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"Client": {
|
"Client": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
@ -120,10 +123,16 @@
|
||||||
"Message": {
|
"Message": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"MessageInbox": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"WorkerMana": {
|
"WorkerMana": {
|
||||||
"dataSource": "bs"
|
"dataSource": "bs"
|
||||||
},
|
},
|
||||||
"DeliveryMethod": {
|
"DeliveryMethod": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"UserConfig": {
|
||||||
|
"dataSource": "vn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.addToOrder = async params => {
|
Self.addToOrder = async params => {
|
||||||
console.log(params);
|
|
||||||
let isEditable = await Self.app.models.Order.isEditable(params.orderFk);
|
let isEditable = await Self.app.models.Order.isEditable(params.orderFk);
|
||||||
|
|
||||||
if (!isEditable)
|
if (!isEditable)
|
||||||
|
|
Loading…
Reference in New Issue