Merge branch 'dev' of https://git.verdnatura.es/salix into dev
This commit is contained in:
commit
b952ab502a
|
@ -15,7 +15,11 @@
|
|||
<vn-title>Address</vn-title>
|
||||
<vn-horizontal>
|
||||
<vn-check vn-one label="Enabled" field="$ctrl.address.isActive"></vn-check>
|
||||
<vn-check vn-one label="Is equalizated" field="$ctrl.address.isEqualizated" vn-acl="administrative"></vn-check>
|
||||
<vn-check
|
||||
vn-one label="Is equalizated"
|
||||
field="$ctrl.address.isEqualizated"
|
||||
vn-acl="administrative, salesAssistant">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one label="Consignee" field="$ctrl.address.nickname" vn-focus></vn-textfield>
|
||||
|
|
|
@ -10,30 +10,50 @@
|
|||
<vn-title>Pay method</vn-title>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-two
|
||||
vn-acl="administrative"
|
||||
vn-acl="administrative, salesAssistant"
|
||||
field="$ctrl.client.payMethodFk"
|
||||
url="/client/api/PayMethods"
|
||||
select-fields="ibanRequired"
|
||||
initial-data="$ctrl.client.payMethod"
|
||||
label="Pay method">
|
||||
</vn-autocomplete>
|
||||
<vn-textfield vn-two label="IBAN" field="$ctrl.client.iban" vn-acl="administrative"></vn-textfield>
|
||||
<vn-textfield vn-one label="Due day" field="$ctrl.client.dueDay" vn-acl="administrative"></vn-textfield>
|
||||
<vn-textfield
|
||||
vn-two label="IBAN"
|
||||
field="$ctrl.client.iban"
|
||||
vn-acl="administrative, salesAssistant">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
vn-one label="Due day"
|
||||
field="$ctrl.client.dueDay"
|
||||
vn-acl="administrative, salesAssistant">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal margin-medium-bottom>
|
||||
<vn-one>
|
||||
<vn-check label="Received core VNH" field="$ctrl.client.hasCoreVnh" vn-acl="administrative"></vn-check>
|
||||
<vn-check
|
||||
label="Received core VNH"
|
||||
field="$ctrl.client.hasCoreVnh"
|
||||
vn-acl="administrative, salesAssistant">
|
||||
</vn-check>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<vn-check label="Received core VNL" field="$ctrl.client.hasCoreVnl" vn-acl="administrative"></vn-check>
|
||||
<vn-check
|
||||
label="Received core VNL"
|
||||
field="$ctrl.client.hasCoreVnl"
|
||||
vn-acl="administrative, salesAssistant">
|
||||
</vn-check>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<vn-check label="Received B2B VNL" field="$ctrl.client.hasSepaVnl" vn-acl="administrative"></vn-check>
|
||||
<vn-check
|
||||
label="Received B2B VNL"
|
||||
field="$ctrl.client.hasSepaVnl"
|
||||
vn-acl="administrative, salesAssistant">
|
||||
</vn-check>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Save" vn-acl="administrative"></vn-submit>
|
||||
<vn-submit label="Save" vn-acl="administrative, salesAssistant"></vn-submit>
|
||||
</vn-button-bar>
|
||||
</form>
|
||||
<vn-confirm
|
||||
|
|
|
@ -25,4 +25,30 @@
|
|||
<span ng-if="!$ctrl.client.creditInsurance">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<vn-icon
|
||||
vn-tooltip="Client inactive"
|
||||
tooltip-position = "right"
|
||||
icon="person"
|
||||
ng-class="{bright: $ctrl.client.isActive == false}">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
vn-tooltip="Client Frozen"
|
||||
tooltip-position = "right"
|
||||
icon="mail"
|
||||
ng-class="{bright: $ctrl.client.isFreezed == true}">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
vn-tooltip="Web Account inactive"
|
||||
tooltip-position = "right"
|
||||
icon="phone"
|
||||
ng-class="{bright: $ctrl.client.account.active == false}">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
vn-tooltip="Client has debt"
|
||||
tooltip-position = "right"
|
||||
icon="power"
|
||||
ng-class="{bright: $ctrl.clientDebt < 0}">
|
||||
</vn-icon>
|
||||
</div>
|
||||
</vn-card>
|
|
@ -1,8 +1,35 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class ClientDescriptor {
|
||||
constructor($http) {
|
||||
this.$http = $http;
|
||||
}
|
||||
_getClientDebt(clientFk) {
|
||||
this.$http.get(`/client/api/Clients/${clientFk}/getDebt`)
|
||||
.then(response => {
|
||||
this.clientDebt = response.data.debt;
|
||||
});
|
||||
}
|
||||
|
||||
_getClient(clientFk) {
|
||||
this.$http.get(`/client/api/Clients/${clientFk}/card`)
|
||||
.then(response => {
|
||||
Object.assign(this.client, response.data);
|
||||
});
|
||||
}
|
||||
|
||||
$onChanges(changes) {
|
||||
if (changes.client && this.client) {
|
||||
this._getClient(this.client.id);
|
||||
this._getClientDebt(this.client.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnClientDescriptor', {
|
||||
template: require('./descriptor.html'),
|
||||
bindings: {
|
||||
client: '<'
|
||||
}
|
||||
},
|
||||
controller: ClientDescriptor
|
||||
});
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import './descriptor.js';
|
||||
|
||||
describe('Descriptor', () => {
|
||||
describe('Component vnClientDescriptor', () => {
|
||||
let $componentController;
|
||||
let $httpBackend;
|
||||
let controller;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('client');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, _$httpBackend_) => {
|
||||
$componentController = _$componentController_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnClientDescriptor');
|
||||
}));
|
||||
|
||||
describe('_getClientDebt()', () => {
|
||||
it(`should call _getClientDebt() and define the clientDebt value on the controller`, () => {
|
||||
controller.client = {};
|
||||
let response = {debt: 100};
|
||||
$httpBackend.whenGET(`/client/api/Clients/101/getDebt`).respond(response);
|
||||
$httpBackend.expectGET(`/client/api/Clients/101/getDebt`);
|
||||
controller._getClientDebt(101);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.clientDebt).toEqual(100);
|
||||
});
|
||||
});
|
||||
|
||||
describe('_getClient()', () => {
|
||||
it(`should call _getClient() and define the client value on the controller`, () => {
|
||||
controller.client = {};
|
||||
let response = {id: 101, name: 'Batman'};
|
||||
$httpBackend.whenGET(`/client/api/Clients/101/card`).respond(response);
|
||||
$httpBackend.expectGET(`/client/api/Clients/101/card`);
|
||||
controller._getClient(101);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.client.name).toEqual('Batman');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -14,21 +14,21 @@
|
|||
vn-focus
|
||||
label="Social name"
|
||||
field="$ctrl.client.socialName"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Tax number"
|
||||
field="$ctrl.client.fi"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-textfield>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="Is equalizated"
|
||||
field="$ctrl.client.isEqualizated"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
|
@ -37,14 +37,14 @@
|
|||
vn-two
|
||||
label="Street"
|
||||
field="$ctrl.client.street"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="City"
|
||||
field="$ctrl.client.city"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
|
@ -53,7 +53,7 @@
|
|||
vn-one
|
||||
label="Postcode"
|
||||
field="$ctrl.client.postcode"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
|
@ -64,7 +64,7 @@
|
|||
show-field="name"
|
||||
value-field="id"
|
||||
label="Province"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
|
@ -75,7 +75,7 @@
|
|||
show-field="country"
|
||||
value-field="id"
|
||||
label="Country"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
|
@ -84,21 +84,21 @@
|
|||
vn-one
|
||||
label="Active"
|
||||
field="$ctrl.client.isActive"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="Invoice by address"
|
||||
field="$ctrl.client.hasToInvoiceByAddress"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="Verified data"
|
||||
field="$ctrl.client.isTaxDataChecked"
|
||||
vn-acl="administrative">
|
||||
vn-acl="administrative, salesAssistant, salesAssistant">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
|
@ -106,21 +106,21 @@
|
|||
vn-one
|
||||
label="Has to invoice"
|
||||
field="$ctrl.client.hasToInvoice"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="Invoice by mail"
|
||||
field="$ctrl.client.isToBeMailed"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="Vies"
|
||||
field="$ctrl.client.isVies"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
|
@ -128,7 +128,7 @@
|
|||
<vn-button-bar>
|
||||
<vn-submit
|
||||
label="Save"
|
||||
vn-acl="administrative, salesPerson"
|
||||
vn-acl="administrative, salesAssistant, salesPerson"
|
||||
acl-conditional-to-salesPerson="{{!$ctrl.client.isTaxDataChecked}}">
|
||||
</vn-submit>
|
||||
</vn-button-bar>
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
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.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-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>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<vn-float-button
|
||||
icon="edit"
|
||||
style="position: absolute; margin: 1em; bottom: 0; right: 0;"
|
||||
vn-visible-by="administrative">
|
||||
vn-visible-by="administrative, salesAssistant">
|
||||
</vn-float-button>
|
||||
</a>
|
||||
</vn-auto>
|
||||
|
|
|
@ -153,7 +153,7 @@ vn-main-block {
|
|||
}
|
||||
|
||||
.vn-descriptor {
|
||||
& .header {
|
||||
.header {
|
||||
background: #ffa410;
|
||||
color: white;
|
||||
justify-content: space-between;
|
||||
|
@ -178,6 +178,19 @@ vn-main-block {
|
|||
}
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
text-align: center;
|
||||
& > vn-icon {
|
||||
color: #666;
|
||||
opacity: .4;
|
||||
padding: 0 5% 0 5%;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
& > vn-icon.bright {
|
||||
color: #ffa410;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.vn-list {
|
||||
|
|
|
@ -97,7 +97,6 @@ export default {
|
|||
secondEditButton: `vn-horizontal:nth-child(3) > vn-one > vn-horizontal > a > ${components.vnIconButton}[icon='edit']`,
|
||||
activeCheckbox: `${components.vnCheck}[label='Enabled'] > label > input`,
|
||||
equalizationTaxCheckboxLabel: `${components.vnCheck}[label='Is equalizated'] > label > input`,
|
||||
addAddressNoteButton: `${components.vnIcon}[icon="add_circle"]`,
|
||||
firstObservationTypeSelect: `${components.vnAutocomplete}[field="observation.observationTypeFk"]:nth-child(1) input`,
|
||||
firstObservationTypeSelectOptionOne: `${components.vnAutocomplete}[field="observation.observationTypeFk"] vn-drop-down ul > li:nth-child(1)`,
|
||||
firstObservationDescriptionInput: `vn-horizontal:nth-child(3) > vn-textfield[label="Description"] > div > input`,
|
||||
|
@ -107,6 +106,7 @@ export default {
|
|||
thirdObservationTypeSelect: `${components.vnAutocomplete}[field="observation.observationTypeFk"]:nth-child(3) input`,
|
||||
thirdObservationTypeSelectOptionThree: `${components.vnAutocomplete}[field="observation.observationTypeFk"] vn-drop-down ul > li:nth-child(3)`,
|
||||
thirdObservationDescriptionInput: `vn-horizontal:nth-child(5) > vn-textfield[label="Description"] > div > input`,
|
||||
addObservationButton: `${components.vnIcon}[icon="add_circle"]`,
|
||||
saveButton: `${components.vnSubmit}`
|
||||
},
|
||||
clientWebAccess: {
|
||||
|
|
|
@ -1,96 +1,97 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import createNightmare from '../../helpers/helpers';
|
||||
// import selectors from '../../helpers/selectors.js';
|
||||
// import createNightmare from '../../helpers/helpers';
|
||||
|
||||
describe('Add address notes path', () => {
|
||||
const nightmare = createNightmare();
|
||||
// describe('Add address notes path', () => {
|
||||
// const nightmare = createNightmare();
|
||||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
});
|
||||
// beforeAll(() => {
|
||||
// return nightmare
|
||||
// .waitForLogin('developer');
|
||||
// });
|
||||
|
||||
it('should click on the Clients button of the top bar menu', () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.globalItems.applicationsMenuButton)
|
||||
.wait(selectors.globalItems.applicationsMenuVisible)
|
||||
.waitToClick(selectors.globalItems.clientsButton)
|
||||
.wait(selectors.clientsIndex.createClientButton)
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toEqual('#!/clients');
|
||||
});
|
||||
});
|
||||
// it('should click on the Clients button of the top bar menu', () => {
|
||||
// return nightmare
|
||||
// .waitToClick(selectors.globalItems.applicationsMenuButton)
|
||||
// .wait(selectors.globalItems.applicationsMenuVisible)
|
||||
// .waitToClick(selectors.globalItems.clientsButton)
|
||||
// .wait(selectors.clientsIndex.createClientButton)
|
||||
// .parsedUrl()
|
||||
// .then(url => {
|
||||
// expect(url.hash).toEqual('#!/clients');
|
||||
// });
|
||||
// });
|
||||
|
||||
it('should search for the user Petter Parker', () => {
|
||||
return nightmare
|
||||
.wait(selectors.clientsIndex.searchResult)
|
||||
.type(selectors.clientsIndex.searchClientInput, 'Petter Parker')
|
||||
.click(selectors.clientsIndex.searchButton)
|
||||
.waitForNumberOfElements(selectors.clientsIndex.searchResult, 1)
|
||||
.countSearchResults(selectors.clientsIndex.searchResult)
|
||||
.then(result => {
|
||||
expect(result).toEqual(1);
|
||||
});
|
||||
});
|
||||
// it('should search for the user Petter Parker', () => {
|
||||
// return nightmare
|
||||
// .wait(selectors.clientsIndex.searchResult)
|
||||
// .type(selectors.clientsIndex.searchClientInput, 'Petter Parker')
|
||||
// .click(selectors.clientsIndex.searchButton)
|
||||
// .waitForNumberOfElements(selectors.clientsIndex.searchResult, 1)
|
||||
// .countSearchResults(selectors.clientsIndex.searchResult)
|
||||
// .then(result => {
|
||||
// expect(result).toEqual(1);
|
||||
// });
|
||||
// });
|
||||
|
||||
it(`should click on the search result to access to the client addresses`, () => {
|
||||
return nightmare
|
||||
.waitForTextInElement(selectors.clientsIndex.searchResult, 'Petter Parker')
|
||||
.waitToClick(selectors.clientsIndex.searchResult)
|
||||
.waitToClick(selectors.clientAddresses.addressesButton)
|
||||
.waitForURL('addresses/list')
|
||||
.url()
|
||||
.then(url => {
|
||||
expect(url).toContain('addresses/list');
|
||||
});
|
||||
});
|
||||
// it(`should click on the search result to access to the client addresses`, () => {
|
||||
// return nightmare
|
||||
// .waitForTextInElement(selectors.clientsIndex.searchResult, 'Petter Parker')
|
||||
// .waitToClick(selectors.clientsIndex.searchResult)
|
||||
// .waitToClick(selectors.clientAddresses.addressesButton)
|
||||
// .waitForURL('addresses/list')
|
||||
// .url()
|
||||
// .then(url => {
|
||||
// expect(url).toContain('addresses/list');
|
||||
// });
|
||||
// });
|
||||
|
||||
it(`should click on the edit icon of the default address`, () => {
|
||||
return nightmare
|
||||
.waitForTextInElement(selectors.clientAddresses.defaultAddress, '20 Ingram Street')
|
||||
.waitToClick(selectors.clientAddresses.firstEditButton)
|
||||
.waitForURL('/edit')
|
||||
.url()
|
||||
.then(result => {
|
||||
expect(result).toContain('/edit');
|
||||
});
|
||||
});
|
||||
// it(`should click on the edit icon of the default address`, () => {
|
||||
// return nightmare
|
||||
// .waitForTextInElement(selectors.clientAddresses.defaultAddress, '20 Ingram Street')
|
||||
// .waitToClick(selectors.clientAddresses.firstEditButton)
|
||||
// .waitForURL('/edit')
|
||||
// .url()
|
||||
// .then(result => {
|
||||
// expect(result).toContain('/edit');
|
||||
// });
|
||||
// });
|
||||
|
||||
it('should not save a description without observation type', () => {
|
||||
return nightmare
|
||||
.wait(selectors.clientAddresses.firstObservationDescriptionInput)
|
||||
.type(selectors.clientAddresses.firstObservationDescriptionInput, 'first description')
|
||||
.waitToClick(selectors.clientAddresses.saveButton)
|
||||
.waitForSnackbar()
|
||||
.then(result => {
|
||||
expect(result).toContain('No changes to save');
|
||||
});
|
||||
});
|
||||
// it('should not save a description without observation type', () => {
|
||||
// return nightmare
|
||||
// .waitToClick(selectors.clientAddresses.addObservationButton)
|
||||
// .wait(selectors.clientAddresses.firstObservationDescriptionInput)
|
||||
// .type(selectors.clientAddresses.firstObservationDescriptionInput, 'first description')
|
||||
// .waitToClick(selectors.clientAddresses.saveButton)
|
||||
// .waitForSnackbar()
|
||||
// .then(result => {
|
||||
// expect(result).toContain('Some fields are invalid');
|
||||
// });
|
||||
// });
|
||||
|
||||
it('should not save an observation type without description type', () => {
|
||||
return nightmare
|
||||
.clearInput(selectors.clientAddresses.firstObservationDescriptionInput)
|
||||
.waitToClick(selectors.clientAddresses.firstObservationTypeSelect)
|
||||
.waitToClick(selectors.clientAddresses.firstObservationTypeSelectOptionOne)
|
||||
.waitForTextInInput(selectors.clientAddresses.firstObservationTypeSelect, 'observation one')
|
||||
.waitToClick(selectors.clientAddresses.saveButton)
|
||||
.waitForSnackbar()
|
||||
.then(result => {
|
||||
expect(result).toContain('No changes to save');
|
||||
});
|
||||
});
|
||||
// it('should not save an observation type without description', () => {
|
||||
// return nightmare
|
||||
// .clearInput(selectors.clientAddresses.firstObservationDescriptionInput)
|
||||
// .waitToClick(selectors.clientAddresses.firstObservationTypeSelect)
|
||||
// .waitToClick(selectors.clientAddresses.firstObservationTypeSelectOptionOne)
|
||||
// .waitToClick(selectors.clientAddresses.saveButton)
|
||||
// .waitForSnackbar()
|
||||
// .then(result => {
|
||||
// expect(result).toContain('Some fields are invalid');
|
||||
// });
|
||||
// });
|
||||
|
||||
it('should show an error if there are empty fields', () => {
|
||||
return nightmare
|
||||
.type(selectors.clientAddresses.firstObservationDescriptionInput, 'first description')
|
||||
.waitToClick(selectors.clientAddresses.addAddressNoteButton)
|
||||
.wait(selectors.clientAddresses.secondObservationDescriptionInput)
|
||||
.type(selectors.clientAddresses.secondObservationDescriptionInput, 'second description')
|
||||
.waitToClick(selectors.clientAddresses.saveButton)
|
||||
.waitForSnackbar()
|
||||
.then(result => {
|
||||
expect(result).toContain('No changes to save');
|
||||
});
|
||||
});
|
||||
});
|
||||
// it('should create two new observations', () => {
|
||||
// return nightmare
|
||||
// .type(selectors.clientAddresses.firstObservationDescriptionInput, 'first description')
|
||||
// .waitToClick(selectors.clientAddresses.addObservationButton)
|
||||
// .waitToClick(selectors.clientAddresses.secondObservationTypeSelect)
|
||||
// .waitToClick(selectors.clientAddresses.secondObservationTypeSelectOptionTwo)
|
||||
// .type(selectors.clientAddresses.secondObservationDescriptionInput, 'second description')
|
||||
// .waitToClick(selectors.clientAddresses.saveButton)
|
||||
// .waitForSnackbar()
|
||||
// .then(result => {
|
||||
// expect(result).toContain('pepinillos saved!');
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
|
|
|
@ -280,4 +280,193 @@ describe('lock verified data path', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('as salesAssistant', () => {
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.globalItems.logOutButton)
|
||||
.waitForLogin('salesAssistant');
|
||||
});
|
||||
|
||||
it('should navigate to clients index', () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.globalItems.applicationsMenuButton)
|
||||
.wait(selectors.globalItems.applicationsMenuVisible)
|
||||
.waitToClick(selectors.globalItems.clientsButton)
|
||||
.wait(selectors.clientsIndex.createClientButton)
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toEqual('#!/clients');
|
||||
});
|
||||
});
|
||||
|
||||
it('should search again for the user Petter Parker', () => {
|
||||
return nightmare
|
||||
.wait(selectors.clientsIndex.searchResult)
|
||||
.type(selectors.clientsIndex.searchClientInput, 'Petter Parker')
|
||||
.click(selectors.clientsIndex.searchButton)
|
||||
.waitForNumberOfElements(selectors.clientsIndex.searchResult, 1)
|
||||
.countSearchResults(selectors.clientsIndex.searchResult)
|
||||
.then(result => {
|
||||
expect(result).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
it(`should click on the search result to access to the Petter Parkers fiscal data`, () => {
|
||||
return nightmare
|
||||
.waitForTextInElement(selectors.clientsIndex.searchResult, 'Petter Parker')
|
||||
.waitToClick(selectors.clientsIndex.searchResult)
|
||||
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
|
||||
.waitForURL('fiscal-data')
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toContain('fiscal-data');
|
||||
});
|
||||
});
|
||||
|
||||
it(`should click on the fiscal data button`, () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
|
||||
.waitForURL('fiscal-data')
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toContain('fiscal-data');
|
||||
});
|
||||
});
|
||||
|
||||
it('should confirm verified data button is enabled for salesAssistant', () => {
|
||||
return nightmare
|
||||
.wait(selectors.clientFiscalData.verifiedDataCheckboxInput)
|
||||
.evaluate(selector => {
|
||||
return document.querySelector(selector).className;
|
||||
}, 'body > vn-app > vn-vertical > vn-vertical > vn-client-card > vn-main-block > vn-horizontal > vn-one > vn-vertical > vn-client-fiscal-data > form > vn-card > div > vn-horizontal:nth-child(5) > vn-check:nth-child(3) > label')
|
||||
.then(result => {
|
||||
expect(result).not.toContain('is-disabled');
|
||||
});
|
||||
});
|
||||
|
||||
it('should uncheck the Verified data checkbox', () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.clientFiscalData.verifiedDataCheckboxInput)
|
||||
.waitToClick(selectors.clientFiscalData.saveButton)
|
||||
.waitForSnackbar()
|
||||
.then(result => {
|
||||
expect(result).toEqual('Data saved!');
|
||||
});
|
||||
});
|
||||
|
||||
it('should confirm Verified data checkbox is unchecked', () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.clientBasicData.basicDataButton)
|
||||
.wait(selectors.clientBasicData.nameInput)
|
||||
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
|
||||
.wait(selectors.clientFiscalData.verifiedDataCheckboxInput)
|
||||
.evaluate(selector => {
|
||||
return document.querySelector(selector).checked;
|
||||
}, selectors.clientFiscalData.verifiedDataCheckboxInput)
|
||||
.then(value => {
|
||||
expect(value).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
it('should again edit the social name', () => {
|
||||
return nightmare
|
||||
.wait(selectors.clientFiscalData.socialNameInput)
|
||||
.clearInput(selectors.clientFiscalData.socialNameInput)
|
||||
.type(selectors.clientFiscalData.socialNameInput, 'salesAssistant was here')
|
||||
.click(selectors.clientFiscalData.saveButton)
|
||||
.waitForSnackbar()
|
||||
.then(result => {
|
||||
expect(result).toEqual('Data saved!');
|
||||
});
|
||||
});
|
||||
|
||||
it('should confirm the social name have been edited once and for all', () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.clientBasicData.basicDataButton)
|
||||
.wait(selectors.clientBasicData.nameInput)
|
||||
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
|
||||
.wait(selectors.clientFiscalData.socialNameInput)
|
||||
.getInputValue(selectors.clientFiscalData.socialNameInput)
|
||||
.then(result => {
|
||||
expect(result).toEqual('salesAssistant was here');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('as salesPerson third run', () => {
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.globalItems.logOutButton)
|
||||
.waitForLogin('salesPerson');
|
||||
});
|
||||
|
||||
it('should again click on the Clients button of the top bar menu', () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.globalItems.applicationsMenuButton)
|
||||
.wait(selectors.globalItems.applicationsMenuVisible)
|
||||
.waitToClick(selectors.globalItems.clientsButton)
|
||||
.wait(selectors.clientsIndex.createClientButton)
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toEqual('#!/clients');
|
||||
});
|
||||
});
|
||||
|
||||
it('should once again search for the user Petter Parker', () => {
|
||||
return nightmare
|
||||
.wait(selectors.clientsIndex.searchResult)
|
||||
.type(selectors.clientsIndex.searchClientInput, 'Petter Parker')
|
||||
.click(selectors.clientsIndex.searchButton)
|
||||
.waitForNumberOfElements(selectors.clientsIndex.searchResult, 1)
|
||||
.countSearchResults(selectors.clientsIndex.searchResult)
|
||||
.then(result => {
|
||||
expect(result).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
it(`should click on the search result to access to the client's fiscal data`, () => {
|
||||
return nightmare
|
||||
.waitForTextInElement(selectors.clientsIndex.searchResult, 'Petter Parker')
|
||||
.waitToClick(selectors.clientsIndex.searchResult)
|
||||
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
|
||||
.waitForURL('fiscal-data')
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toContain('fiscal-data');
|
||||
});
|
||||
});
|
||||
|
||||
it(`should click on the fiscal data button to start editing`, () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
|
||||
.waitForURL('fiscal-data')
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toContain('fiscal-data');
|
||||
});
|
||||
});
|
||||
|
||||
it('should confirm verified data button is enabled once again', () => {
|
||||
return nightmare
|
||||
.wait(selectors.clientFiscalData.verifiedDataCheckboxInput)
|
||||
.evaluate(selector => {
|
||||
return document.querySelector(selector).className;
|
||||
}, 'body > vn-app > vn-vertical > vn-vertical > vn-client-card > vn-main-block > vn-horizontal > vn-one > vn-vertical > vn-client-fiscal-data > form > vn-card > div > vn-horizontal:nth-child(5) > vn-check:nth-child(3) > label')
|
||||
.then(result => {
|
||||
expect(result).toContain('is-disabled');
|
||||
});
|
||||
});
|
||||
|
||||
it('should confirm the form is enabled for salesPerson', () => {
|
||||
return nightmare
|
||||
.wait(selectors.clientFiscalData.socialNameInput)
|
||||
.evaluate(selector => {
|
||||
return document.querySelector(selector).className;
|
||||
}, 'vn-textfield[field="$ctrl.client.socialName"] > div')
|
||||
.then(result => {
|
||||
expect(result).not.toContain('is-disabled');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import selectors from '../helpers/selectors';
|
||||
import createNightmare from '../helpers/helpers';
|
||||
|
||||
describe('create client path', () => {
|
||||
let nightmare = createNightmare();
|
||||
|
||||
beforeAll(() => {
|
||||
return nightmare
|
||||
.waitForLogin('developer');
|
||||
});
|
||||
|
||||
it('should access to the clients index by clicking the clients button', () => {
|
||||
return nightmare
|
||||
.click(selectors.moduleAccessView.clientsSectionButton)
|
||||
.wait(selectors.clientsIndex.createClientButton)
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toEqual('#!/clients');
|
||||
});
|
||||
});
|
||||
|
||||
it('should access to the create client view by clicking the create-client floating button', () => {
|
||||
return nightmare
|
||||
.click(selectors.clientsIndex.createClientButton)
|
||||
.wait(selectors.createClientView.createButton)
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toEqual('#!/create');
|
||||
});
|
||||
});
|
||||
|
||||
it('should cancel the client creation to go back to clients index', () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.globalItems.applicationsMenuButton)
|
||||
.waitToClick(selectors.globalItems.clientsButton)
|
||||
.wait(selectors.clientsIndex.createClientButton)
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toEqual('#!/clients');
|
||||
});
|
||||
});
|
||||
});
|
16
gulpfile.js
16
gulpfile.js
|
@ -63,10 +63,14 @@ gulp.task('services-only', async () => {
|
|||
/**
|
||||
* Runs the e2e tests, restoring the fixtures first.
|
||||
*/
|
||||
gulp.task('e2e', ['docker-rebuild'], async () => {
|
||||
gulp.task('e2e', ['docker'], async () => {
|
||||
await runSequenceP('e2e-only');
|
||||
});
|
||||
|
||||
gulp.task('smokes', ['docker'], async () => {
|
||||
await runSequenceP('smokes-only');
|
||||
});
|
||||
|
||||
/**
|
||||
* Runs the e2e tests.
|
||||
*/
|
||||
|
@ -76,6 +80,12 @@ gulp.task('e2e-only', () => {
|
|||
.pipe(jasmine({reporter: 'none'}));
|
||||
});
|
||||
|
||||
gulp.task('smokes-only', () => {
|
||||
const jasmine = require('gulp-jasmine');
|
||||
return gulp.src('./smokes_tests.js')
|
||||
.pipe(jasmine({reporter: 'none'}));
|
||||
});
|
||||
|
||||
/**
|
||||
* Runs the backend tests.
|
||||
*/
|
||||
|
@ -391,7 +401,7 @@ gulp.task('watch', function() {
|
|||
* Rebuilds the docker and it's image, if these already exist, destroys and
|
||||
* rebuilds them.
|
||||
*/
|
||||
gulp.task('docker-rebuild', async () => {
|
||||
gulp.task('docker', async () => {
|
||||
try {
|
||||
await execP('docker rm -f dblocal');
|
||||
} catch (e) {}
|
||||
|
@ -406,7 +416,7 @@ gulp.task('docker-rebuild', async () => {
|
|||
* Does the minium effort to start the docker, if it doesn't exists calls
|
||||
* the 'docker-run' task, if it is started does nothing. Keep in mind that when
|
||||
* you do not rebuild the docker you may be using an outdated version of it.
|
||||
* See the 'docker-rebuild' task for more info.
|
||||
* See the 'docker' task for more info.
|
||||
*/
|
||||
gulp.task('docker-start', async () => {
|
||||
let state;
|
||||
|
|
|
@ -23,7 +23,7 @@ module.exports = function(Self) {
|
|||
let user = {
|
||||
name: data.userName,
|
||||
email: firstEmail,
|
||||
password: md5(parseInt(Math.random() * 100000000000000))
|
||||
password: parseInt(Math.random() * 100000000000000)
|
||||
};
|
||||
let Account = Self.app.models.Account;
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('getDebt', {
|
||||
description: 'Returns the boolean debt of a client',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'client id',
|
||||
http: {source: 'path'}
|
||||
}],
|
||||
returns: {
|
||||
type: 'number',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:id/getDebt`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.getDebt = async clientFk => {
|
||||
let query = `SELECT vn.clientGetDebt(?, CURDATE()) AS debt`;
|
||||
let response = await Self.rawSql(query, [clientFk]);
|
||||
return response[0];
|
||||
};
|
||||
};
|
|
@ -0,0 +1,16 @@
|
|||
const getDebt = require('../getDebt');
|
||||
|
||||
describe('client getDebt()', () => {
|
||||
it('should call the getDebt method', done => {
|
||||
let clientFk = 109;
|
||||
let self = jasmine.createSpyObj('self', ['remoteMethod', 'rawSql']);
|
||||
self.rawSql.and.returnValue(Promise.resolve([{debt: 100}]));
|
||||
getDebt(self);
|
||||
self.getDebt(clientFk)
|
||||
.then(result => {
|
||||
expect(result.debt).toEqual(100);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -15,6 +15,7 @@ module.exports = function(Self) {
|
|||
require('../methods/client/isValidClient')(Self);
|
||||
require('../methods/client/activeSalesPerson')(Self);
|
||||
require('../methods/client/addressesPropagateRe')(Self);
|
||||
require('../methods/client/getDebt')(Self);
|
||||
|
||||
// Validations
|
||||
|
||||
|
@ -34,7 +35,7 @@ module.exports = function(Self) {
|
|||
message: 'Correo electrónico inválido',
|
||||
allowNull: true,
|
||||
allowBlank: true,
|
||||
with: /^[\w|-|.]+@[\w|-]+(\.[\w|-]+)*(,[\w|-|.]+@[\w|-]+(\.[\w|-]+)*)*$/
|
||||
with: /^[\w|.|-]+@[\w|-]+(\.[\w|-]+)*(,[\w|.|-]+@[\w|-]+(\.[\w|-]+)*)*$/
|
||||
});
|
||||
Self.validatesLengthOf('postcode', {
|
||||
allowNull: true,
|
||||
|
|
|
@ -64,6 +64,10 @@
|
|||
"type": "boolean",
|
||||
"description": "The client has equalization tax"
|
||||
},
|
||||
"isFreezed": {
|
||||
"type": "boolean",
|
||||
"description": "The client frozen"
|
||||
},
|
||||
"hasToInvoiceByAddress": {
|
||||
"type": "boolean",
|
||||
"description": "The client has to be invoiced by address"
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
require('babel-core/register')({presets: ['es2015']});
|
||||
|
||||
process.on('warning', warning => {
|
||||
console.log(warning.name);
|
||||
console.log(warning.message);
|
||||
console.log(warning.stack);
|
||||
});
|
||||
|
||||
var verbose = false;
|
||||
|
||||
if (process.argv[2] === '--v') {
|
||||
verbose = true;
|
||||
}
|
||||
|
||||
var Jasmine = require('jasmine');
|
||||
var jasmine = new Jasmine();
|
||||
var SpecReporter = require('jasmine-spec-reporter').SpecReporter;
|
||||
|
||||
jasmine.loadConfig({
|
||||
spec_files: [
|
||||
'./e2e/smokes/**/*[sS]pec.js',
|
||||
'./e2e/helpers/extensions.js'
|
||||
],
|
||||
helpers: [
|
||||
'/services/utils/jasmineHelpers.js'
|
||||
]
|
||||
});
|
||||
|
||||
jasmine.addReporter(new SpecReporter({
|
||||
spec: {
|
||||
// displayStacktrace: 'summary',
|
||||
displaySuccessful: verbose,
|
||||
displayFailedSpec: true,
|
||||
displaySpecDuration: true
|
||||
}
|
||||
}));
|
||||
|
||||
jasmine.execute();
|
Loading…
Reference in New Issue