#6943 - Client module redirect to Lilium #2924
|
@ -37,17 +37,11 @@ async function test() {
|
|||
|
||||
const specFiles = [
|
||||
`./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/05*/*[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/11*/*[sS]pec.js`,
|
||||
`./e2e/paths/12*/*[sS]pec.js`,
|
||||
`./e2e/paths/13*/*[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