#6943 - Client module redirect to Lilium #2924
|
@ -37,17 +37,11 @@ async function test() {
|
||||||
|
|
||||||
const specFiles = [
|
const specFiles = [
|
||||||
`./e2e/paths/01*/*[sS]pec.js`,
|
`./e2e/paths/01*/*[sS]pec.js`,
|
||||||
`./e2e/paths/02*/*[sS]pec.js`,
|
|
||||||
`./e2e/paths/03*/*[sS]pec.js`,
|
|
||||||
`./e2e/paths/04*/*[sS]pec.js`,
|
`./e2e/paths/04*/*[sS]pec.js`,
|
||||||
`./e2e/paths/05*/*[sS]pec.js`,
|
`./e2e/paths/05*/*[sS]pec.js`,
|
||||||
`./e2e/paths/07*/*[sS]pec.js`,
|
`./e2e/paths/07*/*[sS]pec.js`,
|
||||||
`./e2e/paths/08*/*[sS]pec.js`,
|
|
||||||
`./e2e/paths/09*/*[sS]pec.js`,
|
|
||||||
`./e2e/paths/10*/*[sS]pec.js`,
|
`./e2e/paths/10*/*[sS]pec.js`,
|
||||||
`./e2e/paths/11*/*[sS]pec.js`,
|
`./e2e/paths/11*/*[sS]pec.js`,
|
||||||
`./e2e/paths/12*/*[sS]pec.js`,
|
|
||||||
`./e2e/paths/13*/*[sS]pec.js`,
|
|
||||||
`./e2e/paths/**/*[sS]pec.js`
|
`./e2e/paths/**/*[sS]pec.js`
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -1,193 +0,0 @@
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
url="Clients/{{$ctrl.$params.id}}/createAddress"
|
|
||||||
id-field="id"
|
|
||||||
data="$ctrl.address"
|
|
||||||
params="$ctrl.address"
|
|
||||||
insert-mode="true"
|
|
||||||
form="form">
|
|
||||||
</vn-watcher>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="Provinces/location"
|
|
||||||
data="provincesLocation"
|
|
||||||
order="id">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="Incoterms"
|
|
||||||
data="incoterms"
|
|
||||||
order="name">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="CustomsAgents"
|
|
||||||
data="customsAgents"
|
|
||||||
order="fiscalName">
|
|
||||||
</vn-crud-model>
|
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-check
|
|
||||||
vn-one
|
|
||||||
label="Default" ng-model="$ctrl.address.isDefaultAddress">
|
|
||||||
</vn-check>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Consignee"
|
|
||||||
ng-model="$ctrl.address.nickname"
|
|
||||||
rule
|
|
||||||
vn-focus>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Street address"
|
|
||||||
ng-model="$ctrl.address.street"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-datalist vn-one
|
|
||||||
label="Postcode"
|
|
||||||
ng-model="$ctrl.address.postalCode"
|
|
||||||
selection="$ctrl.postcode"
|
|
||||||
url="Postcodes/location"
|
|
||||||
fields="['code','townFk']"
|
|
||||||
order="code, townFk"
|
|
||||||
value-field="code"
|
|
||||||
show-field="code"
|
|
||||||
rule>
|
|
||||||
<tpl-item>
|
|
||||||
{{code}} - {{town.name}} ({{town.province.name}},
|
|
||||||
{{town.province.country.name}})
|
|
||||||
</tpl-item>
|
|
||||||
<append>
|
|
||||||
<vn-icon-button
|
|
||||||
icon="add_circle"
|
|
||||||
vn-tooltip="New postcode"
|
|
||||||
ng-click="postcode.open()"
|
|
||||||
vn-acl="deliveryAssistant"
|
|
||||||
vn-acl-action="remove">
|
|
||||||
</vn-icon-button>
|
|
||||||
</append>
|
|
||||||
</vn-datalist>
|
|
||||||
<vn-datalist vn-id="town" vn-one
|
|
||||||
label="City"
|
|
||||||
ng-model="$ctrl.address.city"
|
|
||||||
selection="$ctrl.town"
|
|
||||||
url="Towns/location"
|
|
||||||
fields="['id', 'name', 'provinceFk']"
|
|
||||||
show-field="name"
|
|
||||||
value-field="name">
|
|
||||||
<tpl-item>
|
|
||||||
{{name}}, {{province.name}}
|
|
||||||
({{province.country.name}})
|
|
||||||
</tpl-item>
|
|
||||||
</vn-datalist>
|
|
||||||
<vn-autocomplete vn-id="province" vn-one
|
|
||||||
label="Province"
|
|
||||||
ng-model="$ctrl.address.provinceFk"
|
|
||||||
data="provincesLocation"
|
|
||||||
fields="['id', 'name', 'countryFk']"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
rule>
|
|
||||||
<tpl-item>{{name}} ({{country.name}})</tpl-item>
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
ng-model="$ctrl.address.agencyModeFk"
|
|
||||||
url="AgencyModes/isActive"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
label="Agency">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Phone"
|
|
||||||
ng-model="$ctrl.address.phone"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Mobile"
|
|
||||||
ng-model="$ctrl.address.mobile"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
ng-model="$ctrl.address.incotermsFk"
|
|
||||||
data="incoterms"
|
|
||||||
show-field="name"
|
|
||||||
value-field="code"
|
|
||||||
label="Incoterms">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
ng-model="$ctrl.address.customsAgentFk"
|
|
||||||
data="customsAgents"
|
|
||||||
show-field="fiscalName"
|
|
||||||
value-field="id"
|
|
||||||
label="Customs agent">
|
|
||||||
<append>
|
|
||||||
<vn-icon-button
|
|
||||||
icon="add_circle"
|
|
||||||
vn-tooltip="New customs agent"
|
|
||||||
ng-click="$ctrl.showCustomAgent($event)">
|
|
||||||
</vn-icon-button>
|
|
||||||
</append>
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit label="Save"></vn-submit>
|
|
||||||
<vn-button
|
|
||||||
label="Cancel"
|
|
||||||
ui-sref="client.card.address.index">
|
|
||||||
</vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<!-- New postcode dialog -->
|
|
||||||
<vn-geo-postcode vn-id="postcode"
|
|
||||||
on-response="$ctrl.onResponse($response)">
|
|
||||||
</vn-geo-postcode>
|
|
||||||
|
|
||||||
<!-- Create custom agent dialog -->
|
|
||||||
<vn-dialog class="edit"
|
|
||||||
vn-id="customAgent"
|
|
||||||
on-accept="$ctrl.onCustomAgentAccept()"
|
|
||||||
message="New customs agent">
|
|
||||||
<tpl-body>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield vn-one vn-focus
|
|
||||||
label="NIF"
|
|
||||||
ng-model="$ctrl.newCustomsAgent.nif"
|
|
||||||
required="true">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield vn-one
|
|
||||||
label="Fiscal name"
|
|
||||||
ng-model="$ctrl.newCustomsAgent.fiscalName"
|
|
||||||
required="true">
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield vn-one
|
|
||||||
label="Street"
|
|
||||||
ng-model="$ctrl.newCustomsAgent.street">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield vn-one
|
|
||||||
label="Phone"
|
|
||||||
ng-model="$ctrl.newCustomsAgent.phone">
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
</tpl-body>
|
|
||||||
<tpl-buttons>
|
|
||||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
|
||||||
<button response="accept" translate>Create</button>
|
|
||||||
</tpl-buttons>
|
|
||||||
</vn-dialog>
|
|
|
@ -1,90 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
export default class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
|
|
||||||
this.address = {
|
|
||||||
isActive: true,
|
|
||||||
isDefaultAddress: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
this.$.watcher.submit().then(res => {
|
|
||||||
if (this.address.isDefaultAddress)
|
|
||||||
this.client.defaultAddressFk = res.data.id;
|
|
||||||
|
|
||||||
this.$state.go('client.card.address.index');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
showCustomAgent(event) {
|
|
||||||
if (event.defaultPrevented) return;
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
this.$.customAgent.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
onCustomAgentAccept() {
|
|
||||||
return this.$http.post(`CustomsAgents`, this.newCustomsAgent)
|
|
||||||
.then(res => this.address.customsAgentFk = res.data.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
get town() {
|
|
||||||
return this._town;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Town auto complete
|
|
||||||
set town(selection) {
|
|
||||||
this._town = selection;
|
|
||||||
|
|
||||||
if (!selection) return;
|
|
||||||
|
|
||||||
const province = selection.province;
|
|
||||||
const postcodes = selection.postcodes;
|
|
||||||
|
|
||||||
if (!this.address.provinceFk)
|
|
||||||
this.address.provinceFk = province.id;
|
|
||||||
|
|
||||||
if (postcodes.length === 1)
|
|
||||||
this.address.postalCode = postcodes[0].code;
|
|
||||||
}
|
|
||||||
|
|
||||||
get postcode() {
|
|
||||||
return this._postcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Postcode auto complete
|
|
||||||
set postcode(selection) {
|
|
||||||
this._postcode = selection;
|
|
||||||
|
|
||||||
if (!selection) return;
|
|
||||||
|
|
||||||
const town = selection.town;
|
|
||||||
const province = town.province;
|
|
||||||
|
|
||||||
if (!this.address.city)
|
|
||||||
this.address.city = town.name;
|
|
||||||
|
|
||||||
if (!this.address.provinceFk)
|
|
||||||
this.address.provinceFk = province.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
onResponse(response) {
|
|
||||||
this.address.postalCode = response.code;
|
|
||||||
this.address.city = response.city;
|
|
||||||
this.address.provinceFk = response.provinceFk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientAddressCreate', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,130 +0,0 @@
|
||||||
import './index';
|
|
||||||
import watcher from 'core/mocks/watcher';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientAddressCreate', () => {
|
|
||||||
let $scope;
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
let $element;
|
|
||||||
let $state;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$state_, _$httpBackend_) => {
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$state = _$state_;
|
|
||||||
$state.params.id = '1234';
|
|
||||||
$element = angular.element('<vn-client-address-create></vn-client-address-create>');
|
|
||||||
controller = $componentController('vnClientAddressCreate', {$element, $scope});
|
|
||||||
controller.$.watcher = watcher;
|
|
||||||
controller.$.watcher.submit = () => {
|
|
||||||
return {
|
|
||||||
then: callback => {
|
|
||||||
callback({data: {id: 124}});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
controller.client = {id: 1101, defaultAddressFk: 121};
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should define and set address property', () => {
|
|
||||||
expect(controller.address.isActive).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onSubmit()', () => {
|
|
||||||
it('should perform a PATCH and not set value to defaultAddressFk property', () => {
|
|
||||||
jest.spyOn(controller.$state, 'go');
|
|
||||||
controller.address.isDefaultAddress = false;
|
|
||||||
controller.onSubmit();
|
|
||||||
|
|
||||||
expect(controller.client.defaultAddressFk).toEqual(121);
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('client.card.address.index');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should perform a PATCH and set a value to defaultAddressFk property', () => {
|
|
||||||
jest.spyOn(controller.$state, 'go');
|
|
||||||
controller.address.isDefaultAddress = true;
|
|
||||||
controller.onSubmit();
|
|
||||||
|
|
||||||
expect(controller.client.defaultAddressFk).toEqual(124);
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('client.card.address.index');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('town() setter', () => {
|
|
||||||
it(`should set provinceFk property`, () => {
|
|
||||||
controller.town = {
|
|
||||||
provinceFk: 1,
|
|
||||||
code: 46001,
|
|
||||||
province: {
|
|
||||||
id: 1,
|
|
||||||
name: 'New york',
|
|
||||||
country: {
|
|
||||||
id: 2,
|
|
||||||
name: 'USA'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
postcodes: []
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.address.provinceFk).toEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should set provinceFk property and fill the postalCode if there's just one`, () => {
|
|
||||||
controller.town = {
|
|
||||||
provinceFk: 1,
|
|
||||||
code: 46001,
|
|
||||||
province: {
|
|
||||||
id: 1,
|
|
||||||
name: 'New york',
|
|
||||||
country: {
|
|
||||||
id: 2,
|
|
||||||
name: 'USA'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
postcodes: [{code: '46001'}]
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.address.provinceFk).toEqual(1);
|
|
||||||
expect(controller.address.postalCode).toEqual('46001');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('postcode() setter', () => {
|
|
||||||
it(`should set the town and province properties`, () => {
|
|
||||||
controller.postcode = {
|
|
||||||
townFk: 1,
|
|
||||||
code: 46001,
|
|
||||||
town: {
|
|
||||||
id: 1,
|
|
||||||
name: 'New York',
|
|
||||||
province: {
|
|
||||||
id: 1,
|
|
||||||
name: 'New york',
|
|
||||||
country: {
|
|
||||||
id: 2,
|
|
||||||
name: 'USA'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.address.city).toEqual('New York');
|
|
||||||
expect(controller.address.provinceFk).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onCustomAgentAccept()', () => {
|
|
||||||
it(`should create a new customs agent and then set the customsAgentFk property on the address`, () => {
|
|
||||||
const expectedResult = {id: 1, fiscalName: 'Customs agent one'};
|
|
||||||
$httpBackend.when('POST', 'CustomsAgents').respond(200, expectedResult);
|
|
||||||
controller.onCustomAgentAccept();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.address.customsAgentFk).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,237 +0,0 @@
|
||||||
|
|
||||||
<mg-ajax
|
|
||||||
path="Addresses/{{edit.params.addressId}}"
|
|
||||||
actions="$ctrl.address = edit.model"
|
|
||||||
options="mgEdit">
|
|
||||||
</mg-ajax>
|
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
url="Clients/{{$ctrl.$params.id}}/updateAddress"
|
|
||||||
id-field="id"
|
|
||||||
data="$ctrl.address"
|
|
||||||
form="form">
|
|
||||||
</vn-watcher>
|
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="AddressObservations"
|
|
||||||
fields="['id', 'addressFk', 'observationTypeFk', 'description']"
|
|
||||||
link="{addressFk: $ctrl.$params.addressId}"
|
|
||||||
data="observations"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-crud-model
|
|
||||||
url="ObservationTypes"
|
|
||||||
fields="['id', 'description']"
|
|
||||||
data="types"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-check
|
|
||||||
vn-one
|
|
||||||
label="Enabled"
|
|
||||||
ng-model="$ctrl.address.isActive">
|
|
||||||
</vn-check>
|
|
||||||
<vn-check
|
|
||||||
vn-one
|
|
||||||
label="Is equalizated"
|
|
||||||
ng-model="$ctrl.address.isEqualizated"
|
|
||||||
vn-acl="administrative, salesAssistant">
|
|
||||||
</vn-check>
|
|
||||||
<vn-check
|
|
||||||
vn-one
|
|
||||||
label="Is Logiflora allowed"
|
|
||||||
ng-model="$ctrl.address.isLogifloraAllowed"
|
|
||||||
vn-acl="salesAssistant">
|
|
||||||
</vn-check>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Consignee"
|
|
||||||
ng-model="$ctrl.address.nickname"
|
|
||||||
rule
|
|
||||||
vn-focus>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Street"
|
|
||||||
ng-model="$ctrl.address.street"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-datalist vn-one
|
|
||||||
label="Postcode"
|
|
||||||
ng-model="$ctrl.address.postalCode"
|
|
||||||
selection="$ctrl.postcode"
|
|
||||||
url="Postcodes/location"
|
|
||||||
fields="['code','townFk']"
|
|
||||||
order="code, townFk"
|
|
||||||
value-field="code"
|
|
||||||
show-field="code"
|
|
||||||
rule>
|
|
||||||
<tpl-item>
|
|
||||||
{{code}} - {{town.name}} ({{town.province.name}},
|
|
||||||
{{town.province.country.name}})
|
|
||||||
</tpl-item>
|
|
||||||
<append>
|
|
||||||
<vn-icon-button
|
|
||||||
icon="add_circle"
|
|
||||||
vn-tooltip="New postcode"
|
|
||||||
ng-click="postcode.open()"
|
|
||||||
vn-acl="deliveryAssistant"
|
|
||||||
vn-acl-action="remove">
|
|
||||||
</vn-icon-button>
|
|
||||||
</append>
|
|
||||||
</vn-datalist>
|
|
||||||
<vn-datalist vn-id="town" vn-one
|
|
||||||
label="City"
|
|
||||||
ng-model="$ctrl.address.city"
|
|
||||||
selection="$ctrl.town"
|
|
||||||
url="Towns/location"
|
|
||||||
fields="['id', 'name', 'provinceFk']"
|
|
||||||
show-field="name"
|
|
||||||
value-field="name">
|
|
||||||
<tpl-item>
|
|
||||||
{{name}}, {{province.name}}
|
|
||||||
({{province.country.name}})
|
|
||||||
</tpl-item>
|
|
||||||
</vn-datalist>
|
|
||||||
<vn-autocomplete vn-id="province" vn-one
|
|
||||||
label="Province"
|
|
||||||
ng-model="$ctrl.address.provinceFk"
|
|
||||||
url="Provinces/location"
|
|
||||||
fields="['id', 'name', 'countryFk']"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
rule>
|
|
||||||
<tpl-item>{{name}} ({{country.name}})</tpl-item>
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
ng-model="$ctrl.address.agencyModeFk"
|
|
||||||
url="AgencyModes/isActive"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
label="Agency">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Phone"
|
|
||||||
ng-model="$ctrl.address.phone"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Mobile"
|
|
||||||
ng-model="$ctrl.address.mobile"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
ng-model="$ctrl.address.incotermsFk"
|
|
||||||
url="Incoterms"
|
|
||||||
show-field="name"
|
|
||||||
value-field="code"
|
|
||||||
label="Incoterms">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
ng-model="$ctrl.address.customsAgentFk"
|
|
||||||
url="CustomsAgents"
|
|
||||||
show-field="fiscalName"
|
|
||||||
value-field="id"
|
|
||||||
label="Customs agent">
|
|
||||||
<append>
|
|
||||||
<vn-icon-button
|
|
||||||
icon="add_circle"
|
|
||||||
vn-tooltip="New customs agent"
|
|
||||||
ng-click="$ctrl.showCustomAgent($event)">
|
|
||||||
</vn-icon-button>
|
|
||||||
</append>
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-title>Notes</vn-title>
|
|
||||||
<div name="observations">
|
|
||||||
<vn-horizontal ng-repeat="observation in observations">
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
vn-focus
|
|
||||||
data="types"
|
|
||||||
ng-model="observation.observationTypeFk"
|
|
||||||
show-field="description"
|
|
||||||
label="Observation type"
|
|
||||||
rule="AddressObservation">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-textfield
|
|
||||||
vn-two
|
|
||||||
label="Description"
|
|
||||||
ng-model="observation.description"
|
|
||||||
rule="AddressObservation">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-none>
|
|
||||||
<vn-icon-button
|
|
||||||
vn-tooltip="Remove note"
|
|
||||||
icon="delete"
|
|
||||||
ng-click="$ctrl.removeObservation($index)"
|
|
||||||
tabindex="-1">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-none>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-icon-button
|
|
||||||
vn-bind="+"
|
|
||||||
vn-tooltip="Add note"
|
|
||||||
icon="add_circle"
|
|
||||||
ng-if="types.length > observations.length"
|
|
||||||
ng-click="model.insert()">
|
|
||||||
</vn-icon-button>
|
|
||||||
</div>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit label="Save"></vn-submit>
|
|
||||||
<vn-button ng-click="$ctrl.cancel()" label="Cancel"></vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<!-- New postcode dialog -->
|
|
||||||
<vn-geo-postcode vn-id="postcode"
|
|
||||||
on-response="$ctrl.onResponse($response)">
|
|
||||||
</vn-geo-postcode>
|
|
||||||
|
|
||||||
<!-- Create custom agent dialog -->
|
|
||||||
<vn-dialog class="edit"
|
|
||||||
vn-id="customAgent"
|
|
||||||
on-accept="$ctrl.onCustomAgentAccept()"
|
|
||||||
message="New customs agent">
|
|
||||||
<tpl-body>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield vn-one vn-focus
|
|
||||||
label="NIF"
|
|
||||||
ng-model="$ctrl.newCustomsAgent.nif"
|
|
||||||
required="true">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield vn-one
|
|
||||||
label="Fiscal name"
|
|
||||||
ng-model="$ctrl.newCustomsAgent.fiscalName"
|
|
||||||
required="true">
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield vn-one
|
|
||||||
label="Street"
|
|
||||||
ng-model="$ctrl.newCustomsAgent.street">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield vn-one
|
|
||||||
label="Phone"
|
|
||||||
ng-model="$ctrl.newCustomsAgent.phone">
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
</tpl-body>
|
|
||||||
<tpl-buttons>
|
|
||||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
|
||||||
<button response="accept" translate>Create</button>
|
|
||||||
</tpl-buttons>
|
|
||||||
</vn-dialog>
|
|
|
@ -1,94 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
export default class Controller extends Section {
|
|
||||||
removeObservation(index) {
|
|
||||||
this.$.watcher.setDirty();
|
|
||||||
this.$.model.remove(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel() {
|
|
||||||
this.goToIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
goToIndex() {
|
|
||||||
this.$state.go('client.card.address.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
this.$.watcher.submit()
|
|
||||||
.then(() => this.$.model.save(true))
|
|
||||||
.then(() => {
|
|
||||||
this.card.reload();
|
|
||||||
this.goToIndex();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
showCustomAgent(event) {
|
|
||||||
if (event.defaultPrevented) return;
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
this.$.customAgent.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
onCustomAgentAccept() {
|
|
||||||
return this.$http.post(`CustomsAgents`, this.newCustomsAgent)
|
|
||||||
.then(res => this.address.customsAgentFk = res.data.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
get town() {
|
|
||||||
return this._town;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Town auto complete
|
|
||||||
set town(selection) {
|
|
||||||
const oldValue = this._town;
|
|
||||||
this._town = selection;
|
|
||||||
|
|
||||||
if (!selection || !oldValue) return;
|
|
||||||
|
|
||||||
const province = selection.province;
|
|
||||||
const postcodes = selection.postcodes;
|
|
||||||
|
|
||||||
if (!this.address.provinceFk)
|
|
||||||
this.address.provinceFk = province.id;
|
|
||||||
|
|
||||||
if (!this.address.postalCode && postcodes.length === 1)
|
|
||||||
this.address.postalCode = postcodes[0].code;
|
|
||||||
}
|
|
||||||
|
|
||||||
get postcode() {
|
|
||||||
return this._postcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Postcode auto complete
|
|
||||||
set postcode(selection) {
|
|
||||||
const oldValue = this._postcode;
|
|
||||||
this._postcode = selection;
|
|
||||||
|
|
||||||
if (!selection || !oldValue) return;
|
|
||||||
|
|
||||||
const town = selection.town;
|
|
||||||
const province = town.province;
|
|
||||||
|
|
||||||
if (!this.address.city)
|
|
||||||
this.address.city = town.name;
|
|
||||||
|
|
||||||
if (!this.address.provinceFk)
|
|
||||||
this.address.provinceFk = province.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
onResponse(response) {
|
|
||||||
this.address.postalCode = response.code;
|
|
||||||
this.address.city = response.city;
|
|
||||||
this.address.provinceFk = response.provinceFk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientAddressEdit', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
require: {
|
|
||||||
card: '^vnClientCard'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,77 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientAddressEdit', () => {
|
|
||||||
let $scope;
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
let $element;
|
|
||||||
let $state;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$state_, _$httpBackend_) => {
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$state = _$state_;
|
|
||||||
$state.params.addressId = '1';
|
|
||||||
$element = angular.element('<vn-client-address-edit></vn-client-address-edit>');
|
|
||||||
controller = $componentController('vnClientAddressEdit', {$element, $scope});
|
|
||||||
controller.address = {id: 1, customsAgentFk: null};
|
|
||||||
controller.$.watcher = {
|
|
||||||
setDirty: () => {},
|
|
||||||
setPristine: () => {},
|
|
||||||
realSubmit: () => {},
|
|
||||||
check: () => {},
|
|
||||||
notifySaved: () => {}
|
|
||||||
};
|
|
||||||
controller.$.model = {
|
|
||||||
remove: () => {},
|
|
||||||
save: () => {}
|
|
||||||
};
|
|
||||||
controller.card = {
|
|
||||||
reload: () => {}
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('removeObservation()', () => {
|
|
||||||
it('should call $.watcher.setDirty() and $.model.remove(index)', () => {
|
|
||||||
jest.spyOn(controller.$.watcher, 'setDirty');
|
|
||||||
jest.spyOn(controller.$.model, 'remove');
|
|
||||||
controller.removeObservation(1);
|
|
||||||
|
|
||||||
expect(controller.$.model.remove).toHaveBeenCalledWith(1);
|
|
||||||
expect(controller.$.watcher.setDirty).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('cancel()', () => {
|
|
||||||
it('should call goToIndex()', () => {
|
|
||||||
jest.spyOn(controller, 'goToIndex');
|
|
||||||
controller.cancel();
|
|
||||||
|
|
||||||
expect(controller.goToIndex).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('goToIndex()', () => {
|
|
||||||
it('should call $state.go("client.card.address.index")', () => {
|
|
||||||
jest.spyOn(controller.$state, 'go');
|
|
||||||
controller.goToIndex();
|
|
||||||
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('client.card.address.index');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onCustomAgentAccept()', () => {
|
|
||||||
it(`should now create a new customs agent and then set the customsAgentFk property on the address`, () => {
|
|
||||||
const expectedResult = {id: 1, fiscalName: 'Customs agent one'};
|
|
||||||
$httpBackend.when('POST', 'CustomsAgents').respond(200, expectedResult);
|
|
||||||
controller.onCustomAgentAccept();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.address.customsAgentFk).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,91 +0,0 @@
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="Clients/{{$ctrl.$params.id}}/addresses"
|
|
||||||
filter="$ctrl.filter"
|
|
||||||
limit="10"
|
|
||||||
data="$ctrl.addresses"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-portal slot="topbar">
|
|
||||||
<vn-searchbar
|
|
||||||
placeholder="Search by consignee"
|
|
||||||
info="You can search by consignee id or name"
|
|
||||||
model="model"
|
|
||||||
expr-builder="$ctrl.exprBuilder(param, value)"
|
|
||||||
auto-state="false">
|
|
||||||
</vn-searchbar>
|
|
||||||
</vn-portal>
|
|
||||||
<vn-data-viewer
|
|
||||||
model="model"
|
|
||||||
class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-md">
|
|
||||||
<div
|
|
||||||
ng-repeat="address in $ctrl.addresses"
|
|
||||||
class="address">
|
|
||||||
<a
|
|
||||||
ui-sref="client.card.address.edit({addressId: {{::address.id}}})"
|
|
||||||
class="vn-pa-sm border-solid border-radius"
|
|
||||||
ng-class="{'item-disabled': !address.isActive}"
|
|
||||||
translate-attr="{title: 'Edit consignee'}">
|
|
||||||
<vn-none
|
|
||||||
class="vn-pr-sm"
|
|
||||||
ng-click="$ctrl.onStarClick($event)">
|
|
||||||
<vn-icon-button
|
|
||||||
ng-if="$ctrl.isDefaultAddress(address)"
|
|
||||||
icon="star"
|
|
||||||
translate-attr="{title: 'Default address'}">
|
|
||||||
</vn-icon-button>
|
|
||||||
<vn-icon-button
|
|
||||||
ng-if="!$ctrl.isDefaultAddress(address)"
|
|
||||||
icon="star_border"
|
|
||||||
ng-click="$ctrl.setDefault(address)"
|
|
||||||
translate-attr="{title: 'Set as default'}">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-none>
|
|
||||||
<vn-one
|
|
||||||
style="overflow: hidden; min-width: 14em;">
|
|
||||||
<div class="ellipsize"><b>{{::address.nickname}} - #{{::address.id}}</b></div>
|
|
||||||
<div class="ellipsize" name="street">{{::address.street}}</div>
|
|
||||||
<div class="ellipsize">
|
|
||||||
<span ng-show="::address.postalCode">{{::address.postalCode}} -</span>
|
|
||||||
<span ng-show="::address.city">{{::address.city}},</span>
|
|
||||||
<span ng-show="::address.province.name">{{::address.province.name}},</span>
|
|
||||||
{{::address.province.country.name}}
|
|
||||||
</div>
|
|
||||||
<div class="ellipsize">
|
|
||||||
{{::address.phone}}<span ng-if="::address.mobile">, </span>
|
|
||||||
{{::address.mobile}}
|
|
||||||
</div>
|
|
||||||
<vn-check
|
|
||||||
vn-one label="Is equalizated"
|
|
||||||
ng-model="address.isEqualizated"
|
|
||||||
disabled="true">
|
|
||||||
</vn-check>
|
|
||||||
<vn-check
|
|
||||||
vn-one label="Is Logiflora allowed"
|
|
||||||
ng-model="address.isLogifloraAllowed"
|
|
||||||
disabled="true">
|
|
||||||
</vn-check>
|
|
||||||
</vn-one>
|
|
||||||
<vn-vertical
|
|
||||||
vn-one
|
|
||||||
ng-if="address.observations.length"
|
|
||||||
class="vn-hide-narrow vn-px-md border-solid-left"
|
|
||||||
style="height: 6em; overflow: auto;">
|
|
||||||
<vn-one ng-repeat="observation in address.observations track by $index" ng-class="{'vn-pt-sm': $index}">
|
|
||||||
<b>{{::observation.observationType.description}}:</b>
|
|
||||||
<span>{{::observation.description}}</span>
|
|
||||||
</vn-one>
|
|
||||||
</vn-vertical>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</vn-card>
|
|
||||||
</vn-data-viewer>
|
|
||||||
<vn-float-button
|
|
||||||
vn-bind="+"
|
|
||||||
fixed-bottom-right
|
|
||||||
vn-tooltip="New consignee"
|
|
||||||
ui-sref="client.card.address.create"
|
|
||||||
icon="add"
|
|
||||||
label="Add">
|
|
||||||
</vn-float-button>
|
|
|
@ -1,97 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
this.filter = {
|
|
||||||
fields: [
|
|
||||||
'id',
|
|
||||||
'isDefaultAddress',
|
|
||||||
'isActive',
|
|
||||||
'nickname',
|
|
||||||
'street',
|
|
||||||
'city',
|
|
||||||
'provinceFk',
|
|
||||||
'phone',
|
|
||||||
'mobile',
|
|
||||||
'isEqualizated',
|
|
||||||
'isLogifloraAllowed',
|
|
||||||
'postalCode'
|
|
||||||
],
|
|
||||||
order: [
|
|
||||||
'isDefaultAddress DESC',
|
|
||||||
'isActive DESC',
|
|
||||||
'nickname ASC'],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
relation: 'observations',
|
|
||||||
scope: {
|
|
||||||
include: 'observationType'
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
relation: 'province',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'name', 'countryFk'],
|
|
||||||
include: {
|
|
||||||
relation: 'country',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'name']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onStarClick(event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
setDefault(address) {
|
|
||||||
let query = `Clients/${this.$params.id}`;
|
|
||||||
let params = {defaultAddressFk: address.id};
|
|
||||||
this.$http.patch(query, params).then(res => {
|
|
||||||
if (res.data) {
|
|
||||||
this.client.defaultAddressFk = res.data.defaultAddressFk;
|
|
||||||
this.sortAddresses();
|
|
||||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
isDefaultAddress(address) {
|
|
||||||
return this.client && this.client.defaultAddressFk === address.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sort address by default address
|
|
||||||
*/
|
|
||||||
sortAddresses() {
|
|
||||||
if (!this.client || !this.addresses) return;
|
|
||||||
this.addresses = this.addresses.sort((a, b) => {
|
|
||||||
return this.isDefaultAddress(b) - this.isDefaultAddress(a);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
exprBuilder(param, value) {
|
|
||||||
switch (param) {
|
|
||||||
case 'search':
|
|
||||||
return /^\d+$/.test(value)
|
|
||||||
? {id: value}
|
|
||||||
: {nickname: {like: `%${value}%`}};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Controller.$inject = ['$element', '$scope'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientAddressIndex', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,84 +0,0 @@
|
||||||
import './index';
|
|
||||||
import crudModel from 'core/mocks/crud-model';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientAddressIndex', () => {
|
|
||||||
let controller;
|
|
||||||
let $scope;
|
|
||||||
let $stateParams;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$stateParams_, _$httpBackend_) => {
|
|
||||||
$stateParams = _$stateParams_;
|
|
||||||
$stateParams.id = 1;
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
const $element = angular.element('<vn-client-address-index></vn-client-address-index>');
|
|
||||||
controller = $componentController('vnClientAddressIndex', {$element, $scope});
|
|
||||||
controller.client = {id: 1101, defaultAddressFk: 121};
|
|
||||||
controller.$.model = crudModel;
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('setDefault()', () => {
|
|
||||||
it('should perform a PATCH and set a value to defaultAddressFk property', () => {
|
|
||||||
jest.spyOn(controller, 'sortAddresses');
|
|
||||||
let address = {id: 1};
|
|
||||||
let data = {defaultAddressFk: address.id};
|
|
||||||
let expectedResult = {defaultAddressFk: address.id};
|
|
||||||
|
|
||||||
$httpBackend.expect('PATCH', `Clients/1`, data).respond(200, expectedResult);
|
|
||||||
controller.setDefault(address);
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.client.defaultAddressFk).toEqual(1);
|
|
||||||
expect(controller.sortAddresses).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isDefaultAddress()', () => {
|
|
||||||
it('should return true if a passed address is the current default one', () => {
|
|
||||||
let address = {id: 121};
|
|
||||||
let result = controller.isDefaultAddress(address);
|
|
||||||
|
|
||||||
expect(result).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false if a passed address is the current default one', () => {
|
|
||||||
let address = {id: 1};
|
|
||||||
let result = controller.isDefaultAddress(address);
|
|
||||||
|
|
||||||
expect(result).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('sortAddresses()', () => {
|
|
||||||
it('should return an array of addresses sorted by client defaultAddressFk', () => {
|
|
||||||
controller.client.defaultAddressFk = 123;
|
|
||||||
controller.addresses = [
|
|
||||||
{id: 121, nickname: 'My address one'},
|
|
||||||
{id: 122, nickname: 'My address two'},
|
|
||||||
{id: 123, nickname: 'My address three'}];
|
|
||||||
|
|
||||||
controller.sortAddresses();
|
|
||||||
|
|
||||||
expect(controller.addresses[0].id).toEqual(123);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('exprBuilder()', () => {
|
|
||||||
it('should return a filter based on a search by id', () => {
|
|
||||||
const filter = controller.exprBuilder('search', '123');
|
|
||||||
|
|
||||||
expect(filter).toEqual({id: '123'});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return a filter based on a search by name', () => {
|
|
||||||
const filter = controller.exprBuilder('search', 'Bruce Wayne');
|
|
||||||
|
|
||||||
expect(filter).toEqual({nickname: {like: '%Bruce Wayne%'}});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,21 +0,0 @@
|
||||||
@import "variables";
|
|
||||||
@import "./effects";
|
|
||||||
|
|
||||||
vn-client-address-index {
|
|
||||||
.address {
|
|
||||||
padding-bottom: $spacing-md;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
& > a {
|
|
||||||
@extend %clickable;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
color: inherit;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
# Index
|
|
||||||
Set as default: Establecer como predeterminado
|
|
||||||
Active first to set as default: Active primero para marcar como predeterminado
|
|
||||||
Search by consignee: Buscar por consignatario
|
|
||||||
You can search by consignee id or name: Puedes buscar por el id o nombre del consignatario
|
|
||||||
# Edit
|
|
||||||
Enabled: Activo
|
|
||||||
Is equalizated: Recargo de equivalencia
|
|
||||||
Observation type: Tipo de observación
|
|
||||||
Description: Descripción
|
|
||||||
The observation type must be unique: El tipo de observación ha de ser único
|
|
||||||
Remove note: Quitar nota
|
|
||||||
Add note: Añadir nota
|
|
||||||
Customs agent: Agente de aduanas
|
|
||||||
New customs agent: Nuevo agente de aduanas
|
|
||||||
# Create
|
|
||||||
Street address: Dirección postal
|
|
||||||
Default: Predeterminado
|
|
||||||
Consignee: Consignatario
|
|
||||||
Postcode: Código postal
|
|
||||||
Town/City: Ciudad
|
|
||||||
Province: Provincia
|
|
||||||
Agency: Agencia
|
|
||||||
Phone: Teléfono
|
|
||||||
Mobile: Móvil
|
|
||||||
|
|
||||||
# Common
|
|
||||||
Fiscal name: Nombre fiscal
|
|
||||||
Street: Dirección fiscal
|
|
||||||
Is Logiflora allowed: Compra directa en Holanda
|
|
|
@ -1,106 +0,0 @@
|
||||||
<tpl-title translate>
|
|
||||||
New payment
|
|
||||||
</tpl-title>
|
|
||||||
<tpl-body>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="Companies"
|
|
||||||
data="companies"
|
|
||||||
order="code"
|
|
||||||
required="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-date-picker
|
|
||||||
label="Date"
|
|
||||||
ng-model="$ctrl.receipt.payed"
|
|
||||||
vn-name="payed"
|
|
||||||
required="true">
|
|
||||||
</vn-date-picker>
|
|
||||||
<vn-autocomplete
|
|
||||||
data="companies"
|
|
||||||
label="Company"
|
|
||||||
show-field="code"
|
|
||||||
value-field="id"
|
|
||||||
ng-model="$ctrl.companyFk"
|
|
||||||
vn-name="company"
|
|
||||||
required="true">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete
|
|
||||||
label="Bank"
|
|
||||||
url="Accountings"
|
|
||||||
show-field="bank"
|
|
||||||
value-field="id"
|
|
||||||
fields="['accountingTypeFk']"
|
|
||||||
include="{relation: 'accountingType'}"
|
|
||||||
ng-model="$ctrl.bankFk"
|
|
||||||
vn-name="bank"
|
|
||||||
search-function="$ctrl.bankSearchFunc($search)"
|
|
||||||
selection="$ctrl.bankSelection"
|
|
||||||
order="id"
|
|
||||||
required="true">
|
|
||||||
<tpl-item>{{id}}: {{bank}}</tpl-item>
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-input-number
|
|
||||||
vn-focus
|
|
||||||
label="Amount"
|
|
||||||
ng-model="$ctrl.amountPaid"
|
|
||||||
vn-name="amountPaid"
|
|
||||||
step="0.01"
|
|
||||||
required="true"
|
|
||||||
max="$ctrl.maxAmount">
|
|
||||||
</vn-input-number>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-vertical ng-show="$ctrl.bankSelection.accountingType.code == 'compensation'">
|
|
||||||
<h6 translate>Compensation</h6>
|
|
||||||
<vn-textfield
|
|
||||||
ng-model="$ctrl.receipt.compensationAccount"
|
|
||||||
vn-name="compensationAccount"
|
|
||||||
label="Compensation Account"
|
|
||||||
on-change="$ctrl.accountShortToStandard(value)">
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-vertical>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
label="Reference"
|
|
||||||
ng-model="$ctrl.receipt.description"
|
|
||||||
vn-name="description"
|
|
||||||
rule
|
|
||||||
required="true">
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-vertical ng-show="$ctrl.bankSelection.accountingType.code == 'cash'">
|
|
||||||
<h6 translate>Cash</h6>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-input-number
|
|
||||||
ng-model="$ctrl.deliveredAmount"
|
|
||||||
label="Delivered amount"
|
|
||||||
step="0.01"
|
|
||||||
vn-name="deliveredAmount">
|
|
||||||
</vn-input-number>
|
|
||||||
<vn-input-number
|
|
||||||
disabled="true"
|
|
||||||
ng-model="$ctrl.amountToReturn"
|
|
||||||
label="Amount to return"
|
|
||||||
vn-name="amountToReturn">
|
|
||||||
</vn-input-number>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-vertical>
|
|
||||||
<vn-horizontal ng-show="$ctrl.bankSelection.accountingType.code == 'cash'">
|
|
||||||
<vn-check
|
|
||||||
label="View receipt"
|
|
||||||
ng-model="$ctrl.viewReceipt"
|
|
||||||
vn-name="viewReceipt">
|
|
||||||
</vn-check>
|
|
||||||
<vn-check
|
|
||||||
label="Send email"
|
|
||||||
ng-model="$ctrl.sendEmail"
|
|
||||||
vn-name="sendEmail">
|
|
||||||
</vn-check>
|
|
||||||
</vn-horizontal>
|
|
||||||
</tpl-body>
|
|
||||||
<tpl-buttons>
|
|
||||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
|
||||||
<button response="accept" translate vn-focus>Accept</button>
|
|
||||||
</tpl-buttons>
|
|
|
@ -1,218 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Dialog from 'core/components/dialog';
|
|
||||||
|
|
||||||
class Controller extends Dialog {
|
|
||||||
constructor($element, $, $transclude, vnReport, vnEmail) {
|
|
||||||
super($element, $, $transclude);
|
|
||||||
this.vnReport = vnReport;
|
|
||||||
this.vnEmail = vnEmail;
|
|
||||||
this.receipt = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
set payed(value) {
|
|
||||||
this.receipt.payed = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
set amountPaid(value) {
|
|
||||||
this.receipt.amountPaid = value;
|
|
||||||
this.amountToReturn = this.deliveredAmount - value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get amountPaid() {
|
|
||||||
return this.receipt.amountPaid;
|
|
||||||
}
|
|
||||||
|
|
||||||
set clientFk(value) {
|
|
||||||
if (!value) return;
|
|
||||||
this.receipt.clientFk = value;
|
|
||||||
|
|
||||||
const filter = {
|
|
||||||
fields: ['email'],
|
|
||||||
where: {
|
|
||||||
id: value
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$http.get(`Clients/findOne`, {filter})
|
|
||||||
.then(res => {
|
|
||||||
this.receipt.email = res.data.email;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get clientFk() {
|
|
||||||
return this.receipt.clientFk;
|
|
||||||
}
|
|
||||||
|
|
||||||
get companyFk() {
|
|
||||||
if (!this.receipt.companyFk)
|
|
||||||
this.receipt.companyFk = this.vnConfig.companyFk;
|
|
||||||
return this.receipt.companyFk;
|
|
||||||
}
|
|
||||||
|
|
||||||
set companyFk(value) {
|
|
||||||
this.receipt.companyFk = value;
|
|
||||||
this.getAmountPaid();
|
|
||||||
}
|
|
||||||
|
|
||||||
set description(value) {
|
|
||||||
this.receipt.description = value;
|
|
||||||
this.originalDescription = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get description() {
|
|
||||||
return this.receipt.description;
|
|
||||||
}
|
|
||||||
|
|
||||||
get bankSelection() {
|
|
||||||
return this._bankSelection;
|
|
||||||
}
|
|
||||||
|
|
||||||
set bankSelection(value) {
|
|
||||||
this._bankSelection = value;
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
const accountingType = value.accountingType;
|
|
||||||
|
|
||||||
this.receipt.description = [];
|
|
||||||
this.viewReceipt = accountingType.code == 'cash';
|
|
||||||
if (accountingType.code == 'compensation')
|
|
||||||
this.receipt.description = '';
|
|
||||||
else {
|
|
||||||
if (accountingType.receiptDescription != null && accountingType.receiptDescription != '')
|
|
||||||
this.receipt.description.push(accountingType.receiptDescription);
|
|
||||||
if (this.originalDescription)
|
|
||||||
this.receipt.description.push(this.originalDescription);
|
|
||||||
this.receipt.description = this.receipt.description.join(', ');
|
|
||||||
}
|
|
||||||
this.maxAmount = accountingType && accountingType.maxAmount;
|
|
||||||
|
|
||||||
this.receipt.payed = Date.vnNew();
|
|
||||||
if (accountingType.daysInFuture)
|
|
||||||
this.receipt.payed.setDate(this.receipt.payed.getDate() + accountingType.daysInFuture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set deliveredAmount(value) {
|
|
||||||
this._deliveredAmount = value;
|
|
||||||
this.amountToReturn = value - this.receipt.amountPaid;
|
|
||||||
}
|
|
||||||
|
|
||||||
get amountToReturn() {
|
|
||||||
return this._amountToReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
set amountToReturn(value) {
|
|
||||||
if (isNaN(value)) return;
|
|
||||||
|
|
||||||
value = value.toFixed(2);
|
|
||||||
|
|
||||||
if (Number.isInteger(value))
|
|
||||||
value = parseInt(value);
|
|
||||||
else value = parseFloat(value);
|
|
||||||
|
|
||||||
this._amountToReturn = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get deliveredAmount() {
|
|
||||||
return this._deliveredAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
get bankFk() {
|
|
||||||
if (!this.receipt.bankFk)
|
|
||||||
this.receipt.bankFk = this.vnConfig.bankFk;
|
|
||||||
|
|
||||||
return this.receipt.bankFk;
|
|
||||||
}
|
|
||||||
|
|
||||||
set bankFk(value) {
|
|
||||||
this.receipt.bankFk = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
accountShortToStandard(value) {
|
|
||||||
if (value) {
|
|
||||||
this.receipt.compensationAccount = value.replace('.', '0'.repeat(11 - value.length));
|
|
||||||
const params = {bankAccount: this.receipt.compensationAccount};
|
|
||||||
this.$http.get(`Clients/getClientOrSupplierReference`, {params})
|
|
||||||
.then(res => {
|
|
||||||
if (res.data.clientId) {
|
|
||||||
this.receipt.description = this.$t('Client Compensation Reference', {
|
|
||||||
clientId: res.data.clientId,
|
|
||||||
clientName: res.data.clientName
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.receipt.description = this.$t('Supplier Compensation Reference', {
|
|
||||||
supplierId: res.data.supplierId,
|
|
||||||
supplierName: res.data.supplierName
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else
|
|
||||||
this.receipt.description = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
getAmountPaid() {
|
|
||||||
const filter = {
|
|
||||||
where: {
|
|
||||||
clientFk: this.$params.id ?? this.clientFk,
|
|
||||||
companyFk: this.receipt.companyFk
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$http.get(`ClientRisks`, {filter}).then(res => {
|
|
||||||
this.receipt.amountPaid = (res.data.length && res.data[0].amount) || null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
responseHandler(response) {
|
|
||||||
if (response !== 'accept')
|
|
||||||
return super.responseHandler(response);
|
|
||||||
|
|
||||||
const exceededAmount = this.receipt.amountPaid > this.maxAmount;
|
|
||||||
const isCash = this.bankSelection.accountingType.code == 'cash';
|
|
||||||
if (isCash && exceededAmount)
|
|
||||||
return this.vnApp.showError(this.$t('Amount exceeded', {maxAmount: this.maxAmount}));
|
|
||||||
|
|
||||||
if (isCash && this.sendEmail && !this.receipt.email)
|
|
||||||
return this.vnApp.showError(this.$t('There is no assigned email for this client'));
|
|
||||||
|
|
||||||
let receiptId;
|
|
||||||
return this.$http.post(`Clients/${this.clientFk}/createReceipt`, this.receipt)
|
|
||||||
.then(res => {
|
|
||||||
receiptId = res.data.id;
|
|
||||||
super.responseHandler(response);
|
|
||||||
})
|
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')))
|
|
||||||
.then(() => {
|
|
||||||
if (!this.sendEmail || !isCash) return;
|
|
||||||
const params = {
|
|
||||||
recipient: this.receipt.email
|
|
||||||
};
|
|
||||||
this.vnEmail.send(`Receipts/${receiptId}/receipt-email`, params);
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
if (this.viewReceipt)
|
|
||||||
this.vnReport.show(`Receipts/${receiptId}/receipt-pdf`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bankSearchFunc($search) {
|
|
||||||
return /^\d+$/.test($search)
|
|
||||||
? {id: $search}
|
|
||||||
: {bank: {like: '%' + $search + '%'}};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope', '$transclude', 'vnReport', 'vnEmail'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientBalanceCreate', {
|
|
||||||
slotTemplate: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
payed: '<?',
|
|
||||||
bankFk: '<?',
|
|
||||||
amountPaid: '<?',
|
|
||||||
clientFk: '<?',
|
|
||||||
companyFk: '<?',
|
|
||||||
description: '<?',
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,140 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientBalancCreate', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
let $httpParamSerializer;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$httpParamSerializer = _$httpParamSerializer_;
|
|
||||||
let $scope = $rootScope.$new();
|
|
||||||
const $element = angular.element('<vn-client-balance-create></vn-client-balance-create>');
|
|
||||||
const $transclude = {
|
|
||||||
$$boundTransclude: {
|
|
||||||
$$slots: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
controller = $componentController('vnClientBalanceCreate', {$element, $scope, $transclude});
|
|
||||||
controller.receipt = {
|
|
||||||
clientFk: 1101,
|
|
||||||
companyFk: 442
|
|
||||||
};
|
|
||||||
controller.bankSelection = {accountingType: {code: 'myCode'}};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('bankSelection() setter', () => {
|
|
||||||
it('should set the receipt description property', () => {
|
|
||||||
controller.originalDescription = 'Albaran: 1, 2';
|
|
||||||
controller.bankSelection = {
|
|
||||||
id: 1,
|
|
||||||
bank: 'Cash',
|
|
||||||
accountingType: {
|
|
||||||
id: 2,
|
|
||||||
receiptDescription: 'Cash'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.receipt.description).toEqual('Cash, Albaran: 1, 2');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('amountToReturn() setter', () => {
|
|
||||||
it('should set the amount to return with a maximum of two decimals', () => {
|
|
||||||
controller.amountToReturn = 200.1451789;
|
|
||||||
|
|
||||||
expect(controller.amountToReturn).toEqual(200.15);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getAmountPaid()', () => {
|
|
||||||
it('should make an http GET query and then set the receipt amountPaid property', () => {
|
|
||||||
controller.$params = {id: 1101};
|
|
||||||
const receipt = controller.receipt;
|
|
||||||
const filter = {
|
|
||||||
where: {
|
|
||||||
clientFk: 1101,
|
|
||||||
companyFk: 442
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const serializedParams = $httpParamSerializer({filter});
|
|
||||||
$httpBackend.expect('GET', `ClientRisks?${serializedParams}`).respond([{amount: 20}]);
|
|
||||||
controller.getAmountPaid();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(receipt.amountPaid).toEqual(20);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('responseHandler()', () => {
|
|
||||||
it('should make an http POST query and then call to the parent responseHandler() method', () => {
|
|
||||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
|
||||||
jest.spyOn(controller.vnReport, 'show');
|
|
||||||
|
|
||||||
controller.$params = {id: 1101};
|
|
||||||
|
|
||||||
$httpBackend.expect('POST', `Clients/1101/createReceipt`).respond({id: 1});
|
|
||||||
controller.responseHandler('accept');
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
|
||||||
expect(controller.vnReport.show).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should make an http POST query and then call to the report show() method', () => {
|
|
||||||
const receiptId = 1;
|
|
||||||
|
|
||||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
|
||||||
jest.spyOn(controller.vnReport, 'show');
|
|
||||||
window.open = jest.fn();
|
|
||||||
|
|
||||||
controller.$params = {id: 1101};
|
|
||||||
controller.viewReceipt = true;
|
|
||||||
|
|
||||||
$httpBackend.expect('POST', `Clients/1101/createReceipt`).respond({id: receiptId});
|
|
||||||
controller.responseHandler('accept');
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
|
||||||
expect(controller.vnReport.show).toHaveBeenCalledWith(`Receipts/${receiptId}/receipt-pdf`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('deliveredAmount() setter', () => {
|
|
||||||
it('should set the deliveredAmount property', () => {
|
|
||||||
controller.amountPaid = 999;
|
|
||||||
controller.deliveredAmount = 1000;
|
|
||||||
|
|
||||||
expect(controller.amountToReturn).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('accountShortToStandard()', () => {
|
|
||||||
it('should get de account in stardard format', () => {
|
|
||||||
const shortAccount = '4.3';
|
|
||||||
controller.accountShortToStandard(shortAccount);
|
|
||||||
|
|
||||||
expect(controller.receipt.compensationAccount).toEqual('4000000003');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('bankSearchFunc()', () => {
|
|
||||||
it('should return the filter by id property for an input of a number', () => {
|
|
||||||
const bankId = 1;
|
|
||||||
const result = controller.bankSearchFunc(bankId);
|
|
||||||
|
|
||||||
expect(result).toEqual({id: bankId});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return the filter by bank property for an input of an string', () => {
|
|
||||||
const bankName = 'Bank of America';
|
|
||||||
const result = controller.bankSearchFunc(bankName);
|
|
||||||
|
|
||||||
expect(result).toEqual({bank: {like: '%' + bankName + '%'}});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,4 +0,0 @@
|
||||||
View receipt: Ver recibo
|
|
||||||
Amount exceeded: Según ley contra el fraude no se puede recibir cobros por importe igual o superior a {{maxAmount}}
|
|
||||||
Client Compensation Reference: "({{clientId}}) Ntro Cliente: {{clientName}}"
|
|
||||||
Supplier Compensation Reference: "({{supplierId}}) Ntro Proveedor: {{supplierName}}"
|
|
|
@ -1,163 +0,0 @@
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="Receipts/filter"
|
|
||||||
limit="20"
|
|
||||||
data="$ctrl.balances">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-crud-model
|
|
||||||
vn-id="riskModel"
|
|
||||||
url="ClientRisks"
|
|
||||||
filter="$ctrl.filter"
|
|
||||||
data="$ctrl.clientRisks">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="Companies"
|
|
||||||
data="companies"
|
|
||||||
order="code">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-side-menu side="right">
|
|
||||||
<div class="vn-pa-md">
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
vn-id="company"
|
|
||||||
ng-model="$ctrl.companyId"
|
|
||||||
data="companies"
|
|
||||||
show-field="code"
|
|
||||||
value-field="id"
|
|
||||||
label="Company">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<div
|
|
||||||
class="totalBox"
|
|
||||||
style="text-align: center;"
|
|
||||||
ng-if="$ctrl.clientRisks.length">
|
|
||||||
<h6 translate>Total by company</h6>
|
|
||||||
<vn-label-value
|
|
||||||
ng-repeat="riskByCompany in $ctrl.clientRisks"
|
|
||||||
label="{{riskByCompany.company.code}}"
|
|
||||||
value="{{riskByCompany.amount | currency: 'EUR':2}}">
|
|
||||||
</vn-label-value>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</vn-side-menu>
|
|
||||||
<div class="vn-w-lg">
|
|
||||||
<vn-data-viewer model="model">
|
|
||||||
<vn-card>
|
|
||||||
<vn-table model="model">
|
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th expand>Date</vn-th>
|
|
||||||
<vn-th>Creation date</vn-th>
|
|
||||||
<vn-th>Employee</vn-th>
|
|
||||||
<vn-th>Reference</vn-th>
|
|
||||||
<vn-th number>Bank</vn-th>
|
|
||||||
<vn-th number>Debit</vn-th>
|
|
||||||
<vn-th number>Havings</vn-th>
|
|
||||||
<vn-th number>Balance</vn-th>
|
|
||||||
<vn-th center>Conciliated</vn-th>
|
|
||||||
<vn-th></vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr ng-repeat="balance in $ctrl.balances">
|
|
||||||
<vn-td expand>
|
|
||||||
<span title="{{::balance.payed | date:'dd/MM/yyyy'}}">
|
|
||||||
{{::balance.payed | date:'dd/MM/yyyy'}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink-datetime>
|
|
||||||
<span title="{{::balance.created | date:'dd/MM/yyyy HH:mm'}}">
|
|
||||||
{{::balance.created | date:'dd/MM/yyyy HH:mm'}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td>
|
|
||||||
<span
|
|
||||||
vn-click-stop="workerDescriptor.show($event, balance.workerFk)"
|
|
||||||
class="link">
|
|
||||||
{{::balance.userName}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td-editable disabled="balance.isInvoice || !$ctrl.isAdministrative" expand>
|
|
||||||
<text>
|
|
||||||
<div ng-show="::balance.description">
|
|
||||||
<span
|
|
||||||
ng-if="balance.isInvoice"
|
|
||||||
title="{{'BILL' | translate: {ref: balance.description} }}"
|
|
||||||
vn-click-stop="$ctrl.showInvoiceOutDescriptor($event, balance)"
|
|
||||||
class="link">
|
|
||||||
{{'BILL' | translate: {ref: balance.description} }}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
ng-if="!balance.isInvoice"
|
|
||||||
title="{{::balance.description}}">
|
|
||||||
{{balance.description}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</text>
|
|
||||||
<field>
|
|
||||||
<vn-textfield vn-acl="administrative" class="dense" vn-focus
|
|
||||||
ng-model="balance.description"
|
|
||||||
on-change="$ctrl.changeDescription(balance)">
|
|
||||||
</vn-textfield>
|
|
||||||
</field>
|
|
||||||
</vn-td-editable>
|
|
||||||
<vn-td number>{{::balance.bankFk}}</vn-td>
|
|
||||||
<vn-td number expand>{{::balance.debit | currency: 'EUR':2}}</vn-td>
|
|
||||||
<vn-td number expand>{{::balance.credit | currency: 'EUR':2}}</vn-td>
|
|
||||||
<vn-td number expand>{{balance.balance | currency: 'EUR':2}}</vn-td>
|
|
||||||
<vn-td center shrink>
|
|
||||||
<vn-check
|
|
||||||
ng-model="balance.isConciliate"
|
|
||||||
disabled="true">
|
|
||||||
</vn-check>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td center shrink>
|
|
||||||
<a ng-show="balance.hasPdf"
|
|
||||||
target="_blank"
|
|
||||||
href="api/InvoiceOuts/{{::balance.id}}/download?access_token={{::$ctrl.vnToken.tokenMultimedia}}">
|
|
||||||
<vn-icon-button
|
|
||||||
icon="cloud_download"
|
|
||||||
title="{{'Download PDF' | translate}}">
|
|
||||||
</vn-icon-button>
|
|
||||||
</a>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td center shrink ng-if="balance.isCompensation">
|
|
||||||
<vn-icon-button
|
|
||||||
vn-dialog="send_compensation"
|
|
||||||
icon="outgoing_mail"
|
|
||||||
title="{{'Send compensation' | translate}}">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-td>
|
|
||||||
<vn-confirm
|
|
||||||
vn-id="send_compensation"
|
|
||||||
on-accept="$ctrl.sendEmail(balance)"
|
|
||||||
question="Notify compensation"
|
|
||||||
message="Send compensation">
|
|
||||||
</vn-confirm>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
</vn-card>
|
|
||||||
</vn-data-viewer>
|
|
||||||
</div>
|
|
||||||
<vn-float-button
|
|
||||||
vn-acl="salesAssistant"
|
|
||||||
vn-acl-action="remove"
|
|
||||||
icon="add"
|
|
||||||
vn-tooltip="New payment"
|
|
||||||
vn-bind="+"
|
|
||||||
fixed-bottom-right
|
|
||||||
ng-click="balanceCreate.show()">
|
|
||||||
</vn-float-button>
|
|
||||||
<vn-client-balance-create
|
|
||||||
vn-id="balance-create"
|
|
||||||
on-accept="$ctrl.getData()"
|
|
||||||
company-fk="$ctrl.companyId"
|
|
||||||
client-fk="$ctrl.$params.id">
|
|
||||||
</vn-client-balance-create>
|
|
||||||
<vn-worker-descriptor-popover
|
|
||||||
vn-id="workerDescriptor">
|
|
||||||
</vn-worker-descriptor-popover>
|
|
||||||
<vn-invoice-out-descriptor-popover
|
|
||||||
vn-id="invoiceOutDescriptor">
|
|
||||||
</vn-invoice-out-descriptor-popover>
|
|
|
@ -1,105 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $, vnEmail) {
|
|
||||||
super($element, $);
|
|
||||||
this.vnEmail = vnEmail;
|
|
||||||
this.filter = {
|
|
||||||
include: {
|
|
||||||
relation: 'company',
|
|
||||||
scope: {
|
|
||||||
fields: ['code'],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get companyId() {
|
|
||||||
if (!this._companyId)
|
|
||||||
this.companyId = this.vnConfig.companyFk;
|
|
||||||
|
|
||||||
return this._companyId;
|
|
||||||
}
|
|
||||||
|
|
||||||
set companyId(value) {
|
|
||||||
this._companyId = value;
|
|
||||||
|
|
||||||
if (value) this.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
get balances() {
|
|
||||||
return this._balances;
|
|
||||||
}
|
|
||||||
|
|
||||||
set balances(value) {
|
|
||||||
this._balances = value;
|
|
||||||
|
|
||||||
const riskModel = this.$.riskModel;
|
|
||||||
if (value && riskModel.data)
|
|
||||||
this.getBalances();
|
|
||||||
}
|
|
||||||
|
|
||||||
get isAdministrative() {
|
|
||||||
return this.aclService.hasAny(['administrative']);
|
|
||||||
}
|
|
||||||
|
|
||||||
getData() {
|
|
||||||
return this.$.model.applyFilter(null, {
|
|
||||||
clientId: this.$params.id,
|
|
||||||
companyId: this.companyId
|
|
||||||
}).then(() => this.$.riskModel.applyFilter({
|
|
||||||
where: {
|
|
||||||
clientFk: this.$params.id,
|
|
||||||
companyFk: this.companyId
|
|
||||||
}
|
|
||||||
})).then(() => this.getBalances());
|
|
||||||
}
|
|
||||||
|
|
||||||
getCurrentBalance() {
|
|
||||||
const clientRisks = this.$.riskModel.data;
|
|
||||||
const selectedCompany = this.companyId;
|
|
||||||
const currentBalance = clientRisks.find(balance => {
|
|
||||||
return balance.companyFk === selectedCompany;
|
|
||||||
});
|
|
||||||
|
|
||||||
return currentBalance && currentBalance.amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
getBalances() {
|
|
||||||
const balances = this.$.model.data;
|
|
||||||
balances.forEach((balance, index) => {
|
|
||||||
if (index === 0)
|
|
||||||
balance.balance = this.getCurrentBalance();
|
|
||||||
if (index > 0) {
|
|
||||||
let previousBalance = balances[index - 1];
|
|
||||||
balance.balance = previousBalance.balance - (previousBalance.debit - previousBalance.credit);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
showInvoiceOutDescriptor(event, balance) {
|
|
||||||
if (!balance.isInvoice) return;
|
|
||||||
if (event.defaultPrevented) return;
|
|
||||||
|
|
||||||
this.$.invoiceOutDescriptor.show(event.target, balance.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
changeDescription(balance) {
|
|
||||||
const params = {description: balance.description};
|
|
||||||
const endpoint = `Receipts/${balance.id}`;
|
|
||||||
this.$http.patch(endpoint, params)
|
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
|
|
||||||
}
|
|
||||||
|
|
||||||
sendEmail(balance) {
|
|
||||||
return this.vnEmail.send(`Receipts/${balance.id}/balance-compensation-email`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope', 'vnEmail'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientBalanceIndex', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
});
|
|
|
@ -1,169 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientBalanceIndex', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
let $scope = $rootScope.$new();
|
|
||||||
const $element = angular.element('<vn-client-balance-index></vn-client-balance-index>');
|
|
||||||
controller = $componentController('vnClientBalanceIndex', {$element, $scope});
|
|
||||||
controller.$.model = {applyFilter: () => {}};
|
|
||||||
controller.$.riskModel = {
|
|
||||||
applyFilter: () => {},
|
|
||||||
data:
|
|
||||||
[{
|
|
||||||
clientFk: 1101,
|
|
||||||
companyFk: 442,
|
|
||||||
amount: 713.24,
|
|
||||||
company: {
|
|
||||||
id: 442,
|
|
||||||
code: 'VNL'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('getData()', () => {
|
|
||||||
it('should apply the filters on he models and get the client balance', () => {
|
|
||||||
controller._companyId = 442;
|
|
||||||
controller.$params.id = 1101;
|
|
||||||
jest.spyOn(controller, 'getBalances').mockReturnThis();
|
|
||||||
jest.spyOn(controller.$.model, 'applyFilter').mockReturnValue(Promise.resolve());
|
|
||||||
jest.spyOn(controller.$.riskModel, 'applyFilter').mockReturnValue(Promise.resolve());
|
|
||||||
|
|
||||||
controller.getData().then(() => {
|
|
||||||
expect(controller.$.model.applyFilter).toHaveBeenCalledWith(null, {'clientId': 1101, 'companyId': 442});
|
|
||||||
expect(controller.$.riskModel.applyFilter).toHaveBeenCalledWith({'where': {'clientFk': 1101, 'companyFk': 442}});
|
|
||||||
expect(controller.getBalances).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('company setter/getter', () => {
|
|
||||||
it('should return the company and then call getData()', () => {
|
|
||||||
jest.spyOn(controller, 'getData').mockReturnThis();
|
|
||||||
controller.companyId = 442;
|
|
||||||
|
|
||||||
expect(controller._companyId).toEqual(442);
|
|
||||||
expect(controller.getData).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getCurrentBalance()', () => {
|
|
||||||
it('should return the client balance amount', () => {
|
|
||||||
controller._companyId = 442;
|
|
||||||
let result = controller.getCurrentBalance();
|
|
||||||
|
|
||||||
expect(result).toEqual(713.24);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getBalances()', () => {
|
|
||||||
it('should return the total client balance amount', () => {
|
|
||||||
jest.spyOn(controller, 'getCurrentBalance');
|
|
||||||
controller._companyId = 442;
|
|
||||||
controller.$.model = {data:
|
|
||||||
[{
|
|
||||||
id: 1,
|
|
||||||
debit: 1000,
|
|
||||||
credit: null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
debit: null,
|
|
||||||
credit: 500
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
debit: null,
|
|
||||||
credit: 300
|
|
||||||
}
|
|
||||||
]};
|
|
||||||
controller.getBalances();
|
|
||||||
const expectedBalances = controller.$.model.data;
|
|
||||||
|
|
||||||
expect(expectedBalances[0].balance).toEqual(713.24);
|
|
||||||
expect(expectedBalances[1].balance).toEqual(-286.76);
|
|
||||||
expect(expectedBalances[2].balance).toEqual(213.24);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('balances() setter', () => {
|
|
||||||
it('should set the balances data and not call the getBalances() method', () => {
|
|
||||||
jest.spyOn(controller, 'getBalances');
|
|
||||||
controller.$.riskModel.data = null;
|
|
||||||
controller.balances = [{
|
|
||||||
id: 1,
|
|
||||||
debit: 1000,
|
|
||||||
credit: null
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
debit: null,
|
|
||||||
credit: 500
|
|
||||||
}, {
|
|
||||||
id: 3,
|
|
||||||
debit: null,
|
|
||||||
credit: 300
|
|
||||||
}];
|
|
||||||
|
|
||||||
expect(controller.balances).toBeDefined();
|
|
||||||
expect(controller.getBalances).not.toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set the balances data and then call the getBalances() method', () => {
|
|
||||||
jest.spyOn(controller, 'getBalances').mockReturnThis();
|
|
||||||
controller.balances = [{
|
|
||||||
id: 1,
|
|
||||||
debit: 1000,
|
|
||||||
credit: null
|
|
||||||
}, {
|
|
||||||
id: 2,
|
|
||||||
debit: null,
|
|
||||||
credit: 500
|
|
||||||
}, {
|
|
||||||
id: 3,
|
|
||||||
debit: null,
|
|
||||||
credit: 300
|
|
||||||
}];
|
|
||||||
|
|
||||||
expect(controller.balances).toBeDefined();
|
|
||||||
expect(controller.getBalances).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('changeDescription()', () => {
|
|
||||||
it('should make an http PATCH query', () => {
|
|
||||||
const expectedParams = {description: 'Web'};
|
|
||||||
|
|
||||||
$httpBackend.expect('PATCH', `Receipts/1`, expectedParams).respond(200);
|
|
||||||
controller.changeDescription({
|
|
||||||
id: 1,
|
|
||||||
description: 'Web',
|
|
||||||
accountingType: {
|
|
||||||
description: 'Cash'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$httpBackend.flush();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('sendEmail()', () => {
|
|
||||||
it('should send an email', () => {
|
|
||||||
jest.spyOn(controller.vnEmail, 'send');
|
|
||||||
|
|
||||||
const $data = {id: 1103};
|
|
||||||
|
|
||||||
controller.sendEmail($data);
|
|
||||||
|
|
||||||
const expectedPath = `Receipts/${$data.id}/balance-compensation-email`;
|
|
||||||
|
|
||||||
expect(controller.vnEmail.send).toHaveBeenCalledWith(expectedPath);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,3 +0,0 @@
|
||||||
BILL: N/INV {{ref}}
|
|
||||||
Notify compensation: Do you want to report compensation to the client by mail?
|
|
||||||
Send compensation: Send compensation
|
|
|
@ -1,13 +0,0 @@
|
||||||
Creation date: Fecha de creación
|
|
||||||
Reference: Referencia
|
|
||||||
Bank: Caja
|
|
||||||
Debit: Debe
|
|
||||||
Conciliated: Conciliado
|
|
||||||
New payment: Añadir pago
|
|
||||||
Havings: Haber
|
|
||||||
Balance: Balance
|
|
||||||
Total by company: Total por empresa
|
|
||||||
Download PDF: Descargar PDF
|
|
||||||
Send compensation: Enviar compensación
|
|
||||||
BILL: N/FRA {{ref}}
|
|
||||||
Notify compensation: ¿Desea informar de la compensación al cliente por correo?
|
|
|
@ -1,2 +0,0 @@
|
||||||
Compensation: Compensación
|
|
||||||
Cash: Efectivo
|
|
|
@ -1,103 +0,0 @@
|
||||||
<mg-ajax path="Clients/{{patch.params.id}}" options="vnPatch"></mg-ajax>
|
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
data="$ctrl.client"
|
|
||||||
form="form"
|
|
||||||
save="patch">
|
|
||||||
</vn-watcher>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="ContactChannels"
|
|
||||||
data="contactChannels">
|
|
||||||
</vn-crud-model>
|
|
||||||
<form name="form" vn-http-submit="$ctrl.onSubmit()" class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Comercial Name"
|
|
||||||
ng-model="$ctrl.client.name"
|
|
||||||
rule
|
|
||||||
vn-focus>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
ng-model="$ctrl.client.businessTypeFk"
|
|
||||||
url="BusinessTypes"
|
|
||||||
show-field="description"
|
|
||||||
value-field="code"
|
|
||||||
label="Business type">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Contact"
|
|
||||||
ng-model="$ctrl.client.contact"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Email"
|
|
||||||
ng-model="$ctrl.client.email"
|
|
||||||
rule
|
|
||||||
info="You can save multiple emails">
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Phone"
|
|
||||||
ng-model="$ctrl.client.phone"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Mobile"
|
|
||||||
ng-model="$ctrl.client.mobile"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-worker-autocomplete
|
|
||||||
vn-one
|
|
||||||
ng-model="$ctrl.client.salesPersonFk"
|
|
||||||
departments="['VT', 'shopping']"
|
|
||||||
show-field="nickname"
|
|
||||||
label="Salesperson"
|
|
||||||
vn-acl="salesAssistant">
|
|
||||||
</vn-worker-autocomplete>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
ng-model="$ctrl.client.contactChannelFk"
|
|
||||||
data="contactChannels"
|
|
||||||
label="Channel">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete
|
|
||||||
ng-model="$ctrl.client.transferorFk"
|
|
||||||
url="Clients"
|
|
||||||
search-function="$ctrl.transferorSearchFunction($search)"
|
|
||||||
where="{id: {neq: $ctrl.client.id}}"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
label="Previous client"
|
|
||||||
info="In case of a company succession, specify the grantor company"
|
|
||||||
rule>
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit
|
|
||||||
disabled="!watcher.dataChanged()"
|
|
||||||
label="Save">
|
|
||||||
</vn-submit>
|
|
||||||
<vn-button
|
|
||||||
class="cancel"
|
|
||||||
label="Undo changes"
|
|
||||||
disabled="!watcher.dataChanged()"
|
|
||||||
ng-click="watcher.loadOriginalData()">
|
|
||||||
</vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</form>
|
|
|
@ -1,22 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
export default class Controller extends Section {
|
|
||||||
transferorSearchFunction($search) {
|
|
||||||
return /^\d+$/.test($search)
|
|
||||||
? {id: $search}
|
|
||||||
: {name: {like: '%' + $search + '%'}};
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
return this.$.watcher.submit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientBasicData', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,16 +0,0 @@
|
||||||
Comercial Name: Nombre comercial
|
|
||||||
Tax number: NIF/CIF
|
|
||||||
Social name: Razón social
|
|
||||||
Phone: Teléfono
|
|
||||||
Mobile: Móvil
|
|
||||||
Fax: Fax
|
|
||||||
Email: E-mail
|
|
||||||
Salesperson: Comercial
|
|
||||||
Channel: Canal
|
|
||||||
You can save multiple emails: >-
|
|
||||||
Puede guardar varios correos electrónicos encadenándolos mediante comas
|
|
||||||
sin espacios, ejemplo: user@dominio.com, user2@dominio.com siendo el primer
|
|
||||||
correo electrónico el principal
|
|
||||||
Contact: Contacto
|
|
||||||
Undo changes: Deshacer cambios
|
|
||||||
Business type: Tipo de negocio
|
|
|
@ -1,103 +0,0 @@
|
||||||
<mg-ajax path="Clients/{{patch.params.id}}" options="vnPatch"></mg-ajax>
|
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
data="$ctrl.client"
|
|
||||||
form="form"
|
|
||||||
save="patch">
|
|
||||||
</vn-watcher>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="PayMethods"
|
|
||||||
data="paymethods">
|
|
||||||
</vn-crud-model>
|
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete
|
|
||||||
label="Billing data"
|
|
||||||
vn-acl="salesAssistant, hr"
|
|
||||||
ng-model="$ctrl.client.payMethodFk"
|
|
||||||
data="paymethods"
|
|
||||||
fields="['isIbanRequiredForClients']"
|
|
||||||
initial-data="$ctrl.client.payMethod">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-input-number
|
|
||||||
min="0"
|
|
||||||
step="1"
|
|
||||||
label="Due day"
|
|
||||||
ng-model="$ctrl.client.dueDay"
|
|
||||||
vn-acl="salesAssistant, hr"
|
|
||||||
rule>
|
|
||||||
</vn-input-number>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
label="IBAN"
|
|
||||||
ng-keyup="$ctrl.client.iban = $ctrl.client.iban.toUpperCase()"
|
|
||||||
ng-model="$ctrl.client.iban"
|
|
||||||
rule
|
|
||||||
on-change="$ctrl.autofillBic()"
|
|
||||||
vn-acl="salesAssistant, hr">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-autocomplete
|
|
||||||
label="Swift / BIC"
|
|
||||||
url="BankEntities"
|
|
||||||
ng-model="$ctrl.client.bankEntityFk"
|
|
||||||
fields="['name', 'bic']"
|
|
||||||
initial-data="$ctrl.client.bankEntityFk"
|
|
||||||
on-change="$ctrl.autofillBic()"
|
|
||||||
search-function="{or: [{bic: {like: $search +'%'}}, {name: {like: '%'+ $search +'%'}}]}"
|
|
||||||
value-field="id"
|
|
||||||
show-field="bic"
|
|
||||||
vn-acl="salesAssistant, hr"
|
|
||||||
disabled="$ctrl.ibanCountry == 'ES'">
|
|
||||||
<tpl-item>
|
|
||||||
<div>{{::bic}}</div>
|
|
||||||
<div class="text-secondary text-caption">{{::name}}</div>
|
|
||||||
</tpl-item>
|
|
||||||
<append>
|
|
||||||
<vn-icon-button
|
|
||||||
vn-auto
|
|
||||||
icon="add_circle"
|
|
||||||
vn-click-stop="bankEntity.show({countryFk: $ctrl.client.countryFk})"
|
|
||||||
vn-tooltip="New bank entity"
|
|
||||||
vn-acl="salesAssistant, hr">
|
|
||||||
</vn-icon-button>
|
|
||||||
</append>
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-check
|
|
||||||
label="Received LCR"
|
|
||||||
ng-model="$ctrl.client.hasLcr"
|
|
||||||
vn-acl="salesAssistant, hr">
|
|
||||||
</vn-check>
|
|
||||||
<vn-check
|
|
||||||
label="Received core VNL"
|
|
||||||
ng-model="$ctrl.client.hasCoreVnl"
|
|
||||||
vn-acl="salesAssistant, hr">
|
|
||||||
</vn-check>
|
|
||||||
<vn-check
|
|
||||||
label="Received B2B VNL"
|
|
||||||
ng-model="$ctrl.client.hasSepaVnl"
|
|
||||||
vn-acl="salesAssistant, hr">
|
|
||||||
</vn-check>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit
|
|
||||||
disabled="!watcher.dataChanged()"
|
|
||||||
label="Save">
|
|
||||||
</vn-submit>
|
|
||||||
<vn-button
|
|
||||||
class="cancel"
|
|
||||||
label="Undo changes"
|
|
||||||
disabled="!watcher.dataChanged()"
|
|
||||||
ng-click="watcher.loadOriginalData()">
|
|
||||||
</vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</form>
|
|
||||||
<vn-new-bank-entity
|
|
||||||
vn-id="bankEntity"
|
|
||||||
on-accept="$ctrl.onAccept($data)">
|
|
||||||
</vn-new-bank-entity>
|
|
|
@ -1,77 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
export default class Controller extends Section {
|
|
||||||
get client() {
|
|
||||||
return this._client;
|
|
||||||
}
|
|
||||||
|
|
||||||
set client(value) {
|
|
||||||
this._client = value;
|
|
||||||
|
|
||||||
if (!value) return;
|
|
||||||
|
|
||||||
if (!value.bankEntityFk)
|
|
||||||
this.autofillBic();
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
let shouldNotify = false;
|
|
||||||
|
|
||||||
if (this.hasPaymethodChanges())
|
|
||||||
shouldNotify = true;
|
|
||||||
|
|
||||||
this.$.watcher.submit().then(() => {
|
|
||||||
if (shouldNotify)
|
|
||||||
this.vnApp.showMessage(this.$t('Notification sent!'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
hasPaymethodChanges() {
|
|
||||||
let orgData = this.$.watcher.orgData;
|
|
||||||
|
|
||||||
let payMethod = orgData.payMethodFk != this.client.payMethodFk;
|
|
||||||
let iban = orgData.iban != this.client.iban;
|
|
||||||
let dueDay = orgData.dueDay != this.client.dueDay;
|
|
||||||
|
|
||||||
return payMethod || iban || dueDay;
|
|
||||||
}
|
|
||||||
|
|
||||||
onAccept(data) {
|
|
||||||
this.client.bankEntityFk = data.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
get ibanCountry() {
|
|
||||||
if (!this.client || !this.client.iban) return false;
|
|
||||||
|
|
||||||
let countryCode = this.client.iban.substr(0, 2);
|
|
||||||
|
|
||||||
return countryCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
autofillBic() {
|
|
||||||
if (!this.client || !this.client.iban) return;
|
|
||||||
|
|
||||||
let bankEntityId = parseInt(this.client.iban.substr(4, 4));
|
|
||||||
let filter = {where: {id: bankEntityId}};
|
|
||||||
|
|
||||||
if (this.ibanCountry != 'ES') return;
|
|
||||||
|
|
||||||
this.$http.get(`BankEntities`, {filter}).then(response => {
|
|
||||||
const hasData = response.data && response.data[0];
|
|
||||||
|
|
||||||
if (hasData)
|
|
||||||
this.client.bankEntityFk = response.data[0].id;
|
|
||||||
else if (!hasData)
|
|
||||||
this.client.bankEntityFk = null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientBillingData', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,94 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientBillingData', () => {
|
|
||||||
let $httpBackend;
|
|
||||||
let $scope;
|
|
||||||
let controller;
|
|
||||||
let vnApp;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _vnApp_) => {
|
|
||||||
let $element = angular.element('<vn-client-billing-data></vn-client-billing-data>');
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
vnApp = _vnApp_;
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$scope.watcher = {};
|
|
||||||
jest.spyOn(vnApp, 'showError');
|
|
||||||
controller = $componentController('vnClientBillingData', {$element, $scope});
|
|
||||||
controller.client = {id: 1101, name: 'Client name', payMethodFk: 4};
|
|
||||||
$scope.watcher.orgData = {id: 1101, name: 'Client name', payMethodFk: 4};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('hasPaymethodChanges()', () => {
|
|
||||||
it(`should return true if there are changes on payMethod data`, () => {
|
|
||||||
controller.client.payMethodFk = 5;
|
|
||||||
|
|
||||||
expect(controller.hasPaymethodChanges()).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should return false if there are no changes on payMethod data`, () => {
|
|
||||||
controller.client.payMethodFk = 4;
|
|
||||||
|
|
||||||
expect(controller.hasPaymethodChanges()).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onAccept()', () => {
|
|
||||||
it('should assign the response id to the client bankEntityFk', () => {
|
|
||||||
const expectedResponse = {id: 999};
|
|
||||||
controller.onAccept(expectedResponse);
|
|
||||||
|
|
||||||
expect(controller.client.bankEntityFk).toEqual(expectedResponse.id);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('autofillBic()', () => {
|
|
||||||
it(`Should do nothing if there is not client`, () => {
|
|
||||||
controller.client = undefined;
|
|
||||||
|
|
||||||
controller.autofillBic();
|
|
||||||
|
|
||||||
expect(controller.client).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`Should do nothing if the iban is not spanish`, () => {
|
|
||||||
controller.client.iban = 'FR9121000418450200051332';
|
|
||||||
|
|
||||||
controller.autofillBic();
|
|
||||||
|
|
||||||
expect(controller.client.bankEntityFk).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`Should set the bankEntityId in the client`, () => {
|
|
||||||
controller.client.iban = 'ES9121000418450200051332';
|
|
||||||
|
|
||||||
$httpBackend.whenRoute('GET', `BankEntities`).respond([{id: 123}]);
|
|
||||||
controller.autofillBic();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.client.bankEntityFk).toEqual(123);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`Should set clients bankEntityFk to null if no bank entity founds`, () => {
|
|
||||||
controller.client.iban = 'ES9121000418450200051332';
|
|
||||||
|
|
||||||
$httpBackend.whenRoute('GET', `BankEntities`).respond([]);
|
|
||||||
controller.autofillBic();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.client.bankEntityFk).toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('ibanCountry()', () => {
|
|
||||||
it('should return a country code from iban', () => {
|
|
||||||
controller.client.iban = 'ES123';
|
|
||||||
let countryCode = controller.ibanCountry;
|
|
||||||
|
|
||||||
expect(countryCode).toEqual('ES');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,14 +0,0 @@
|
||||||
Changed terms: Payment terms have changed
|
|
||||||
Notify customer?: Do you want to notify customer?
|
|
||||||
No: No
|
|
||||||
Yes, notify: Yes, notify
|
|
||||||
Notification sent!: Notification sent!
|
|
||||||
Notification error: Error while sending notification
|
|
||||||
Yes, propagate: Yes, propagate
|
|
||||||
Equivalent tax spreaded: Equivalent tax spreaded
|
|
||||||
Invoice by address: Invoice by address
|
|
||||||
Equalization tax: Equalization tax
|
|
||||||
Due day: Due day
|
|
||||||
Received core VNL: VNL core received
|
|
||||||
Received B2B VNL: VNL B2B received
|
|
||||||
Save: Save
|
|
|
@ -1,17 +0,0 @@
|
||||||
Changed terms: Has modificado las condiciones de pago
|
|
||||||
Notify customer?: ¿Deseas notificar al cliente de dichos cambios?
|
|
||||||
No: No
|
|
||||||
Yes, notify: Sí, notificar
|
|
||||||
Notification sent!: ¡Notificación enviada!
|
|
||||||
Notification error: Error al enviar notificación
|
|
||||||
Yes, propagate: Si, propagar
|
|
||||||
Equivalent tax spreaded: Recargo de equivalencia propagado
|
|
||||||
Invoice by address: Facturar por consignatario
|
|
||||||
Equalization tax: Recargo de equivalencia
|
|
||||||
Due day: Vencimiento
|
|
||||||
Received LCR: Recibido LCR
|
|
||||||
Received core VNL: Recibido core VNL
|
|
||||||
Received B2B VNL: Recibido B2B VNL
|
|
||||||
Save: Guardar
|
|
||||||
New bank entity: Nueva entidad bancaria
|
|
||||||
Name can't be empty: El nombre no puede quedar vacío
|
|
|
@ -1,5 +0,0 @@
|
||||||
<vn-portal slot="menu">
|
|
||||||
<vn-client-descriptor client="$ctrl.client"></vn-client-descriptor>
|
|
||||||
<vn-left-menu source="card"></vn-left-menu>
|
|
||||||
</vn-portal>
|
|
||||||
<ui-view></ui-view>
|
|
|
@ -1,15 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import ModuleCard from 'salix/components/module-card';
|
|
||||||
|
|
||||||
export default class Controller extends ModuleCard {
|
|
||||||
reload() {
|
|
||||||
this.$http.get(`Clients/${this.$params.id}/getCard`)
|
|
||||||
.then(res => this.client = res.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientCard', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientCard', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
let data = {id: 1, name: 'fooName'};
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_, $stateParams) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
|
|
||||||
let $element = angular.element('<div></div>');
|
|
||||||
controller = $componentController('vnClientCard', {$element});
|
|
||||||
|
|
||||||
$stateParams.id = data.id;
|
|
||||||
$httpBackend.whenRoute('GET', 'Clients/:id/getCard').respond(data);
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should request data and set it on the controller', () => {
|
|
||||||
controller.$onInit();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.client).toEqual(data);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,85 +0,0 @@
|
||||||
<div class="search-panel">
|
|
||||||
<form class="vn-pa-lg" ng-submit="$ctrl.onSearch()">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield vn-focus
|
|
||||||
vn-one
|
|
||||||
label="General search"
|
|
||||||
ng-model="filter.search"
|
|
||||||
vn-focus>
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Item id"
|
|
||||||
ng-model="filter.itemId">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
ng-model="filter.buyerId"
|
|
||||||
url="TicketRequests/getItemTypeWorker"
|
|
||||||
search-function="{firstName: $search}"
|
|
||||||
show-field="nickname"
|
|
||||||
value-field="id"
|
|
||||||
label="Buyer">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
ng-model="filter.typeId"
|
|
||||||
url="ItemTypes"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
label="Type"
|
|
||||||
fields="['categoryFk']"
|
|
||||||
include="'category'">
|
|
||||||
<tpl-item>
|
|
||||||
<div>{{name}}</div>
|
|
||||||
<div class="text-caption text-secondary">
|
|
||||||
{{category.name}}
|
|
||||||
</div>
|
|
||||||
</tpl-item>
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
url="ItemCategories"
|
|
||||||
label="Category"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
ng-model="filter.categoryId">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
url="Campaigns/latest"
|
|
||||||
label="Campaign"
|
|
||||||
translate-fields="['code']"
|
|
||||||
show-field="code"
|
|
||||||
value-field="id"
|
|
||||||
ng-model="filter.campaign"
|
|
||||||
order="dated DESC"
|
|
||||||
selection="$ctrl.campaignSelection"
|
|
||||||
search-function="{dated: {like: '%'+ $search +'%'}}">
|
|
||||||
<tpl-item>
|
|
||||||
{{code}} {{dated | date: 'yyyy'}}
|
|
||||||
</tpl-item>
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-date-picker
|
|
||||||
vn-one
|
|
||||||
label="From"
|
|
||||||
ng-model="filter.from"
|
|
||||||
on-change="$ctrl.onChangeDate(value)">
|
|
||||||
</vn-date-picker>
|
|
||||||
<vn-date-picker
|
|
||||||
vn-one
|
|
||||||
label="To"
|
|
||||||
ng-model="filter.to"
|
|
||||||
on-change="$ctrl.onChangeDate(value)">
|
|
||||||
</vn-date-picker>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal class="vn-mt-lg">
|
|
||||||
<vn-submit label="Search"></vn-submit>
|
|
||||||
</vn-horizontal>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
|
@ -1,56 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
|
||||||
|
|
||||||
class Controller extends SearchPanel {
|
|
||||||
constructor($, $element) {
|
|
||||||
super($, $element);
|
|
||||||
|
|
||||||
this.filter = this.$.filter;
|
|
||||||
|
|
||||||
if (!this.dateParams)
|
|
||||||
this.getUpcomingCampaing();
|
|
||||||
}
|
|
||||||
|
|
||||||
get dateParams() {
|
|
||||||
if (this.$params.q) {
|
|
||||||
const params = JSON.parse(this.$params.q);
|
|
||||||
|
|
||||||
if (params.from || params.to)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
getUpcomingCampaing() {
|
|
||||||
this.$http.get('Campaigns/upcoming').then(res => {
|
|
||||||
this.filter.campaign = res.data.id;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onChangeDate(value) {
|
|
||||||
if (value)
|
|
||||||
this.filter.campaign = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
get campaignSelection() {
|
|
||||||
return this._campaignSelection;
|
|
||||||
}
|
|
||||||
|
|
||||||
set campaignSelection(value) {
|
|
||||||
this._campaignSelection = value;
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
const from = new Date(value.dated);
|
|
||||||
from.setDate(from.getDate() - value.scopeDays);
|
|
||||||
|
|
||||||
this.filter.to = value.dated;
|
|
||||||
this.filter.from = from;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnConsumptionSearchPanel', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,31 +0,0 @@
|
||||||
import './index.js';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnConsumptionSearchPanel', () => {
|
|
||||||
let $httpBackend;
|
|
||||||
let $element;
|
|
||||||
let controller;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$element = angular.element(`<div></div>`);
|
|
||||||
controller = $componentController('vnConsumptionSearchPanel', {$element});
|
|
||||||
controller.$.filter = {};
|
|
||||||
$httpBackend.expect('GET', 'Campaigns/upcoming').respond(200, {id: 1});
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('getUpcomingCampaing()', () => {
|
|
||||||
it(`should make an HTTP query and then set the campaign property`, () => {
|
|
||||||
$httpBackend.expect('GET', 'Campaigns/upcoming').respond(200, {id: 2, code: 'allSaints'});
|
|
||||||
controller.getUpcomingCampaing();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
const filter = controller.$.filter;
|
|
||||||
|
|
||||||
expect(filter.campaign).toEqual(2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,3 +0,0 @@
|
||||||
allSaints: All Saints Day
|
|
||||||
valentinesDay: Valentine's Day
|
|
||||||
mothersDay: Mother's day
|
|
|
@ -1,7 +0,0 @@
|
||||||
Item id: Id artículo
|
|
||||||
From: Desde
|
|
||||||
To: Hasta
|
|
||||||
Campaign: Campaña
|
|
||||||
allSaints: Día de todos los Santos
|
|
||||||
valentinesDay: Día de San Valentín
|
|
||||||
mothersDay: Día de la madre
|
|
|
@ -1,97 +0,0 @@
|
||||||
<vn-crud-model vn-id="model"
|
|
||||||
url="Clients/consumption"
|
|
||||||
link="{clientFk: $ctrl.$params.id}"
|
|
||||||
filter="::$ctrl.filter"
|
|
||||||
limit="20"
|
|
||||||
user-params="::$ctrl.filterParams"
|
|
||||||
data="sales"
|
|
||||||
order="itemTypeFk, itemName, itemSize, description">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-portal slot="topbar">
|
|
||||||
<vn-searchbar
|
|
||||||
panel="vn-consumption-search-panel"
|
|
||||||
suggested-filter="$ctrl.filterParams"
|
|
||||||
info="Search by item id or name"
|
|
||||||
model="model"
|
|
||||||
auto-state="false">
|
|
||||||
</vn-searchbar>
|
|
||||||
</vn-portal>
|
|
||||||
<vn-data-viewer model="model">
|
|
||||||
<vn-card class="vn-pa-lg vn-w-lg">
|
|
||||||
<section class="header">
|
|
||||||
<vn-tool-bar class="vn-mb-md">
|
|
||||||
<vn-button disabled="!model.userParams.from || !model.userParams.to"
|
|
||||||
icon="picture_as_pdf"
|
|
||||||
ng-click="$ctrl.showReport()"
|
|
||||||
vn-tooltip="Open as PDF">
|
|
||||||
</vn-button>
|
|
||||||
<vn-button disabled="!model.userParams.from || !model.userParams.to"
|
|
||||||
icon="email"
|
|
||||||
ng-click="confirm.show()"
|
|
||||||
vn-tooltip="Send to email">
|
|
||||||
</vn-button>
|
|
||||||
<vn-check
|
|
||||||
label="Group by item"
|
|
||||||
on-change="$ctrl.changeGrouped(value)">
|
|
||||||
</vn-check>
|
|
||||||
</vn-tool-bar>
|
|
||||||
</section>
|
|
||||||
<vn-table model="model">
|
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th field="itemFk" number>Item</vn-th>
|
|
||||||
<vn-th field="ticketFk" number>Ticket</vn-th>
|
|
||||||
<vn-th field="shipped" expand>Fecha</vn-th>
|
|
||||||
<vn-th field="description" expand>Description</vn-th>
|
|
||||||
<vn-th field="quantity" number>Quantity</vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr
|
|
||||||
ng-repeat="sale in sales">
|
|
||||||
<vn-td number>
|
|
||||||
<span
|
|
||||||
ng-click="itemDescriptor.show($event, sale.itemFk)"
|
|
||||||
class="link">
|
|
||||||
{{::sale.itemFk}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td number>
|
|
||||||
<span
|
|
||||||
ng-click="ticketDescriptor.show($event, sale.ticketFk)"
|
|
||||||
class="link">
|
|
||||||
{{::sale.ticketFk}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td expand>{{::sale.shipped | date: 'dd/MM/yyyy'}}</vn-td>
|
|
||||||
<vn-td vn-fetched-tags wide>
|
|
||||||
<div>
|
|
||||||
<vn-one title="{{::sale.concept}}">{{::sale.concept}}</vn-one>
|
|
||||||
<vn-one ng-if="::sale.subName">
|
|
||||||
<h3 title="{{::sale.subName}}">{{::sale.subName}}</h3>
|
|
||||||
</vn-one>
|
|
||||||
</div>
|
|
||||||
<vn-fetched-tags
|
|
||||||
max-length="6"
|
|
||||||
item="::sale"
|
|
||||||
tabindex="-1">
|
|
||||||
</vn-fetched-tags>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td number>{{::sale.quantity | dashIfEmpty}}</vn-td>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
</vn-card>
|
|
||||||
</vn-data-viewer>
|
|
||||||
<vn-item-descriptor-popover
|
|
||||||
vn-id="item-descriptor"
|
|
||||||
warehouse-fk="$ctrl.vnConfig.warehouseFk">
|
|
||||||
</vn-item-descriptor-popover>
|
|
||||||
<vn-ticket-descriptor-popover
|
|
||||||
vn-id="ticket-descriptor">
|
|
||||||
</vn-ticket-descriptor-popover>
|
|
||||||
<vn-confirm
|
|
||||||
vn-id="confirm"
|
|
||||||
question="Please, confirm"
|
|
||||||
message="The consumption report will be sent"
|
|
||||||
on-accept="$ctrl.sendEmail()">
|
|
||||||
</vn-confirm>
|
|
|
@ -1,75 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $, vnReport, vnEmail) {
|
|
||||||
super($element, $);
|
|
||||||
this.vnReport = vnReport;
|
|
||||||
this.vnEmail = vnEmail;
|
|
||||||
|
|
||||||
this.filter = {
|
|
||||||
where: {
|
|
||||||
isPackaging: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setDefaultFilter();
|
|
||||||
}
|
|
||||||
|
|
||||||
setDefaultFilter() {
|
|
||||||
const minDate = Date.vnNew();
|
|
||||||
minDate.setHours(0, 0, 0, 0);
|
|
||||||
minDate.setMonth(minDate.getMonth() - 2);
|
|
||||||
|
|
||||||
const maxDate = Date.vnNew();
|
|
||||||
maxDate.setHours(23, 59, 59, 59);
|
|
||||||
|
|
||||||
this.filterParams = {
|
|
||||||
from: minDate,
|
|
||||||
to: maxDate
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get reportParams() {
|
|
||||||
const userParams = this.$.model.userParams;
|
|
||||||
return Object.assign({
|
|
||||||
recipient: this.client.email,
|
|
||||||
recipientId: this.client.id
|
|
||||||
}, userParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
showTicketDescriptor(event, sale) {
|
|
||||||
if (!sale.isTicket) return;
|
|
||||||
|
|
||||||
this.$.ticketDescriptor.show(event.target, sale.origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
showReport() {
|
|
||||||
const path = `Clients/${this.client.id}/campaign-metrics-pdf`;
|
|
||||||
this.vnReport.show(path, this.reportParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
sendEmail() {
|
|
||||||
const path = `Clients/${this.client.id}/campaign-metrics-email`;
|
|
||||||
this.vnEmail.send(path, this.reportParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
changeGrouped(value) {
|
|
||||||
const model = this.$.model;
|
|
||||||
|
|
||||||
model.addFilter({}, {grouped: value});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope', 'vnReport', 'vnEmail'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientConsumption', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
},
|
|
||||||
require: {
|
|
||||||
card: '^vnClientCard'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,67 +0,0 @@
|
||||||
import './index.js';
|
|
||||||
import crudModel from 'core/mocks/crud-model';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientConsumption', () => {
|
|
||||||
let $scope;
|
|
||||||
let controller;
|
|
||||||
let $httpParamSerializer;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$httpParamSerializer_, _$httpBackend_) => {
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$httpParamSerializer = _$httpParamSerializer_;
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
const $element = angular.element('<vn-client-consumption></vn-client-consumption');
|
|
||||||
controller = $componentController('vnClientConsumption', {$element, $scope});
|
|
||||||
controller.$.model = crudModel;
|
|
||||||
controller.client = {
|
|
||||||
id: 1101
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('showReport()', () => {
|
|
||||||
it('should call the window.open function', () => {
|
|
||||||
jest.spyOn(window, 'open').mockReturnThis();
|
|
||||||
|
|
||||||
const now = Date.vnNew();
|
|
||||||
controller.$.model.userParams = {
|
|
||||||
from: now,
|
|
||||||
to: now
|
|
||||||
};
|
|
||||||
|
|
||||||
controller.showReport();
|
|
||||||
|
|
||||||
const clientId = controller.client.id;
|
|
||||||
const expectedParams = {
|
|
||||||
recipientId: clientId,
|
|
||||||
from: now,
|
|
||||||
to: now
|
|
||||||
};
|
|
||||||
const serializedParams = $httpParamSerializer(expectedParams);
|
|
||||||
const expectedPath = `api/Clients/${clientId}/campaign-metrics-pdf?${serializedParams}`;
|
|
||||||
|
|
||||||
expect(window.open).toHaveBeenCalledWith(expectedPath);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('sendEmail()', () => {
|
|
||||||
it('should make a GET query sending the report', () => {
|
|
||||||
const now = Date.vnNew();
|
|
||||||
controller.$.model.userParams = {
|
|
||||||
from: now,
|
|
||||||
to: now
|
|
||||||
};
|
|
||||||
const clientId = controller.client.id;
|
|
||||||
const expectedPath = `Clients/${clientId}/campaign-metrics-email`;
|
|
||||||
|
|
||||||
$httpBackend.expect('POST', expectedPath).respond({});
|
|
||||||
controller.sendEmail();
|
|
||||||
$httpBackend.flush();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
Group by item: Agrupar por artículo
|
|
||||||
Open as PDF: Abrir como PDF
|
|
||||||
Send to email: Enviar por email
|
|
||||||
Search by item id or name: Buscar por id de artículo o nombre
|
|
||||||
The consumption report will be sent: Se enviará el informe de consumo
|
|
||||||
Please, confirm: Por favor, confirma
|
|
|
@ -1,61 +0,0 @@
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="ClientContacts"
|
|
||||||
fields="['id', 'name', 'phone', 'clientFk']"
|
|
||||||
link="{clientFk: $ctrl.$params.id}"
|
|
||||||
data="contacts"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
data="contacts"
|
|
||||||
form="form">
|
|
||||||
</vn-watcher>
|
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal ng-repeat="contact in contacts">
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Name"
|
|
||||||
ng-model="contact.name"
|
|
||||||
rule="ClientContact">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Phone"
|
|
||||||
ng-model="contact.phone"
|
|
||||||
rule="ClientContact"
|
|
||||||
vn-focus>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-none>
|
|
||||||
<vn-icon-button
|
|
||||||
vn-tooltip="Remove contact"
|
|
||||||
icon="delete"
|
|
||||||
tabindex="-1"
|
|
||||||
ng-click="model.remove($index)">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-none>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-one>
|
|
||||||
<vn-icon-button
|
|
||||||
vn-bind="+"
|
|
||||||
vn-tooltip="Add contact"
|
|
||||||
icon="add_circle"
|
|
||||||
ng-click="$ctrl.add()">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-one>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit
|
|
||||||
disabled="!watcher.dataChanged()"
|
|
||||||
label="Save">
|
|
||||||
</vn-submit>
|
|
||||||
<!-- # #2680 Undo changes button bugs -->
|
|
||||||
<!-- <vn-button
|
|
||||||
class="cancel"
|
|
||||||
label="Undo changes"
|
|
||||||
disabled="!watcher.dataChanged()"
|
|
||||||
ng-click="watcher.loadOriginalData()">
|
|
||||||
</vn-button> -->
|
|
||||||
</vn-button-bar>
|
|
||||||
</form>
|
|
|
@ -1,28 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
add() {
|
|
||||||
this.$.model.insert({
|
|
||||||
clientFk: this.client.id,
|
|
||||||
name: this.$t('Phone'),
|
|
||||||
phone: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
this.$.watcher.check();
|
|
||||||
this.$.model.save().then(() => {
|
|
||||||
this.$.watcher.notifySaved();
|
|
||||||
this.$.watcher.updateOriginalData();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientContact', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,150 +0,0 @@
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
url="Clients/createWithUser"
|
|
||||||
data="$ctrl.client"
|
|
||||||
insert-mode="true"
|
|
||||||
form="form">
|
|
||||||
</vn-watcher>
|
|
||||||
<form name="form" vn-http-submit="$ctrl.onSubmit()" class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-two
|
|
||||||
label="Comercial Name"
|
|
||||||
ng-model="$ctrl.client.name"
|
|
||||||
rule
|
|
||||||
vn-focus>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-worker-autocomplete
|
|
||||||
label="Salesperson"
|
|
||||||
ng-model="$ctrl.client.salesPersonFk"
|
|
||||||
departments="['VT']"
|
|
||||||
show-field="nickname">
|
|
||||||
</vn-worker-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-id="businessTypeFk"
|
|
||||||
ng-model="$ctrl.client.businessTypeFk"
|
|
||||||
url="BusinessTypes"
|
|
||||||
show-field="description"
|
|
||||||
value-field="code"
|
|
||||||
label="Business type"
|
|
||||||
rule>
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-textfield
|
|
||||||
label="Tax number"
|
|
||||||
ng-model="$ctrl.client.fi"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
label="Business name"
|
|
||||||
ng-model="$ctrl.client.socialName"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-two
|
|
||||||
label="Street"
|
|
||||||
ng-model="$ctrl.client.street"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-datalist
|
|
||||||
label="Postcode"
|
|
||||||
ng-model="$ctrl.client.postcode"
|
|
||||||
selection="$ctrl.postcode"
|
|
||||||
url="Postcodes/location"
|
|
||||||
fields="['code','townFk']"
|
|
||||||
order="code, townFk"
|
|
||||||
value-field="code"
|
|
||||||
show-field="code"
|
|
||||||
rule>
|
|
||||||
<tpl-item>
|
|
||||||
{{code}} - {{town.name}} ({{town.province.name}},
|
|
||||||
{{town.province.country.name}})
|
|
||||||
</tpl-item>
|
|
||||||
<append>
|
|
||||||
<vn-icon-button
|
|
||||||
icon="add_circle"
|
|
||||||
vn-tooltip="New postcode"
|
|
||||||
ng-click="postcode.open()"
|
|
||||||
vn-acl="deliveryAssistant"
|
|
||||||
vn-acl-action="remove">
|
|
||||||
</vn-icon-button>
|
|
||||||
</append>
|
|
||||||
</vn-datalist>
|
|
||||||
<vn-datalist
|
|
||||||
vn-id="town"
|
|
||||||
label="City"
|
|
||||||
ng-model="$ctrl.client.city"
|
|
||||||
selection="$ctrl.town"
|
|
||||||
url="Towns/location"
|
|
||||||
fields="['id', 'name', 'provinceFk']"
|
|
||||||
value-field="name">
|
|
||||||
<tpl-item>
|
|
||||||
{{name}}, {{province.name}}
|
|
||||||
({{province.country.name}})
|
|
||||||
</tpl-item>
|
|
||||||
</vn-datalist>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-id="province"
|
|
||||||
label="Province"
|
|
||||||
ng-model="$ctrl.client.provinceFk"
|
|
||||||
selection="$ctrl.province"
|
|
||||||
url="Provinces/location"
|
|
||||||
fields="['id', 'name', 'countryFk']"
|
|
||||||
rule>
|
|
||||||
<tpl-item>{{name}} ({{country.name}})</tpl-item>
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-id="country"
|
|
||||||
label="Country"
|
|
||||||
ng-model="$ctrl.client.countryFk"
|
|
||||||
url="Countries"
|
|
||||||
show-field="name">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
label="Web user"
|
|
||||||
ng-model="$ctrl.client.userName"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield
|
|
||||||
label="Email"
|
|
||||||
ng-model="$ctrl.client.email"
|
|
||||||
rule
|
|
||||||
info="You can save multiple emails">
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-check
|
|
||||||
label="Is equalizated"
|
|
||||||
ng-model="$ctrl.client.isEqualizated">
|
|
||||||
</vn-check>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit
|
|
||||||
disabled="!watcher.dataChanged()"
|
|
||||||
label="Create">
|
|
||||||
</vn-submit>
|
|
||||||
<vn-button
|
|
||||||
class="cancel"
|
|
||||||
label="Cancel"
|
|
||||||
ui-sref="client.index">
|
|
||||||
</vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</form>
|
|
||||||
<!-- New postcode dialog -->
|
|
||||||
<vn-geo-postcode
|
|
||||||
vn-id="postcode"
|
|
||||||
on-response="$ctrl.onResponse($response)">
|
|
||||||
</vn-geo-postcode>
|
|
|
@ -1,95 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
export default class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
this.client = {
|
|
||||||
active: true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
return this.$.watcher.submit().then(json => {
|
|
||||||
this.$state.go('client.card.basicData', {id: json.data.id});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get province() {
|
|
||||||
return this._province;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Province auto complete
|
|
||||||
set province(selection) {
|
|
||||||
this._province = selection;
|
|
||||||
|
|
||||||
if (!selection) return;
|
|
||||||
|
|
||||||
const country = selection.country;
|
|
||||||
|
|
||||||
if (!this.client.countryFk)
|
|
||||||
this.client.countryFk = country.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
get town() {
|
|
||||||
return this._town;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Town auto complete
|
|
||||||
set town(selection) {
|
|
||||||
this._town = selection;
|
|
||||||
|
|
||||||
if (!selection) return;
|
|
||||||
|
|
||||||
const province = selection.province;
|
|
||||||
const country = province.country;
|
|
||||||
const postcodes = selection.postcodes;
|
|
||||||
|
|
||||||
if (!this.client.provinceFk)
|
|
||||||
this.client.provinceFk = province.id;
|
|
||||||
|
|
||||||
if (!this.client.countryFk)
|
|
||||||
this.client.countryFk = country.id;
|
|
||||||
|
|
||||||
if (postcodes.length === 1)
|
|
||||||
this.client.postcode = postcodes[0].code;
|
|
||||||
}
|
|
||||||
|
|
||||||
get postcode() {
|
|
||||||
return this._postcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Postcode auto complete
|
|
||||||
set postcode(selection) {
|
|
||||||
this._postcode = selection;
|
|
||||||
|
|
||||||
if (!selection) return;
|
|
||||||
|
|
||||||
const town = selection.town;
|
|
||||||
const province = town.province;
|
|
||||||
const country = province.country;
|
|
||||||
|
|
||||||
if (!this.client.city)
|
|
||||||
this.client.city = town.name;
|
|
||||||
|
|
||||||
if (!this.client.provinceFk)
|
|
||||||
this.client.provinceFk = province.id;
|
|
||||||
|
|
||||||
if (!this.client.countryFk)
|
|
||||||
this.client.countryFk = country.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
onResponse(response) {
|
|
||||||
this.client.postcode = response.code;
|
|
||||||
this.client.city = response.city;
|
|
||||||
this.client.provinceFk = response.provinceFk;
|
|
||||||
this.client.countryFk = response.countryFk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientCreate', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,122 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientCreate', () => {
|
|
||||||
let $scope;
|
|
||||||
let $state;
|
|
||||||
let controller;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$state_) => {
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$state = _$state_;
|
|
||||||
$scope.watcher = {
|
|
||||||
submit: () => {
|
|
||||||
return {
|
|
||||||
then: callback => {
|
|
||||||
callback({data: {id: '1234'}});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const $element = angular.element('<vn-client-create></vn-client-create>');
|
|
||||||
controller = $componentController('vnClientCreate', {$element, $scope});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should define and set scope, state and client properties', () => {
|
|
||||||
expect(controller.$).toBe($scope);
|
|
||||||
expect(controller.$state).toBe($state);
|
|
||||||
expect(controller.client.active).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onSubmit()', () => {
|
|
||||||
it(`should call submit() on the watcher then expect a callback`, () => {
|
|
||||||
jest.spyOn($state, 'go');
|
|
||||||
controller.onSubmit();
|
|
||||||
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('client.card.basicData', {id: '1234'});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('province() setter', () => {
|
|
||||||
it(`should set countryFk property`, () => {
|
|
||||||
controller.client.countryFk = null;
|
|
||||||
controller.province = {
|
|
||||||
id: 1,
|
|
||||||
name: 'New york',
|
|
||||||
country: {
|
|
||||||
id: 2,
|
|
||||||
name: 'USA'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.client.countryFk).toEqual(2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('town() setter', () => {
|
|
||||||
it(`should set provinceFk property`, () => {
|
|
||||||
controller.town = {
|
|
||||||
provinceFk: 1,
|
|
||||||
code: 46001,
|
|
||||||
province: {
|
|
||||||
id: 1,
|
|
||||||
name: 'New york',
|
|
||||||
country: {
|
|
||||||
id: 2,
|
|
||||||
name: 'USA'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
postcodes: []
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.client.provinceFk).toEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should set provinceFk property and fill the postalCode if there's just one`, () => {
|
|
||||||
controller.town = {
|
|
||||||
provinceFk: 1,
|
|
||||||
code: 46001,
|
|
||||||
province: {
|
|
||||||
id: 1,
|
|
||||||
name: 'New york',
|
|
||||||
country: {
|
|
||||||
id: 2,
|
|
||||||
name: 'USA'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
postcodes: [{code: '46001'}]
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.client.provinceFk).toEqual(1);
|
|
||||||
expect(controller.client.postcode).toEqual('46001');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('postcode() setter', () => {
|
|
||||||
it(`should set the town, provinceFk and contryFk properties`, () => {
|
|
||||||
controller.postcode = {
|
|
||||||
townFk: 1,
|
|
||||||
code: 46001,
|
|
||||||
town: {
|
|
||||||
id: 1,
|
|
||||||
name: 'New York',
|
|
||||||
province: {
|
|
||||||
id: 1,
|
|
||||||
name: 'New york',
|
|
||||||
country: {
|
|
||||||
id: 2,
|
|
||||||
name: 'USA'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.client.city).toEqual('New York');
|
|
||||||
expect(controller.client.provinceFk).toEqual(1);
|
|
||||||
expect(controller.client.countryFk).toEqual(2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,11 +0,0 @@
|
||||||
Name: Nombre
|
|
||||||
Tax number: NIF/CIF
|
|
||||||
Business name: Razón social
|
|
||||||
Web user: Usuario Web
|
|
||||||
Email: E-mail
|
|
||||||
Create and edit: Crear y editar
|
|
||||||
You can save multiple emails: >-
|
|
||||||
Puede guardar varios correos electrónicos encadenándolos mediante comas
|
|
||||||
sin espacios, ejemplo: user@dominio.com, user2@dominio.com siendo el primer
|
|
||||||
correo electrónico el principal
|
|
||||||
The type of business must be filled in basic data: El tipo de negocio debe estar rellenado en datos básicos
|
|
|
@ -1,37 +0,0 @@
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-input-number
|
|
||||||
vn-one
|
|
||||||
min="0"
|
|
||||||
label="Credit"
|
|
||||||
ng-model="$ctrl.creditClassification.credit"
|
|
||||||
rule
|
|
||||||
vn-focus>
|
|
||||||
</vn-input-number>
|
|
||||||
<vn-input-number
|
|
||||||
vn-one
|
|
||||||
min="0"
|
|
||||||
step="1"
|
|
||||||
label="Grade"
|
|
||||||
ng-model="$ctrl.creditClassification.grade"
|
|
||||||
rule>
|
|
||||||
</vn-input-number>
|
|
||||||
<vn-date-picker
|
|
||||||
vn-one
|
|
||||||
label="Since"
|
|
||||||
ng-model="$ctrl.creditClassification.started">
|
|
||||||
</vn-date-picker>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit
|
|
||||||
label="Save">
|
|
||||||
</vn-submit>
|
|
||||||
<vn-button
|
|
||||||
class="cancel"
|
|
||||||
label="Cancel"
|
|
||||||
ui-sref="client.card.creditInsurance.index"></vn-button>
|
|
||||||
</vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</form>
|
|
|
@ -1,40 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
this.creditClassification = {
|
|
||||||
started: this.$filter('date')(Date.vnNew(), 'yyyy-MM-dd HH:mm')
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
if (this.$.form.$invalid)
|
|
||||||
return this.vnApp.showError(this.$t('Some fields are invalid'));
|
|
||||||
|
|
||||||
let query = `creditClassifications/createWithInsurance`;
|
|
||||||
let data = this.creditClassification;
|
|
||||||
data.clientFk = this.client.id;
|
|
||||||
|
|
||||||
this.$http.post(query, data).then(res => {
|
|
||||||
if (res.data) {
|
|
||||||
this.card.reload();
|
|
||||||
this.$state.go('client.card.creditInsurance.index');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientCreditInsuranceCreate', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
require: {
|
|
||||||
card: '^vnClientCard'
|
|
||||||
},
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,48 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientCreditInsuranceCreate', () => {
|
|
||||||
let controller;
|
|
||||||
let $scope;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$scope.form = {
|
|
||||||
$invalid: false
|
|
||||||
};
|
|
||||||
const $element = angular.element('<vn-client-credit-insurance-create></vn-client-credit-insurance-create>');
|
|
||||||
controller = $componentController('vnClientCreditInsuranceCreate', {$element, $scope});
|
|
||||||
controller.client = {id: 1101};
|
|
||||||
controller.card = {
|
|
||||||
reload: () => {}
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('onSubmit()', () => {
|
|
||||||
it('should perform a POST query', () => {
|
|
||||||
let started = Date.vnNew();
|
|
||||||
controller.creditClassification = {
|
|
||||||
started: started,
|
|
||||||
credit: 300,
|
|
||||||
grade: 1
|
|
||||||
};
|
|
||||||
|
|
||||||
let newData = {
|
|
||||||
started: started,
|
|
||||||
credit: 300,
|
|
||||||
grade: 1,
|
|
||||||
clientFk: 1101
|
|
||||||
};
|
|
||||||
|
|
||||||
$httpBackend.whenPOST(`creditClassifications/createWithInsurance`, newData).respond(200, true);
|
|
||||||
$httpBackend.expectPOST(`creditClassifications/createWithInsurance`, newData);
|
|
||||||
controller.onSubmit();
|
|
||||||
$httpBackend.flush();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,68 +0,0 @@
|
||||||
<vn-data-viewer
|
|
||||||
data="$ctrl.classifications"
|
|
||||||
class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-md">
|
|
||||||
<vn-horizontal
|
|
||||||
ng-repeat="classification in $ctrl.classifications track by classification.id"
|
|
||||||
class="vn-pb-md insurance"
|
|
||||||
style="align-items: center;">
|
|
||||||
<vn-one
|
|
||||||
class="vn-pa-sm border-solid border-radius"
|
|
||||||
ng-class="{'item-hightlight': !classification.finished,'item-disabled': classification.finished}">
|
|
||||||
<vn-horizontal style="align-items: center;">
|
|
||||||
<vn-none class="vn-px-md">
|
|
||||||
<vn-icon-button
|
|
||||||
ng-if="!classification.finished"
|
|
||||||
icon="lock"
|
|
||||||
vn-tooltip="Close contract"
|
|
||||||
ng-click="$ctrl.closeContract(classification)">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-none>
|
|
||||||
<vn-one class="border-solid-right">
|
|
||||||
<div><vn-label translate>Since</vn-label> {{::classification.started | date:'dd/MM/yyyy'}}</div>
|
|
||||||
<div><vn-label translate>To</vn-label> {{classification.finished | date:'dd/MM/yyyy'}}</div>
|
|
||||||
</vn-one>
|
|
||||||
<vn-vertical vn-one class="vn-px-md">
|
|
||||||
<vn-horizontal ng-repeat="insurance in classification.insurances track by insurance.id">
|
|
||||||
<vn-one>
|
|
||||||
<vn-label-value label="Credit"
|
|
||||||
value="{{::insurance.credit}}">
|
|
||||||
</vn-label-value>
|
|
||||||
</vn-one>
|
|
||||||
<vn-one>
|
|
||||||
<vn-label-value label="Grade"
|
|
||||||
value="{{::insurance.grade}}">
|
|
||||||
</vn-label-value>
|
|
||||||
</vn-one>
|
|
||||||
<vn-one>
|
|
||||||
<vn-label-value label="Date"
|
|
||||||
value="{{::insurance.created | date:'dd/MM/yyyy' }}">
|
|
||||||
</vn-label-value>
|
|
||||||
</vn-one>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-vertical>
|
|
||||||
<a vn-auto ui-sref="client.card.creditInsurance.insurance.index({classificationId: {{classification.id}}})">
|
|
||||||
<vn-icon-button icon="preview" vn-tooltip="View credits"></vn-icon-button>
|
|
||||||
</a>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-one>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
</vn-data-viewer>
|
|
||||||
<vn-float-button
|
|
||||||
ng-if="$ctrl.canCreateNew()"
|
|
||||||
vn-acl="insurance"
|
|
||||||
vn-acl-action="remove"
|
|
||||||
vn-tooltip="New contract"
|
|
||||||
fixed-bottom-right
|
|
||||||
ui-sref="client.card.creditInsurance.create"
|
|
||||||
icon="add"
|
|
||||||
vn-bind="+"
|
|
||||||
label="Add">
|
|
||||||
</vn-float-button>
|
|
||||||
<vn-confirm
|
|
||||||
vn-id="close-contract"
|
|
||||||
on-accept="$ctrl.returnDialog()"
|
|
||||||
question="Close contract"
|
|
||||||
message="Are you sure you want to close this contract?">
|
|
||||||
</vn-confirm>
|
|
|
@ -1,68 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
$onChanges() {
|
|
||||||
if (this.client && this.client.id)
|
|
||||||
this._getClassifications(this.client.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
_getClassifications(clientId) {
|
|
||||||
let filter = {
|
|
||||||
order: 'finished ASC, started DESC',
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
relation: 'insurances',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'credit', 'created', 'grade'],
|
|
||||||
order: 'created DESC',
|
|
||||||
limit: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
],
|
|
||||||
where: {client: clientId}
|
|
||||||
};
|
|
||||||
filter = encodeURIComponent(JSON.stringify(filter));
|
|
||||||
|
|
||||||
let query = `CreditClassifications?filter=${filter}`;
|
|
||||||
this.$http.get(query).then(res => {
|
|
||||||
if (res.data)
|
|
||||||
this.classifications = res.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
canCreateNew() {
|
|
||||||
if (!this.classifications)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
let items = this.classifications;
|
|
||||||
for (let i = 0; i < items.length; i++) {
|
|
||||||
if (!items[i].finished)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
closeContract(classification) {
|
|
||||||
this.classificationId = classification.id;
|
|
||||||
this.$.closeContract.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
returnDialog() {
|
|
||||||
let params = {finished: Date.vnNow()};
|
|
||||||
this.$http.patch(`CreditClassifications/${this.classificationId}`, params).then(() => {
|
|
||||||
this._getClassifications(this.client.id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientCreditInsuranceIndex', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,88 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientCreditInsuranceIndex', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
let $scope;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_, $rootScope) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
const $element = angular.element('<vn-client-credit-insurance-index></vn-client-credit-insurance-index>');
|
|
||||||
controller = $componentController('vnClientCreditInsuranceIndex', {$element, $scope});
|
|
||||||
controller.client = {id: 1101};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('_getClassifications()', () => {
|
|
||||||
it('should perform a GET query to define the classifications property in the controller', () => {
|
|
||||||
let res = ['some classifications'];
|
|
||||||
let query = 'CreditClassifications?filter=%7B%22order%22%3A%22finished%20ASC%2C%20started%20DESC%22%2C%22include%22%3A%5B%7B%22relation%22%3A%22insurances%22%2C%22scope%22%3A%7B%22fields%22%3A%5B%22id%22%2C%22credit%22%2C%22created%22%2C%22grade%22%5D%2C%22order%22%3A%22created%20DESC%22%2C%22limit%22%3A2%7D%7D%5D%2C%22where%22%3A%7B%7D%7D';
|
|
||||||
|
|
||||||
$httpBackend.whenGET(query).respond(res);
|
|
||||||
$httpBackend.expectGET(query);
|
|
||||||
controller._getClassifications();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.classifications).toEqual(['some classifications']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('canCreateNew()', () => {
|
|
||||||
it(`should return false if doesn't have classifications`, () => {
|
|
||||||
let result = controller.canCreateNew();
|
|
||||||
|
|
||||||
expect(result).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should return false if finds a classification without due date`, () => {
|
|
||||||
controller.classifications = [
|
|
||||||
{finished: Date.vnNow()},
|
|
||||||
{finished: null}
|
|
||||||
];
|
|
||||||
|
|
||||||
let result = controller.canCreateNew();
|
|
||||||
|
|
||||||
expect(result).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should return true if all classifications are defined with due date`, () => {
|
|
||||||
controller.classifications = [
|
|
||||||
{finished: Date.vnNow()},
|
|
||||||
{finished: Date.vnNow()}
|
|
||||||
];
|
|
||||||
|
|
||||||
let result = controller.canCreateNew();
|
|
||||||
|
|
||||||
expect(result).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('closeContract()', () => {
|
|
||||||
it('should define the classificationId property of the controller and then call the show method()', () => {
|
|
||||||
controller.$.closeContract = {show: () => {}};
|
|
||||||
jest.spyOn(controller.$.closeContract, 'show');
|
|
||||||
|
|
||||||
expect(controller.classificationId).toBeFalsy();
|
|
||||||
controller.closeContract({id: 1});
|
|
||||||
|
|
||||||
expect(controller.classificationId).toEqual(1);
|
|
||||||
expect(controller.$.closeContract.show).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('returnDialog()', () => {
|
|
||||||
it('should call the returnDialog method and perform a PATCH query, then call _getClassifications method', () => {
|
|
||||||
jest.spyOn(controller, '_getClassifications').mockReturnThis();
|
|
||||||
controller.classificationId = 1;
|
|
||||||
$httpBackend.expect('PATCH', `CreditClassifications/1`).respond(200);
|
|
||||||
controller.returnDialog();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller._getClassifications).toHaveBeenCalledWith(1101);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,4 +0,0 @@
|
||||||
Contract credit insurance: Contratos de seguro de crédito
|
|
||||||
Close contract: Cerrar contrato
|
|
||||||
View credits: Ver créditos
|
|
||||||
Are you sure you want to close this contract?: ¿Seguro que quieres cerrar este contrato?
|
|
|
@ -1,5 +0,0 @@
|
||||||
vn-client-credit-insurance-index{
|
|
||||||
.insurance:last-child {
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
url="CreditClassifications/{{$ctrl.$params.classificationId}}/insurances"
|
|
||||||
data="$ctrl.insurance"
|
|
||||||
insert-mode="true"
|
|
||||||
form="form">
|
|
||||||
</vn-watcher>
|
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-input-number
|
|
||||||
min="0"
|
|
||||||
label="Credit"
|
|
||||||
ng-model="$ctrl.insurance.credit"
|
|
||||||
rule="CreditInsurance"
|
|
||||||
vn-focus>
|
|
||||||
</vn-input-number>
|
|
||||||
<vn-date-picker
|
|
||||||
label="Date"
|
|
||||||
ng-model="$ctrl.insurance.created">
|
|
||||||
</vn-date-picker>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-input-number
|
|
||||||
min="0"
|
|
||||||
step="1"
|
|
||||||
label="Grade"
|
|
||||||
ng-model="$ctrl.insurance.grade"
|
|
||||||
rule="CreditInsurance">
|
|
||||||
</vn-input-number>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit label="Save"></vn-submit>
|
|
||||||
<vn-button
|
|
||||||
label="Cancel"
|
|
||||||
ui-sref="client.card.creditInsurance.insurance.index({classificationId: $ctrl.$params.classificationId})">
|
|
||||||
</vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</form>
|
|
|
@ -1,33 +0,0 @@
|
||||||
import ngModule from '../../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
this.insurance = {
|
|
||||||
created: this.$filter('date')(Date.vnNew(), 'yyyy-MM-dd HH:mm:ss')
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
let params = {classificationId: this.$params.classificationId};
|
|
||||||
let state = 'client.card.creditInsurance.insurance.index';
|
|
||||||
|
|
||||||
this.$.watcher.submitGo(state, params).then(() => {
|
|
||||||
this.card.reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientCreditInsuranceInsuranceCreate', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
require: {
|
|
||||||
card: '^vnClientCard'
|
|
||||||
},
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,40 +0,0 @@
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="CreditInsurances"
|
|
||||||
link="{creditClassificationFk: $ctrl.$params.classificationId}"
|
|
||||||
limit="20"
|
|
||||||
data="insurances"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<div class="vn-w-xs">
|
|
||||||
<vn-data-viewer model="model">
|
|
||||||
<vn-card>
|
|
||||||
<vn-table model="model">
|
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th>Created</vn-th>
|
|
||||||
<vn-th number>Grade</vn-th>
|
|
||||||
<vn-th number>Credit</vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr ng-repeat="insurance in insurances">
|
|
||||||
<vn-td>{{::insurance.created | date: 'dd/MM/yyyy'}}</vn-td>
|
|
||||||
<vn-td number>{{::insurance.grade}}</vn-td>
|
|
||||||
<vn-td number>{{::insurance.credit | currency: 'EUR': 2}}</vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
</vn-card>
|
|
||||||
</vn-data-viewer>
|
|
||||||
</div>
|
|
||||||
<a
|
|
||||||
ng-if="!$ctrl.isClosed"
|
|
||||||
vn-acl="insurance"
|
|
||||||
vn-acl-action="remove"
|
|
||||||
ui-sref="client.card.creditInsurance.insurance.create({classificationId: {{$ctrl.$params.classificationId}}})"
|
|
||||||
fixed-bottom-right
|
|
||||||
vn-tooltip="New credit"
|
|
||||||
vn-bind="+">
|
|
||||||
<vn-float-button icon="add"></vn-float-button>
|
|
||||||
</a>
|
|
|
@ -1,38 +0,0 @@
|
||||||
import ngModule from '../../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
this.isClosed = true;
|
|
||||||
this.filter = {
|
|
||||||
include: [
|
|
||||||
{relation: 'classification'}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
$onInit() {
|
|
||||||
let filter = {
|
|
||||||
fields: ['finished'],
|
|
||||||
where: {id: this.$params.classificationId}
|
|
||||||
};
|
|
||||||
filter = encodeURIComponent(JSON.stringify(filter));
|
|
||||||
|
|
||||||
let query = `CreditClassifications?filter=${filter}`;
|
|
||||||
this.$http.get(query).then(res => {
|
|
||||||
if (res.data)
|
|
||||||
this.isClosed = res.data[0].finished != null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientCreditInsuranceInsuranceIndex', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,33 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientCreditInsuranceInsuranceIndex', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
let $scope;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_, $rootScope) => {
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
const $element = angular.element('<vn-client-credit-insurance-insurance-index></vn-client-credit-insurance-insurance-index>');
|
|
||||||
controller = $componentController('vnClientCreditInsuranceInsuranceIndex', {$element, $scope});
|
|
||||||
controller.$params = {classificationId: 1};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('$onInit()', () => {
|
|
||||||
it('should perform a query to GET credit the credit classification', () => {
|
|
||||||
let res = [{finished: 'some value'}];
|
|
||||||
let query = 'CreditClassifications?filter=%7B%22fields%22%3A%5B%22finished%22%5D%2C%22where%22%3A%7B%22id%22%3A1%7D%7D';
|
|
||||||
|
|
||||||
$httpBackend.whenGET(query).respond(res);
|
|
||||||
$httpBackend.expectGET(query);
|
|
||||||
controller.$onInit();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.isClosed).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1 +0,0 @@
|
||||||
Created: Creado
|
|
|
@ -1,79 +0,0 @@
|
||||||
<mg-ajax path="Clients/{{post.params.id}}/setRating" options="vnPost"></mg-ajax>
|
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
url="Clients"
|
|
||||||
data="$ctrl.client"
|
|
||||||
id-value="$ctrl.$params.id"
|
|
||||||
insert-mode="true"
|
|
||||||
form="form"
|
|
||||||
save="post">
|
|
||||||
</vn-watcher>
|
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-input-number
|
|
||||||
vn-one
|
|
||||||
label="Rating"
|
|
||||||
ng-model="$ctrl.client.rating"
|
|
||||||
vn-focus
|
|
||||||
rule>
|
|
||||||
</vn-input-number>
|
|
||||||
<vn-input-number
|
|
||||||
vn-one
|
|
||||||
label="Recommended credit"
|
|
||||||
ng-model="$ctrl.client.recommendedCredit"
|
|
||||||
rule>
|
|
||||||
</vn-input-number>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit
|
|
||||||
disabled="!watcher.dataChanged()"
|
|
||||||
label="Save">
|
|
||||||
</vn-submit>
|
|
||||||
</vn-button-bar>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="ClientInformas"
|
|
||||||
filter="$ctrl.filter"
|
|
||||||
link="{clientFk: $ctrl.$params.id}"
|
|
||||||
limit="20"
|
|
||||||
data="clientInformas"
|
|
||||||
order="created DESC"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-data-viewer
|
|
||||||
model="model"
|
|
||||||
class="vn-w-md">
|
|
||||||
<vn-card>
|
|
||||||
<vn-table model="model" class="vn-mt-lg">
|
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th shrink-date field="created">Since</vn-th>
|
|
||||||
<vn-th field="workerFk">Employee</vn-th>
|
|
||||||
<vn-th field="rating" number>Rating</vn-th>
|
|
||||||
<vn-th field="recommendedCredit" number>Recommended credit</vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr ng-repeat="clientInforma in clientInformas">
|
|
||||||
<vn-td shrink-datetime>{{::clientInforma.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<span
|
|
||||||
ng-click="workerDescriptor.show($event, clientInforma.workerFk)"
|
|
||||||
class="link">
|
|
||||||
{{::clientInforma.worker.user.nickname}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td number>{{::clientInforma.rating}}</vn-td>
|
|
||||||
<vn-td number>{{::clientInforma.recommendedCredit | currency: 'EUR'}}</vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
</vn-card>
|
|
||||||
</vn-data-viewer>
|
|
||||||
<vn-worker-descriptor-popover
|
|
||||||
vn-id="workerDescriptor">
|
|
||||||
</vn-worker-descriptor-popover>
|
|
|
@ -1,32 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
export default class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
|
|
||||||
this.filter = {
|
|
||||||
include: [{
|
|
||||||
relation: 'worker',
|
|
||||||
scope: {
|
|
||||||
fields: ['id'],
|
|
||||||
include: {
|
|
||||||
relation: 'user',
|
|
||||||
scope: {
|
|
||||||
fields: ['nickname']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
onSubmit() {
|
|
||||||
this.$.watcher.submit()
|
|
||||||
.then(() => this.$state.reload());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientCreditManagement', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,2 +0,0 @@
|
||||||
Recommended credit: Crédito recomendado
|
|
||||||
Rating: Clasificación
|
|
|
@ -1,37 +0,0 @@
|
||||||
<mg-ajax path="Clients/{{patch.params.id}}" options="vnPatch"></mg-ajax>
|
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
data="$ctrl.client"
|
|
||||||
form="form"
|
|
||||||
save="patch">
|
|
||||||
</vn-watcher>
|
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-input-number
|
|
||||||
vn-one
|
|
||||||
min="0"
|
|
||||||
label="Credit"
|
|
||||||
ng-model="$ctrl.client.credit"
|
|
||||||
vn-focus
|
|
||||||
rule>
|
|
||||||
</vn-input-number>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit
|
|
||||||
ng-if="watcher.dataChanged()"
|
|
||||||
label="Save">
|
|
||||||
</vn-submit>
|
|
||||||
<vn-button
|
|
||||||
ng-click="$ctrl.cancel()"
|
|
||||||
label="Cancel">
|
|
||||||
</vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</form>
|
|
||||||
<vn-confirm
|
|
||||||
vn-id="confirmation"
|
|
||||||
on-accept="$ctrl.returnDialog()"
|
|
||||||
question="Esta modificación retrasará el plazo del próximo recobro"
|
|
||||||
message="¿Desea continuar?">
|
|
||||||
</vn-confirm>
|
|
|
@ -1,42 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
onSubmit() {
|
|
||||||
this.$http.get(`Recoveries/${this.$params.id}/hasActiveRecovery`).then(res => {
|
|
||||||
let activeRecovery = res.data;
|
|
||||||
if (activeRecovery)
|
|
||||||
this.$.confirmation.show();
|
|
||||||
else
|
|
||||||
this.addCredit();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel() {
|
|
||||||
this.goToIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
returnDialog() {
|
|
||||||
this.addCredit();
|
|
||||||
}
|
|
||||||
|
|
||||||
goToIndex() {
|
|
||||||
this.$state.go('client.card.credit.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
addCredit() {
|
|
||||||
this.$.watcher.submit().then(
|
|
||||||
() => {
|
|
||||||
this.goToIndex();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientCreditCreate', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,94 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientCreditCreate', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
let $state;
|
|
||||||
let $scope;
|
|
||||||
let client;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_, $rootScope, _$state_) => {
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$scope.confirmation = {show: () => {
|
|
||||||
return {
|
|
||||||
then: () => {}
|
|
||||||
};
|
|
||||||
}};
|
|
||||||
$scope.watcher = {
|
|
||||||
submit: () => {
|
|
||||||
return {
|
|
||||||
then: callback => {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
client = {credit: 0};
|
|
||||||
$state = _$state_;
|
|
||||||
$state.params.id = 1101;
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
const $element = angular.element('<vn-client-credit-create></vn-client-credit-create>');
|
|
||||||
controller = $componentController('vnClientCreditCreate', {$element, $scope});
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('onSubmit()', () => {
|
|
||||||
it('should perform a query to check (GET) if the client has an active recovery', () => {
|
|
||||||
$httpBackend.whenGET(`Recoveries/1101/hasActiveRecovery`).respond(true);
|
|
||||||
$httpBackend.expectGET(`Recoveries/1101/hasActiveRecovery`);
|
|
||||||
controller.onSubmit();
|
|
||||||
$httpBackend.flush();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call show() method when the client have a recovery', () => {
|
|
||||||
jest.spyOn(controller.$.confirmation, 'show');
|
|
||||||
$httpBackend.whenGET(`Recoveries/1101/hasActiveRecovery`).respond(true);
|
|
||||||
$httpBackend.expectGET(`Recoveries/1101/hasActiveRecovery`);
|
|
||||||
controller.onSubmit();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.$.confirmation.show).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call addCredit() method when the client doesnt have a recovery', () => {
|
|
||||||
jest.spyOn(controller, 'addCredit');
|
|
||||||
$httpBackend.whenGET(`Recoveries/1101/hasActiveRecovery`).respond(false);
|
|
||||||
$httpBackend.expectGET(`Recoveries/1101/hasActiveRecovery`);
|
|
||||||
controller.onSubmit();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.addCredit).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('cancel()', () => {
|
|
||||||
it('should call goToIndex()', () => {
|
|
||||||
jest.spyOn(controller, 'goToIndex');
|
|
||||||
controller.cancel();
|
|
||||||
|
|
||||||
expect(controller.goToIndex).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('returnDialog()', () => {
|
|
||||||
it('should call addCredit() when is called with accept', () => {
|
|
||||||
jest.spyOn(controller, 'addCredit');
|
|
||||||
controller.returnDialog();
|
|
||||||
|
|
||||||
expect(controller.addCredit).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('addCredit()', () => {
|
|
||||||
it('should call the function go() on $state to go to the credit list', () => {
|
|
||||||
jest.spyOn($state, 'go');
|
|
||||||
client.credit = 1;
|
|
||||||
controller.addCredit();
|
|
||||||
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('client.card.credit.index');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,50 +0,0 @@
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="ClientCredits"
|
|
||||||
filter="::$ctrl.filter"
|
|
||||||
link="{clientFk: $ctrl.$params.id}"
|
|
||||||
limit="20"
|
|
||||||
data="credits"
|
|
||||||
order="created DESC"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-data-viewer
|
|
||||||
model="model"
|
|
||||||
class="vn-w-md">
|
|
||||||
<vn-card>
|
|
||||||
<vn-table model="model">
|
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th field="created">Since</vn-th>
|
|
||||||
<vn-th field="workerFk">Employee</vn-th>
|
|
||||||
<vn-th field="amount" number>Credit</vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr ng-repeat="credit in credits track by credit.id">
|
|
||||||
<vn-td shrink-datetime>{{::credit.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>
|
|
||||||
<vn-td>
|
|
||||||
<span
|
|
||||||
ng-click="workerDescriptor.show($event, credit.worker.id)"
|
|
||||||
class="link">
|
|
||||||
{{::credit.worker.user.name}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td number>{{::credit.amount | currency:'EUR':2}}</vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
</vn-card>
|
|
||||||
</vn-data-viewer>
|
|
||||||
<vn-float-button
|
|
||||||
icon="add"
|
|
||||||
ui-sref="client.card.credit.create"
|
|
||||||
vn-acl="teamBoss"
|
|
||||||
vn-acl-action="remove"
|
|
||||||
vn-tooltip="New credit"
|
|
||||||
vn-bind="+"
|
|
||||||
fixed-bottom-right>
|
|
||||||
</vn-float-button>
|
|
||||||
<vn-worker-descriptor-popover
|
|
||||||
vn-id="workerDescriptor">
|
|
||||||
</vn-worker-descriptor-popover>
|
|
|
@ -1,31 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
this.filter = {
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
relation: 'worker',
|
|
||||||
scope: {
|
|
||||||
fields: ['id'],
|
|
||||||
include: {
|
|
||||||
relation: 'user',
|
|
||||||
scope: {
|
|
||||||
fields: ['name']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientCreditIndex', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,2 +0,0 @@
|
||||||
Since : Desde
|
|
||||||
Employee : Empleado
|
|
|
@ -1,200 +0,0 @@
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="Defaulters/filter"
|
|
||||||
filter="::$ctrl.filter"
|
|
||||||
limit="20"
|
|
||||||
order="amount DESC"
|
|
||||||
data="$ctrl.defaulters"
|
|
||||||
on-data-change="$ctrl.reCheck()"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-portal slot="topbar">
|
|
||||||
<vn-searchbar
|
|
||||||
vn-focus
|
|
||||||
placeholder="Search client"
|
|
||||||
info="Search client by id or name"
|
|
||||||
auto-state="false"
|
|
||||||
model="model">
|
|
||||||
</vn-searchbar>
|
|
||||||
</vn-portal>
|
|
||||||
<vn-card>
|
|
||||||
<smart-table
|
|
||||||
model="model"
|
|
||||||
options="$ctrl.smartTableOptions"
|
|
||||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
|
||||||
<slot-actions>
|
|
||||||
<div>
|
|
||||||
<div class="totalBox" style="text-align: center;">
|
|
||||||
<h6 translate>Total</h6>
|
|
||||||
<vn-label-value
|
|
||||||
label="Balance due"
|
|
||||||
value="{{$ctrl.balanceDueTotal | currency: 'EUR': 2}}">
|
|
||||||
</vn-label-value>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="vn-pa-md">
|
|
||||||
<vn-button
|
|
||||||
disabled="$ctrl.checked.length == 0"
|
|
||||||
ng-click="notesDialog.show()"
|
|
||||||
name="notesDialog"
|
|
||||||
vn-tooltip="Add observation"
|
|
||||||
icon="icon-notes">
|
|
||||||
</vn-button>
|
|
||||||
</div>
|
|
||||||
</slot-actions>
|
|
||||||
<slot-table>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th shrink>
|
|
||||||
<vn-multi-check
|
|
||||||
model="model">
|
|
||||||
</vn-multi-check>
|
|
||||||
</th>
|
|
||||||
<th field="clientFk">
|
|
||||||
<span translate>Client</span>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<span translate>Es trabajador</span>
|
|
||||||
</th>
|
|
||||||
<th field="salesPersonFk">
|
|
||||||
<span translate>Comercial</span>
|
|
||||||
</th>
|
|
||||||
<th field="countryFk">
|
|
||||||
<span translate>Country</span>
|
|
||||||
</th>
|
|
||||||
<th field="payMethod"
|
|
||||||
vn-tooltip="Pay Method">
|
|
||||||
<span translate>P.Method</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
field="amount"
|
|
||||||
vn-tooltip="Balance due">
|
|
||||||
<span translate>Balance D.</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
field="workerFk"
|
|
||||||
vn-tooltip="Worker who made the last observation">
|
|
||||||
<span translate>Author</span>
|
|
||||||
</th>
|
|
||||||
<th field="observation" expand>
|
|
||||||
<span translate>Last observation</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
vn-tooltip="Last observation date"
|
|
||||||
field="created">
|
|
||||||
<span translate>L. O. Date</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
vn-tooltip="Credit insurance"
|
|
||||||
field="creditInsurance"
|
|
||||||
shrink>
|
|
||||||
<span translate>Credit I.</span>
|
|
||||||
</th>
|
|
||||||
<th field="defaulterSinced">
|
|
||||||
<span translate>From</span>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr ng-repeat="defaulter in $ctrl.defaulters">
|
|
||||||
<td shrink>
|
|
||||||
<vn-check
|
|
||||||
ng-model="defaulter.checked"
|
|
||||||
on-change="$ctrl.saveChecked(defaulter.clientFk)"
|
|
||||||
vn-click-stop>
|
|
||||||
</vn-check>
|
|
||||||
</td>
|
|
||||||
<td title="{{::defaulter.clientName}}">
|
|
||||||
<span
|
|
||||||
vn-click-stop="clientDescriptor.show($event, defaulter.clientFk)"
|
|
||||||
title ="{{::defaulter.clientName}}"
|
|
||||||
class="link">
|
|
||||||
{{::defaulter.clientName}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<vn-check
|
|
||||||
ng-model="defaulter.isWorker"
|
|
||||||
disabled="true">
|
|
||||||
</vn-check>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span
|
|
||||||
title="{{::defaulter.salesPersonName}}"
|
|
||||||
vn-click-stop="workerDescriptor.show($event, defaulter.salesPersonFk)"
|
|
||||||
class="link">
|
|
||||||
{{::defaulter.salesPersonName | dashIfEmpty}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{::defaulter.country}}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{::defaulter.payMethod}}
|
|
||||||
</td>
|
|
||||||
<td>{{::defaulter.amount | currency: 'EUR': 2}}</td>
|
|
||||||
<td>
|
|
||||||
<span
|
|
||||||
title="{{::defaulter.workerName}}"
|
|
||||||
vn-click-stop="workerDescriptor.show($event, defaulter.workerFk)"
|
|
||||||
class="link">
|
|
||||||
{{::defaulter.workerName | dashIfEmpty}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td expand>
|
|
||||||
<vn-textarea
|
|
||||||
vn-three
|
|
||||||
disabled="true"
|
|
||||||
ng-model="defaulter.observation">
|
|
||||||
</vn-textarea>
|
|
||||||
</td>
|
|
||||||
<td shrink-date>
|
|
||||||
<span class="chip {{::$ctrl.chipColor(defaulter.created)}}">
|
|
||||||
{{::defaulter.created | date: 'dd/MM/yyyy'}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td shrink>{{::defaulter.creditInsurance | currency: 'EUR': 2}}</td>
|
|
||||||
<td shrink-date>{{::defaulter.defaulterSinced | date: 'dd/MM/yyyy'}}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</slot-table>
|
|
||||||
</smart-table>
|
|
||||||
</vn-card>
|
|
||||||
<vn-client-descriptor-popover
|
|
||||||
vn-id="client-descriptor">
|
|
||||||
</vn-client-descriptor-popover>
|
|
||||||
<vn-worker-descriptor-popover
|
|
||||||
vn-id="worker-descriptor">
|
|
||||||
</vn-worker-descriptor-popover>
|
|
||||||
<vn-popup vn-id="dialog-summary-client">
|
|
||||||
<vn-client-summary
|
|
||||||
client="$ctrl.clientSelected">
|
|
||||||
</vn-client-summary>
|
|
||||||
</vn-popup>
|
|
||||||
|
|
||||||
<!-- Dialog of add notes button -->
|
|
||||||
<vn-dialog
|
|
||||||
vn-id="notesDialog"
|
|
||||||
on-accept="$ctrl.onResponse()">
|
|
||||||
<tpl-body>
|
|
||||||
<section class="SMSDialog">
|
|
||||||
<h5 class="vn-py-sm">{{$ctrl.$t('Add observation to all selected clients', {total: $ctrl.checked.length})}}</h5>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textarea vn-one
|
|
||||||
vn-id="message"
|
|
||||||
label="Message"
|
|
||||||
ng-model="$ctrl.defaulter.observation"
|
|
||||||
rows="3"
|
|
||||||
required="true"
|
|
||||||
rule>
|
|
||||||
</vn-textarea>
|
|
||||||
</vn-horizontal>
|
|
||||||
</section>
|
|
||||||
</tpl-body>
|
|
||||||
<tpl-buttons>
|
|
||||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
|
||||||
<button response="accept" translate>Save</button>
|
|
||||||
</tpl-buttons>
|
|
||||||
</vn-dialog>
|
|
|
@ -1,199 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import UserError from 'core/lib/user-error';
|
|
||||||
|
|
||||||
export default class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
this.defaulter = {};
|
|
||||||
this.defaulters = [];
|
|
||||||
this.checkedDefaulers = [];
|
|
||||||
|
|
||||||
this.smartTableOptions = {
|
|
||||||
activeButtons: {
|
|
||||||
search: true
|
|
||||||
},
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
field: 'clientFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'Clients',
|
|
||||||
showField: 'name',
|
|
||||||
valueField: 'id'
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
field: 'salesPersonFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'Workers/activeWithInheritedRole',
|
|
||||||
where: `{role: 'salesPerson'}`,
|
|
||||||
searchFunction: '{firstName: $search}',
|
|
||||||
showField: 'name',
|
|
||||||
valueField: 'id',
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
field: 'countryFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'Countries',
|
|
||||||
showField: 'country',
|
|
||||||
valueField: 'id'
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
field: 'payMethodFk',
|
|
||||||
autocomplete: {
|
|
||||||
showField: 'name',
|
|
||||||
valueField: 'id'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'workerFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'Workers/activeWithInheritedRole',
|
|
||||||
searchFunction: '{firstName: $search}',
|
|
||||||
showField: 'name',
|
|
||||||
valueField: 'id',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'observation',
|
|
||||||
searchable: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'created',
|
|
||||||
datepicker: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'defaulterSinced',
|
|
||||||
datepicker: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getBalanceDueTotal();
|
|
||||||
}
|
|
||||||
|
|
||||||
set defaulters(value) {
|
|
||||||
if (!value || !value.length) return;
|
|
||||||
for (let defaulter of value)
|
|
||||||
defaulter.isWorker = defaulter.businessTypeFk === 'worker';
|
|
||||||
|
|
||||||
this._defaulters = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get defaulters() {
|
|
||||||
return this._defaulters;
|
|
||||||
}
|
|
||||||
|
|
||||||
get checked() {
|
|
||||||
const clients = this.$.model.data || [];
|
|
||||||
const checkedLines = [];
|
|
||||||
for (let defaulter of clients) {
|
|
||||||
if (defaulter.checked)
|
|
||||||
checkedLines.push(defaulter);
|
|
||||||
}
|
|
||||||
|
|
||||||
return checkedLines;
|
|
||||||
}
|
|
||||||
|
|
||||||
saveChecked(clientId) {
|
|
||||||
this.checkedDefaulers = this.checkedDefaulers.includes(clientId) ?
|
|
||||||
this.checkedDefaulers.filter(id => id !== clientId) : [...this.checkedDefaulers, clientId];
|
|
||||||
}
|
|
||||||
|
|
||||||
reCheck() {
|
|
||||||
if (!this.$.model.data || !this.checkedDefaulers.length) return;
|
|
||||||
|
|
||||||
this.$.model.data.forEach(defaulter => {
|
|
||||||
defaulter.checked = this.checkedDefaulers.includes(defaulter.clientFk);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getBalanceDueTotal() {
|
|
||||||
this.$http.get('Defaulters/filter')
|
|
||||||
.then(res => {
|
|
||||||
if (!res.data) return 0;
|
|
||||||
|
|
||||||
this.balanceDueTotal = res.data.reduce(
|
|
||||||
(accumulator, currentValue) => {
|
|
||||||
return accumulator + (currentValue['amount'] || 0);
|
|
||||||
}, 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
chipColor(date) {
|
|
||||||
const day = 24 * 60 * 60 * 1000;
|
|
||||||
const today = Date.vnNew();
|
|
||||||
today.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
const observationShipped = new Date(date);
|
|
||||||
observationShipped.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
const difference = today - observationShipped;
|
|
||||||
|
|
||||||
if (difference > (day * 20))
|
|
||||||
return 'alert';
|
|
||||||
if (difference > (day * 10))
|
|
||||||
return 'warning';
|
|
||||||
}
|
|
||||||
|
|
||||||
onResponse() {
|
|
||||||
if (!this.defaulter.observation)
|
|
||||||
throw new UserError(`The message can't be empty`);
|
|
||||||
|
|
||||||
const params = [];
|
|
||||||
for (let defaulter of this.checked) {
|
|
||||||
params.push({
|
|
||||||
text: this.defaulter.observation,
|
|
||||||
clientFk: defaulter.clientFk
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$http.post(`ClientObservations`, params) .then(() => {
|
|
||||||
this.vnApp.showSuccess(this.$t('Observation saved!'));
|
|
||||||
this.sendMail();
|
|
||||||
this.$state.reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
sendMail() {
|
|
||||||
const params = {
|
|
||||||
defaulters: this.checked,
|
|
||||||
observation: this.defaulter.observation,
|
|
||||||
};
|
|
||||||
this.$http.post(`Defaulters/observationEmail`, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
exprBuilder(param, value) {
|
|
||||||
switch (param) {
|
|
||||||
case 'creditInsurance':
|
|
||||||
case 'amount':
|
|
||||||
case 'clientFk':
|
|
||||||
case 'workerFk':
|
|
||||||
case 'countryFk':
|
|
||||||
case 'payMethod':
|
|
||||||
case 'salesPersonFk':
|
|
||||||
return {[`d.${param}`]: value};
|
|
||||||
case 'created':
|
|
||||||
return {'d.created': {
|
|
||||||
between: this.dateRange(value)}
|
|
||||||
};
|
|
||||||
case 'defaulterSinced':
|
|
||||||
return {'d.defaulterSinced': {
|
|
||||||
between: this.dateRange(value)}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dateRange(value) {
|
|
||||||
const minHour = new Date(value);
|
|
||||||
minHour.setHours(0, 0, 0, 0);
|
|
||||||
const maxHour = new Date(value);
|
|
||||||
maxHour.setHours(23, 59, 59, 59);
|
|
||||||
|
|
||||||
return [minHour, maxHour];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientDefaulter', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,179 +0,0 @@
|
||||||
import './index';
|
|
||||||
import crudModel from 'core/mocks/crud-model';
|
|
||||||
|
|
||||||
describe('client defaulter', () => {
|
|
||||||
describe('Component vnClientDefaulter', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
const $element = angular.element('<vn-client-defaulter></vn-client-defaulter>');
|
|
||||||
controller = $componentController('vnClientDefaulter', {$element});
|
|
||||||
controller.$.model = crudModel;
|
|
||||||
controller.$.model.data = [
|
|
||||||
{clientFk: 1101, amount: 125},
|
|
||||||
{clientFk: 1102, amount: 500},
|
|
||||||
{clientFk: 1103, amount: 250}
|
|
||||||
];
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('checked() getter', () => {
|
|
||||||
it('should return the checked lines', () => {
|
|
||||||
const data = controller.$.model.data;
|
|
||||||
data[1].checked = true;
|
|
||||||
data[2].checked = true;
|
|
||||||
|
|
||||||
const checkedRows = controller.checked;
|
|
||||||
|
|
||||||
const firstCheckedRow = checkedRows[0];
|
|
||||||
const secondCheckedRow = checkedRows[1];
|
|
||||||
|
|
||||||
expect(firstCheckedRow.clientFk).toEqual(1102);
|
|
||||||
expect(secondCheckedRow.clientFk).toEqual(1103);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('chipColor()', () => {
|
|
||||||
it('should return undefined when the date is the present', () => {
|
|
||||||
let today = Date.vnNew();
|
|
||||||
let result = controller.chipColor(today);
|
|
||||||
|
|
||||||
expect(result).toEqual(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return warning when the date is 10 days in the past', () => {
|
|
||||||
let pastDate = Date.vnNew();
|
|
||||||
pastDate = pastDate.setDate(pastDate.getDate() - 11);
|
|
||||||
let result = controller.chipColor(pastDate);
|
|
||||||
|
|
||||||
expect(result).toEqual('warning');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return alert when the date is 20 days in the past', () => {
|
|
||||||
let pastDate = Date.vnNew();
|
|
||||||
pastDate = pastDate.setDate(pastDate.getDate() - 21);
|
|
||||||
let result = controller.chipColor(pastDate);
|
|
||||||
|
|
||||||
expect(result).toEqual('alert');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onResponse()', () => {
|
|
||||||
it('should return error for empty message', () => {
|
|
||||||
let error;
|
|
||||||
try {
|
|
||||||
controller.onResponse();
|
|
||||||
} catch (e) {
|
|
||||||
error = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(error).toBeDefined();
|
|
||||||
expect(error.message).toBe(`The message can't be empty`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return saved message', () => {
|
|
||||||
const data = controller.$.model.data;
|
|
||||||
data[1].checked = true;
|
|
||||||
controller.defaulter = {observation: 'My new observation'};
|
|
||||||
|
|
||||||
const params = [{text: controller.defaulter.observation, clientFk: data[1].clientFk}];
|
|
||||||
|
|
||||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
|
||||||
$httpBackend.expect('GET', `Defaulters/filter`).respond(200);
|
|
||||||
$httpBackend.expect('POST', `ClientObservations`, params).respond(200, params);
|
|
||||||
$httpBackend.expect('POST', `Defaulters/observationEmail`).respond(200);
|
|
||||||
|
|
||||||
controller.onResponse();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Observation saved!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('exprBuilder()', () => {
|
|
||||||
it('should search by sales person', () => {
|
|
||||||
const expr = controller.exprBuilder('salesPersonFk', '5');
|
|
||||||
|
|
||||||
expect(expr).toEqual({'d.salesPersonFk': '5'});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should search by client', () => {
|
|
||||||
const expr = controller.exprBuilder('clientFk', '5');
|
|
||||||
|
|
||||||
expect(expr).toEqual({'d.clientFk': '5'});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getBalanceDueTotal()', () => {
|
|
||||||
it('should return balance due total', () => {
|
|
||||||
const defaulters = controller.$.model.data;
|
|
||||||
$httpBackend.when('GET', `Defaulters/filter`).respond(defaulters);
|
|
||||||
|
|
||||||
controller.getBalanceDueTotal();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.balanceDueTotal).toEqual(875);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('dateRange()', () => {
|
|
||||||
it('should return two dates with the hours at the start and end of the given date', () => {
|
|
||||||
const now = Date.vnNew();
|
|
||||||
|
|
||||||
const today = now.getDate();
|
|
||||||
|
|
||||||
const dateRange = controller.dateRange(now);
|
|
||||||
const start = dateRange[0].toString();
|
|
||||||
const end = dateRange[1].toString();
|
|
||||||
|
|
||||||
expect(start).toContain(today);
|
|
||||||
expect(start).toContain('00:00:00');
|
|
||||||
|
|
||||||
expect(end).toContain(today);
|
|
||||||
expect(end).toContain('23:59:59');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('reCheck()', () => {
|
|
||||||
it(`should recheck buys`, () => {
|
|
||||||
controller.$.model.data = [
|
|
||||||
{checked: false, clientFk: 1},
|
|
||||||
{checked: false, clientFk: 2},
|
|
||||||
{checked: false, clientFk: 3},
|
|
||||||
{checked: false, clientFk: 4},
|
|
||||||
];
|
|
||||||
controller.checkedDefaulers = [1, 2];
|
|
||||||
|
|
||||||
controller.reCheck();
|
|
||||||
|
|
||||||
expect(controller.$.model.data[0].checked).toEqual(true);
|
|
||||||
expect(controller.$.model.data[1].checked).toEqual(true);
|
|
||||||
expect(controller.$.model.data[2].checked).toEqual(false);
|
|
||||||
expect(controller.$.model.data[3].checked).toEqual(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('saveChecked()', () => {
|
|
||||||
it(`should check buy`, () => {
|
|
||||||
const buyCheck = 3;
|
|
||||||
controller.checkedDefaulers = [1, 2];
|
|
||||||
|
|
||||||
controller.saveChecked(buyCheck);
|
|
||||||
|
|
||||||
expect(controller.checkedDefaulers[2]).toEqual(buyCheck);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should uncheck buy`, () => {
|
|
||||||
const buyUncheck = 3;
|
|
||||||
controller.checkedDefaulers = [1, 2, 3];
|
|
||||||
|
|
||||||
controller.saveChecked(buyUncheck);
|
|
||||||
|
|
||||||
expect(controller.checkedDefaulers[2]).toEqual(undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,14 +0,0 @@
|
||||||
Add observation: Añadir observación
|
|
||||||
Add observation to all selected clients: Añadir observación a {{total}} cliente(s) seleccionado(s)
|
|
||||||
Balance D.: Saldo V.
|
|
||||||
Credit I.: Crédito A.
|
|
||||||
Last observation: Última observación
|
|
||||||
L. O. Date: Fecha Ú. O.
|
|
||||||
Last observation date: Fecha última observación
|
|
||||||
Search client: Buscar clientes
|
|
||||||
Worker who made the last observation: Trabajador que ha realizado la última observación
|
|
||||||
Email sended!: Email enviado!
|
|
||||||
Observation saved!: Observación añadida!
|
|
||||||
P.Method: F.Pago
|
|
||||||
Pay Method: Forma de Pago
|
|
||||||
Country: Pais
|
|
|
@ -1,3 +0,0 @@
|
||||||
<slot-descriptor>
|
|
||||||
<vn-client-descriptor></vn-client-descriptor>
|
|
||||||
</slot-descriptor>
|
|
|
@ -1,9 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import DescriptorPopover from 'salix/components/descriptor-popover';
|
|
||||||
|
|
||||||
class Controller extends DescriptorPopover {}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientDescriptorPopover', {
|
|
||||||
slotTemplate: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,136 +0,0 @@
|
||||||
<vn-descriptor-content
|
|
||||||
module="client"
|
|
||||||
description="$ctrl.client.name"
|
|
||||||
summary="$ctrl.$.summary">
|
|
||||||
<slot-menu>
|
|
||||||
<a class="vn-item"
|
|
||||||
ui-sref="ticket.create({clientFk: $ctrl.client.id})"
|
|
||||||
name="simpleTicket"
|
|
||||||
translate>
|
|
||||||
Simple ticket
|
|
||||||
</a>
|
|
||||||
<vn-item
|
|
||||||
ng-click="$ctrl.showSMSDialog()"
|
|
||||||
translate>
|
|
||||||
Send SMS
|
|
||||||
</vn-item>
|
|
||||||
</slot-menu>
|
|
||||||
<slot-body>
|
|
||||||
<div class="attributes">
|
|
||||||
<vn-label-value
|
|
||||||
label="Pay method"
|
|
||||||
value="{{$ctrl.client.payMethod.name}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Credit"
|
|
||||||
value="{{$ctrl.client.credit | currency: 'EUR': 2}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Secured credit"
|
|
||||||
value="{{$ctrl.client.creditInsurance | currency: 'EUR': 2}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Risk"
|
|
||||||
value="{{$ctrl.client.debt | currency: 'EUR':2}}"
|
|
||||||
ng-class="{alert: $ctrl.client.debt > $ctrl.client.credit}"
|
|
||||||
info="Invoices minus payments plus orders not yet invoiced">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Sales person">
|
|
||||||
<span
|
|
||||||
ng-click="workerDescriptor.show($event, $ctrl.client.salesPersonFk)"
|
|
||||||
class="link">
|
|
||||||
{{$ctrl.client.salesPersonUser.name}}
|
|
||||||
</span>
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Business type"
|
|
||||||
value="{{$ctrl.client.businessType.description}}">
|
|
||||||
</vn-label-value>
|
|
||||||
</div>
|
|
||||||
<div class="icons">
|
|
||||||
<vn-icon
|
|
||||||
vn-tooltip="Client inactive"
|
|
||||||
icon="icon-disabled"
|
|
||||||
ng-if="$ctrl.client.isActive == false">
|
|
||||||
</vn-icon>
|
|
||||||
<vn-icon
|
|
||||||
vn-tooltip="Client frozen"
|
|
||||||
icon="icon-frozen"
|
|
||||||
ng-if="$ctrl.client.isFreezed == true">
|
|
||||||
</vn-icon>
|
|
||||||
<vn-icon
|
|
||||||
vn-tooltip="Web Account inactive"
|
|
||||||
icon="icon-noweb"
|
|
||||||
ng-if="$ctrl.client.account.active == false">
|
|
||||||
</vn-icon>
|
|
||||||
<vn-icon
|
|
||||||
vn-tooltip="Client has debt"
|
|
||||||
icon="icon-risk"
|
|
||||||
ng-if="$ctrl.client.debt > $ctrl.client.credit">
|
|
||||||
</vn-icon>
|
|
||||||
<vn-icon
|
|
||||||
vn-tooltip="Client not checked"
|
|
||||||
icon="icon-no036"
|
|
||||||
ng-if="$ctrl.client.isTaxDataChecked == false">
|
|
||||||
</vn-icon>
|
|
||||||
<vn-icon-button
|
|
||||||
vn-tooltip="{{$ctrl.clientUnpaid()}}"
|
|
||||||
icon="icon-clientUnpaid"
|
|
||||||
ui-sref="client.card.unpaid"
|
|
||||||
ng-if="$ctrl.client.unpaid">
|
|
||||||
</vn-icon-button>
|
|
||||||
</div>
|
|
||||||
<div class="quicklinks">
|
|
||||||
<div ng-transclude="btnOne">
|
|
||||||
<vn-quick-link
|
|
||||||
tooltip="Client ticket list"
|
|
||||||
state="['ticket.index', {q: $ctrl.filter}]"
|
|
||||||
icon="icon-ticket">
|
|
||||||
</vn-quick-link>
|
|
||||||
</div>
|
|
||||||
<div ng-transclude="btnTwo">
|
|
||||||
<vn-quick-link
|
|
||||||
tooltip="Client invoices list"
|
|
||||||
state="['invoiceOut.index', {q: $ctrl.filter}]"
|
|
||||||
icon="icon-invoice">
|
|
||||||
</vn-quick-link>
|
|
||||||
</div>
|
|
||||||
<div ng-transclude="btnThree">
|
|
||||||
<vn-quick-link
|
|
||||||
tooltip="New order"
|
|
||||||
state="['order.create', {clientFk: $ctrl.id}]"
|
|
||||||
icon="icon-basketadd">
|
|
||||||
</vn-quick-link>
|
|
||||||
</div>
|
|
||||||
<div ng-transclude="btnFour">
|
|
||||||
<vn-quick-link
|
|
||||||
vn-acl="hr"
|
|
||||||
vn-acl-action="remove"
|
|
||||||
tooltip="Go to user"
|
|
||||||
state="['account.card.summary', {id: $ctrl.id}]"
|
|
||||||
icon="face">
|
|
||||||
</vn-quick-link>
|
|
||||||
</div>
|
|
||||||
<div ng-transclude="btnFive">
|
|
||||||
<vn-quick-link
|
|
||||||
ng-if="$ctrl.client.supplier.nif"
|
|
||||||
tooltip="Go to supplier"
|
|
||||||
state="['supplier.card.summary', {id: $ctrl.client.supplier.id}]"
|
|
||||||
icon="icon-supplier">
|
|
||||||
</vn-quick-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</slot-body>
|
|
||||||
</vn-descriptor-content>
|
|
||||||
<vn-sms-dialog
|
|
||||||
vn-id="sms"
|
|
||||||
on-send="$ctrl.onSmsSend($sms)"
|
|
||||||
sms="$ctrl.newSMS">
|
|
||||||
</vn-sms-dialog>
|
|
||||||
<vn-worker-descriptor-popover
|
|
||||||
vn-id="workerDescriptor">
|
|
||||||
</vn-worker-descriptor-popover>
|
|
||||||
<vn-popup vn-id="summary">
|
|
||||||
<vn-client-summary client="$ctrl.client"></vn-client-summary>
|
|
||||||
</vn-popup>
|
|
|
@ -1,61 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Descriptor from 'salix/components/descriptor';
|
|
||||||
|
|
||||||
class Controller extends Descriptor {
|
|
||||||
get entity() {
|
|
||||||
return super.entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
set entity(value) {
|
|
||||||
super.entity = value;
|
|
||||||
|
|
||||||
if (value && this.$params.sendSMS)
|
|
||||||
this.showSMSDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
get client() {
|
|
||||||
return this.entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
set client(value) {
|
|
||||||
this.entity = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get filter() {
|
|
||||||
return JSON.stringify({clientFk: this.id});
|
|
||||||
}
|
|
||||||
|
|
||||||
loadData() {
|
|
||||||
return this.getData(`Clients/${this.id}/getCard`)
|
|
||||||
.then(res => this.entity = res.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
showSMSDialog() {
|
|
||||||
const client = this.client || {};
|
|
||||||
this.newSMS = {
|
|
||||||
destinationFk: this.id,
|
|
||||||
destination: this.$params.phone || client.mobile || client.phone,
|
|
||||||
message: this.$params.message || ''
|
|
||||||
};
|
|
||||||
this.$.sms.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
onSmsSend(sms) {
|
|
||||||
return this.$http.post(`Clients/${this.id}/sendSms`, sms)
|
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('SMS sent')));
|
|
||||||
}
|
|
||||||
|
|
||||||
clientUnpaid() {
|
|
||||||
return this.$t(`Unpaid`) + '<br/>'
|
|
||||||
+ this.$t(`Unpaid Dated`, {dated: this.client.unpaid.dated}) + '<br/>'
|
|
||||||
+ this.$t(`Unpaid Amount`, {amount: this.client.unpaid.amount});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientDescriptor', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,26 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('vnClientDescriptor', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
controller = $componentController('vnClientDescriptor', {$element: null});
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('loadData()', () => {
|
|
||||||
it(`should perform a get query to store the client data into the controller`, () => {
|
|
||||||
const id = 1;
|
|
||||||
const response = 'foo';
|
|
||||||
|
|
||||||
$httpBackend.expectGET(`Clients/${id}/getCard`).respond(response);
|
|
||||||
controller.id = id;
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.client).toEqual(response);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,11 +0,0 @@
|
||||||
Simple ticket: Ticket simple
|
|
||||||
View consumer report: Ver informe de consumo
|
|
||||||
From date: Fecha desde
|
|
||||||
To date: Fecha hasta
|
|
||||||
Go to user: Ir al usuario
|
|
||||||
Go to supplier: Ir al proveedor
|
|
||||||
Client invoices list: Listado de facturas del cliente
|
|
||||||
Pay method: Forma de pago
|
|
||||||
Unpaid Dated: "Fecha: {{dated | date:'dd/MM/yyyy'}}"
|
|
||||||
Unpaid Amount: "Importe: {{amount | currency: 'EUR':2}}"
|
|
||||||
Business type: Tipo de negocio
|
|
|
@ -1,108 +0,0 @@
|
||||||
<mg-ajax path="dms/upload" options="vnPost"></mg-ajax>
|
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
data="$ctrl.dms">
|
|
||||||
</vn-watcher>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="Companies"
|
|
||||||
data="companies"
|
|
||||||
order="code">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="Warehouses"
|
|
||||||
data="warehouses"
|
|
||||||
order="name">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="DmsTypes"
|
|
||||||
data="dmsTypes"
|
|
||||||
order="name">
|
|
||||||
</vn-crud-model>
|
|
||||||
<form
|
|
||||||
name="form"
|
|
||||||
ng-submit="$ctrl.onSubmit()"
|
|
||||||
class="vn-ma-md"
|
|
||||||
enctype="multipart/form-data">
|
|
||||||
<div class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
vn-focus
|
|
||||||
label="Reference"
|
|
||||||
ng-model="$ctrl.dms.reference"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Company"
|
|
||||||
ng-model="$ctrl.dms.companyId"
|
|
||||||
data="companies"
|
|
||||||
show-field="code"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Warehouse"
|
|
||||||
ng-model="$ctrl.dms.warehouseId"
|
|
||||||
data="warehouses"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Type"
|
|
||||||
ng-model="$ctrl.dms.dmsTypeId"
|
|
||||||
data="dmsTypes"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textarea
|
|
||||||
vn-one
|
|
||||||
label="Description"
|
|
||||||
ng-model="$ctrl.dms.description"
|
|
||||||
rule>
|
|
||||||
</vn-textarea>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-input-file
|
|
||||||
vn-one
|
|
||||||
label="File"
|
|
||||||
ng-model="$ctrl.dms.files"
|
|
||||||
on-change="$ctrl.onFileChange($files)"
|
|
||||||
accept="{{$ctrl.allowedContentTypes}}"
|
|
||||||
required="true"
|
|
||||||
multiple="true">
|
|
||||||
<append>
|
|
||||||
<vn-icon vn-none
|
|
||||||
color-marginal
|
|
||||||
title="{{$ctrl.contentTypesInfo}}"
|
|
||||||
icon="info">
|
|
||||||
</vn-icon>
|
|
||||||
</append>
|
|
||||||
</vn-input-file>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-vertical>
|
|
||||||
<vn-check
|
|
||||||
label="Generate identifier for original file"
|
|
||||||
ng-model="$ctrl.dms.hasFile">
|
|
||||||
</vn-check>
|
|
||||||
</vn-vertical>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit
|
|
||||||
disabled="!watcher.dataChanged()"
|
|
||||||
label="Upload">
|
|
||||||
</vn-submit>
|
|
||||||
<vn-button
|
|
||||||
class="cancel"
|
|
||||||
label="Cancel"
|
|
||||||
ui-sref="client.card.dms.index">
|
|
||||||
</vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
|
@ -1,113 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
this.dms = {
|
|
||||||
files: [],
|
|
||||||
hasFile: false,
|
|
||||||
hasFileAttached: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get client() {
|
|
||||||
return this._client;
|
|
||||||
}
|
|
||||||
|
|
||||||
set client(value) {
|
|
||||||
this._client = value;
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
this.setDefaultParams();
|
|
||||||
this.getAllowedContentTypes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getAllowedContentTypes() {
|
|
||||||
this.$http.get('DmsContainers/allowedContentTypes').then(res => {
|
|
||||||
const contentTypes = res.data.join(', ');
|
|
||||||
this.allowedContentTypes = contentTypes;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get contentTypesInfo() {
|
|
||||||
return this.$t('ContentTypesInfo', {
|
|
||||||
allowedContentTypes: this.allowedContentTypes
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setDefaultParams() {
|
|
||||||
const params = {filter: {
|
|
||||||
where: {code: 'paymentsLaw'}
|
|
||||||
}};
|
|
||||||
this.$http.get('DmsTypes/findOne', {params}).then(res => {
|
|
||||||
const dmsType = res.data && res.data;
|
|
||||||
const companyId = this.vnConfig.companyFk;
|
|
||||||
const warehouseId = this.vnConfig.warehouseFk;
|
|
||||||
const defaultParams = {
|
|
||||||
reference: this.client.id,
|
|
||||||
warehouseId: warehouseId,
|
|
||||||
companyId: companyId,
|
|
||||||
dmsTypeId: dmsType.id,
|
|
||||||
description: this.$t('ClientFileDescription', {
|
|
||||||
dmsTypeName: dmsType.name,
|
|
||||||
clientId: this.client.id,
|
|
||||||
clientName: this.client.name
|
|
||||||
}).toUpperCase()
|
|
||||||
};
|
|
||||||
|
|
||||||
this.dms = Object.assign(this.dms, defaultParams);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
const query = `clients/${this.client.id}/uploadFile`;
|
|
||||||
const options = {
|
|
||||||
method: 'POST',
|
|
||||||
url: query,
|
|
||||||
params: this.dms,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': undefined
|
|
||||||
},
|
|
||||||
transformRequest: files => {
|
|
||||||
const formData = new FormData();
|
|
||||||
|
|
||||||
for (let i = 0; i < files.length; i++)
|
|
||||||
formData.append(files[i].name, files[i]);
|
|
||||||
|
|
||||||
return formData;
|
|
||||||
},
|
|
||||||
data: this.dms.files
|
|
||||||
};
|
|
||||||
this.$http(options).then(res => {
|
|
||||||
if (res) {
|
|
||||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
|
||||||
this.$.watcher.updateOriginalData();
|
|
||||||
this.$state.go('client.card.dms.index');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onFileChange(files) {
|
|
||||||
let hasFileAttached = false;
|
|
||||||
|
|
||||||
if (files.length > 0)
|
|
||||||
hasFileAttached = true;
|
|
||||||
|
|
||||||
this.$.$applyAsync(() => {
|
|
||||||
this.dms.hasFileAttached = hasFileAttached;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientDmsCreate', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,74 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientDmsCreate', () => {
|
|
||||||
let controller;
|
|
||||||
let $scope;
|
|
||||||
let $httpBackend;
|
|
||||||
let $httpParamSerializer;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$httpParamSerializer = _$httpParamSerializer_;
|
|
||||||
const $element = angular.element('<vn-client-create></vn-client-create>');
|
|
||||||
controller = $componentController('vnClientDmsCreate', {$element, $scope});
|
|
||||||
controller._client = {id: 1101, name: 'Bruce wayne'};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('client() setter', () => {
|
|
||||||
it('should set the client data and then call setDefaultParams() and getAllowedContentTypes()', () => {
|
|
||||||
jest.spyOn(controller, 'setDefaultParams');
|
|
||||||
jest.spyOn(controller, 'getAllowedContentTypes');
|
|
||||||
controller.client = {
|
|
||||||
id: 15,
|
|
||||||
name: 'Bruce wayne'
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.client).toBeDefined();
|
|
||||||
expect(controller.setDefaultParams).toHaveBeenCalledWith();
|
|
||||||
expect(controller.getAllowedContentTypes).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('setDefaultParams()', () => {
|
|
||||||
it('should perform a GET query and define the dms property on controller', () => {
|
|
||||||
const params = {filter: {
|
|
||||||
where: {code: 'paymentsLaw'}
|
|
||||||
}};
|
|
||||||
let serializedParams = $httpParamSerializer(params);
|
|
||||||
$httpBackend.expect('GET', `DmsTypes/findOne?${serializedParams}`).respond({id: 12, code: 'paymentsLaw'});
|
|
||||||
controller.setDefaultParams();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.dms).toBeDefined();
|
|
||||||
expect(controller.dms.reference).toEqual(1101);
|
|
||||||
expect(controller.dms.dmsTypeId).toEqual(12);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onFileChange()', () => {
|
|
||||||
it('should set dms hasFileAttached property to true if has any files', () => {
|
|
||||||
const files = [{id: 1, name: 'MyFile'}];
|
|
||||||
controller.onFileChange(files);
|
|
||||||
$scope.$apply();
|
|
||||||
|
|
||||||
expect(controller.dms.hasFileAttached).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getAllowedContentTypes()', () => {
|
|
||||||
it('should make an HTTP GET request to get the allowed content types', () => {
|
|
||||||
const expectedResponse = ['image/png', 'image/jpg'];
|
|
||||||
$httpBackend.expect('GET', `DmsContainers/allowedContentTypes`).respond(expectedResponse);
|
|
||||||
controller.getAllowedContentTypes();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.allowedContentTypes).toBeDefined();
|
|
||||||
expect(controller.allowedContentTypes).toEqual('image/png, image/jpg');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,7 +0,0 @@
|
||||||
vn-ticket-request {
|
|
||||||
.vn-textfield {
|
|
||||||
margin: 0!important;
|
|
||||||
max-width: 100px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
data="$ctrl.dms">
|
|
||||||
</vn-watcher>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="Warehouses"
|
|
||||||
data="warehouses">
|
|
||||||
</vn-crud-model>
|
|
||||||
<form
|
|
||||||
name="form"
|
|
||||||
ng-submit="$ctrl.onSubmit()"
|
|
||||||
class="vn-ma-md"
|
|
||||||
enctype="multipart/form-data">
|
|
||||||
<div class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
vn-focus
|
|
||||||
label="Reference"
|
|
||||||
ng-model="$ctrl.dms.reference"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-autocomplete vn-one required="true"
|
|
||||||
label="Company"
|
|
||||||
ng-model="$ctrl.dms.companyId"
|
|
||||||
url="Companies"
|
|
||||||
show-field="code"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one required="true"
|
|
||||||
label="Warehouse"
|
|
||||||
ng-model="$ctrl.dms.warehouseId"
|
|
||||||
data="warehouses"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete vn-one required="true"
|
|
||||||
label="Type"
|
|
||||||
ng-model="$ctrl.dms.dmsTypeId"
|
|
||||||
url="DmsTypes"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textarea
|
|
||||||
vn-one
|
|
||||||
required="true"
|
|
||||||
label="Description"
|
|
||||||
ng-model="$ctrl.dms.description"
|
|
||||||
rule>
|
|
||||||
</vn-textarea>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-input-file
|
|
||||||
vn-one
|
|
||||||
label="File"
|
|
||||||
ng-model="$ctrl.dms.files"
|
|
||||||
on-change="$ctrl.onFileChange($files)"
|
|
||||||
accept="{{$ctrl.allowedContentTypes}}"
|
|
||||||
required="true"
|
|
||||||
multiple="true">
|
|
||||||
<append>
|
|
||||||
<vn-icon vn-none
|
|
||||||
color-marginal
|
|
||||||
title="{{$ctrl.contentTypesInfo}}"
|
|
||||||
icon="info">
|
|
||||||
</vn-icon>
|
|
||||||
</append>
|
|
||||||
</vn-input-file>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-vertical>
|
|
||||||
<vn-check disabled="true"
|
|
||||||
label="Generate identifier for original file"
|
|
||||||
ng-model="$ctrl.dms.hasFile">
|
|
||||||
</vn-check>
|
|
||||||
</vn-vertical>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit label="Save"></vn-submit>
|
|
||||||
<vn-button ui-sref="client.card.dms.index" label="Cancel"></vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
|
@ -1,94 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
get client() {
|
|
||||||
return this._client;
|
|
||||||
}
|
|
||||||
|
|
||||||
set client(value) {
|
|
||||||
this._client = value;
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
this.setDefaultParams();
|
|
||||||
this.getAllowedContentTypes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getAllowedContentTypes() {
|
|
||||||
this.$http.get('DmsContainers/allowedContentTypes').then(res => {
|
|
||||||
const contentTypes = res.data.join(', ');
|
|
||||||
this.allowedContentTypes = contentTypes;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get contentTypesInfo() {
|
|
||||||
return this.$t('ContentTypesInfo', {
|
|
||||||
allowedContentTypes: this.allowedContentTypes
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setDefaultParams() {
|
|
||||||
const path = `Dms/${this.$params.dmsId}`;
|
|
||||||
this.$http.get(path).then(res => {
|
|
||||||
const dms = res.data && res.data;
|
|
||||||
this.dms = {
|
|
||||||
reference: dms.reference,
|
|
||||||
warehouseId: dms.warehouseFk,
|
|
||||||
companyId: dms.companyFk,
|
|
||||||
dmsTypeId: dms.dmsTypeFk,
|
|
||||||
description: dms.description,
|
|
||||||
hasFile: dms.hasFile,
|
|
||||||
hasFileAttached: false,
|
|
||||||
files: []
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
const query = `dms/${this.$params.dmsId}/updateFile`;
|
|
||||||
const options = {
|
|
||||||
method: 'POST',
|
|
||||||
url: query,
|
|
||||||
params: this.dms,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': undefined
|
|
||||||
},
|
|
||||||
transformRequest: files => {
|
|
||||||
const formData = new FormData();
|
|
||||||
|
|
||||||
for (let i = 0; i < files.length; i++)
|
|
||||||
formData.append(files[i].name, files[i]);
|
|
||||||
|
|
||||||
return formData;
|
|
||||||
},
|
|
||||||
data: this.dms.files
|
|
||||||
};
|
|
||||||
this.$http(options).then(res => {
|
|
||||||
if (res) {
|
|
||||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
|
||||||
this.$.watcher.updateOriginalData();
|
|
||||||
this.$state.go('client.card.dms.index');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onFileChange(files) {
|
|
||||||
let hasFileAttached = false;
|
|
||||||
if (files.length > 0)
|
|
||||||
hasFileAttached = true;
|
|
||||||
|
|
||||||
this.$.$applyAsync(() => {
|
|
||||||
this.dms.hasFileAttached = hasFileAttached;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientDmsEdit', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
client: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,81 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientDmsEdit', () => {
|
|
||||||
let controller;
|
|
||||||
let $scope;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
const $element = angular.element('<vn-client-dms-edit></vn-client-dms-edit>');
|
|
||||||
controller = $componentController('vnClientDmsEdit', {$element, $scope});
|
|
||||||
controller._client = {id: 1};
|
|
||||||
controller.$params = {dmsId: 1};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('client() setter', () => {
|
|
||||||
it('should set the client data and then call setDefaultParams() and getAllowedContentTypes()', () => {
|
|
||||||
jest.spyOn(controller, 'setDefaultParams');
|
|
||||||
jest.spyOn(controller, 'getAllowedContentTypes');
|
|
||||||
controller._client = undefined;
|
|
||||||
controller.client = {
|
|
||||||
id: 15
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.setDefaultParams).toHaveBeenCalledWith();
|
|
||||||
expect(controller.client).toBeDefined();
|
|
||||||
expect(controller.getAllowedContentTypes).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('setDefaultParams()', () => {
|
|
||||||
it('should perform a GET query and define the dms property on controller', () => {
|
|
||||||
const dmsId = 1;
|
|
||||||
const expectedResponse = {
|
|
||||||
reference: 1101,
|
|
||||||
warehouseFk: 1,
|
|
||||||
companyFk: 442,
|
|
||||||
dmsTypeFk: 12,
|
|
||||||
description: 'Test',
|
|
||||||
hasFile: false,
|
|
||||||
hasFileAttached: false
|
|
||||||
};
|
|
||||||
|
|
||||||
$httpBackend.expect('GET', `Dms/${dmsId}`).respond(expectedResponse);
|
|
||||||
controller.setDefaultParams();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.dms).toBeDefined();
|
|
||||||
expect(controller.dms.reference).toEqual(1101);
|
|
||||||
expect(controller.dms.dmsTypeId).toEqual(12);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onFileChange()', () => {
|
|
||||||
it('should set dms hasFileAttached property to true if has any files', () => {
|
|
||||||
const files = [{id: 1, name: 'MyFile'}];
|
|
||||||
controller.dms = {hasFileAttached: false};
|
|
||||||
controller.onFileChange(files);
|
|
||||||
$scope.$apply();
|
|
||||||
|
|
||||||
expect(controller.dms.hasFileAttached).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getAllowedContentTypes()', () => {
|
|
||||||
it('should make an HTTP GET request to get the allowed content types', () => {
|
|
||||||
const expectedResponse = ['image/png', 'image/jpg'];
|
|
||||||
$httpBackend.expect('GET', `DmsContainers/allowedContentTypes`).respond(expectedResponse);
|
|
||||||
controller.getAllowedContentTypes();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.allowedContentTypes).toBeDefined();
|
|
||||||
expect(controller.allowedContentTypes).toEqual('image/png, image/jpg');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,7 +0,0 @@
|
||||||
vn-ticket-request {
|
|
||||||
.vn-textfield {
|
|
||||||
margin: 0!important;
|
|
||||||
max-width: 100px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="ClientDms"
|
|
||||||
link="{clientFk: $ctrl.$params.id}"
|
|
||||||
filter="::$ctrl.filter"
|
|
||||||
limit="20"
|
|
||||||
data="$ctrl.clientDms"
|
|
||||||
order="dmsFk DESC"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-data-viewer
|
|
||||||
model="model"
|
|
||||||
class="vn-w-lg">
|
|
||||||
<vn-card>
|
|
||||||
<vn-table model="model">
|
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th field="dmsFk" shrink>Id</vn-th>
|
|
||||||
<vn-th field="dmsTypeFk" shrink>Type</vn-th>
|
|
||||||
<vn-th field="hardCopyNumber" shrink number>Order</vn-th>
|
|
||||||
<vn-th field="reference" shrink>Reference</vn-th>
|
|
||||||
<vn-th expand>Description</vn-th>
|
|
||||||
<vn-th field="hasFile" shrink>Original</vn-th>
|
|
||||||
<vn-th shrink>File</vn-th>
|
|
||||||
<vn-th>Employee</vn-th>
|
|
||||||
<vn-th field="created">Created</vn-th>
|
|
||||||
<vn-th shrink></vn-th>
|
|
||||||
<vn-th shrink></vn-th>
|
|
||||||
<vn-th shrink></vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr ng-repeat="document in $ctrl.clientDms">
|
|
||||||
<vn-td number shrink>{{::document.dmsFk}}</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<span title="{{::document.dms.dmsType.name}}">
|
|
||||||
{{::document.dms.dmsType.name}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink number>
|
|
||||||
<span class="chip" title="{{::document.dms.hardCopyNumber}}"
|
|
||||||
ng-class="{'message': document.dms.hardCopyNumber}">
|
|
||||||
{{::document.dms.hardCopyNumber}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<span title="{{::document.dms.reference}}">
|
|
||||||
{{::document.dms.reference}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td expand>
|
|
||||||
<span title="{{::document.dms.description}}">
|
|
||||||
{{::document.dms.description}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-check
|
|
||||||
ng-model="document.dms.hasFile"
|
|
||||||
disabled="true">
|
|
||||||
</vn-check>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<span title="{{'Download file' | translate}}" class="link"
|
|
||||||
ng-click="$ctrl.downloadFile(document.dmsFk)">
|
|
||||||
{{::document.dms.file}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<span class="link"
|
|
||||||
ng-click="workerDescriptor.show($event, document.dms.workerFk)">
|
|
||||||
{{::document.dms.worker.user.name | dashIfEmpty}}
|
|
||||||
</span></vn-td>
|
|
||||||
<vn-td shrink-datetime>
|
|
||||||
{{::document.dms.created | date:'dd/MM/yyyy HH:mm'}}
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-icon-button title="{{'Download file' | translate}}"
|
|
||||||
icon="cloud_download"
|
|
||||||
ng-click="$ctrl.downloadFile(document.dmsFk)">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-icon-button ui-sref="client.card.dms.edit({dmsId: {{::document.dmsFk}}})"
|
|
||||||
icon="edit"
|
|
||||||
title="{{'Edit file' | translate}}">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-icon-button
|
|
||||||
icon="delete"
|
|
||||||
ng-click="confirm.show($index)"
|
|
||||||
title="{{'Remove file' | translate}}"
|
|
||||||
tabindex="-1">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
</vn-card>
|
|
||||||
</vn-data-viewer>
|
|
||||||
<vn-worker-descriptor-popover
|
|
||||||
vn-id="workerDescriptor">
|
|
||||||
</vn-worker-descriptor-popover>
|
|
||||||
<a ui-sref="client.card.dms.create"
|
|
||||||
vn-tooltip="Upload file"
|
|
||||||
vn-bind="+"
|
|
||||||
fixed-bottom-right>
|
|
||||||
<vn-float-button icon="add"></vn-float-button>
|
|
||||||
</a>
|
|
||||||
<vn-confirm
|
|
||||||
vn-id="confirm"
|
|
||||||
message="This file will be deleted"
|
|
||||||
question="Are you sure you want to continue?"
|
|
||||||
on-accept="$ctrl.deleteDms($data)">
|
|
||||||
</vn-confirm>
|
|
|
@ -1,64 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $, vnFile) {
|
|
||||||
super($element, $, vnFile);
|
|
||||||
this.vnFile = vnFile;
|
|
||||||
this.filter = {
|
|
||||||
include: {
|
|
||||||
relation: 'dms',
|
|
||||||
scope: {
|
|
||||||
fields: [
|
|
||||||
'dmsTypeFk',
|
|
||||||
'reference',
|
|
||||||
'hardCopyNumber',
|
|
||||||
'workerFk',
|
|
||||||
'description',
|
|
||||||
'hasFile',
|
|
||||||
'file',
|
|
||||||
'created',
|
|
||||||
],
|
|
||||||
include: [{
|
|
||||||
relation: 'dmsType',
|
|
||||||
scope: {
|
|
||||||
fields: ['name']
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
relation: 'worker',
|
|
||||||
scope: {
|
|
||||||
fields: ['id'],
|
|
||||||
include: {
|
|
||||||
relation: 'user',
|
|
||||||
scope: {
|
|
||||||
fields: ['name']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteDms(index) {
|
|
||||||
const dmsFk = this.clientDms[index].dmsFk;
|
|
||||||
return this.$http.post(`ClientDms/${dmsFk}/removeFile`)
|
|
||||||
.then(() => {
|
|
||||||
this.$.model.remove(index);
|
|
||||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
downloadFile(dmsId) {
|
|
||||||
this.vnFile.download(`api/dms/${dmsId}/downloadFile`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope', 'vnFile'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientDmsIndex', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
});
|
|
|
@ -1,37 +0,0 @@
|
||||||
import './index';
|
|
||||||
import crudModel from 'core/mocks/crud-model';
|
|
||||||
|
|
||||||
describe('Client', () => {
|
|
||||||
describe('Component vnClientDmsIndex', () => {
|
|
||||||
let $scope;
|
|
||||||
let $httpBackend;
|
|
||||||
let controller;
|
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
controller = $componentController('vnClientDmsIndex', {$element: null, $scope});
|
|
||||||
controller.$.model = crudModel;
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('deleteDms()', () => {
|
|
||||||
it('should make an HTTP Post query', () => {
|
|
||||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
|
||||||
jest.spyOn(controller.$.model, 'remove');
|
|
||||||
|
|
||||||
const dmsId = 1;
|
|
||||||
const dmsIndex = 0;
|
|
||||||
controller.clientDms = [{dmsFk: 1}];
|
|
||||||
|
|
||||||
$httpBackend.expectPOST(`ClientDms/${dmsId}/removeFile`).respond();
|
|
||||||
controller.deleteDms(dmsIndex);
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.$.model.remove).toHaveBeenCalledWith(dmsIndex);
|
|
||||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,9 +0,0 @@
|
||||||
Type: Tipo
|
|
||||||
File management: Gestión documental
|
|
||||||
File: Fichero
|
|
||||||
Hard copy: Copia
|
|
||||||
This file will be deleted: Este fichero va a ser borrado
|
|
||||||
Are you sure?: Estas seguro?
|
|
||||||
File deleted: Fichero eliminado
|
|
||||||
Remove file: Eliminar fichero
|
|
||||||
Download file: Descargar fichero
|
|
|
@ -1,6 +0,0 @@
|
||||||
vn-client-risk-index {
|
|
||||||
.totalBox {
|
|
||||||
display: table;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
ClientFileDescription: "{{dmsTypeName}} from client {{clientName}} id {{clientId}}"
|
|
||||||
ContentTypesInfo: Allowed file types {{allowedContentTypes}}
|
|
|
@ -1,14 +0,0 @@
|
||||||
Upload file: Subir fichero
|
|
||||||
Edit file: Editar fichero
|
|
||||||
Upload: Subir
|
|
||||||
File: Fichero
|
|
||||||
ClientFileDescription: "{{dmsTypeName}} del cliente {{clientName}} id {{clientId}}"
|
|
||||||
ContentTypesInfo: "Tipos de archivo permitidos: {{allowedContentTypes}}"
|
|
||||||
Generate identifier for original file: Generar identificador para archivo original
|
|
||||||
File management: Gestión documental
|
|
||||||
Hard copy: Copia
|
|
||||||
This file will be deleted: Este fichero va a ser borrado
|
|
||||||
Are you sure?: Estas seguro?
|
|
||||||
File deleted: Fichero eliminado
|
|
||||||
Remove file: Eliminar fichero
|
|
||||||
Download file: Descargar fichero
|
|
|
@ -1,319 +0,0 @@
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="Clients/extendedListFilter"
|
|
||||||
limit="20">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-portal slot="topbar">
|
|
||||||
<vn-searchbar
|
|
||||||
vn-focus
|
|
||||||
panel="vn-client-search-panel"
|
|
||||||
placeholder="Search client"
|
|
||||||
info="Search client by id or name"
|
|
||||||
auto-state="false"
|
|
||||||
model="model">
|
|
||||||
</vn-searchbar>
|
|
||||||
</vn-portal>
|
|
||||||
<vn-card>
|
|
||||||
<smart-table
|
|
||||||
model="model"
|
|
||||||
view-config-id="clientsDetail"
|
|
||||||
options="$ctrl.smartTableOptions"
|
|
||||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
|
||||||
<slot-table>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th></th>
|
|
||||||
<th field="id">
|
|
||||||
<span translate>Identifier</span>
|
|
||||||
</th>
|
|
||||||
<th field="name">
|
|
||||||
<span translate>Name</span>
|
|
||||||
</th>
|
|
||||||
<th field="socialName">
|
|
||||||
<span translate>Social name</span>
|
|
||||||
</th>
|
|
||||||
<th field="fi">
|
|
||||||
<span translate>Tax number</span>
|
|
||||||
</th>
|
|
||||||
<th field="salesPersonFk">
|
|
||||||
<span translate>Salesperson</span>
|
|
||||||
</th>
|
|
||||||
<th field="credit">
|
|
||||||
<span translate>Credit</span>
|
|
||||||
</th>
|
|
||||||
<th field="creditInsurance">
|
|
||||||
<span translate>Credit insurance</span>
|
|
||||||
</th>
|
|
||||||
<th field="phone">
|
|
||||||
<span translate>Phone</span>
|
|
||||||
</th>
|
|
||||||
<th field="mobile">
|
|
||||||
<span translate>Mobile</span>
|
|
||||||
</th>
|
|
||||||
<th field="street">
|
|
||||||
<span translate>Street</span>
|
|
||||||
</th>
|
|
||||||
<th field="countryFk">
|
|
||||||
<span translate>Country</span>
|
|
||||||
</th>
|
|
||||||
<th field="provinceFk">
|
|
||||||
<span translate>Province</span>
|
|
||||||
</th>
|
|
||||||
<th field="city">
|
|
||||||
<span translate>City</span>
|
|
||||||
</th>
|
|
||||||
<th field="postcode">
|
|
||||||
<span translate>Postcode</span>
|
|
||||||
</th>
|
|
||||||
<th field="email">
|
|
||||||
<span translate>Email</span>
|
|
||||||
</th>
|
|
||||||
<th field="created">
|
|
||||||
<span translate>Created</span>
|
|
||||||
</th>
|
|
||||||
<th field="businessTypeFk">
|
|
||||||
<span translate>Business type</span>
|
|
||||||
</th>
|
|
||||||
<th field="payMethodFk">
|
|
||||||
<span translate>Billing data</span>
|
|
||||||
</th>
|
|
||||||
<th field="sageTaxTypeFk">
|
|
||||||
<span translate>Sage tax type</span>
|
|
||||||
</th>
|
|
||||||
<th field="sageTransactionTypeFk">
|
|
||||||
<span translate>Sage tr. type</span>
|
|
||||||
</th>
|
|
||||||
<th field="isActive" centered>
|
|
||||||
<span translate>Active</span>
|
|
||||||
</th>
|
|
||||||
<th field="isVies" centered>
|
|
||||||
<span translate>Vies</span>
|
|
||||||
</th>
|
|
||||||
<th field="isTaxDataChecked" centered>
|
|
||||||
<span translate>Verified data</span>
|
|
||||||
</th>
|
|
||||||
<th field="isEqualizated" centered>
|
|
||||||
<span translate>Is equalizated</span>
|
|
||||||
</th>
|
|
||||||
<th field="isFreezed" centered>
|
|
||||||
<span translate>Freezed</span>
|
|
||||||
</th>
|
|
||||||
<th field="hasToInvoice" centered>
|
|
||||||
<span translate>Invoice</span>
|
|
||||||
</th>
|
|
||||||
<th field="hasToInvoiceByAddress" centered>
|
|
||||||
<span translate>Invoice by address</span>
|
|
||||||
</th>
|
|
||||||
<th field="isToBeMailed" centered>
|
|
||||||
<span translate>Mailing</span>
|
|
||||||
</th>
|
|
||||||
<th field="hasLcr" centered>
|
|
||||||
<span translate>Received LCR</span>
|
|
||||||
</th>
|
|
||||||
<th field="hasCoreVnl" centered>
|
|
||||||
<span translate>Received core VNL</span>
|
|
||||||
</th>
|
|
||||||
<th field="hasSepaVnl" centered>
|
|
||||||
<span translate>Received B2B VNL</span>
|
|
||||||
</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr ng-repeat="client in model.data"
|
|
||||||
vn-anchor="::{
|
|
||||||
state: 'client.card.summary',
|
|
||||||
params: {id: client.id}
|
|
||||||
}">
|
|
||||||
<td>
|
|
||||||
<vn-icon-button ng-show="::client.isActive == false"
|
|
||||||
vn-tooltip="Client inactive"
|
|
||||||
icon="icon-disabled">
|
|
||||||
</vn-icon-button>
|
|
||||||
<vn-icon-button ng-show="::client.isActive && client.isFreezed == true"
|
|
||||||
vn-tooltip="Client frozen"
|
|
||||||
icon="icon-frozen">
|
|
||||||
</vn-icon-button>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span
|
|
||||||
vn-click-stop="clientDescriptor.show($event, client.id)"
|
|
||||||
class="link">
|
|
||||||
{{::client.id}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>{{::client.name}}</td>
|
|
||||||
<td>{{::client.socialName}}</td>
|
|
||||||
<td>{{::client.fi}}</td>
|
|
||||||
<td>
|
|
||||||
<span
|
|
||||||
vn-click-stop="workerDescriptor.show($event, client.salesPersonFk)"
|
|
||||||
ng-class="{'link': client.salesPersonFk}">
|
|
||||||
{{::client.salesPerson | dashIfEmpty}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>{{::client.credit}}</td>
|
|
||||||
<td>{{::client.creditInsurance | dashIfEmpty}}</td>
|
|
||||||
<td>{{::client.phone | dashIfEmpty}}</td>
|
|
||||||
<td>{{::client.mobile | dashIfEmpty}}</td>
|
|
||||||
<td>{{::client.street | dashIfEmpty}}</td>
|
|
||||||
<td>{{::client.country | dashIfEmpty}}</td>
|
|
||||||
<td>{{::client.province | dashIfEmpty}}</td>
|
|
||||||
<td>{{::client.city | dashIfEmpty}}</td>
|
|
||||||
<td>{{::client.postcode | dashIfEmpty}}</td>
|
|
||||||
<td class="vn-w-xs" title="{{::client.email}}">{{::client.email | dashIfEmpty}}</td>
|
|
||||||
<td>{{::client.created | date:'dd/MM/yyyy'}}</td>
|
|
||||||
<td>{{::client.businessType | dashIfEmpty}}</td>
|
|
||||||
<td>{{::client.payMethod | dashIfEmpty}}</td>
|
|
||||||
<td>{{::client.sageTaxType | dashIfEmpty}}</td>
|
|
||||||
<td>{{::client.sageTransactionType | dashIfEmpty}}</td>
|
|
||||||
<td centered>
|
|
||||||
<vn-chip ng-class="::{
|
|
||||||
'success': client.isActive,
|
|
||||||
'alert': !client.isActive,
|
|
||||||
}">
|
|
||||||
{{ ::client.isActive ? 'Yes' : 'No' | translate}}
|
|
||||||
</vn-chip>
|
|
||||||
</td>
|
|
||||||
<td centered>
|
|
||||||
<vn-chip ng-class="::{
|
|
||||||
'success': client.isVies,
|
|
||||||
'alert': !client.isVies,
|
|
||||||
}">
|
|
||||||
{{ ::client.isVies ? 'Yes' : 'No' | translate}}
|
|
||||||
</vn-chip>
|
|
||||||
</td>
|
|
||||||
<td centered>
|
|
||||||
<vn-chip ng-class="::{
|
|
||||||
'success': client.isTaxDataChecked,
|
|
||||||
'alert': !client.isTaxDataChecked,
|
|
||||||
}">
|
|
||||||
{{ ::client.isTaxDataChecked ? 'Yes' : 'No' | translate}}
|
|
||||||
</vn-chip>
|
|
||||||
</td>
|
|
||||||
<td centered>
|
|
||||||
<vn-chip ng-class="::{
|
|
||||||
'success': client.isEqualizated,
|
|
||||||
'alert': !client.isEqualizated,
|
|
||||||
}">
|
|
||||||
{{ ::client.isEqualizated ? 'Yes' : 'No' | translate}}
|
|
||||||
</vn-chip>
|
|
||||||
</td>
|
|
||||||
<td centered>
|
|
||||||
<vn-chip ng-class="::{
|
|
||||||
'success': client.isFreezed,
|
|
||||||
'alert': !client.isFreezed,
|
|
||||||
}">
|
|
||||||
{{ ::client.isFreezed ? 'Yes' : 'No' | translate}}
|
|
||||||
</vn-chip>
|
|
||||||
</td>
|
|
||||||
<td centered>
|
|
||||||
<vn-chip ng-class="::{
|
|
||||||
'success': client.hasToInvoice,
|
|
||||||
'alert': !client.hasToInvoice,
|
|
||||||
}">
|
|
||||||
{{ ::client.hasToInvoice ? 'Yes' : 'No' | translate}}
|
|
||||||
</vn-chip>
|
|
||||||
</td>
|
|
||||||
<td centered>
|
|
||||||
<vn-chip ng-class="::{
|
|
||||||
'success': client.hasToInvoiceByAddress,
|
|
||||||
'alert': !client.hasToInvoiceByAddress,
|
|
||||||
}">
|
|
||||||
{{ ::client.hasToInvoiceByAddress ? 'Yes' : 'No' | translate}}
|
|
||||||
</vn-chip>
|
|
||||||
</td>
|
|
||||||
<td centered>
|
|
||||||
<vn-chip ng-class="::{
|
|
||||||
'success': client.isToBeMailed,
|
|
||||||
'alert': !client.isToBeMailed,
|
|
||||||
}">
|
|
||||||
{{ ::client.isToBeMailed ? 'Yes' : 'No' | translate}}
|
|
||||||
</vn-chip>
|
|
||||||
</td>
|
|
||||||
<td centered>
|
|
||||||
<vn-chip ng-class="::{
|
|
||||||
'success': client.hasLcr,
|
|
||||||
'alert': !client.hasLcr,
|
|
||||||
}">
|
|
||||||
{{ ::client.hasLcr ? 'Yes' : 'No' | translate}}
|
|
||||||
</vn-chip>
|
|
||||||
</td>
|
|
||||||
<td centered>
|
|
||||||
<vn-chip ng-class="::{
|
|
||||||
'success': client.hasCoreVnl,
|
|
||||||
'alert': !client.hasCoreVnl,
|
|
||||||
}">
|
|
||||||
{{ ::client.hasCoreVnl ? 'Yes' : 'No' | translate}}
|
|
||||||
</vn-chip>
|
|
||||||
</td>
|
|
||||||
<td centered>
|
|
||||||
<vn-chip ng-class="::{
|
|
||||||
'success': client.hasSepaVnl,
|
|
||||||
'alert': !client.hasSepaVnl,
|
|
||||||
}">
|
|
||||||
{{ ::client.hasSepaVnl ? 'Yes' : 'No' | translate}}
|
|
||||||
</vn-chip>
|
|
||||||
</td>
|
|
||||||
<td shrink>
|
|
||||||
<vn-horizontal class="buttons">
|
|
||||||
<vn-icon-button vn-anchor="{state: 'ticket.index', params: {q: {clientFk: client.id} } }"
|
|
||||||
vn-tooltip="Client tickets"
|
|
||||||
icon="icon-ticket">
|
|
||||||
</vn-icon-button>
|
|
||||||
<vn-icon-button
|
|
||||||
vn-click-stop="$ctrl.preview(client)"
|
|
||||||
vn-tooltip="Preview"
|
|
||||||
icon="preview">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-horizontal>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</slot-table>
|
|
||||||
</smart-table>
|
|
||||||
</vn-card>
|
|
||||||
<a ui-sref="client.create" vn-tooltip="New client" vn-bind="+" fixed-bottom-right>
|
|
||||||
<vn-float-button icon="add"></vn-float-button>
|
|
||||||
</a>
|
|
||||||
<vn-client-descriptor-popover
|
|
||||||
vn-id="client-descriptor">
|
|
||||||
</vn-client-descriptor-popover>
|
|
||||||
<vn-worker-descriptor-popover
|
|
||||||
vn-id="worker-descriptor">
|
|
||||||
</vn-worker-descriptor-popover>
|
|
||||||
|
|
||||||
<vn-popup vn-id="preview">
|
|
||||||
<vn-client-summary
|
|
||||||
client="$ctrl.clientSelected">
|
|
||||||
</vn-client-summary>
|
|
||||||
</vn-popup>
|
|
||||||
<vn-contextmenu
|
|
||||||
vn-id="contextmenu"
|
|
||||||
targets="['smart-table']"
|
|
||||||
model="model"
|
|
||||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
|
||||||
<slot-menu>
|
|
||||||
<vn-item translate
|
|
||||||
ng-if="contextmenu.isFilterAllowed()"
|
|
||||||
ng-click="contextmenu.filterBySelection()">
|
|
||||||
Filter by selection
|
|
||||||
</vn-item>
|
|
||||||
<vn-item translate
|
|
||||||
ng-if="contextmenu.isFilterAllowed()"
|
|
||||||
ng-click="contextmenu.excludeSelection()">
|
|
||||||
Exclude selection
|
|
||||||
</vn-item>
|
|
||||||
<vn-item translate
|
|
||||||
ng-if="contextmenu.isFilterAllowed()"
|
|
||||||
ng-click="contextmenu.removeFilter()">
|
|
||||||
Remove filter
|
|
||||||
</vn-item>
|
|
||||||
<vn-item translate
|
|
||||||
ng-click="contextmenu.removeAllFilters()">
|
|
||||||
Remove all filters
|
|
||||||
</vn-item>
|
|
||||||
</slot-menu>
|
|
||||||
</vn-contextmenu>
|
|
|
@ -1,184 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
|
|
||||||
this.smartTableOptions = {
|
|
||||||
activeButtons: {
|
|
||||||
search: true,
|
|
||||||
shownColumns: true,
|
|
||||||
},
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
field: 'socialName',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'Clients',
|
|
||||||
showField: 'socialName',
|
|
||||||
valueField: 'socialName',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'created',
|
|
||||||
datepicker: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'countryFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'Countries',
|
|
||||||
showField: 'name',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'provinceFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'Provinces'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'salesPersonFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'Workers/activeWithInheritedRole',
|
|
||||||
where: `{role: 'salesPerson'}`,
|
|
||||||
searchFunction: '{firstName: $search}',
|
|
||||||
showField: 'nickname',
|
|
||||||
valueField: 'id',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'businessTypeFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'BusinessTypes',
|
|
||||||
valueField: 'code',
|
|
||||||
showField: 'description',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'payMethodFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'PayMethods',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'sageTaxTypeFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'SageTaxTypes',
|
|
||||||
showField: 'vat',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'sageTransactionTypeFk',
|
|
||||||
autocomplete: {
|
|
||||||
url: 'SageTransactionTypes',
|
|
||||||
showField: 'transaction',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'isActive',
|
|
||||||
checkbox: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'isVies',
|
|
||||||
checkbox: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'isTaxDataChecked',
|
|
||||||
checkbox: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'isEqualizated',
|
|
||||||
checkbox: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'isFreezed',
|
|
||||||
checkbox: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'hasToInvoice',
|
|
||||||
checkbox: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'hasToInvoiceByAddress',
|
|
||||||
checkbox: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'isToBeMailed',
|
|
||||||
checkbox: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'hasSepaVnl',
|
|
||||||
checkbox: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'hasLcr',
|
|
||||||
checkbox: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'hasCoreVnl',
|
|
||||||
checkbox: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
exprBuilder(param, value) {
|
|
||||||
switch (param) {
|
|
||||||
case 'created':
|
|
||||||
return {'c.created': {
|
|
||||||
between: this.dateRange(value)}
|
|
||||||
};
|
|
||||||
case 'id':
|
|
||||||
case 'name':
|
|
||||||
case 'socialName':
|
|
||||||
case 'fi':
|
|
||||||
case 'credit':
|
|
||||||
case 'creditInsurance':
|
|
||||||
case 'phone':
|
|
||||||
case 'mobile':
|
|
||||||
case 'street':
|
|
||||||
case 'city':
|
|
||||||
case 'postcode':
|
|
||||||
case 'email':
|
|
||||||
case 'isActive':
|
|
||||||
case 'isVies':
|
|
||||||
case 'isTaxDataChecked':
|
|
||||||
case 'isEqualizated':
|
|
||||||
case 'isFreezed':
|
|
||||||
case 'hasToInvoice':
|
|
||||||
case 'hasToInvoiceByAddress':
|
|
||||||
case 'isToBeMailed':
|
|
||||||
case 'hasSepaVnl':
|
|
||||||
case 'hasLcr':
|
|
||||||
case 'hasCoreVnl':
|
|
||||||
case 'countryFk':
|
|
||||||
case 'provinceFk':
|
|
||||||
case 'salesPersonFk':
|
|
||||||
case 'businessTypeFk':
|
|
||||||
case 'payMethodFk':
|
|
||||||
case 'sageTaxTypeFk':
|
|
||||||
case 'sageTransactionTypeFk':
|
|
||||||
return {[`c.${param}`]: value};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dateRange(value) {
|
|
||||||
const minHour = new Date(value);
|
|
||||||
minHour.setHours(0, 0, 0, 0);
|
|
||||||
const maxHour = new Date(value);
|
|
||||||
maxHour.setHours(23, 59, 59, 59);
|
|
||||||
|
|
||||||
return [minHour, maxHour];
|
|
||||||
}
|
|
||||||
|
|
||||||
preview(client) {
|
|
||||||
this.clientSelected = client;
|
|
||||||
this.$.preview.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientExtendedList', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,3 +0,0 @@
|
||||||
Mailing: Env. emails
|
|
||||||
Sage tr. type: Tipo tr. sage
|
|
||||||
Yes: Sí
|
|
|
@ -1,6 +0,0 @@
|
||||||
@import "variables";
|
|
||||||
|
|
||||||
vn-chip.success,
|
|
||||||
vn-chip.alert {
|
|
||||||
color: $color-font-bg
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue