Merge branch 'dev' of https://git.verdnatura.es/salix into dev
This commit is contained in:
commit
77e0494b37
|
@ -1,8 +1,15 @@
|
|||
<mg-ajax path="/client/api/Clients/{{index.params.id}}/listAddresses" options="mgIndex"></mg-ajax>
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/client/api/Addresses"
|
||||
filter="::$ctrl.filter"
|
||||
link="{clientFk: $ctrl.$stateParams.id}"
|
||||
data="addresses">
|
||||
</vn-crud-model>
|
||||
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-title vn-one>Addresses</vn-title>
|
||||
<vn-horizontal ng-repeat="address in index.model.items track by address.id" class="pad-medium-top" style="align-items: center;">
|
||||
<vn-horizontal ng-repeat="address in addresses" class="pad-medium-top" style="align-items: center;">
|
||||
<vn-one border-radius class="pad-small border-solid"
|
||||
ng-class="{'bg-main': address.isDefaultAddress,'bg-opacity-item': !address.isActive && !address.isDefaultAddress}">
|
||||
<vn-horizontal style="align-items: center;">
|
||||
|
@ -56,7 +63,6 @@
|
|||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-paging index="index" total="index.model.total"></vn-paging>
|
||||
<vn-float-button
|
||||
vn-bind="+"
|
||||
fixed-bottom-right
|
||||
|
|
|
@ -1,20 +1,28 @@
|
|||
import ngModule from '../../module';
|
||||
|
||||
class Controller {
|
||||
constructor($http, $scope) {
|
||||
constructor($http, $scope, $stateParams) {
|
||||
this.$http = $http;
|
||||
this.$scope = $scope;
|
||||
this.$stateParams = $stateParams;
|
||||
this.filter = {
|
||||
include: {
|
||||
observations: 'observationType'
|
||||
},
|
||||
order: ['isDefaultAddress DESC', 'isActive DESC', 'nickname ASC']
|
||||
};
|
||||
}
|
||||
|
||||
setDefault(address) {
|
||||
if (address.isActive) {
|
||||
let params = {isDefaultAddress: true};
|
||||
this.$http.patch(`/client/api/Addresses/${address.id}`, params).then(
|
||||
() => this.$scope.index.accept()
|
||||
() => this.$scope.model.refresh()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$http', '$scope'];
|
||||
Controller.$inject = ['$http', '$scope', '$stateParams'];
|
||||
|
||||
ngModule.component('vnClientAddressIndex', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<mg-ajax path="/client/api/Clients/{{patch.params.id}}" options="vnPatch"></mg-ajax>
|
||||
<mg-ajax path="/client/api/Clients/{{patch.params.id}}/updateBasicData" options="vnPatch"></mg-ajax>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.client"
|
||||
|
|
|
@ -16,53 +16,48 @@ describe('Client', () => {
|
|||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
$scope = $rootScope.$new();
|
||||
let submit = jasmine.createSpy('submit').and.returnValue(Promise.resolve());
|
||||
$scope.watcher = {submit};
|
||||
$scope.watcher = {
|
||||
submit: () => {
|
||||
return {
|
||||
then: callback => {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
$httpBackend.get = jasmine.createSpy('get').and.returnValue(Promise.resolve());
|
||||
controller = $componentController('vnClientBillingData', {$scope: $scope}, {$http: $httpBackend});
|
||||
controller.client = {id: 101, name: 'Client name', payMethodFk: 4};
|
||||
}));
|
||||
|
||||
describe('copyData()', () => {
|
||||
it(`should define billData using client's data`, () => {
|
||||
controller.client = {
|
||||
dueDay: 0,
|
||||
iban: null,
|
||||
payMethodFk: 1
|
||||
};
|
||||
controller.billData = {};
|
||||
controller.copyData(controller.client);
|
||||
|
||||
expect(controller.billData).toEqual(controller.client);
|
||||
describe('client()', () => {
|
||||
it(`should call setter client`, () => {
|
||||
expect(controller.orgData).toEqual(controller.client);
|
||||
});
|
||||
});
|
||||
|
||||
describe('submit()', () => {
|
||||
it(`should call submit() on the watcher then receive a callback`, done => {
|
||||
spyOn(controller, 'checkPaymentChanges');
|
||||
controller.submit()
|
||||
.then(() => {
|
||||
expect(controller.$.watcher.submit).toHaveBeenCalledWith();
|
||||
expect(controller.checkPaymentChanges).toHaveBeenCalledWith();
|
||||
done();
|
||||
});
|
||||
describe('hasPaymethodChanged()', () => {
|
||||
it(`should call hasPaymethodChanged() and return true if there are changes on payMethod data`, () => {
|
||||
controller.client.payMethodFk = 5;
|
||||
|
||||
expect(controller.hasPaymethodChanged()).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should call hasPaymethodChanged() and return false if there are no changes on payMethod data`, () => {
|
||||
controller.client.payMethodFk = 4;
|
||||
|
||||
expect(controller.hasPaymethodChanged()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkPaymentChanges()', () => {
|
||||
it(`should not call sendMail.show() if there are no changes on billing data`, () => {
|
||||
controller.billData = {marvelHero: 'Silver Surfer'};
|
||||
controller.client = {marvelHero: 'Silver Surfer'};
|
||||
controller.checkPaymentChanges();
|
||||
describe('onSubmit()', () => {
|
||||
it(`should call notifyChanges() if there are changes on payMethod data`, () => {
|
||||
spyOn(controller, 'notifyChanges');
|
||||
controller.client.payMethodFk = 5;
|
||||
controller.onSubmit();
|
||||
|
||||
expect(controller.$http.get).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it(`should call sendMail.show() if there are changes on billing data object`, () => {
|
||||
controller.billData = {id: '123', marvelHero: 'Silver Surfer'};
|
||||
controller.client = {id: '123', marvelHero: 'Spider-Man'};
|
||||
controller.checkPaymentChanges();
|
||||
|
||||
expect(controller.$http.get).toHaveBeenCalled();
|
||||
expect(controller.hasPaymethodChanged()).toBeTruthy();
|
||||
expect(controller.notifyChanges).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<mg-ajax path="/client/api/Clients/{{patch.params.id}}" options="vnPatch"></mg-ajax>
|
||||
<mg-ajax path="/client/api/Clients/{{patch.params.id}}/updateBillingData" options="vnPatch"></mg-ajax>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.client"
|
||||
form="form"
|
||||
save="patch">
|
||||
</vn-watcher>
|
||||
<form name="form" ng-submit="$ctrl.submit()">
|
||||
<form name="form" ng-submit="$ctrl.onSubmit()">
|
||||
<vn-card pad-large>
|
||||
<vn-title>Pay method</vn-title>
|
||||
<vn-horizontal>
|
||||
|
@ -36,8 +36,8 @@
|
|||
<vn-horizontal pad-small-v>
|
||||
<vn-one>
|
||||
<vn-check
|
||||
label="Received core VNH"
|
||||
field="$ctrl.client.hasCoreVnh"
|
||||
label="Received LCR"
|
||||
field="$ctrl.client.hasLcr"
|
||||
vn-acl="administrative, salesAssistant">
|
||||
</vn-check>
|
||||
</vn-one>
|
||||
|
|
|
@ -2,47 +2,42 @@ import ngModule from '../module';
|
|||
|
||||
export default class Controller {
|
||||
constructor($scope, $http, vnApp, $translate) {
|
||||
this.$ = $scope;
|
||||
this.$scope = $scope;
|
||||
this.$http = $http;
|
||||
this.vnApp = vnApp;
|
||||
this.translate = $translate;
|
||||
this.billData = {};
|
||||
this.copyData();
|
||||
}
|
||||
|
||||
$onChanges() {
|
||||
this.copyData();
|
||||
set client(value) {
|
||||
this._client = value;
|
||||
|
||||
if (value)
|
||||
this.orgData = Object.assign({}, value);
|
||||
}
|
||||
|
||||
copyData() {
|
||||
if (this.client) {
|
||||
this.billData.payMethodFk = this.client.payMethodFk;
|
||||
this.billData.iban = this.client.iban;
|
||||
this.billData.dueDay = this.client.dueDay;
|
||||
}
|
||||
get client() {
|
||||
return this._client;
|
||||
}
|
||||
|
||||
submit() {
|
||||
return this.$.watcher.submit().then(
|
||||
() => this.checkPaymentChanges());
|
||||
onSubmit() {
|
||||
this.$scope.watcher.submit().then(() => {
|
||||
if (this.hasPaymethodChanged())
|
||||
this.notifyChanges();
|
||||
});
|
||||
}
|
||||
|
||||
checkPaymentChanges() {
|
||||
let equals = true;
|
||||
Object.keys(this.billData).forEach(
|
||||
val => {
|
||||
if (this.billData[val] !== this.client[val]) {
|
||||
this.billData[val] = this.client[val];
|
||||
equals = false;
|
||||
}
|
||||
}
|
||||
notifyChanges() {
|
||||
this.$http.get(`/mailer/notification/payment-update/${this.client.id}`).then(
|
||||
() => this.vnApp.showMessage(this.translate.instant('Notification sent!'))
|
||||
);
|
||||
}
|
||||
|
||||
if (!equals) {
|
||||
this.$http.get(`/mailer/notification/payment-update/${this.client.id}`).then(
|
||||
() => this.vnApp.showMessage(this.translate.instant('Notification sent!'))
|
||||
);
|
||||
}
|
||||
hasPaymethodChanged() {
|
||||
let payMethod = this.orgData.payMethodFk != this.client.payMethodFk;
|
||||
let iban = this.orgData.iban != this.client.iban;
|
||||
let dueDay = this.orgData.dueDay != this.client.dueDay;
|
||||
|
||||
return payMethod || iban || dueDay;
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$scope', '$http', 'vnApp', '$translate'];
|
||||
|
|
|
@ -9,7 +9,6 @@ Equivalent tax spreaded: Equivalent tax spreaded
|
|||
Invoice by address: Invoice by address
|
||||
Equalization tax: Equalization tax
|
||||
Due day: Due day
|
||||
Received core VNH: VNH core received
|
||||
Received core VNL: VNL core received
|
||||
Received B2B VNL: VNL B2B received
|
||||
Save: Save
|
|
@ -9,7 +9,7 @@ Equivalent tax spreaded: Recargo de equivalencia propagado
|
|||
Invoice by address: Facturar por consignatario
|
||||
Equalization tax: Recargo de equivalencia
|
||||
Due day: Vencimiento
|
||||
Received core VNH: Recibido core VNH
|
||||
Received LCR: Recibido LCR
|
||||
Received core VNL: Recibido core VNL
|
||||
Received B2B VNL: Recibido B2B VNL
|
||||
Save: Guardar
|
|
@ -19,7 +19,7 @@ describe('Client', () => {
|
|||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
$scope = $rootScope.$new();
|
||||
$scope.form = {$invalid: false};
|
||||
$scope.index = {accept: () => {}};
|
||||
$scope.model = {refresh: () => {}};
|
||||
controller = $componentController('vnClientContactIndex', {$scope: $scope}, {$state: $state});
|
||||
controller.client = {
|
||||
id: 101
|
||||
|
@ -70,11 +70,11 @@ describe('Client', () => {
|
|||
|
||||
describe('submit()', () => {
|
||||
it("should perfom a query to delete contacts", () => {
|
||||
controller._oldContacts = [];
|
||||
controller._oldContacts[1] = {id: 1, clientFk: 101, name: 'My contact 1', phone: '123456789'};
|
||||
controller._oldContacts[2] = {id: 2, clientFk: 101, name: 'My contact 2', phone: '123456789'};
|
||||
controller.oldContacts = [];
|
||||
controller.oldContacts[1] = {id: 1, clientFk: 101, name: 'My contact 1', phone: '123456789'};
|
||||
controller.oldContacts[2] = {id: 2, clientFk: 101, name: 'My contact 2', phone: '123456789'};
|
||||
|
||||
controller._contacts = [
|
||||
controller.contacts = [
|
||||
{id: 2, name: 'My contact 2', phone: '123456789'}
|
||||
];
|
||||
controller.removedContacts = [1];
|
||||
|
@ -93,11 +93,11 @@ describe('Client', () => {
|
|||
});
|
||||
|
||||
it("should perfom a query to update contacts", () => {
|
||||
controller._oldContacts = [];
|
||||
controller._oldContacts[1] = {id: 1, clientFk: 101, name: 'My contact 1', phone: '123456789'};
|
||||
controller._oldContacts[2] = {id: 2, clientFk: 101, name: 'My contact 2', phone: '123456789'};
|
||||
controller.oldContacts = [];
|
||||
controller.oldContacts[1] = {id: 1, clientFk: 101, name: 'My contact 1', phone: '123456789'};
|
||||
controller.oldContacts[2] = {id: 2, clientFk: 101, name: 'My contact 2', phone: '123456789'};
|
||||
|
||||
controller._contacts = [
|
||||
controller.contacts = [
|
||||
{id: 1, clientFk: 101, name: 'My contact 1', phone: '123456789'},
|
||||
{id: 2, clientFk: 101, name: 'My contact 2', phone: '111111111'}
|
||||
];
|
||||
|
@ -119,11 +119,11 @@ describe('Client', () => {
|
|||
});
|
||||
|
||||
it("should perfom a query to create new contact", () => {
|
||||
controller._oldContacts = [];
|
||||
controller._oldContacts[1] = {id: 1, name: 'My contact 1', phone: '123456789'};
|
||||
controller._oldContacts[2] = {id: 2, name: 'My contact 2', phone: '123456789'};
|
||||
controller.oldContacts = [];
|
||||
controller.oldContacts[1] = {id: 1, name: 'My contact 1', phone: '123456789'};
|
||||
controller.oldContacts[2] = {id: 2, name: 'My contact 2', phone: '123456789'};
|
||||
|
||||
controller._contacts = [
|
||||
controller.contacts = [
|
||||
{id: 1, name: 'My contact 1', phone: '123456789'},
|
||||
{id: 2, name: 'My contact 2', phone: '123456789'},
|
||||
{name: 'My contact 3', phone: '123456789'}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
<mg-ajax
|
||||
path="/client/api/Clients/{{index.params.id}}/contacts"
|
||||
options="mgIndex"
|
||||
actions="$ctrl.contacts = index.model">
|
||||
</mg-ajax>
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/client/api/ClientContacts"
|
||||
link="{clientFk: $ctrl.$stateParams.id}"
|
||||
data="contacts" on-data-change="$ctrl.onDataChange()">
|
||||
</vn-crud-model>
|
||||
|
||||
<form name="form" ng-submit="$ctrl.submit()">
|
||||
<vn-card pad-large>
|
||||
<vn-title>Contacts</vn-title>
|
||||
<vn-horizontal ng-repeat="contact in index.model track by $index">
|
||||
<vn-horizontal ng-repeat="contact in contacts">
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Name"
|
||||
|
|
|
@ -1,25 +1,18 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class Controller {
|
||||
constructor($http, $scope, $translate, vnApp) {
|
||||
constructor($http, $scope, $stateParams, $translate, vnApp) {
|
||||
this.$http = $http;
|
||||
this.$scope = $scope;
|
||||
this.$stateParams = $stateParams;
|
||||
this.$translate = $translate;
|
||||
this.vnApp = vnApp;
|
||||
this.removedContacts = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for contacts and original contacts
|
||||
* @param {Object} value - Contacts object
|
||||
*/
|
||||
set contacts(value) {
|
||||
this._contacts = value;
|
||||
this.oldContacts = value;
|
||||
}
|
||||
|
||||
get contacts() {
|
||||
return this._contacts;
|
||||
onDataChange() {
|
||||
this.contacts = this.$scope.model.data;
|
||||
this.oldContacts = this.$scope.model.data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,7 +57,7 @@ class Controller {
|
|||
|
||||
this.$http.post(query, data).then(() => {
|
||||
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||
this.$scope.index.accept();
|
||||
this.$scope.model.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -85,7 +78,7 @@ class Controller {
|
|||
add() {
|
||||
let data = {
|
||||
clientFk: this.client.id,
|
||||
name: 'Teléfono',
|
||||
name: this.$translate.instant('Phone'),
|
||||
phone: null
|
||||
};
|
||||
this.contacts.push(data);
|
||||
|
@ -115,7 +108,7 @@ class Controller {
|
|||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$http', '$scope', '$translate', 'vnApp'];
|
||||
Controller.$inject = ['$http', '$scope', '$stateParams', '$translate', 'vnApp'];
|
||||
|
||||
ngModule.component('vnClientContactIndex', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
vn-one
|
||||
label="Credit"
|
||||
model="$ctrl.creditClassification.credit",
|
||||
rule="CreditInsurance.credit"
|
||||
rule="creditInsurance.credit"
|
||||
step="1"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
|
@ -20,7 +20,7 @@
|
|||
vn-one
|
||||
label="Since"
|
||||
model="$ctrl.creditClassification.started"
|
||||
ini-options="{dateFormat: 'd-m-Y'}">
|
||||
ini-options="{enableTime: true, dateFormat: 'd-m-Y', time_24hr: true}">
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
|
|
|
@ -14,15 +14,17 @@ class Controller {
|
|||
|
||||
submit() {
|
||||
if (this.$scope.form.$invalid)
|
||||
return this.vnApp.showMessage(this.$translate.instant('Some fields are invalid'));
|
||||
return this.vnApp.showError(this.$translate.instant('Some fields are invalid'));
|
||||
|
||||
let query = `/client/api/creditClassifications/createWithInsurance`;
|
||||
let data = this.creditClassification;
|
||||
data.clientFk = this.client.id;
|
||||
|
||||
this.$http.post(query, data).then((res, err) => {
|
||||
if (res.data)
|
||||
this.$http.post(query, data).then(res => {
|
||||
if (res.data) {
|
||||
this.card.reload();
|
||||
this.$state.go('client.card.creditInsurance.index');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +34,9 @@ Controller.$inject = ['$http', '$filter', '$state', '$scope', '$translate', 'vnA
|
|||
ngModule.component('vnClientCreditInsuranceCreate', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
require: {
|
||||
card: '^vnClientCard'
|
||||
},
|
||||
bindings: {
|
||||
client: '<'
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ describe('Client', () => {
|
|||
describe('_getClassifications()', () => {
|
||||
it('should perform a GET query to define the classifications property in the controller', () => {
|
||||
let res = ['some classifications'];
|
||||
let query = '/client/api/CreditClassifications?filter=%7B%22order%22%3A%22finished%20ASC%2C%20started%20DESC%22%2C%22include%22%3A%5B%7B%22relation%22%3A%22creditInsurances%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';
|
||||
let query = '/client/api/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);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<div><vn-label translate>To</vn-label> {{classification.finished | date:'dd/MM/yyyy'}}</div>
|
||||
</vn-one>
|
||||
<vn-vertical vn-one pad-medium-h>
|
||||
<vn-horizontal ng-repeat="insurance in classification.creditInsurances track by insurance.id">
|
||||
<vn-horizontal ng-repeat="insurance in classification.insurances track by insurance.id">
|
||||
<vn-one>
|
||||
<vn-label-value label="Credit"
|
||||
value="{{::insurance.credit}}">
|
||||
|
|
|
@ -17,7 +17,7 @@ class Controller {
|
|||
order: 'finished ASC, started DESC',
|
||||
include: [
|
||||
{
|
||||
relation: 'creditInsurances',
|
||||
relation: 'insurances',
|
||||
scope: {
|
||||
fields: ['id', 'credit', 'created', 'grade'],
|
||||
order: 'created DESC',
|
||||
|
|
|
@ -3,5 +3,4 @@ New contract: Nuevo contrato
|
|||
Close contract: Cerrar contrato
|
||||
Edit contract: Modificar contrato
|
||||
View credits: Ver créditos
|
||||
Are you sure you want to close this contract?: ¿Seguro que quieres cerrar este contrato?
|
||||
Grade: Grado
|
||||
Are you sure you want to close this contract?: ¿Seguro que quieres cerrar este contrato?
|
|
@ -1,12 +1,11 @@
|
|||
<mg-ajax path="/client/api/CreditClassifications/{{post.params.classificationId}}/creditInsurances" options="vnPost"></mg-ajax>
|
||||
<mg-ajax path="/client/api/CreditClassifications/{{post.params.classificationId}}/insurances" options="vnPost"></mg-ajax>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.insurance"
|
||||
form="form"
|
||||
save="post">
|
||||
</vn-watcher>
|
||||
<form name="form"
|
||||
ng-submit="watcher.submitGo('client.card.creditInsurance.insurance.index', {classificationId: post.params.classificationId})">
|
||||
<form name="form" ng-submit="$ctrl.onSubmit()">
|
||||
<vn-card pad-large>
|
||||
<vn-title>New credit</vn-title>
|
||||
<vn-horizontal>
|
||||
|
@ -22,7 +21,7 @@
|
|||
<vn-date-picker vn-one
|
||||
label="Date"
|
||||
model="$ctrl.insurance.created"
|
||||
ini-options="{enableTime: true, dateFormat: 'd-m-Y h:i', time_24hr: true}">
|
||||
ini-options="{enableTime: true, dateFormat: 'd-m-Y', time_24hr: true}">
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
|
|
|
@ -1,18 +1,32 @@
|
|||
import ngModule from '../../../module';
|
||||
|
||||
class Controller {
|
||||
constructor($filter) {
|
||||
constructor($scope, $state, $filter) {
|
||||
this.$scope = $scope;
|
||||
this.$state = $state;
|
||||
this.insurance = {
|
||||
created: $filter('date')(new Date(), 'yyyy-MM-dd HH:mm')
|
||||
created: $filter('date')(new Date(), 'yyyy-MM-dd HH:mm:ss')
|
||||
};
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
let params = {classificationId: this.$state.params.classificationId};
|
||||
let state = 'client.card.creditInsurance.insurance.index';
|
||||
|
||||
this.$scope.watcher.submitGo(state, params).then(() => {
|
||||
this.card.reload();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$filter'];
|
||||
Controller.$inject = ['$scope', '$state', '$filter'];
|
||||
|
||||
ngModule.component('vnClientCreditInsuranceInsuranceCreate', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
require: {
|
||||
card: '^vnClientCard'
|
||||
},
|
||||
bindings: {
|
||||
client: '<'
|
||||
}
|
||||
|
|
|
@ -12,10 +12,10 @@ describe('Client', () => {
|
|||
|
||||
beforeEach(angular.mock.inject((_$componentController_, _$httpBackend_) => {
|
||||
$componentController = _$componentController_;
|
||||
let $state = {params: {classificationId: 1}};
|
||||
let $stateParams = {classificationId: 1};
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
controller = $componentController('vnClientCreditInsuranceInsuranceIndex', {$state: $state});
|
||||
controller = $componentController('vnClientCreditInsuranceInsuranceIndex', {$stateParams: $stateParams});
|
||||
}));
|
||||
|
||||
it('should perform a query to GET credit the credit classification', () => {
|
||||
|
|
|
@ -1,28 +1,39 @@
|
|||
<mg-ajax path="/client/api/CreditClassifications/{{index.params.classificationId}}/creditInsurances" options="vnIndex"></mg-ajax>
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/client/api/CreditInsurances"
|
||||
link="{creditClassification: $ctrl.$stateParams.classificationId}"
|
||||
limit="20"
|
||||
data="insurances">
|
||||
</vn-crud-model>
|
||||
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-title>Requested credits</vn-title>
|
||||
<table class="vn-grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th number translate>Credit</th>
|
||||
<th number translate>Grade</th>
|
||||
<th translate>Created</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="insurance in index.model track by insurance.id" class="list list-element">
|
||||
<td number>{{::insurance.credit | currency: '€': 2}}</td>
|
||||
<td number>{{::insurance.grade}}</td>
|
||||
<td>{{::insurance.created | date: 'dd/MM/yyyy'}}</td>
|
||||
</tr>
|
||||
<tr ng-if="index.model.count === 0" class="list list-element">
|
||||
<td colspan="6" style="text-align: center" translate>No results</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th number>Credit</vn-th>
|
||||
<vn-th number>Grade</vn-th>
|
||||
<vn-th>Created</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="insurance in insurances">
|
||||
<vn-td number>{{::insurance.credit | currency: ' €': 2}}</vn-td>
|
||||
<vn-td number>{{::insurance.grade}}</vn-td>
|
||||
<vn-td>{{::insurance.created | date: 'dd/MM/yyyy'}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
<vn-pagination
|
||||
model="model"
|
||||
scroll-selector="ui-view">
|
||||
</vn-pagination>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<button
|
||||
|
@ -30,9 +41,8 @@
|
|||
translate
|
||||
ui-sref="client.card.creditInsurance.index">Back</button>
|
||||
</vn-button-bar>
|
||||
<vn-paging vn-one margin-large-top index="index" total="index.model.count"></vn-paging>
|
||||
</vn-vertical>
|
||||
<a ui-sref="client.card.creditInsurance.insurance.create({classificationId: {{index.params.classificationId}}})"
|
||||
<a ui-sref="client.card.creditInsurance.insurance.create({classificationId: {{$ctrl.$stateParams.classificationId}}})"
|
||||
fixed-bottom-right vn-tooltip="New credit" vn-bind="+" ng-if="!$ctrl.isClosed">
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
|
@ -1,19 +1,21 @@
|
|||
import ngModule from '../../../module';
|
||||
import FilterList from 'core/src/lib/filter-list';
|
||||
|
||||
class Controller extends FilterList {
|
||||
constructor($scope, $timeout, $state, $http) {
|
||||
super($scope, $timeout, $state);
|
||||
this.modelName = 'creditClassificationFk';
|
||||
this.modelId = $state.params.classificationId;
|
||||
this.isClosed = true;
|
||||
class Controller {
|
||||
constructor($stateParams, $http) {
|
||||
this.$stateParams = $stateParams;
|
||||
this.$http = $http;
|
||||
this.isClosed = true;
|
||||
this.filter = {
|
||||
include: [
|
||||
{relation: 'classification'}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
let filter = {
|
||||
fields: ['finished'],
|
||||
where: {id: this.modelId}
|
||||
where: {id: this.$stateParams.classificationId}
|
||||
};
|
||||
filter = encodeURIComponent(JSON.stringify(filter));
|
||||
|
||||
|
@ -25,7 +27,7 @@ class Controller extends FilterList {
|
|||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$timeout', '$state', '$http'];
|
||||
Controller.$inject = ['$stateParams', '$http'];
|
||||
|
||||
ngModule.component('vnClientCreditInsuranceInsuranceIndex', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -1,29 +1,41 @@
|
|||
<mg-ajax path="/client/api/ClientCredits/filter" options="vnIndexNonAuto"></mg-ajax>
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/client/api/ClientCredits"
|
||||
filter="::$ctrl.filter"
|
||||
link="{clientFk: $ctrl.$stateParams.id}"
|
||||
limit="20"
|
||||
data="credits">
|
||||
</vn-crud-model>
|
||||
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-title>Credit</vn-title>
|
||||
<vn-grid-header on-order="$ctrl.onOrder(field, order)">
|
||||
<vn-column-header vn-one pad-medium-h field="amount" text="Credit"></vn-column-header>
|
||||
<vn-column-header vn-two pad-medium-h field="created" text="Since" default-order="ASC"></vn-column-header>
|
||||
<vn-column-header vn-two pad-medium-h field="worker.firstName" text="Employee" order-locked></vn-column-header>
|
||||
</vn-grid-header>
|
||||
<vn-one class="list list-content">
|
||||
<vn-horizontal
|
||||
vn-one class="list list-element text-center"
|
||||
pad-small-bottom
|
||||
ng-repeat="credit in index.model.instances track by credit.id">
|
||||
<vn-one pad-medium-h>{{::credit.amount | number:2}} €</vn-one>
|
||||
<vn-two pad-medium-h>{{::credit.created | date:'dd/MM/yyyy HH:mm'}}</vn-two>
|
||||
<vn-two pad-medium-h>{{::credit.worker.firstName}} {{::credit.worker.name}}</vn-two>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
<vn-one class="text-center pad-small-v" ng-if="index.model.count === 0" translate>No results</vn-one>
|
||||
<vn-horizontal vn-one class="list list-footer"></vn-horizontal>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th field="amount">Credit</vn-th>
|
||||
<vn-th field="created" default-order="DESC">Since</vn-th>
|
||||
<vn-th>Employee</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="credit in credits track by credit.id">
|
||||
<vn-td>{{::credit.amount | number:2}} €</vn-td>
|
||||
<vn-td>{{::credit.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>
|
||||
<vn-td>{{::credit.worker.firstName}} {{::credit.worker.name}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
<vn-pagination
|
||||
model="model"
|
||||
scroll-selector="ui-view">
|
||||
</vn-pagination>
|
||||
</vn-card>
|
||||
<vn-paging vn-one margin-large-top index="index" total="index.model.count"></vn-paging>
|
||||
<!-- <vn-auto-paging vn-one margin-large-top index="index" total="index.model.count" items="$ctrl.instances"></vn-auto-paging> -->
|
||||
</vn-vertical>
|
||||
<a ui-sref="client.card.credit.create" vn-bind="+" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
|
|
|
@ -1,7 +1,24 @@
|
|||
import ngModule from '../../module';
|
||||
import FilterClientList from '../../filter-client-list';
|
||||
|
||||
class Controller {
|
||||
constructor($stateParams) {
|
||||
this.$stateParams = $stateParams;
|
||||
this.filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'worker',
|
||||
scope: {
|
||||
fields: ['firstName', 'name']
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$stateParams'];
|
||||
|
||||
ngModule.component('vnClientCreditIndex', {
|
||||
template: require('./index.html'),
|
||||
controller: FilterClientList
|
||||
controller: Controller
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<mg-ajax path="/client/api/Clients/{{patch.params.id}}" options="vnPatch"></mg-ajax>
|
||||
<mg-ajax path="/client/api/Clients/{{patch.params.id}}/updateFiscalData/" options="vnPatch"></mg-ajax>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.client"
|
||||
|
|
|
@ -1,37 +1,58 @@
|
|||
<mg-ajax path="/client/api/greuges/filter" options="vnIndexNonAuto"></mg-ajax>
|
||||
<mg-ajax path="/client/api/greuges/{{edit.params.id}}/sumAmount" options="mgEdit"></mg-ajax>
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/client/api/greuges"
|
||||
filter="::$ctrl.filter"
|
||||
link="{clientFk: $ctrl.$stateParams.id}"
|
||||
limit="20"
|
||||
data="greuges">
|
||||
</vn-crud-model>
|
||||
|
||||
<mg-ajax
|
||||
path="/client/api/greuges/{{$ctrl.$stateParams.id}}/sumAmount"
|
||||
options="mgEdit">
|
||||
</mg-ajax>
|
||||
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-title>Greuge</vn-title>
|
||||
<vn-grid-header on-order="$ctrl.onOrder(field, order)">
|
||||
<vn-column-header vn-one pad-medium-h field="shipped" text="Date" default-order="ASC"></vn-column-header>
|
||||
<vn-column-header vn-two pad-medium-h field="description" text="Comment"></vn-column-header>
|
||||
<vn-column-header vn-one pad-medium-h field="amount" text="Amount"></vn-column-header>
|
||||
<vn-column-header vn-one pad-medium-h field="greugeTypeFk" text="Type"></vn-column-header>
|
||||
</vn-grid-header>
|
||||
<vn-one class="list list-content">
|
||||
<vn-horizontal
|
||||
class="list list-element text-center"
|
||||
pad-small-bottom
|
||||
ng-repeat="greuge in index.model.instances track by greuge.id">
|
||||
<vn-one pad-medium-h>{{::greuge.shipped | date:'dd/MM/yyyy HH:mm' }}</vn-one>
|
||||
<vn-two pad-medium-h>{{::greuge.description}}</vn-two>
|
||||
<vn-one pad-medium-h>{{::greuge.amount | number:2}} €</vn-one>
|
||||
<vn-one pad-medium-h>{{::greuge.greugeType.name}}</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
<vn-one class="text-center pad-small-v" ng-if="index.model.count === 0" translate>No results</vn-one>
|
||||
<vn-horizontal vn-one class="list list-footer text-center">
|
||||
<vn-one pad-medium-h></vn-one>
|
||||
<vn-two pad-medium-h></vn-two>
|
||||
<vn-one pad-medium-h ng-if="index.model.count > 0">{{edit.model.sumAmount | number:2}} €</vn-one>
|
||||
<vn-one pad-medium-h></vn-one>
|
||||
</vn-horizontal>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th field="shipped" default-order="DESC">Date</vn-th>
|
||||
<vn-th field="description">Comment</vn-th>
|
||||
<vn-th field="amount">Amount</vn-th>
|
||||
<vn-th field="greugeTypeFk">Type</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="greuge in greuges">
|
||||
<vn-td>{{::greuge.shipped | date:'dd/MM/yyyy HH:mm' }}</vn-td>
|
||||
<vn-td>{{::greuge.description}}</vn-td>
|
||||
<vn-td>{{::greuge.amount | currency: ' €': 2}}</vn-td>
|
||||
<vn-td>{{::greuge.greugeType.name}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
<vn-tfoot ng-if="model.data.length > 0">
|
||||
<vn-tr>
|
||||
<vn-td></vn-td>
|
||||
<vn-td></vn-td>
|
||||
<vn-td>
|
||||
<strong>{{edit.model.sumAmount | currency: ' €': 2}}</strong>
|
||||
</vn-td>
|
||||
<vn-td></vn-td>
|
||||
</vn-tr>
|
||||
</vn-tfoot>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
<vn-pagination
|
||||
model="model"
|
||||
scroll-selector="ui-view">
|
||||
</vn-pagination>
|
||||
</vn-card>
|
||||
<vn-paging margin-large-top vn-one index="index" total="index.model.count"></vn-paging>
|
||||
<!-- <vn-auto-paging margin-large-top vn-one index="index" total="index.model.count" items="$ctrl.instances"></vn-auto-paging> -->
|
||||
</vn-vertical>
|
||||
<a ui-sref="client.card.greuge.create" vn-bind="+" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
|
|
|
@ -1,7 +1,24 @@
|
|||
import ngModule from '../../module';
|
||||
import FilterClientList from '../../filter-client-list';
|
||||
|
||||
class Controller {
|
||||
constructor($stateParams) {
|
||||
this.$stateParams = $stateParams;
|
||||
this.filter = {
|
||||
include: [
|
||||
{
|
||||
relation: "greugeType",
|
||||
scope: {
|
||||
fields: ["id", "name"]
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$stateParams'];
|
||||
|
||||
ngModule.component('vnClientGreugeIndex', {
|
||||
template: require('./index.html'),
|
||||
controller: FilterClientList
|
||||
controller: Controller
|
||||
});
|
||||
|
|
|
@ -10,12 +10,9 @@ export default class Controller {
|
|||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return {
|
||||
or: [
|
||||
{id: value},
|
||||
{name: {regexp: value}}
|
||||
]
|
||||
};
|
||||
return /^\d+$/.test(value)
|
||||
? {id: value}
|
||||
: {name: {regexp: value}};
|
||||
case 'phone':
|
||||
return {
|
||||
or: [
|
||||
|
|
|
@ -1,35 +1,42 @@
|
|||
<mg-ajax path="/client/api/InvoiceOuts/filter" options="vnIndexNonAuto"></mg-ajax>
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/client/api/InvoiceOuts"
|
||||
filter="{}"
|
||||
link="{clientFk: $ctrl.$stateParams.id}"
|
||||
limit="20"
|
||||
data="invoices">
|
||||
</vn-crud-model>
|
||||
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-title>Invoices</vn-title>
|
||||
<vn-vertical style="text-align: center;">
|
||||
<vn-grid-header on-order="$ctrl.onOrder(field, order)">
|
||||
<vn-column-header vn-one field="ref" text="Reference" default-order="ASC"></vn-column-header>
|
||||
<vn-column-header vn-one field="issued" text="Issue date"></vn-column-header>
|
||||
<vn-column-header vn-one field="dued" text="Due date"></vn-column-header>
|
||||
<vn-column-header vn-one field="amount" text="Amount"></vn-column-header>
|
||||
</vn-grid-header>
|
||||
<vn-vertical>
|
||||
<vn-one
|
||||
ng-if="index.model.count > 0"
|
||||
class="list list-content">
|
||||
<vn-horizontal
|
||||
class="list list-element"
|
||||
pad-small-bottom
|
||||
ng-repeat="invoice in index.model.instances track by invoice.id">
|
||||
<vn-one>{{::invoice.ref}}</vn-one>
|
||||
<vn-one>{{::invoice.issued | date:'dd/MM/yyyy' }}</vn-one>
|
||||
<vn-one>{{::invoice.dued | date:'dd/MM/yyyy' }}</vn-one>
|
||||
<vn-one>{{::invoice.amount | currency:'€':2}}</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
<vn-one class="text-center pad-small-v" ng-if="index.model.count === 0" translate>No results</vn-one>
|
||||
</vn-vertical>
|
||||
<vn-horizontal vn-one class="list list-footer"></vn-horizontal>
|
||||
</vn-vertical>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th field="ref" default-order="DESC">Reference</vn-th>
|
||||
<vn-th field="issued">Issue date</vn-th>
|
||||
<vn-th field="dued">Due date</vn-th>
|
||||
<vn-th field="amount">Amount</vn-th>
|
||||
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="invoice in invoices">
|
||||
<vn-td>{{::invoice.ref}}</vn-td>
|
||||
<vn-td>{{::invoice.issued | date:'dd/MM/yyyy' }}</vn-td>
|
||||
<vn-td>{{::invoice.dued | date:'dd/MM/yyyy' }}</vn-td>
|
||||
<vn-td>{{::invoice.amount | currency:' €': 2}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
<vn-pagination
|
||||
model="model"
|
||||
scroll-selector="ui-view">
|
||||
</vn-pagination>
|
||||
</vn-card>
|
||||
<vn-paging margin-large-top vn-one index="index" total="index.model.count"></vn-paging>
|
||||
<!-- <vn-auto-paging margin-large-top vn-one index="index" total="index.model.count" items="$ctrl.instances"></vn-auto-paging> -->
|
||||
</vn-vertical>
|
|
@ -1,13 +1,12 @@
|
|||
import ngModule from '../module';
|
||||
import FilterClientList from '../filter-client-list';
|
||||
|
||||
class Controller extends FilterClientList {
|
||||
constructor($scope, $timeout, $state, $stateParams) {
|
||||
super($scope, $timeout, $state);
|
||||
$scope.$stateParams = $stateParams;
|
||||
class Controller {
|
||||
constructor($stateParams) {
|
||||
this.$stateParams = $stateParams;
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$scope', '$timeout', '$state', '$stateParams'];
|
||||
|
||||
Controller.$inject = ['$stateParams'];
|
||||
|
||||
ngModule.component('vnClientInvoice', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
Active: Activo
|
||||
Add contact: Añadir contacto
|
||||
Amount: Importe
|
||||
Client: Cliente
|
||||
Clients: Clientes
|
||||
Comercial Name: Comercial
|
||||
Contacts: Contactos
|
||||
Basic data: Datos básicos
|
||||
Back: Volver
|
||||
Fiscal data: Datos Fiscales
|
||||
Addresses: Consignatarios
|
||||
Web access: Acceso web
|
||||
|
@ -21,6 +25,4 @@ Credit : Crédito
|
|||
Credit contracts: Contratos de crédito
|
||||
Verified data: Datos comprobados
|
||||
Mandate: Mandato
|
||||
Amount: Importe
|
||||
Back: Volver
|
||||
Contacts: Contactos
|
||||
Remove contact: Eliminar
|
|
@ -1,31 +1,43 @@
|
|||
<mg-ajax path="/client/api/Mandates/filter" options="vnIndexNonAuto"></mg-ajax>
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/client/api/Mandates"
|
||||
filter="::$ctrl.filter"
|
||||
link="{clientFk: $ctrl.$stateParams.id}"
|
||||
limit="20"
|
||||
data="mandates">
|
||||
</vn-crud-model>
|
||||
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-title>Mandate</vn-title>
|
||||
<vn-grid-header on-order="$ctrl.onOrder(field, order)">
|
||||
<vn-column-header vn-one pad-medium-h field="id" text="Id"></vn-column-header>
|
||||
<vn-column-header vn-one pad-medium-h field="companyFk" text="Company"></vn-column-header>
|
||||
<vn-column-header vn-one pad-medium-h field="mandateTypeFk" text="Type"></vn-column-header>
|
||||
<vn-column-header vn-one pad-medium-h field="created" text="Register date" default-order="ASC"></vn-column-header>
|
||||
<vn-column-header vn-one pad-medium-h field="finished" text="End date"></vn-column-header>
|
||||
</vn-grid-header>
|
||||
<vn-one class="list list-content">
|
||||
<vn-horizontal
|
||||
vn-one class="list list-element text-center"
|
||||
pad-small-bottom
|
||||
ng-repeat="mandate in index.model.instances track by mandate.id">
|
||||
<vn-one pad-medium-h>{{::mandate.id}}</vn-one>
|
||||
<vn-one pad-medium-h>{{::mandate.company.code}}</vn-one>
|
||||
<vn-one pad-medium-h>{{::mandate.mandateType.name}}</vn-one>
|
||||
<vn-one pad-medium-h>{{::mandate.created | date:'dd/MM/yyyy HH:mm' }}</vn-one>
|
||||
<vn-one pad-medium-h>{{::mandate.finished | date:'dd/MM/yyyy HH:mm' || '-'}}</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
<vn-one class="text-center pad-small-v" ng-if="index.model.count === 0" translate>No results</vn-one>
|
||||
<vn-horizontal vn-one class="list list-footer"></vn-horizontal>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th field="id">Id</vn-th>
|
||||
<vn-th field="companyFk">Company</vn-th>
|
||||
<vn-th field="mandateTypeFk">Type</vn-th>
|
||||
<vn-th field="created" default-order="DESC">Register date</vn-th>
|
||||
<vn-th field="finished">End date</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="mandate in mandates">
|
||||
<vn-td>{{::mandate.id}}</vn-td>
|
||||
<vn-td>{{::mandate.company.code}}</vn-td>
|
||||
<vn-td>{{::mandate.mandateType.name}}</vn-td>
|
||||
<vn-td>{{::mandate.created | date:'dd/MM/yyyy HH:mm' }}</vn-td>
|
||||
<vn-td>{{::mandate.finished | date:'dd/MM/yyyy HH:mm' || '-'}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
<vn-pagination
|
||||
model="model"
|
||||
scroll-selector="ui-view">
|
||||
</vn-pagination>
|
||||
</vn-card>
|
||||
<vn-paging vn-one margin-large-top index="index" total="index.model.count"></vn-paging>
|
||||
<!-- <vn-auto-paging vn-one margin-large-top index="index" total="index.model.count" items="$ctrl.instances"></vn-auto-paging> -->
|
||||
</vn-vertical>
|
|
@ -1,7 +1,30 @@
|
|||
import ngModule from '../module';
|
||||
import FilterClientList from '../filter-client-list';
|
||||
|
||||
class Controller {
|
||||
constructor($stateParams) {
|
||||
this.$stateParams = $stateParams;
|
||||
this.filter = {
|
||||
include: [
|
||||
{
|
||||
relation: "mandateType",
|
||||
scope: {
|
||||
fields: ["id", "name"]
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: "company",
|
||||
scope: {
|
||||
fields: ["id", "code"]
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$stateParams'];
|
||||
|
||||
ngModule.component('vnClientMandate', {
|
||||
template: require('./index.html'),
|
||||
controller: FilterClientList
|
||||
controller: Controller
|
||||
});
|
||||
|
|
|
@ -1,25 +1,31 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/client/api/clientObservations"
|
||||
filter="{order: 'created DESC'}"
|
||||
link="{clientFk: $ctrl.$stateParams.id}"
|
||||
data="notes">
|
||||
</vn-crud-model>
|
||||
|
||||
<vn-vertical>
|
||||
<vn-card ng-show="$ctrl.observations.length" pad-large>
|
||||
<vn-card pad-large>
|
||||
<vn-title>Notes</vn-title>
|
||||
<vn-vertical
|
||||
ng-repeat="n in $ctrl.observations"
|
||||
ng-repeat="note in notes"
|
||||
pad-small
|
||||
border-solid
|
||||
border-radius
|
||||
margin-small-bottom>
|
||||
<vn-horizontal margin-small-bottom style="color: #666">
|
||||
<vn-one>{{::n.worker.firstName}} {{::n.worker.name}}</vn-one>
|
||||
<vn-auto>{{::n.created | date:'dd/MM/yyyy HH:mm'}}</vn-auto>
|
||||
<vn-one>{{::note.worker.firstName}} {{::note.worker.name}}</vn-one>
|
||||
<vn-auto>{{::note.created | date:'dd/MM/yyyy HH:mm'}}</vn-auto>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="text">
|
||||
{{::n.text}}
|
||||
{{::note.text}}
|
||||
</vn-horizontal>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
</vn-vertical>
|
||||
<vn-float-button
|
||||
fixed-bottom-right
|
||||
ng-click="$ctrl.newObservation()"
|
||||
vn-bind="+"
|
||||
icon="add">
|
||||
</vn-float-button>
|
||||
|
||||
<a ui-sref="client.card.note.create({id: $ctrl.$stateParams.id})" vn-bind="+" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
||||
|
|
|
@ -1,31 +1,12 @@
|
|||
import ngModule from '../../module';
|
||||
|
||||
export default class Controller {
|
||||
constructor($http, $state) {
|
||||
this.$http = $http;
|
||||
this.$state = $state;
|
||||
}
|
||||
|
||||
$onChanges() {
|
||||
if (this.client) {
|
||||
this.getObservation(this.client.id);
|
||||
}
|
||||
}
|
||||
|
||||
getObservation(clientId) {
|
||||
let json = JSON.stringify({where: {clientFk: this.client.id}, order: 'created DESC'});
|
||||
this.$http.get(`/client/api/clientObservations?filter=${json}`).then(
|
||||
json => {
|
||||
this.observations = json.data;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
newObservation() {
|
||||
this.$state.go("client.card.note.create", {id: this.client.id});
|
||||
constructor($stateParams) {
|
||||
this.$stateParams = $stateParams;
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$http', '$state'];
|
||||
|
||||
Controller.$inject = ['$stateParams'];
|
||||
|
||||
ngModule.component('vnClientNote', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
import './index';
|
||||
|
||||
describe('Client', () => {
|
||||
describe('Component vnClientNote', () => {
|
||||
let $componentController;
|
||||
let $state;
|
||||
let $httpBackend;
|
||||
let controller;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('client');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, _$state_, _$httpBackend_) => {
|
||||
$componentController = _$componentController_;
|
||||
$state = _$state_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
controller = $componentController('vnClientNote', {$state: $state});
|
||||
}));
|
||||
|
||||
describe('$onChanges()', () => {
|
||||
it(`should call getObservation() with the client id`, () => {
|
||||
controller.client = {
|
||||
id: 1234
|
||||
};
|
||||
spyOn(controller, 'getObservation').and.returnValue();
|
||||
controller.$onChanges();
|
||||
|
||||
expect(controller.getObservation).toHaveBeenCalledWith(1234);
|
||||
});
|
||||
});
|
||||
|
||||
describe('$getObservation()', () => {
|
||||
it(`should request to GET the client notes`, () => {
|
||||
controller.client = {id: '1234'};
|
||||
let jsonString = JSON.stringify({where: {clientFk: '1234'}, order: 'created DESC'});
|
||||
let json = {data: 'some data'};
|
||||
$httpBackend.when('GET', `/client/api/clientObservations?filter=${jsonString}`).respond(json);
|
||||
$httpBackend.expectGET(`/client/api/clientObservations?filter=${jsonString}`, {Accept: 'application/json, text/plain, */*'});
|
||||
controller.getObservation();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.observations).toEqual(json);
|
||||
});
|
||||
});
|
||||
|
||||
describe('$newObservation()', () => {
|
||||
it(`should redirect the user to the newObservation view`, () => {
|
||||
controller.client = {id: '1234'};
|
||||
spyOn(controller.$state, 'go');
|
||||
controller.newObservation();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('client.card.note.create', Object({id: '1234'}));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,37 +1,53 @@
|
|||
<mg-ajax path="/client/api/Recoveries/filter" options="vnIndexNonAuto"></mg-ajax>
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/client/api/Recoveries"
|
||||
filter="{}"
|
||||
link="{clientFk: $ctrl.$stateParams.id}"
|
||||
limit="20"
|
||||
data="recoveries">
|
||||
</vn-crud-model>
|
||||
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-title>Recovery</vn-title>
|
||||
<vn-grid-header on-order="$ctrl.onOrder(field, order)">
|
||||
<vn-column-header vn-one pad-medium-h field="started" text="Since" default-order="ASC"></vn-column-header>
|
||||
<vn-column-header vn-one pad-medium-h field="finished" text="To"></vn-column-header>
|
||||
<vn-column-header vn-one pad-medium-h field="amount" text="Amount"></vn-column-header>
|
||||
<vn-column-header vn-one pad-medium-h field="period" text="Period"></vn-column-header>
|
||||
</vn-grid-header>
|
||||
<vn-one class="list list-content">
|
||||
<vn-horizontal
|
||||
vn-one class="list list-element text-center"
|
||||
pad-small-bottom
|
||||
ng-repeat="recovery in index.model.instances track by $index">
|
||||
<vn-none pad-medium-h orange>
|
||||
<i class="material-icons pointer"
|
||||
vn-tooltip="Finish that recovery period"
|
||||
ng-if="!recovery.finished"
|
||||
ng-click="$ctrl.setFinished(recovery)">lock</i>
|
||||
</vn-none>
|
||||
<vn-one pad-medium-h>{{::recovery.started | date:'dd/MM/yyyy' }}</vn-one>
|
||||
<vn-one pad-medium-h>{{recovery.finished | date:'dd/MM/yyyy' }}</vn-one>
|
||||
<vn-one pad-medium-h>{{::recovery.amount | currency:'€':0}}</vn-one>
|
||||
<vn-one pad-medium-h>{{::recovery.period}}</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
<vn-one class="text-center pad-small-v" ng-if="index.model.count === 0" translate>No results</vn-one>
|
||||
<vn-horizontal vn-one class="list list-footer"></vn-horizontal>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th></vn-th>
|
||||
<vn-th field="started" default-order="DESC">Since</vn-th>
|
||||
<vn-th field="finished">To</vn-th>
|
||||
<vn-th field="amount">Amount</vn-th>
|
||||
<vn-th field="period">Period</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="recovery in recoveries">
|
||||
<vn-td>
|
||||
<vn-icon
|
||||
class="bright pointer"
|
||||
icon="lock"
|
||||
vn-tooltip="Finish that recovery period"
|
||||
ng-if="!recovery.finished"
|
||||
ng-click="$ctrl.setFinished(recovery)">
|
||||
</vn-icon>
|
||||
</vn-td>
|
||||
<vn-td>{{::recovery.started | date:'dd/MM/yyyy' }}</vn-td>
|
||||
<vn-td>{{recovery.finished | date:'dd/MM/yyyy' }}</vn-td>
|
||||
<vn-td>{{::recovery.amount | currency:' €': 0}}</vn-td>
|
||||
<vn-td>{{::recovery.period}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
<vn-pagination
|
||||
model="model"
|
||||
scroll-selector="ui-view">
|
||||
</vn-pagination>
|
||||
</vn-card>
|
||||
<vn-paging vn-one margin-large-top index="index" total="index.model.count"></vn-paging>
|
||||
<!-- <vn-auto-paging vn-one margin-large-top index="index" total="index.model.count" items="$ctrl.instances"></vn-auto-paging> -->
|
||||
</vn-vertical>
|
||||
<a ui-sref="client.card.recovery.create" vn-bind="+" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
import ngModule from '../../module';
|
||||
import FilterClientList from '../../filter-client-list';
|
||||
|
||||
class Controller extends FilterClientList {
|
||||
constructor($scope, $timeout, $state, $http) {
|
||||
super($scope, $timeout, $state);
|
||||
class Controller {
|
||||
constructor($stateParams, $scope, $http) {
|
||||
this.$stateParams = $stateParams;
|
||||
this.$scope = $scope;
|
||||
this.$http = $http;
|
||||
}
|
||||
|
||||
setFinished(recovery) {
|
||||
if (!recovery.finished) {
|
||||
let params = {finished: Date.now()};
|
||||
this.$http.patch(`/client/api/Recoveries/${recovery.id}`, params).then(
|
||||
() => this.$.index.accept()
|
||||
() => this.$scope.model.refresh()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$timeout', '$state', '$http'];
|
||||
Controller.$inject = ['$stateParams', '$scope', '$http'];
|
||||
|
||||
ngModule.component('vnClientRecoveryIndex', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -118,8 +118,8 @@
|
|||
</vn-label-value>
|
||||
<p>
|
||||
<vn-check
|
||||
label="Received core VNH"
|
||||
field="$ctrl.summary.hasCoreVnh"
|
||||
label="Received LCR"
|
||||
field="$ctrl.summary.hasLcr"
|
||||
disabled="true">
|
||||
</vn-check>
|
||||
</p>
|
||||
|
@ -199,9 +199,16 @@
|
|||
<vn-label-value label="Credit"
|
||||
value="{{$ctrl.summary.credit | currency:'€ ':2}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Secured credit"
|
||||
value="{{$ctrl.summary.creditInsurance | currency:'€ ':2}}">
|
||||
</vn-label-value>
|
||||
<vn-horizontal>
|
||||
<vn-one>
|
||||
<vn-label-value label="Secured credit"
|
||||
value="{{$ctrl.summary.creditInsurance | currency:'€ ':2}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one title="Grade">
|
||||
{{$ctrl.grade ? ' / ' + $ctrl.grade : ' / - '}}
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-vertical>
|
||||
|
|
|
@ -11,8 +11,12 @@ class Controller {
|
|||
return;
|
||||
|
||||
this.$http.get(`/client/api/Clients/${this.client.id}/summary`).then(res => {
|
||||
if (res && res.data)
|
||||
if (res && res.data) {
|
||||
this.summary = res.data;
|
||||
|
||||
if (res.data.classifications.length)
|
||||
this.grade = res.data.classifications[0].insurances[0].grade;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
<vn-horizontal margin-medium-top>
|
||||
<vn-one></vn-one>
|
||||
<vn-auto>
|
||||
<vn-spinner enable="$ctrl.watchScroll"></vn-spinner>
|
||||
</vn-auto>
|
||||
<vn-one></vn-one>
|
||||
</vn-horizontal>
|
|
@ -1,123 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import getWatchers from '../../lib/get-watchers';
|
||||
|
||||
class AutoPaging {
|
||||
constructor($http, $window, $element, $timeout, vnApp, $translate, $scope) {
|
||||
this.$http = $http;
|
||||
this.$window = $window;
|
||||
this.$element = $element;
|
||||
this.$timeout = $timeout;
|
||||
this.vnApp = vnApp;
|
||||
this.$translate = $translate;
|
||||
this.$scope = $scope;
|
||||
|
||||
this.numPerPage = null;
|
||||
this.maxItems = 0;
|
||||
this.watchScroll = false;
|
||||
this.waitingNewPage = false;
|
||||
|
||||
this.handlerScroll = this.onScroll.bind(this);
|
||||
}
|
||||
|
||||
get numPages() {
|
||||
return this.numPerPage ? Math.ceil(this.maxItems / this.numPerPage) : 0;
|
||||
}
|
||||
|
||||
loadNewPage() {
|
||||
this.index.filter.page++;
|
||||
this.waitingNewPage = true;
|
||||
|
||||
this.index.accept().then(res => {
|
||||
this.$timeout(() => {
|
||||
res.instances.forEach(item => {
|
||||
this.items.push(item);
|
||||
});
|
||||
this.$scope.$apply();
|
||||
this.checkWatchers();
|
||||
});
|
||||
if (this.index.filter.page == this.numPages) {
|
||||
this.cancelScroll();
|
||||
}
|
||||
this.waitingNewPage = false;
|
||||
});
|
||||
}
|
||||
|
||||
checkPosition() {
|
||||
let element = this.$element[0].querySelector('vn-spinner');
|
||||
let position = element.getBoundingClientRect();
|
||||
let isVisible = position.y < document.body.offsetHeight + 150;
|
||||
if (this.currentPage < this.numPages && isVisible && !this.waitingNewPage) {
|
||||
this.loadNewPage();
|
||||
}
|
||||
}
|
||||
|
||||
onScroll() {
|
||||
this.checkPosition();
|
||||
}
|
||||
|
||||
startScroll() {
|
||||
this.watchScroll = true;
|
||||
this.checkPosition();
|
||||
let mainView = this.$window.document.querySelector('.main-view > ui-view.ng-scope');
|
||||
angular.element(mainView).bind("scroll", this.handlerScroll);
|
||||
}
|
||||
|
||||
cancelScroll() {
|
||||
this.watchScroll = false;
|
||||
let mainView = this.$window.document.querySelector('.main-view > ui-view.ng-scope');
|
||||
angular.element(mainView).unbind("scroll", this.handlerScroll);
|
||||
}
|
||||
|
||||
checkScroll() {
|
||||
if (this.numPages > this.currentPage && !this.watchScroll) {
|
||||
this.startScroll();
|
||||
} else if (this.numPages <= this.currentPage && this.watchScroll) {
|
||||
this.cancelScroll();
|
||||
}
|
||||
}
|
||||
|
||||
checkWatchers() {
|
||||
let watchers = getWatchers();
|
||||
if (watchers > 3000 && this.watchScroll) {
|
||||
this.cancelScroll();
|
||||
this.vnApp.showMessage(
|
||||
this.$translate.instant('Auto-scroll interrupted, please adjust the search')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$onChanges(changes) {
|
||||
if (!this.index) return;
|
||||
|
||||
this.numPerPage = this.index.filter.size;
|
||||
this.currentPage = this.index.filter.page;
|
||||
this.currentInstances = this.items;
|
||||
if (changes.total)
|
||||
this.maxItems = changes.total.currentValue;
|
||||
|
||||
this.checkScroll();
|
||||
}
|
||||
|
||||
$postLink() {
|
||||
this.checkScroll();
|
||||
}
|
||||
|
||||
$doCheck() {
|
||||
if (this.index && this.index.filter && this.index.filter.page && this.index.filter.page != this.currentPage) {
|
||||
this.currentPage = this.index.filter.page;
|
||||
this.checkScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AutoPaging.$inject = ['$http', '$window', '$element', '$timeout', 'vnApp', '$translate', '$scope'];
|
||||
|
||||
ngModule.component('vnAutoPaging', {
|
||||
template: require('./auto-paging.html'),
|
||||
bindings: {
|
||||
index: '<',
|
||||
total: '<',
|
||||
items: '<'
|
||||
},
|
||||
controller: AutoPaging
|
||||
});
|
|
@ -1,61 +0,0 @@
|
|||
import './auto-paging.js';
|
||||
import template from './auto-paging.html';
|
||||
|
||||
describe('Component vnAutoPaging', () => {
|
||||
let $http;
|
||||
let $window;
|
||||
let $element;
|
||||
let $timeout;
|
||||
let controller;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('client');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, _$httpBackend_, _$window_, _$timeout_) => {
|
||||
$http = _$httpBackend_;
|
||||
$window = _$window_;
|
||||
$timeout = _$timeout_;
|
||||
$element = angular.element(`<div>${template}</div>`);
|
||||
|
||||
controller = _$componentController_('vnAutoPaging', {$http, $window, $element, $timeout});
|
||||
}));
|
||||
|
||||
describe('onChanges: actions when index object changes', () => {
|
||||
beforeEach(() => {
|
||||
controller.index = {
|
||||
filter: {
|
||||
size: 5,
|
||||
page: 1
|
||||
}
|
||||
};
|
||||
controller.items = [1, 2, 3, 4, 5];
|
||||
});
|
||||
|
||||
it('call startScroll() if there are pages to load', () => {
|
||||
let changes = {
|
||||
total: {
|
||||
currentValue: 20
|
||||
}
|
||||
};
|
||||
spyOn(controller, 'startScroll');
|
||||
|
||||
controller.$onChanges(changes);
|
||||
|
||||
expect(controller.startScroll).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('call stopScroll() if there are not pages to load', () => {
|
||||
let changes = {
|
||||
total: {
|
||||
currentValue: 5
|
||||
}
|
||||
};
|
||||
controller.watchScroll = true;
|
||||
spyOn(controller, 'cancelScroll');
|
||||
controller.$onChanges(changes);
|
||||
|
||||
expect(controller.cancelScroll).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -17,11 +17,6 @@
|
|||
</div>
|
||||
<label class="mdl-textfield__label" translate>{{::$ctrl.label}}</label>
|
||||
</div>
|
||||
<i class="material-icons pointer"
|
||||
ng-show="!$ctrl.disabled && $ctrl.hasValue && ($ctrl.hasFocus || $ctrl.hasMouseIn)"
|
||||
ng-click="$ctrl.clear()">
|
||||
clear
|
||||
</i>
|
||||
</div>
|
||||
<vn-drop-down
|
||||
vn-id="drop-down"
|
||||
|
|
|
@ -31,6 +31,15 @@ export default class Autocomplete extends Input {
|
|||
this.element.querySelector('.mdl-textfield'));
|
||||
}
|
||||
|
||||
set url(value) {
|
||||
this._url = value;
|
||||
this.refreshSelection();
|
||||
}
|
||||
|
||||
get url() {
|
||||
return this._url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {any} The autocomplete value.
|
||||
*/
|
||||
|
|
|
@ -21,6 +21,16 @@ describe('Component vnAutocomplete', () => {
|
|||
controller = _$componentController_('vnAutocomplete', {$element, $scope, $httpBackend, $transclude: null});
|
||||
}));
|
||||
|
||||
describe('url() setter', () => {
|
||||
it(`should set url controllers property and call refreshSelection`, () => {
|
||||
spyOn(controller, "refreshSelection");
|
||||
controller.url = "url";
|
||||
|
||||
expect(controller.url).toEqual("url");
|
||||
expect(controller.refreshSelection).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('field() setter/getter', () => {
|
||||
it(`should set field controllers property`, () => {
|
||||
controller.field = data.id;
|
||||
|
|
|
@ -5,6 +5,7 @@ vn-drop-down {
|
|||
.dropdown {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: inherit;
|
||||
|
||||
& > .filter {
|
||||
position: relative;
|
||||
|
|
|
@ -26,6 +26,7 @@ export default class IconMenu extends Input {
|
|||
|
||||
onClick(event) {
|
||||
event.preventDefault();
|
||||
if (this.onOpen) this.onOpen();
|
||||
this.showDropDown();
|
||||
}
|
||||
|
||||
|
@ -81,7 +82,8 @@ ngModule.component('vnIconMenu', {
|
|||
multiple: '<?',
|
||||
onChange: '&?',
|
||||
icon: '@?',
|
||||
translateFields: '<?'
|
||||
translateFields: '<?',
|
||||
onOpen: '&?'
|
||||
},
|
||||
transclude: {
|
||||
tplItem: '?tplItem'
|
||||
|
|
|
@ -34,7 +34,6 @@ import './float-button/float-button';
|
|||
import './step-control/step-control';
|
||||
import './label-value/label-value';
|
||||
import './paging/paging';
|
||||
import './auto-paging/auto-paging';
|
||||
import './pagination/pagination';
|
||||
import './searchbar/searchbar';
|
||||
import './table';
|
||||
|
|
|
@ -14,7 +14,7 @@ import './style.scss';
|
|||
class Pagination extends Component {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.scrollOffset = 20;
|
||||
this.scrollOffset = 150;
|
||||
this.scrollHandler = e => this.onScroll(e);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,15 +75,6 @@ export default class Popover extends Component {
|
|||
|
||||
this.document.addEventListener('keydown', this.docKeyDownHandler);
|
||||
this.document.addEventListener('focusin', this.docFocusInHandler);
|
||||
let firstFocusable = this.element.querySelector('input, textarea');
|
||||
if (firstFocusable) {
|
||||
firstFocusable.addEventListener('focus', () => {
|
||||
firstFocusable.select();
|
||||
});
|
||||
setTimeout(() => {
|
||||
firstFocusable.focus();
|
||||
}, 200);
|
||||
}
|
||||
|
||||
this.deregisterCallback = this.$transitions.onStart({}, () => this.hide());
|
||||
this.relocate();
|
||||
|
@ -136,10 +127,10 @@ export default class Popover extends Component {
|
|||
|
||||
let arrowHeight = Math.sqrt(Math.pow(arrowRect.height, 2) * 2) / 2;
|
||||
|
||||
let top = parentRect.top + parentRect.height + arrowHeight;
|
||||
let left = parentRect.left;
|
||||
let height = popoverRect.height;
|
||||
let width = Math.max(popoverRect.width, parentRect.width);
|
||||
let top = parentRect.top + parentRect.height + arrowHeight;
|
||||
let left = parentRect.left + parentRect.width / 2 - width / 2;
|
||||
|
||||
let margin = 10;
|
||||
let showTop = top + height + margin > window.innerHeight;
|
||||
|
|
|
@ -19,25 +19,24 @@
|
|||
}
|
||||
& > .popover {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
box-shadow: 0 .1em .4em rgba(1, 1, 1, .4);
|
||||
z-index: 0;
|
||||
|
||||
& > .arrow {
|
||||
width: 1em;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin: -.5em;
|
||||
background-color: white;
|
||||
box-shadow: 0 .1em .4em rgba(1, 1, 1, .4);
|
||||
position: absolute;
|
||||
transform: rotate(45deg);
|
||||
z-index: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
& > .content {
|
||||
width: 100%;
|
||||
border-radius: .1em;
|
||||
overflow: auto;
|
||||
background-color: white;
|
||||
z-index: 1;
|
||||
height: inherit;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ export default class CrudModel extends ModelProxy {
|
|||
this.refresh();
|
||||
}
|
||||
|
||||
refresh(usFilter, usData) {
|
||||
refresh(usFilter) {
|
||||
if (!this.url) return;
|
||||
|
||||
let myFilter = {
|
||||
|
@ -27,8 +27,7 @@ export default class CrudModel extends ModelProxy {
|
|||
where: mergeWhere(this.link, this.where),
|
||||
include: this.include,
|
||||
order: this.order,
|
||||
limit: this.limit,
|
||||
userData: this.userData
|
||||
limit: this.limit
|
||||
};
|
||||
|
||||
let filter = this.filter;
|
||||
|
@ -47,9 +46,16 @@ export default class CrudModel extends ModelProxy {
|
|||
sendRequest(filter, append) {
|
||||
this.cancelRequest();
|
||||
this.canceler = this.$q.defer();
|
||||
let options = {timeout: this.canceler.promise};
|
||||
let json = encodeURIComponent(JSON.stringify(filter));
|
||||
return this.$http.get(`${this.url}?filter=${json}`, options).then(
|
||||
|
||||
let options = {
|
||||
timeout: this.canceler.promise,
|
||||
params: {filter: filter}
|
||||
};
|
||||
|
||||
if (this.userParams instanceof Object)
|
||||
Object.assign(options.params, this.userParams);
|
||||
|
||||
return this.$http.get(this.url, options).then(
|
||||
json => this.onRemoteDone(json, filter, append),
|
||||
json => this.onRemoteError(json)
|
||||
);
|
||||
|
@ -118,7 +124,7 @@ export default class CrudModel extends ModelProxy {
|
|||
return changes;
|
||||
}
|
||||
|
||||
save(ignoreChanges) {
|
||||
save() {
|
||||
let changes = this.getChanges();
|
||||
|
||||
if (!changes)
|
||||
|
@ -146,7 +152,7 @@ ngModule.component('vnCrudModel', {
|
|||
order: '@?',
|
||||
limit: '<?',
|
||||
filter: '<?',
|
||||
userData: '<?',
|
||||
userParams: '<?',
|
||||
primaryKey: '@?',
|
||||
autoLoad: '<?'
|
||||
}
|
||||
|
@ -225,8 +231,6 @@ function mergeFilters(src, dst) {
|
|||
res.order = src.order;
|
||||
if (src.limit)
|
||||
res.limit = src.limit;
|
||||
if (src.userData)
|
||||
res.userData = src.userData;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,15 @@ export default class RestModel {
|
|||
this.clear();
|
||||
}
|
||||
|
||||
set staticData(value) {
|
||||
this._staticData = value;
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
get staticData() {
|
||||
return this._staticData;
|
||||
}
|
||||
|
||||
get isLoading() {
|
||||
return this.canceler != null;
|
||||
}
|
||||
|
@ -48,11 +57,11 @@ export default class RestModel {
|
|||
|
||||
this.clear();
|
||||
this.sendRequest(filter);
|
||||
} else if (this.staticData) {
|
||||
} else if (this._staticData) {
|
||||
if (search)
|
||||
this.data = this.$filter('filter')(this.staticData, search);
|
||||
this.data = this.$filter('filter')(this._staticData, search);
|
||||
else
|
||||
this.data = this.staticData;
|
||||
this.data = this._staticData;
|
||||
this.dataChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,14 +105,34 @@ export default class Controller extends Component {
|
|||
}
|
||||
|
||||
pushFilterToState(filter) {
|
||||
let history = window.history || {pushState: () => {
|
||||
console.error('Error in history.pushState(): Browser incompatibility error');
|
||||
}};
|
||||
let aux = window.location.hash.split('?q=');
|
||||
if (Object.keys(filter).length)
|
||||
history.pushState({}, null, `${aux[0]}?q=${encodeURIComponent(JSON.stringify(filter))}`);
|
||||
else
|
||||
history.pushState({}, null, aux[0]);
|
||||
let state = window.location.hash.split('?')[0];
|
||||
let keys = Object.keys(filter);
|
||||
|
||||
if (keys.length) {
|
||||
let hashFilter = {};
|
||||
|
||||
keys.forEach(key => {
|
||||
let value = filter[key];
|
||||
|
||||
if (value instanceof Date)
|
||||
hashFilter[key] = value;
|
||||
else
|
||||
switch (typeof value) {
|
||||
case 'number':
|
||||
case 'string':
|
||||
case 'boolean':
|
||||
hashFilter[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
let search = encodeURIComponent(JSON.stringify(hashFilter));
|
||||
state += `?q=${search}`;
|
||||
}
|
||||
|
||||
if (!window.history)
|
||||
throw new Error('Browser incompatibility: window.history not found');
|
||||
|
||||
window.history.pushState({}, null, state);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,15 +18,17 @@ export default class Table {
|
|||
this.order = order;
|
||||
}
|
||||
|
||||
applyFilter(field = this.field, order = this.order) {
|
||||
this.model.filter.order = `${field} ${order}`;
|
||||
applyOrder(field = this.field, order = this.order) {
|
||||
if (!field) return;
|
||||
|
||||
this.model.order = `${field} ${order}`;
|
||||
this.model.refresh();
|
||||
this.setActiveArrow();
|
||||
}
|
||||
|
||||
$onChanges() {
|
||||
if (this.model)
|
||||
this.applyFilter();
|
||||
if (this.model && this.model.filter)
|
||||
this.applyOrder();
|
||||
}
|
||||
|
||||
setActiveArrow() {
|
||||
|
|
|
@ -13,6 +13,7 @@ vn-table {
|
|||
display: table-header-group;
|
||||
|
||||
vn-th[field] {
|
||||
position: relative;
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
|
@ -77,6 +78,7 @@ vn-table {
|
|||
}
|
||||
|
||||
vn-td, vn-th {
|
||||
vertical-align: middle;
|
||||
display: table-cell;
|
||||
text-align: left;
|
||||
padding: 10px;
|
||||
|
@ -84,6 +86,10 @@ vn-table {
|
|||
&[number]{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
vn-icon.bright, i.bright {
|
||||
color: #f7931e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,29 @@
|
|||
@import "colors";
|
||||
vn-textfield {
|
||||
margin: 20px 0!important;
|
||||
display: block;
|
||||
display: inline-block;
|
||||
|
||||
.leftIcons, .rightIcons, .suffix{
|
||||
display: inline-flex;
|
||||
color: $secondary-font-color;
|
||||
& .material-icons{
|
||||
font-size: 20px!important
|
||||
}
|
||||
}
|
||||
.leftIcons{
|
||||
margin-right: 3px;
|
||||
}
|
||||
.container{
|
||||
& > .container {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
padding-bottom: 2px;
|
||||
display: flex;
|
||||
|
||||
& > .textField {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding-top: 4px;
|
||||
}
|
||||
}
|
||||
.textField{
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
position: relative;
|
||||
padding: 4px 0;
|
||||
.leftIcons, .rightIcons, .suffix {
|
||||
display: flex;
|
||||
color: $secondary-font-color;
|
||||
|
||||
.material-icons {
|
||||
font-size: 20px !important
|
||||
}
|
||||
}
|
||||
.infix {
|
||||
position: relative;
|
||||
|
@ -31,43 +32,61 @@ vn-textfield {
|
|||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
i.pointer {
|
||||
i.clear {
|
||||
visibility: hidden;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #222;
|
||||
}
|
||||
}
|
||||
&:hover i.clear {
|
||||
visibility: visible;
|
||||
}
|
||||
i.visible {
|
||||
visibility: visible;
|
||||
}
|
||||
label {
|
||||
position: absolute;
|
||||
bottom: 2px;
|
||||
bottom: 0;
|
||||
padding: 4px 0!important;
|
||||
pointer-events: none;
|
||||
color: $secondary-font-color;
|
||||
transition-duration: .2s;
|
||||
transition-timing-function: cubic-bezier(.4,0,.2,1);
|
||||
}
|
||||
&.not-empty label{
|
||||
bottom: 24px;
|
||||
color: $main-01;
|
||||
padding: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
input {
|
||||
outline: none;
|
||||
border: none;
|
||||
font-family: "Helvetica","Arial",sans-serif;
|
||||
font-family: "Helvetica", "Arial", sans-serif;
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
background: 0 0;
|
||||
color: inherit;
|
||||
padding: 4px;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 0!important;
|
||||
|
||||
&[type=number] {
|
||||
-moz-appearance: textfield;
|
||||
&::-webkit-outer-spin-button,
|
||||
&::-webkit-inner-spin-button{
|
||||
&::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
&:invalid {
|
||||
box-shadow:none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
.underline{
|
||||
.underline {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 1px;
|
||||
|
@ -76,49 +95,40 @@ vn-textfield {
|
|||
width: 100%;
|
||||
background-color: rgba(0,0,0,.12);
|
||||
}
|
||||
.selected.underline{
|
||||
.selected.underline {
|
||||
background-color: rgb(255,152,0);
|
||||
height: 2px;
|
||||
left: 50%;
|
||||
width: 0px!important;
|
||||
width: 0px !important;
|
||||
transition-duration: 0.2s;
|
||||
transition-timing-function: cubic-bezier(.4,0,.2,1);
|
||||
}
|
||||
&.not-empty {
|
||||
& label {
|
||||
bottom: 24px;
|
||||
color: $main-01;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
div.selected{
|
||||
|
||||
div.selected {
|
||||
&.container{
|
||||
border-bottom: 0px;
|
||||
}
|
||||
& label {
|
||||
label {
|
||||
bottom: 24px;
|
||||
color: $main-01;
|
||||
font-size: 12px;
|
||||
}
|
||||
& .selected.underline{
|
||||
.selected.underline{
|
||||
left: 0;
|
||||
width: 100%!important;
|
||||
}
|
||||
}
|
||||
& > div.container > div.textField > div.infix.invalid{
|
||||
& > div.container > div.textField > div.infix.invalid {
|
||||
@extend div.selected;
|
||||
|
||||
& > span.mdl-textfield__error{
|
||||
& > span.mdl-textfield__error {
|
||||
visibility: visible;
|
||||
margin-top: 9px;
|
||||
}
|
||||
& > label{
|
||||
& > label {
|
||||
color: #d50000;
|
||||
}
|
||||
}
|
||||
.infix.invalid + .underline {
|
||||
&{
|
||||
background-color: #d50000;
|
||||
}
|
||||
background-color: #d50000;
|
||||
}
|
||||
}
|
|
@ -1,36 +1,30 @@
|
|||
<div class="container"
|
||||
ng-class="{selected: $ctrl.hasFocus}"
|
||||
ng-mouseenter="$ctrl.hasMouseIn = true"
|
||||
ng-mouseleave="$ctrl.hasMouseIn = false"
|
||||
style="display: inline-flex"
|
||||
>
|
||||
ng-class="{selected: $ctrl.hasFocus}">
|
||||
<div class="textField">
|
||||
<div class="leftIcons">
|
||||
</div>
|
||||
|
||||
<div class="leftIcons"></div>
|
||||
<div class="infix">
|
||||
<input
|
||||
type="{{$ctrl.type}}"
|
||||
name="{{$ctrl.name}}"
|
||||
ng-model="$ctrl.value"
|
||||
vn-validation="{{$ctrl.rule}}"
|
||||
ng-disabled="$ctrl.disabled"
|
||||
ng-readonly="$ctrl.readonly"
|
||||
ng-focus="$ctrl.hasFocus = true"
|
||||
ng-blur="$ctrl.hasFocus = false"
|
||||
tabindex="{{$ctrl.input.tabindex}}"
|
||||
/>
|
||||
|
||||
<input
|
||||
class="mdl-textfield__input"
|
||||
type="{{$ctrl.type}}"
|
||||
name="{{$ctrl.name}}"
|
||||
ng-model="$ctrl.value"
|
||||
vn-validation="{{$ctrl.rule}}"
|
||||
ng-disabled="$ctrl.disabled"
|
||||
ng-readonly="$ctrl.readonly"
|
||||
ng-focus="$ctrl.hasFocus = true"
|
||||
ng-blur="$ctrl.hasFocus = false"
|
||||
tabindex="{{$ctrl.input.tabindex}}"/>
|
||||
<label class="label" translate>{{::$ctrl.label}}</label>
|
||||
</div>
|
||||
<div class="underline"></div>
|
||||
<div class="selected underline"></div>
|
||||
<div class="suffix">
|
||||
<i class="material-icons pointer"
|
||||
<i class="material-icons clear"
|
||||
translate-attr="{title: 'Clear'}"
|
||||
ng-class="{visible:
|
||||
!$ctrl.disabled
|
||||
&& $ctrl.hasValue
|
||||
&& ($ctrl.hasFocus || $ctrl.hasMouseIn)
|
||||
&& ($ctrl.hasFocus)
|
||||
&& !$ctrl.unclearable}"
|
||||
ng-click="$ctrl.clear()">
|
||||
clear
|
||||
|
|
|
@ -44,6 +44,7 @@ export default class Textfield extends Input {
|
|||
|
||||
if (this.hasValue) this.element.classList.add('not-empty');
|
||||
else this.element.classList.remove('not-empty');
|
||||
this.mdlUpdate();
|
||||
}
|
||||
get value() {
|
||||
return this._value;
|
||||
|
@ -57,6 +58,10 @@ export default class Textfield extends Input {
|
|||
set vnTabIndex(value) {
|
||||
this.input.tabindex = value;
|
||||
}
|
||||
mdlUpdate() {
|
||||
let mdlElement = this.element.firstChild.MaterialTextfield;
|
||||
if (mdlElement) mdlElement.updateClasses_();
|
||||
}
|
||||
clear() {
|
||||
this.value = null;
|
||||
this.input.focus();
|
||||
|
|
|
@ -57,7 +57,7 @@ export default class Th {
|
|||
|
||||
this.updateArrow();
|
||||
|
||||
this.table.applyFilter(this.field, this.order);
|
||||
this.table.applyOrder(this.field, this.order);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,3 +8,4 @@ import './on-error-src';
|
|||
import './zoom-image';
|
||||
import './visible-by';
|
||||
import './bind';
|
||||
import './repeat-last';
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
/**
|
||||
* Calls a passed function if is the last element from an ng-repeat.
|
||||
*
|
||||
* @attribute {String} onLast - Callback function
|
||||
* @return {Object} The directive
|
||||
*/
|
||||
directive.$inject = ['$parse'];
|
||||
export function directive($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function($scope, $element, $attrs) {
|
||||
if ($scope.$last && $attrs.onLast) {
|
||||
let fn = $parse($attrs.onLast);
|
||||
fn($scope);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
ngModule.directive('vnRepeatLast', directive);
|
|
@ -110,7 +110,7 @@
|
|||
"item": "$ctrl.item"
|
||||
}
|
||||
}, {
|
||||
"url" : "/diary",
|
||||
"url" : "/diary?q",
|
||||
"state": "item.card.diary",
|
||||
"component": "vn-item-diary",
|
||||
"params": {
|
||||
|
|
|
@ -88,7 +88,7 @@ describe('Item', () => {
|
|||
|
||||
describe('submit()', () => {
|
||||
it("should return an error message 'The barcode must be unique' when the code isnt unique", () => {
|
||||
spyOn(controller.vnApp, 'showMessage').and.callThrough();
|
||||
spyOn(controller.vnApp, 'showError').and.callThrough();
|
||||
controller.barcodes = [
|
||||
{code: 123454, itemFk: 1, id: 1},
|
||||
{code: 123454, itemFk: 1}
|
||||
|
@ -96,7 +96,7 @@ describe('Item', () => {
|
|||
controller.oldBarcodes = {1: {id: 1, code: 123454, itemFk: 1}};
|
||||
controller.submit();
|
||||
|
||||
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('The barcode must be unique');
|
||||
expect(controller.vnApp.showError).toHaveBeenCalledWith('The barcode must be unique');
|
||||
});
|
||||
|
||||
it("should perfom a query to delete barcodes", () => {
|
||||
|
@ -131,7 +131,7 @@ describe('Item', () => {
|
|||
});
|
||||
|
||||
it("should return a message 'No changes to save' when there are no changes to apply", () => {
|
||||
spyOn(controller.vnApp, 'showMessage').and.callThrough();
|
||||
spyOn(controller.vnApp, 'showError').and.callThrough();
|
||||
controller.oldBarcodes = [
|
||||
{code: 1, itemFk: 1, id: 1},
|
||||
{code: 2, itemFk: 1, id: 2}
|
||||
|
@ -139,7 +139,7 @@ describe('Item', () => {
|
|||
controller.barcodes = [];
|
||||
controller.submit();
|
||||
|
||||
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('No changes to save');
|
||||
expect(controller.vnApp.showError).toHaveBeenCalledWith('No changes to save');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -86,7 +86,7 @@ export default class Controller {
|
|||
}
|
||||
|
||||
if (repeatedBarcodes) {
|
||||
return this.vnApp.showMessage(this.$translate.instant('The barcode must be unique'));
|
||||
return this.vnApp.showError(this.$translate.instant('The barcode must be unique'));
|
||||
}
|
||||
|
||||
canSubmit = barcodesObj.update.length > 0 || barcodesObj.create.length > 0 || barcodesObj.delete.length > 0;
|
||||
|
@ -98,7 +98,7 @@ export default class Controller {
|
|||
this.$scope.watcher.notifySaved();
|
||||
});
|
||||
}
|
||||
this.vnApp.showMessage(this.$translate.instant('No changes to save'));
|
||||
this.vnApp.showError(this.$translate.instant('No changes to save'));
|
||||
}
|
||||
|
||||
setOldBarcodes(response) {
|
||||
|
|
|
@ -25,8 +25,8 @@ describe('Item', () => {
|
|||
|
||||
describe('_getItem()', () => {
|
||||
it('should request to get the item', () => {
|
||||
$httpBackend.whenGET('/item/api/Items/123?filter={"include":[{"relation":"itemType","scope":{"fields":["name","workerFk"],"include":{"relation":"worker","fields":["firstName","name"]}}},{"relation":"origin"},{"relation":"ink"},{"relation":"producer"},{"relation":"intrastat"},{"relation":"expence"}]}').respond({data: 'item'});
|
||||
$httpBackend.expectGET('/item/api/Items/123?filter={"include":[{"relation":"itemType","scope":{"fields":["name","workerFk"],"include":{"relation":"worker","fields":["firstName","name"]}}},{"relation":"origin"},{"relation":"ink"},{"relation":"producer"},{"relation":"intrastat"},{"relation":"expence"}]}');
|
||||
$httpBackend.whenGET('/item/api/Items/123?filter={"include":[{"relation":"itemType","scope":{"fields":["name","workerFk","warehouseFk"],"include":{"relation":"worker","fields":["firstName","name"]}}},{"relation":"origin"},{"relation":"ink"},{"relation":"producer"},{"relation":"intrastat"},{"relation":"expence"}]}').respond({data: 'item'});
|
||||
$httpBackend.expectGET('/item/api/Items/123?filter={"include":[{"relation":"itemType","scope":{"fields":["name","workerFk","warehouseFk"],"include":{"relation":"worker","fields":["firstName","name"]}}},{"relation":"origin"},{"relation":"ink"},{"relation":"producer"},{"relation":"intrastat"},{"relation":"expence"}]}');
|
||||
controller._getItem();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
|
|
@ -35,7 +35,7 @@ class Controller {
|
|||
include: [
|
||||
{relation: "itemType",
|
||||
scope: {
|
||||
fields: ['name', 'workerFk'],
|
||||
fields: ['name', 'workerFk', 'warehouseFk'],
|
||||
include: {
|
||||
relation: 'worker',
|
||||
fields: ['firstName', 'name']
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="item/api/Items/getDiary"
|
||||
filter="::$ctrl.filter"
|
||||
data="sales"
|
||||
auto-load="false">
|
||||
</vn-crud-model>
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
|
@ -8,42 +15,41 @@
|
|||
url="/item/api/Warehouses"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
initial-data="$ctrl.warehouseFk"
|
||||
field="$ctrl.warehouseFk"
|
||||
label="Select warehouse">
|
||||
initial-data="$ctrl.filter.where.warehouseFk"
|
||||
field="$ctrl.filter.where.warehouseFk"
|
||||
label="Select warehouse" on-change="$ctrl.onChange(value)">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<table class="vn-grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th number translate>Date</th>
|
||||
<th number translate>State</th>
|
||||
<th number translate>Origin</th>
|
||||
<th number translate>Reference</th>
|
||||
<th style="text-align: center" translate>Name</th>
|
||||
<th number translate>In</th>
|
||||
<th number translate>Out</th>
|
||||
<th number translate>Balance</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="diary in $ctrl.diary">
|
||||
<td number>{{diary.date | date:'dd/MM/yyyy HH:mm' }}</td>
|
||||
<td number>{{diary.alertLevel | dashIfEmpty}}</td>
|
||||
<td number>{{diary.origin | dashIfEmpty}}</td>
|
||||
<td number>{{diary.reference | dashIfEmpty}}</td>
|
||||
<td style="text-align: center">{{diary.name | dashIfEmpty}}</td>
|
||||
<td number>{{diary.in | dashIfEmpty}}</td>
|
||||
<td number>{{diary.out | dashIfEmpty}}</td>
|
||||
<td number>{{diary.balance | dashIfEmpty}}</td>
|
||||
</tr>
|
||||
<tr ng-if="$ctrl.diary.length === 0" class="list list-element">
|
||||
<td colspan="8" style="text-align: center" translate>No results</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th>Date</vn-th>
|
||||
<vn-th number>Id</vn-th>
|
||||
<vn-th>State</vn-th>
|
||||
<vn-th>Reference</vn-th>
|
||||
<vn-th>Worker</vn-th>
|
||||
<vn-th number>In</vn-th>
|
||||
<vn-th number>Out</vn-th>
|
||||
<vn-th number>Balance</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-class="{'warning': $ctrl.isToday(sale.date)}"
|
||||
ng-repeat="sale in sales" vn-repeat-last on-last="$ctrl.scrollToActive()">
|
||||
<vn-td>{{::sale.date | date:'dd/MM/yyyy HH:mm' }}</vn-td>
|
||||
<vn-td number>{{::sale.origin | dashIfEmpty}}</vn-td>
|
||||
<vn-td>{{::sale.stateName | dashIfEmpty}}</vn-td>
|
||||
<vn-td>{{::sale.reference | dashIfEmpty}}</vn-td>
|
||||
<vn-td>{{sale.name | dashIfEmpty}}</vn-td>
|
||||
<vn-td number>{{::sale.in | dashIfEmpty}}</vn-td>
|
||||
<vn-td number>{{::sale.out | dashIfEmpty}}</vn-td>
|
||||
<vn-td number><span class="balance">{{::sale.balance | dashIfEmpty}}</span></vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-paging margin-large-top vn-one index="$ctrl.diary" total="$ctrl.diary.count"></vn-paging>
|
||||
<!-- <vn-auto-paging margin-large-top vn-one index="index" total="index.model.count" items="$ctrl.instances"></vn-auto-paging> -->
|
||||
</vn-vertical>
|
||||
|
|
|
@ -2,32 +2,96 @@ import ngModule from '../module';
|
|||
import './style.scss';
|
||||
|
||||
class Controller {
|
||||
constructor($scope, $http) {
|
||||
this.$ = $scope;
|
||||
constructor($scope, $http, $state, $window) {
|
||||
this.$scope = $scope;
|
||||
this.$http = $http;
|
||||
this.diary = [];
|
||||
this.$state = $state;
|
||||
this.$window = $window;
|
||||
}
|
||||
|
||||
set warehouseFk(value) {
|
||||
this._getItemDiary(value);
|
||||
this._warehouseFk = value;
|
||||
$postLink() {
|
||||
if (this.item)
|
||||
this.filterBuilder();
|
||||
}
|
||||
|
||||
get warehouseFk() {
|
||||
return this._warehouseFk;
|
||||
set item(value) {
|
||||
this._item = value;
|
||||
|
||||
if (value && this.$scope.model)
|
||||
this.filterBuilder();
|
||||
}
|
||||
|
||||
_getItemDiary(warehouse) {
|
||||
if (warehouse == null)
|
||||
return;
|
||||
let params = {itemFk: this.item.id, warehouseFk: warehouse};
|
||||
this.$http.get(`/item/api/Items/getDiary?params=${JSON.stringify(params)}`).then(res => {
|
||||
this.diary = res.data;
|
||||
});
|
||||
get item() {
|
||||
return this._item;
|
||||
}
|
||||
|
||||
get alertLevelIndex() {
|
||||
let lines = this.$scope.model.data;
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
let isFutureDate = new Date(lines[i].date) > new Date();
|
||||
let isGenreOut = lines[i].alertLevel != 0;
|
||||
|
||||
if (!isFutureDate && !isGenreOut)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
onChange(value) {
|
||||
if (!value) return;
|
||||
|
||||
this.filter.where.warehouseFk = value;
|
||||
this.$scope.model.refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a filter with default values
|
||||
* and aplies query params.
|
||||
*/
|
||||
filterBuilder() {
|
||||
this.filter = {
|
||||
where: {
|
||||
itemFk: this.item.id,
|
||||
warehouseFk: this.item.itemType.warehouseFk
|
||||
}
|
||||
|
||||
};
|
||||
let where = this.filter.where;
|
||||
|
||||
if (this.$state.params.q) {
|
||||
let queryFilter = JSON.parse(this.$state.params.q);
|
||||
where.warehouseFk = queryFilter.warehouseFk;
|
||||
}
|
||||
}
|
||||
|
||||
scrollToActive() {
|
||||
let body = this.$window.document.body;
|
||||
let lineIndex = this.alertLevelIndex;
|
||||
let lines = body.querySelector('vn-tbody').children;
|
||||
|
||||
if (!lineIndex || !lines.length) return;
|
||||
|
||||
lines[lineIndex].scrollIntoView();
|
||||
lines[lineIndex - 1].querySelector('.balance').classList.add('counter');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares a date with the current one
|
||||
* @param {Object} date - Date to compare
|
||||
* @return {Boolean} - Returns true if the two dates equals
|
||||
*/
|
||||
isToday(date) {
|
||||
let today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
let comparedDate = new Date(date);
|
||||
comparedDate.setHours(0, 0, 0, 0);
|
||||
|
||||
if (!(today - comparedDate))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$http'];
|
||||
Controller.$inject = ['$scope', '$http', '$state', '$window'];
|
||||
|
||||
ngModule.component('vnItemDiary', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -17,25 +17,47 @@ describe('Item', () => {
|
|||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
$scope = $rootScope.$new();
|
||||
controller = $componentController('vnItemDiary', {$scope: $scope});
|
||||
controller.item = {id: 3};
|
||||
controller.$scope.model = {};
|
||||
}));
|
||||
|
||||
describe('set warehouseFk()', () => {
|
||||
it(`should call _getItemDiary() with 2 and set warehouseFk`, () => {
|
||||
spyOn(controller, '_getItemDiary');
|
||||
controller.warehouseFk = 2;
|
||||
describe('isToday()', () => {
|
||||
it(`should call isToday() an return true if an specified date is the current date`, () => {
|
||||
let date = new Date();
|
||||
|
||||
expect(controller._getItemDiary).toHaveBeenCalledWith(2);
|
||||
expect(controller.warehouseFk).toEqual(2);
|
||||
let result = controller.isToday(date);
|
||||
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should call isToday() an return false if an specified date is the current date`, () => {
|
||||
let date = '2018-07-03';
|
||||
|
||||
let result = controller.isToday(date);
|
||||
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('_getItemDiary()', () => {
|
||||
it(`should make a request to get the diary hwen is called with a number`, () => {
|
||||
$httpBackend.whenGET('/item/api/Items/getDiary?params={"itemFk":3,"warehouseFk":2}').respond({data: 'item'});
|
||||
$httpBackend.expectGET('/item/api/Items/getDiary?params={"itemFk":3,"warehouseFk":2}');
|
||||
controller._getItemDiary(2);
|
||||
$httpBackend.flush();
|
||||
describe('alertLevelIndex()', () => {
|
||||
it(`should call alertLevelIndex() and return an index from line with alertLevel 0 and current date`, () => {
|
||||
controller.$scope.model = {data: [
|
||||
{name: 'My item 1', alertLevel: 3, date: '2018-05-02'},
|
||||
{name: 'My item 2', alertLevel: 1, date: '2018-05-03'},
|
||||
{name: 'My item 3', alertLevel: 0, date: new Date()}]
|
||||
};
|
||||
let result = controller.alertLevelIndex;
|
||||
|
||||
expect(result).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('set item()', () => {
|
||||
it(`should call filterBuilder()`, () => {
|
||||
spyOn(controller, 'filterBuilder');
|
||||
controller.item = {id: 1};
|
||||
|
||||
expect(controller.filterBuilder).toHaveBeenCalledWith();
|
||||
expect(controller.item).toEqual({id: 1});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,29 +1,41 @@
|
|||
<mg-ajax path="/item/api/ItemLogs/getLog" options="vnIndexNonAuto"></mg-ajax>
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/item/api/ItemLogs"
|
||||
filter="::$ctrl.filter"
|
||||
link="{originFk: $ctrl.$stateParams.id}"
|
||||
limit="20"
|
||||
data="logs">
|
||||
</vn-crud-model>
|
||||
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
<vn-title>Item history</vn-title>
|
||||
<vn-grid-header on-order="$ctrl.onOrder(field, order)">
|
||||
<vn-column-header vn-two pad-medium-h field="description" text="Description"></vn-column-header>
|
||||
<vn-column-header vn-one pad-medium-h field="action" text="Action"></vn-column-header>
|
||||
<vn-column-header vn-one pad-medium-h field="userFk" text="Changed by"></vn-column-header>
|
||||
<vn-column-header vn-one pad-medium-h field="creationDate" text="Date" default-order="ASC"></vn-column-header>
|
||||
</vn-grid-header>
|
||||
<vn-one class="list list-content">
|
||||
<vn-horizontal
|
||||
class="list list-element text-center"
|
||||
pad-small-bottom
|
||||
ng-repeat="itemLog in index.model.instances track by itemLog.id">
|
||||
<vn-two pad-medium-h>{{::itemLog.description}}</vn-two>
|
||||
<vn-one pad-medium-h>{{::itemLog.action}}</vn-one>
|
||||
<vn-one pad-medium-h>{{::itemLog.user.name}}</vn-one>
|
||||
<vn-one pad-medium-h>{{::itemLog.creationDate | date:'dd/MM/yyyy HH:mm'}}</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
<vn-one class="text-center pad-small-v" ng-if="index.model.count === 0" translate>No results</vn-one>
|
||||
<vn-horizontal vn-one class="list list-footer text-center"></vn-horizontal>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th field="description">Description</vn-th>
|
||||
<vn-th field="action">Action</vn-th>
|
||||
<vn-th field="userFk">Changed by</vn-th>
|
||||
<vn-th field="creationDate" default-order="DESC">Date</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="itemLog in logs">
|
||||
<vn-td>{{::itemLog.description}}</vn-td>
|
||||
<vn-td>{{::itemLog.action}}</vn-td>
|
||||
<vn-td>{{::itemLog.user.name}}</vn-td>
|
||||
<vn-td>{{::itemLog.creationDate | date:'dd/MM/yyyy HH:mm'}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
<vn-pagination
|
||||
model="model"
|
||||
scroll-selector="ui-view">
|
||||
</vn-pagination>
|
||||
</vn-card>
|
||||
<vn-paging vn-one margin-large-top index="index" total="index.model.count"></vn-paging>
|
||||
<!-- <vn-auto-paging vn-one margin-large-top index="index" total="index.model.count" items="$ctrl.instances"></vn-auto-paging> -->
|
||||
</vn-vertical>
|
||||
|
|
|
@ -1,7 +1,25 @@
|
|||
import ngModule from '../module';
|
||||
import FilterItemList from '../filter-item-list';
|
||||
|
||||
class Controller {
|
||||
constructor($stateParams) {
|
||||
this.$stateParams = $stateParams;
|
||||
this.filter = {
|
||||
include: [{
|
||||
relation: "item"
|
||||
},
|
||||
{
|
||||
relation: "user",
|
||||
scope: {
|
||||
fields: ["name"]
|
||||
}
|
||||
}]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$stateParams'];
|
||||
|
||||
ngModule.component('vnItemHistory', {
|
||||
template: require('./index.html'),
|
||||
controller: FilterItemList
|
||||
controller: Controller
|
||||
});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/item/api/Items"
|
||||
filter="::$ctrl.filter"
|
||||
url="/item/api/Items/filter"
|
||||
limit="8"
|
||||
order="name ASC"
|
||||
data="items"
|
||||
auto-load="false">
|
||||
</vn-crud-model>
|
||||
|
|
|
@ -8,38 +8,23 @@ class Controller {
|
|||
this.$state = $state;
|
||||
this.$ = $scope;
|
||||
this.itemSelected = null;
|
||||
|
||||
this.filter = {
|
||||
include: [
|
||||
{relation: 'itemType',
|
||||
scope: {
|
||||
fields: ['name', 'workerFk'],
|
||||
include: {
|
||||
relation: 'worker',
|
||||
fields: ['firstName', 'name']
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
order: 'name ASC'
|
||||
};
|
||||
}
|
||||
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return {
|
||||
or: [
|
||||
{id: value},
|
||||
{name: {regexp: value}}
|
||||
]
|
||||
};
|
||||
return /^\d+$/.test(value)
|
||||
? {id: value}
|
||||
: {name: {like: `%${value}%`}};
|
||||
case 'name':
|
||||
case 'description':
|
||||
return {[param]: {regexp: value}};
|
||||
return {[param]: {like: `%${value}%`}};
|
||||
case 'id':
|
||||
case 'typeFk':
|
||||
return {[param]: value};
|
||||
case 'tags':
|
||||
this.$.model.userParams = {tags: value};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,10 @@
|
|||
value="{{::$ctrl.item.size}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Type"
|
||||
value="{{::$ctrl.item.itemType.name}}">
|
||||
value="{{::$ctrl.item.type}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Buyer"
|
||||
value="{{::$ctrl.item.itemType.worker.firstName}} {{::$ctrl.item.itemType.worker.name}}">
|
||||
value="{{::$ctrl.item.firstName}} {{::$ctrl.item.worker}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-horizontal class="buttons">
|
||||
|
|
|
@ -8,12 +8,12 @@ class ItemProduct {
|
|||
|
||||
clone(event) {
|
||||
event.preventDefault();
|
||||
this.ItemList.cloneItem(this.item);
|
||||
this.index.cloneItem(this.item);
|
||||
}
|
||||
|
||||
preview(event) {
|
||||
event.preventDefault();
|
||||
this.ItemList.showItemPreview(this.item);
|
||||
this.index.showItemPreview(this.item);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,6 @@ ngModule.component('vnItemProduct', {
|
|||
},
|
||||
controller: ItemProduct,
|
||||
require: {
|
||||
ItemList: '^vnItemIndex'
|
||||
index: '^vnItemIndex'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/item/api/Items/getLastEntries"
|
||||
filter="::$ctrl.filter"
|
||||
data="entries">
|
||||
</vn-crud-model>
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-vertical>
|
||||
|
@ -6,63 +12,65 @@
|
|||
<vn-date-picker
|
||||
vn-one
|
||||
label="Since"
|
||||
model="$ctrl.entriesDate"
|
||||
model="$ctrl.date"
|
||||
ini-options="{dateFormat: 'd-m-Y'}">
|
||||
</vn-date-picker>
|
||||
<!--datepicker-->
|
||||
</vn-horizontal>
|
||||
<table class="vn-grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th number vn-tooltip="Ignored">Ig</th>
|
||||
<th number translate>Warehouse</th>
|
||||
<th number translate>Landed</th>
|
||||
<th number translate>Entry</th>
|
||||
<th number vn-tooltip="Price Per Unit">P.P.U</th>
|
||||
<th number vn-tooltip="Price Per Package">P.P.P</th>
|
||||
<th number class="expendable" translate>Label</th>
|
||||
<th number>Packing</th>
|
||||
<th number>Grouping</th>
|
||||
<th number class="expendable" translate>Stems</th>
|
||||
<th number translate>Quantity</th>
|
||||
<th number class="expendable" translate>Cost</th>
|
||||
<th number translate>Cube</th>
|
||||
<th number class="expendable" translate>Provider</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="entries in $ctrl.entries">
|
||||
<td number>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th number vn-tooltip="Ignored">Ig</vn-th>
|
||||
<vn-th number>Warehouse</vn-th>
|
||||
<vn-th number>Landed</vn-th>
|
||||
<vn-th number>Entry</vn-th>
|
||||
<vn-th number vn-tooltip="Price Per Unit">P.P.U</vn-th>
|
||||
<vn-th number vn-tooltip="Price Per Package">P.P.P</vn-th>
|
||||
<vn-th number class="expendable">Label</vn-th>
|
||||
<vn-th number>Packing</vn-th>
|
||||
<vn-th number>Grouping</vn-th>
|
||||
<vn-th number class="expendable">Stems</vn-th>
|
||||
<vn-th number>Quantity</vn-th>
|
||||
<vn-th number class="expendable">Cost</vn-th>
|
||||
<vn-th number>Cube</vn-th>
|
||||
<vn-th number class="expendable">Provider</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="entry in entries">
|
||||
<vn-td number>
|
||||
<vn-check
|
||||
field="entries.isIgnored"
|
||||
disabled="true">
|
||||
</vn-check>
|
||||
</td>
|
||||
<td number>{{entries.warehouse| dashIfEmpty}}</td>
|
||||
<td number>{{entries.landed | date:'dd/MM/yyyy HH:mm'}}</td>
|
||||
<td number>{{entries.entryFk | dashIfEmpty}}</td>
|
||||
<td number>{{entries.price2 | dashIfEmpty}}</td>
|
||||
<td number>{{entries.price3 | dashIfEmpty}}</td>
|
||||
<td number class="expendable">{{entries.stickers | dashIfEmpty}}</td>
|
||||
<td number>
|
||||
<div ng-class="{'round': entries.groupingMode == 2}">{{entries.packing | dashIfEmpty}}</div>
|
||||
</td>
|
||||
<td number>
|
||||
<div ng-class="{'round': entries.groupingMode == 1}">{{entries.grouping | dashIfEmpty}}</div>
|
||||
</td>
|
||||
<td number class="expendable">{{entries.stems | dashIfEmpty}}</td>
|
||||
<td number>{{entries.quantity}}</td>
|
||||
<td number class="expendable">{{entries.buyingValue | dashIfEmpty}}</td>
|
||||
<td number>{{entries.packageFk | dashIfEmpty}}</td>
|
||||
<td number class="expendable">{{entries.supplier | dashIfEmpty}}</td>
|
||||
</tr>
|
||||
<tr ng-if="$ctrl.entries.length === 0" class="list list-element">
|
||||
<td colspan="14" style="text-align: center" translate>No results</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</vn-td>
|
||||
<vn-td number>{{entry.warehouse| dashIfEmpty}}</vn-td>
|
||||
<vn-td number>{{entry.landed | date:'dd/MM/yyyy HH:mm'}}</vn-td>
|
||||
<vn-td number>{{entry.entryFk | dashIfEmpty}}</vn-td>
|
||||
<vn-td number>{{entry.price2 | dashIfEmpty}}</vn-td>
|
||||
<vn-td number>{{entry.price3 | dashIfEmpty}}</vn-td>
|
||||
<vn-td number class="expendable">{{entry.stickers | dashIfEmpty}}</vn-td>
|
||||
<vn-td number>
|
||||
<div ng-class="{'counter': entry.groupingMode == 2}">{{entry.packing | dashIfEmpty}}</div>
|
||||
</vn-td>
|
||||
<vn-td number>
|
||||
<span ng-class="{'counter': entry.groupingMode == 1}">{{entry.grouping | dashIfEmpty}}</span>
|
||||
</vn-td>
|
||||
<vn-td number class="expendable">{{entry.stems | dashIfEmpty}}</vn-td>
|
||||
<vn-td number>{{entry.quantity}}</vn-td>
|
||||
<vn-td number class="expendable">{{entry.buyingValue | dashIfEmpty}}</vn-td>
|
||||
<vn-td number>{{entry.packageFk | dashIfEmpty}}</vn-td>
|
||||
<vn-td number class="expendable">{{entry.supplier | dashIfEmpty}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
<vn-pagination
|
||||
model="model"
|
||||
scroll-selector="ui-view">
|
||||
</vn-pagination>
|
||||
</vn-card>
|
||||
<vn-paging margin-large-top vn-one index="$ctrl.entries" total="$ctrl.entries.count"></vn-paging>
|
||||
<!-- <vn-auto-paging margin-large-top vn-one index="index" total="index.model.count" items="$ctrl.instances"></vn-auto-paging> -->
|
||||
</vn-vertical>
|
||||
|
|
|
@ -2,50 +2,38 @@ import ngModule from '../module';
|
|||
import './style.scss';
|
||||
|
||||
class Controller {
|
||||
constructor($scope, $http) {
|
||||
this.$ = $scope;
|
||||
this.$http = $http;
|
||||
this.entries = [];
|
||||
}
|
||||
constructor($scope, $stateParams) {
|
||||
this.$scope = $scope;
|
||||
this.$stateParams = $stateParams;
|
||||
|
||||
set item(value) {
|
||||
this._item = value;
|
||||
this._defaultEntriesDate();
|
||||
this._getLastEntries();
|
||||
}
|
||||
|
||||
get item() {
|
||||
return this._item;
|
||||
}
|
||||
|
||||
set entriesDate(value) {
|
||||
this._entriesDate = value;
|
||||
this._getLastEntries();
|
||||
}
|
||||
|
||||
get entriesDate() {
|
||||
return this._entriesDate;
|
||||
}
|
||||
|
||||
_defaultEntriesDate() {
|
||||
let defaultDate;
|
||||
defaultDate = new Date();
|
||||
let defaultDate = new Date();
|
||||
defaultDate.setDate(defaultDate.getDate() - 75);
|
||||
defaultDate.setHours(0, 0, 0, 0);
|
||||
this._entriesDate = defaultDate;
|
||||
|
||||
this.filter = {
|
||||
where: {
|
||||
itemFk: $stateParams.id,
|
||||
date: defaultDate
|
||||
}
|
||||
};
|
||||
this._date = defaultDate;
|
||||
}
|
||||
|
||||
_getLastEntries() {
|
||||
if (!this.entriesDate || !this.item)
|
||||
return;
|
||||
let filter = {itemFk: this.item.id, date: this.entriesDate};
|
||||
this.$http.get(`/item/api/Items/getLastEntries?filter=${JSON.stringify(filter)}`).then(res => {
|
||||
this.entries = res.data;
|
||||
});
|
||||
set date(value) {
|
||||
this._date = value;
|
||||
|
||||
if (!value) return;
|
||||
|
||||
this.filter.where.date = value;
|
||||
this.$scope.model.refresh();
|
||||
}
|
||||
|
||||
get date() {
|
||||
return this._date;
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$http'];
|
||||
Controller.$inject = ['$scope', '$stateParams'];
|
||||
|
||||
ngModule.component('vnItemLastEntries', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Item', () => {
|
||||
describe('Component vnItemLastEntries', () => {
|
||||
let $componentController;
|
||||
let $scope;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
let defaultDate;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('item');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_) => {
|
||||
$componentController = _$componentController_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
$scope = $rootScope.$new();
|
||||
controller = $componentController('vnItemLastEntries', {$scope: $scope});
|
||||
controller.item = {id: 3};
|
||||
}));
|
||||
|
||||
describe('set item()', () => {
|
||||
it(`should set item and call _defaultEntriesDate() and _getLastEntries()`, () => {
|
||||
spyOn(controller, '_defaultEntriesDate');
|
||||
spyOn(controller, '_getLastEntries');
|
||||
controller.item = [];
|
||||
|
||||
expect(controller._defaultEntriesDate).toHaveBeenCalledWith();
|
||||
expect(controller._getLastEntries).toHaveBeenCalledWith();
|
||||
expect(controller.item).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('set entriesDate()', () => {
|
||||
it(`should set entriesDate and call _getLastEntries()`, () => {
|
||||
spyOn(controller, '_getLastEntries');
|
||||
controller.item = [];
|
||||
controller.entriesDate = new Date();
|
||||
|
||||
expect(controller._getLastEntries).toHaveBeenCalledWith();
|
||||
expect(controller.item).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('_defaultEntriesDate()', () => {
|
||||
it(`should set entriesDate to a date 75 days ago`, () => {
|
||||
defaultDate = new Date();
|
||||
defaultDate.setDate(defaultDate.getDate() - 75);
|
||||
defaultDate.setHours(0, 0, 0, 0);
|
||||
controller._defaultEntriesDate();
|
||||
|
||||
expect(controller.entriesDate).toEqual(defaultDate);
|
||||
});
|
||||
});
|
||||
|
||||
describe('_getLastEntries()', () => {
|
||||
it(`should make a GET if entriesDate and item are defined`, () => {
|
||||
controller._defaultEntriesDate();
|
||||
let filter = {itemFk: controller.item.id, date: controller.entriesDate};
|
||||
$httpBackend.whenGET(`/item/api/Items/getLastEntries?filter=${JSON.stringify(filter)}`).respond([]);
|
||||
$httpBackend.expectGET(`/item/api/Items/getLastEntries?filter=${JSON.stringify(filter)}`);
|
||||
controller._getLastEntries();
|
||||
$httpBackend.flush();
|
||||
// expect(controller.entriesDate).toEqual(defaultDate);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -50,4 +50,5 @@ Add barcode: Añadir código de barras
|
|||
Remove barcode: Quitar código de barras
|
||||
Buyer: Comprador
|
||||
No results: Sin resultados
|
||||
Tag: Etiqueta
|
||||
Tag: Etiqueta
|
||||
Worker: Trabajador
|
|
@ -122,11 +122,11 @@ export default class Controller {
|
|||
});
|
||||
|
||||
if (this.$scope.form.$invalid) {
|
||||
return this.vnApp.showMessage(this.$translate.instant('Some fields are invalid'));
|
||||
return this.vnApp.showError(this.$translate.instant('Some fields are invalid'));
|
||||
}
|
||||
|
||||
if (repeatedWarehouse) {
|
||||
return this.vnApp.showMessage(this.$translate.instant('The niche must be unique'));
|
||||
return this.vnApp.showError(this.$translate.instant('The niche must be unique'));
|
||||
}
|
||||
|
||||
canSubmit = nichesObj.update.length > 0 || nichesObj.create.length > 0 || nichesObj.delete.length > 0;
|
||||
|
@ -138,7 +138,7 @@ export default class Controller {
|
|||
this.$scope.watcher.notifySaved();
|
||||
});
|
||||
}
|
||||
this.vnApp.showMessage(this.$translate.instant('No changes to save'));
|
||||
this.vnApp.showError(this.$translate.instant('No changes to save'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ describe('Item', () => {
|
|||
describe('submit()', () => {
|
||||
it("should return an error message 'The niche must be unique' when the niche warehouse isnt unique", () => {
|
||||
controller.$scope.form = {};
|
||||
spyOn(controller.vnApp, 'showMessage').and.callThrough();
|
||||
spyOn(controller.vnApp, 'showError').and.callThrough();
|
||||
controller.niches = [
|
||||
{warehouseFk: 1, code: 123454, itemFk: 1, id: 1},
|
||||
{warehouseFk: 1, code: 123454, itemFk: 1}
|
||||
|
@ -106,7 +106,7 @@ describe('Item', () => {
|
|||
controller.oldNiches = {1: {warehouseFk: 1, id: 1, code: 123454, itemFk: 1}};
|
||||
controller.submit();
|
||||
|
||||
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('The niche must be unique');
|
||||
expect(controller.vnApp.showError).toHaveBeenCalledWith('The niche must be unique');
|
||||
});
|
||||
|
||||
it("should perfom a query to delete niches", () => {
|
||||
|
@ -144,7 +144,7 @@ describe('Item', () => {
|
|||
|
||||
it("should return a message 'No changes to save' when there are no changes to apply", () => {
|
||||
controller.$scope.form = {$setPristine: () => {}};
|
||||
spyOn(controller.vnApp, 'showMessage').and.callThrough();
|
||||
spyOn(controller.vnApp, 'showError').and.callThrough();
|
||||
controller.oldNiches = [
|
||||
{warehouseFk: 1, code: 1, itemFk: 1, id: 1},
|
||||
{warehouseFk: 2, code: 2, itemFk: 1, id: 2}
|
||||
|
@ -152,7 +152,7 @@ describe('Item', () => {
|
|||
controller.niches = [];
|
||||
controller.submit();
|
||||
|
||||
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('No changes to save');
|
||||
expect(controller.vnApp.showError).toHaveBeenCalledWith('No changes to save');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
model="filter.description">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<!--
|
||||
<vn-horizontal ng-repeat="itemTag in filter.tags">
|
||||
<vn-autocomplete
|
||||
vn-id="tag"
|
||||
|
@ -76,7 +75,6 @@
|
|||
ng-click="filter.tags.push({})">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
-->
|
||||
<vn-horizontal margin-large-top>
|
||||
<vn-submit label="Search"></vn-submit>
|
||||
</vn-horizontal>
|
||||
|
|
|
@ -132,7 +132,7 @@ describe('Item', () => {
|
|||
// TODO: Server validation should be implemented
|
||||
xit("should return an error message 'The tag must be unique' when the tag value isnt unique", () => {
|
||||
controller.$.form = [];
|
||||
spyOn(controller.vnApp, 'showMessage').and.callThrough();
|
||||
spyOn(controller.vnApp, 'showError').and.callThrough();
|
||||
controller.tags = [
|
||||
{typeFk: 1, value: 123454, itemFk: 1, id: 1},
|
||||
{typeFk: 1, value: 123454, itemFk: 1}
|
||||
|
@ -140,7 +140,7 @@ describe('Item', () => {
|
|||
controller.orgTags = {1: {typeFk: 1, id: 1, value: 123454, itemFk: 1}};
|
||||
controller.submit();
|
||||
|
||||
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('The tag must be unique');
|
||||
expect(controller.vnApp.showError).toHaveBeenCalledWith('The tag must be unique');
|
||||
});
|
||||
|
||||
it("should perfom a query to delete tags", () => {
|
||||
|
|
|
@ -29,7 +29,7 @@ export default class Controller {
|
|||
|
||||
let url = `/item/api/Items/${this.$stateParams.id}/updateTaxes`;
|
||||
this.$http.post(url, data).then(
|
||||
() => this.vnApp.showMessage(this._.instant('Data saved!'))
|
||||
() => this.vnApp.showSuccess(this._.instant('Data saved!'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
"url": "/order",
|
||||
"state": "order",
|
||||
"abstract": true,
|
||||
"component": "ui-view"
|
||||
"component": "ui-view",
|
||||
"acl": ["developer"]
|
||||
},
|
||||
{
|
||||
"url": "/index?q",
|
||||
|
|
|
@ -242,4 +242,15 @@ fieldset[disabled] .mdl-textfield .mdl-textfield__label,
|
|||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.counter {
|
||||
background-color: $main-header;
|
||||
color: $color-white;
|
||||
border-radius: 3px;
|
||||
padding: 5px
|
||||
}
|
||||
|
||||
.counter.small {
|
||||
font-size: 0.7em
|
||||
}
|
|
@ -153,8 +153,7 @@
|
|||
"menu": {
|
||||
"description": "Tracking",
|
||||
"icon": "remove_red_eye"
|
||||
},
|
||||
"acl": ["production"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "/edit",
|
||||
|
@ -162,15 +161,8 @@
|
|||
"component": "vn-ticket-tracking-edit",
|
||||
"params": {
|
||||
"ticket": "$ctrl.ticket"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "/create",
|
||||
"state": "ticket.card.tracking.create",
|
||||
"component": "vn-ticket-tracking-create",
|
||||
"params": {
|
||||
"client": "$ctrl.client"
|
||||
}
|
||||
},
|
||||
"acl": ["production"]
|
||||
},
|
||||
{
|
||||
"url" : "/sale-checked",
|
||||
|
@ -195,6 +187,18 @@
|
|||
"description": "Components",
|
||||
"icon": "icon-components"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url" : "/sale-tracking",
|
||||
"state": "ticket.card.saleTracking",
|
||||
"component": "vn-ticket-sale-tracking",
|
||||
"params": {
|
||||
"ticket": "$ctrl.ticket"
|
||||
},
|
||||
"menu": {
|
||||
"description": "Sale tracking",
|
||||
"icon": "assignment"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -67,7 +67,6 @@
|
|||
</table>
|
||||
</vn-vertical>
|
||||
<vn-paging vn-one margin-large-top index="index" total="index.model.count"></vn-paging>
|
||||
<!-- <vn-auto-paging vn-one margin-large-top index="index" total="index.model.count" items="$ctrl.instances"></vn-auto-paging> -->
|
||||
</vn-card>
|
||||
</vn-vertical>
|
||||
<vn-item-descriptor-popover vn-id="descriptor"></vn-item-descriptor-popover>
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<vn-title>New order</vn-title>
|
||||
<vn-autocomplete
|
||||
vn-focus
|
||||
vn-id="client"
|
||||
url="/api/Clients"
|
||||
label="Client"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
field="$ctrl.clientFk">
|
||||
<tpl-item>{{id}}: {{name}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
disabled="!$ctrl.clientFk"
|
||||
url="{{ $ctrl.clientFk ? '/api/Clients/'+ $ctrl.clientFk +'/addresses' : null }}"
|
||||
select-fields=["nickname","street","city"]
|
||||
field="$ctrl.addressFk"
|
||||
show-field="nickname"
|
||||
value-field="id"
|
||||
label="Address">
|
||||
<tpl-item>{{nickname}}: {{street}}, {{city}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-date-picker
|
||||
label="Landed"
|
||||
model="$ctrl.landed"
|
||||
ini-options="{enableTime: false}">
|
||||
</vn-date-picker>
|
||||
<vn-autocomplete
|
||||
disabled="!$ctrl.clientFk || !$ctrl.landed"
|
||||
data="$ctrl._avaibleAgencies"
|
||||
label="Agency"
|
||||
show-field="agency"
|
||||
value-field="id"
|
||||
field="$ctrl.ticket.agencyModeFk">
|
||||
</vn-autocomplete>
|
|
@ -0,0 +1,93 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class Controller {
|
||||
constructor($scope, $http, vnApp, $translate) {
|
||||
this.$scope = $scope;
|
||||
this.$http = $http;
|
||||
this.translate = $translate;
|
||||
this.vnApp = vnApp;
|
||||
this.ticket = {};
|
||||
}
|
||||
|
||||
set ticket(value) {
|
||||
if (value) {
|
||||
this._ticket = value;
|
||||
}
|
||||
}
|
||||
|
||||
get ticket() {
|
||||
return this._ticket;
|
||||
}
|
||||
|
||||
set clientFk(value) {
|
||||
this.ticket.clientFk = value;
|
||||
this.addressFk = null;
|
||||
}
|
||||
|
||||
get clientFk() {
|
||||
return this.ticket.clientFk;
|
||||
}
|
||||
|
||||
set addressFk(value) {
|
||||
this.ticket.addressFk = value;
|
||||
this.getAvaibleAgencies();
|
||||
}
|
||||
|
||||
get addressFk() {
|
||||
return this.ticket.addressFk;
|
||||
}
|
||||
|
||||
set landed(value) {
|
||||
this.ticket.landed = value;
|
||||
this.getAvaibleAgencies();
|
||||
}
|
||||
|
||||
get landed() {
|
||||
return this.ticket.landed;
|
||||
}
|
||||
|
||||
get warehouseFk() {
|
||||
return this.ticket.warehouseFk;
|
||||
}
|
||||
|
||||
getAvaibleAgencies() {
|
||||
this.ticket.agencyModeFk = null;
|
||||
if (this.ticket.landed && this.ticket.addressFk) {
|
||||
let filter = {addressFk: this.ticket.addressFk, landed: this.ticket.landed};
|
||||
filter = encodeURIComponent(JSON.stringify(filter));
|
||||
let query = `/api/Agencies/landsThatDay?filter=${filter}`;
|
||||
this.$http.get(query).then(res => {
|
||||
this._avaibleAgencies = res.data[0];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.createOrder();
|
||||
}
|
||||
|
||||
createOrder() {
|
||||
let params = {
|
||||
landed: this.ticket.landed,
|
||||
addressFk: this.ticket.addressFk,
|
||||
agencyModeFk: this.ticket.agencyModeFk
|
||||
};
|
||||
|
||||
this.$http.post(`order/api/Orders/new`, params).then(res => {
|
||||
this.vnApp.showSuccess(this.translate.instant('Data saved!'));
|
||||
return res.data.id;
|
||||
}).catch(e => {
|
||||
this.vnApp.showError(this.translate.instant(e.data.error.message));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$http', 'vnApp', '$translate'];
|
||||
|
||||
ngModule.component('vnTicketCreateCard', {
|
||||
template: require('./card.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
ticket: '<?'
|
||||
}
|
||||
});
|
|
@ -0,0 +1,79 @@
|
|||
import './card.js';
|
||||
|
||||
describe('Ticket', () => {
|
||||
describe('Component vnTicketCreateCard', () => {
|
||||
let $componentController;
|
||||
let $scope;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('ticket');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_) => {
|
||||
$componentController = _$componentController_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
$scope = $rootScope.$new();
|
||||
controller = $componentController('vnTicketCreateCard', {$scope: $scope});
|
||||
controller.item = {id: 3};
|
||||
}));
|
||||
|
||||
describe('set clientFk', () => {
|
||||
it(`should set addressFk to null and clientFk to a value`, () => {
|
||||
controller.clientFk = 2;
|
||||
|
||||
expect(controller.clientFk).toEqual(2);
|
||||
expect(controller.ticket.addressFk).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('set addressFk', () => {
|
||||
it(`should set agencyModeFk property to null and addressFk to a value`, () => {
|
||||
controller.addressFk = 101;
|
||||
|
||||
expect(controller.addressFk).toEqual(101);
|
||||
expect(controller.ticket.agencyModeFk).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAvaibleAgencies()', () => {
|
||||
it(`should make a query if landed and addressFk exists`, () => {
|
||||
controller.ticket.addressFk = 101;
|
||||
controller.ticket.landed = 101;
|
||||
|
||||
let filter = {addressFk: controller.ticket.addressFk, landed: controller.ticket.landed};
|
||||
filter = encodeURIComponent(JSON.stringify(filter));
|
||||
$httpBackend.whenGET(`/api/Agencies/landsThatDay?filter=${filter}`).respond({data: 1});
|
||||
$httpBackend.expectGET(`/api/Agencies/landsThatDay?filter=${filter}`);
|
||||
|
||||
controller.getAvaibleAgencies();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSubmit()', () => {
|
||||
it(`should call createOrder()`, () => {
|
||||
spyOn(controller, 'createOrder');
|
||||
controller.onSubmit();
|
||||
|
||||
expect(controller.createOrder).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('createOrder()', () => {
|
||||
it(`should make a query`, () => {
|
||||
controller.ticket.addressFk = 101;
|
||||
controller.ticket.agencyModeFk = 101;
|
||||
controller.ticket.landed = 101;
|
||||
|
||||
$httpBackend.whenPOST('order/api/Orders/new').respond({data: 1});
|
||||
$httpBackend.expectPOST('order/api/Orders/new');
|
||||
controller.createOrder();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,18 +1,11 @@
|
|||
<mg-ajax path="/item/api/Tickets" options="vnPost"></mg-ajax>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.ticket"
|
||||
form="form"
|
||||
save="post">
|
||||
</vn-watcher>
|
||||
<form name="form" ng-submit="$ctrl.onSubmit()" margin-medium>
|
||||
<div style="max-width: 70em; margin: 0 auto;">
|
||||
<div margin-medium>
|
||||
<div style="max-width: 70em; margin: 0 auto;" >
|
||||
<vn-card pad-large>
|
||||
<vn-title>New ticket</vn-title>
|
||||
|
||||
<vn-ticket-create-card vn-id="card" on-save=""></vn-ticket-create-card>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Create"></vn-submit>
|
||||
<vn-submit ng-click="$ctrl.onSubmit()" label="Save">
|
||||
</vn-submit>
|
||||
</vn-button-bar>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
|
@ -1,20 +1,18 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class Controller {
|
||||
constructor($scope, $state) {
|
||||
constructor($scope, $http, $state) {
|
||||
this.$ = $scope;
|
||||
this.$http = $http;
|
||||
this.$state = $state;
|
||||
this.Ticket = {};
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.$.watcher.submit().then(
|
||||
json => this.$state.go('ticket.card.data', {id: json.data.id})
|
||||
);
|
||||
async onSubmit() {
|
||||
let newOrderID = await this.$.card.createOrder();
|
||||
this.$state.go("ticket.card.summary", {id: newOrderID});
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$state'];
|
||||
Controller.$inject = ['$scope', '$http', '$state'];
|
||||
|
||||
ngModule.component('vnTicketCreate', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Ticket', () => {
|
||||
describe('Component vnTicketCreate', () => {
|
||||
let $componentController;
|
||||
let $scope;
|
||||
let controller;
|
||||
let $state;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('ticket');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$state_) => {
|
||||
$componentController = _$componentController_;
|
||||
|
||||
$scope = $rootScope.$new();
|
||||
$scope.card = {createOrder: () => {}};
|
||||
$state = _$state_;
|
||||
controller = $componentController('vnTicketCreate', {$scope: $scope, $state: $state});
|
||||
}));
|
||||
|
||||
describe('onSubmit()', () => {
|
||||
it(`should call createOrder()`, () => {
|
||||
spyOn(controller.$.card, 'createOrder');
|
||||
controller.onSubmit();
|
||||
|
||||
expect(controller.$.card.createOrder).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
xit(`should call go()`, () => {
|
||||
spyOn(controller.$state, 'go');
|
||||
controller.onSubmit();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
You can't create an order for a frozen client: No puedes crear una orden a un cliente congelado
|
||||
You can't create an order for a inactive client: No puedes crear una orden a un cliente inactivo
|
||||
You can't create an order for a client that doesn't has tax data verified:
|
||||
No puedes crear una orden a un cliente cuyos datos fiscales no han sido verificados
|
||||
You can't create an order for a client that has a debt: No puedes crear una orden a un cliente que tiene deuda
|
||||
New order: Nueva orden
|
|
@ -8,16 +8,18 @@
|
|||
label="Client"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
field="$ctrl.ticket.clientFk"
|
||||
initial-data="$ctrl.ticket.clientFk"
|
||||
on-change="$ctrl.onChange()">
|
||||
field="$ctrl.clientFk"
|
||||
initial-data="$ctrl.clientFk">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
url="{{$ctrl.getAddresses()}}"
|
||||
data="$ctrl.addresses"
|
||||
label="Address"
|
||||
show-field="nickname"
|
||||
value-field="id"
|
||||
field="$ctrl.ticket.addressFk">
|
||||
<tpl-item>{{::nickname}}
|
||||
<span ng-show="city || province">- {{::city}} ({{::province.name}})</span>
|
||||
</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
url="/api/AgencyModes"
|
||||
|
|
|
@ -13,14 +13,48 @@ class Controller {
|
|||
this.data.registerChild(this);
|
||||
}
|
||||
|
||||
onChange() {
|
||||
if (this.ticket)
|
||||
this.ticket.addressFk = null;
|
||||
set ticket(value) {
|
||||
this._ticket = value;
|
||||
|
||||
if (!value || !value.id) return;
|
||||
|
||||
this.onChange(value.clientFk);
|
||||
}
|
||||
|
||||
getAddresses() {
|
||||
get ticket() {
|
||||
return this._ticket;
|
||||
}
|
||||
|
||||
set clientFk(value) {
|
||||
this.ticket.clientFk = value;
|
||||
this.ticket.addressFk = null;
|
||||
|
||||
this.onChange(value);
|
||||
}
|
||||
|
||||
get clientFk() {
|
||||
if (this.ticket)
|
||||
return `/api/Clients/${this.ticket.clientFk}/addresses`;
|
||||
return this.ticket.clientFk;
|
||||
}
|
||||
|
||||
onChange(value) {
|
||||
let filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'province',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
filter = encodeURIComponent(JSON.stringify(filter));
|
||||
|
||||
let query = `/api/Clients/${value}/addresses?filter=${filter}`;
|
||||
this.$http.get(query).then(res => {
|
||||
if (res.data)
|
||||
this.addresses = res.data;
|
||||
});
|
||||
}
|
||||
|
||||
async onStepChange(state) {
|
||||
|
|
|
@ -19,6 +19,25 @@ describe('ticket', () => {
|
|||
controller = $componentController('vnTicketDataStepOne', {$state: $state});
|
||||
}));
|
||||
|
||||
describe('ticket() setter', () => {
|
||||
it('should set ticket property and call onChange() method ', () => {
|
||||
spyOn(controller, 'onChange');
|
||||
controller.ticket = {id: 1, clientFk: 101};
|
||||
|
||||
expect(controller.onChange).toHaveBeenCalledWith(101);
|
||||
});
|
||||
});
|
||||
|
||||
describe('clientFk() setter', () => {
|
||||
it('should set clientFk property and call onChange() method ', () => {
|
||||
spyOn(controller, 'onChange');
|
||||
controller.ticket = {id: 1, clientFk: 101};
|
||||
controller.clientFk = 102;
|
||||
|
||||
expect(controller.onChange).toHaveBeenCalledWith(102);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isFormInvalid()', () => {
|
||||
it('should check if all form fields are valid', () => {
|
||||
controller.ticket = {
|
||||
|
@ -31,8 +50,7 @@ describe('ticket', () => {
|
|||
landed: new Date()
|
||||
};
|
||||
|
||||
let result = controller.isFormInvalid();
|
||||
expect(result).toBeFalsy();
|
||||
expect(controller.isFormInvalid()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -41,7 +59,7 @@ describe('ticket', () => {
|
|||
let landed = new Date();
|
||||
landed.setHours(0, 0, 0, 0);
|
||||
|
||||
controller.ticket = {
|
||||
controller._ticket = {
|
||||
id: 1,
|
||||
clientFk: 1,
|
||||
addressFk: 121,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue