This commit is contained in:
Vicente Falco 2018-03-12 08:44:15 +01:00
commit 47ea8edb32
95 changed files with 2542 additions and 2583 deletions

View File

@ -1,6 +0,0 @@
{
"salixHost": "localhost",
"salixPort": 3306,
"salixUser": "root",
"salixPassword": ""
}

8
Jenkinsfile vendored
View File

@ -6,16 +6,10 @@ def branchTest = "test";
env.BRANCH_NAME = branchName;
env.TAG = "${env.BUILD_NUMBER}";
env.salixUser="${env.salixUser}";
env.salixPassword="${env.salixPassword}";
env.salixHost = "${env.productionSalixHost}";
env.salixPort = "${env.productionSalixPort}";
switch (branchName){
case branchTest:
env.NODE_ENV = "test";
env.salixHost = "${env.testSalixHost}";
env.salixPort = "${env.testSalixPort}";
break;
case branchProduction:
env.DOCKER_HOST = "tcp://172.16.255.29:2375";
@ -26,7 +20,7 @@ switch (branchName){
node
{
stage ('Print environment variables'){
echo "Branch ${branchName}, Build ${env.TAG}, salixHost ${env.salixHost}, NODE_ENV ${env.NODE_ENV} en docker Host ${env.DOCKER_HOST}"
echo "Branch ${branchName}, Build ${env.TAG}, NODE_ENV ${env.NODE_ENV} en docker Host ${env.DOCKER_HOST}"
}
stage ('Checkout') {
checkout scm

View File

@ -61,29 +61,36 @@
<tpl-item>{{$parent.$parent.item.description}}</tpl-item>
</vn-autocomplete>
<vn-textfield
vn-auto
vn-two
margin-large-right
label="Description"
model="observation.description"
rule="addressObservation.description">
</vn-textfield>
<vn-one pad-medium-top>
<vn-auto pad-medium-top>
<vn-icon
pointer
medium-grey
vn-tooltip="Remove note"
tooltip-position = "left"
icon="remove_circle_outline"
ng-click="$ctrl.removeObservation($index)">
</vn-icon>
<vn-icon
pointer
margin-medium-left
orange
icon="add_circle"
ng-if="observation.showAddIcon && observationsTypes.model.length > $ctrl.observations.length"
ng-click="$ctrl.addObservation()">
</vn-icon>
</vn-one>
</vn-horizontal>
</vn-one>
<vn-one>
<vn-icon
pointer
margin-medium-left
vn-tooltip="Add note"
tooltip-position = "right"
orange
icon="add_circle"
ng-if="observationsTypes.model.length > $ctrl.observations.length"
ng-click="$ctrl.addObservation()">
</vn-icon>
</vn-one>
</vn-card>
<vn-button-bar>
<vn-submit label="Save"></vn-submit>

View File

@ -17,18 +17,6 @@ export default class Controller {
this.observationsRemoved = [];
}
_setIconAdd() {
if (this.observations.length) {
this.observations.map(element => {
element.showAddIcon = false;
return true;
});
this.observations[this.observations.length - 1].showAddIcon = true;
} else {
this.addObservation();
}
}
_setDirtyForm() {
if (this.$scope.form) {
this.$scope.form.$setDirty();
@ -41,20 +29,21 @@ export default class Controller {
}
addObservation() {
this.observations.push({observationTypeFk: null, addressFk: this.address.id, description: null, showAddIcon: true});
this._setIconAdd();
this.observations.push({observationTypeFk: null, addressFk: this.address.id, description: null});
}
removeObservation(index) {
let item = this.observations[index];
if (item) {
this.observations.splice(index, 1);
this._setIconAdd();
if (item.id) {
this.observationsRemoved.push(item.id);
this._setDirtyForm();
}
}
if (this.observations.length === 0 && Object.keys(this.observationsOld).length === 0) {
this._unsetDirtyForm();
}
}
_submitObservations(objectObservations) {
return this.$http.post(`/client/api/AddressObservations/crudAddressObservations`, objectObservations);
@ -65,7 +54,10 @@ export default class Controller {
}
submit() {
this._unsetDirtyForm();
if (this.$scope.form.$invalid) {
return false;
}
let canWatcherSubmit = this.$scope.watcher.dataChanged();
let canObservationsSubmit;
let repeatedTypes = false;
@ -118,6 +110,7 @@ export default class Controller {
this.$translate.instant('No changes to save')
);
}
this._unsetDirtyForm();
}
$onInit() {

View File

@ -23,56 +23,6 @@ describe('Client', () => {
expect(controller.address.id).toEqual(1);
});
describe('_setIconAdd()', () => {
it('should set the propertie sowAddIcon from all observations to false less last one that be true', () => {
controller.observations = [
{id: 1, description: 'Spiderman rocks', showAddIcon: true},
{id: 2, description: 'Batman sucks', showAddIcon: true},
{id: 3, description: 'Ironman rules', showAddIcon: false}
];
controller._setIconAdd();
expect(controller.observations[0].showAddIcon).toBeFalsy();
expect(controller.observations[1].showAddIcon).toBeFalsy();
expect(controller.observations[2].showAddIcon).toBeTruthy();
});
});
describe('addObservation()', () => {
it('should add one empty observation into controller observations collection and call _setIconAdd()', () => {
controller.observations = [];
spyOn(controller, '_setIconAdd').and.callThrough();
controller.addObservation();
expect(controller._setIconAdd).toHaveBeenCalledWith();
expect(controller.observations.length).toEqual(1);
expect(controller.observations[0].id).toBe(undefined);
expect(controller.observations[0].showAddIcon).toBeTruthy();
});
});
describe('removeObservation(index)', () => {
it('should remove an observation that occupies the position in the index given and call _setIconAdd()', () => {
let index = 2;
controller.observations = [
{id: 1, description: 'Spiderman rocks', showAddIcon: false},
{id: 2, description: 'Batman sucks', showAddIcon: false},
{id: 3, description: 'Ironman rules', showAddIcon: true}
];
spyOn(controller, '_setIconAdd').and.callThrough();
controller.removeObservation(index);
expect(controller._setIconAdd).toHaveBeenCalledWith();
expect(controller.observations.length).toEqual(2);
expect(controller.observations[0].showAddIcon).toBeFalsy();
expect(controller.observations[1].showAddIcon).toBeTruthy();
expect(controller.observations[index]).toBe(undefined);
});
});
describe('_observationsEquals', () => {
it('should return true if two observations are equals independent of control attributes', () => {
let ob1 = {id: 1, observationTypeFk: 1, description: 'Spiderman rocks', showAddIcon: true};

View File

@ -2,4 +2,6 @@ Enabled: Activo
Is equalizated: Recargo de equivalencia
Observation type: Tipo de observación
Description: Descripción
The observation type must be unique: El tipo de observación ha de ser único
The observation type must be unique: El tipo de observación ha de ser único
Add note: Añadir nota
Remove note: Quitar nota

View File

@ -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>

View File

@ -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
});

View File

@ -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 client.debt 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.client.debt).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');
});
});
});
});

View File

@ -1,4 +1,6 @@
Since: Desde
Employee: Empleado
No results: Sin resultados
To: Hasta
To: Hasta
Recovery: Recobros
Finish that recovery period: Terminar el recobro

View File

@ -4,7 +4,7 @@
<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="DESC"></vn-column-header>
<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>
@ -13,11 +13,17 @@
<vn-horizontal
vn-one class="list list-element text-center"
pad-small-bottom
ng-repeat="recovery in index.model.instances track by recovery.id">
<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>
ng-repeat="recovery in index.model.instances track by $index">
<vn-none pad-medium-h style="color:#FFA410;">
<i class="material-icons"
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>

View File

@ -1,7 +1,24 @@
import ngModule from '../module';
import FilterClientList from '../filter-client-list';
class ClientRecoveryList extends FilterClientList {
constructor($scope, $timeout, $state, $http) {
super($scope, $timeout, $state);
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()
);
}
}
}
ClientRecoveryList.$inject = ['$scope', '$timeout', '$state', '$http'];
ngModule.component('vnClientRecoveryList', {
template: require('./recovery-list.html'),
controller: FilterClientList
controller: ClientRecoveryList
});

View File

@ -2,45 +2,154 @@
<vn-card class="summary">
<vn-vertical pad-medium>
<vn-auto>
<h5 text-center pad-small-v class="tittle">{{$ctrl.client.name}} - {{$ctrl.client.id}} - {{$ctrl.client.salesPerson.name}}</h5>
<h5 text-center pad-small-v class="tittle">{{$ctrl.summary.name}} - {{$ctrl.summary.id}} - {{$ctrl.summary.salesPerson.name}}</h5>
</vn-auto>
<vn-horizontal vn-one>
<vn-one margin-medium>
<h5 translate>Basic data</h5>
<p><span translate>Commercial name</span>: <b>{{$ctrl.client.name}}</b></p>
<p><span translate>Contact</span>: <b>{{$ctrl.client.contact}}</b></p>
<p><span translate>Phone</span>: <b>{{$ctrl.client.phone}}</b></p>
<p><span translate>Mobile</span>: <b>{{$ctrl.client.mobile}}</b></p>
<p><span translate>Email</span>: <b>{{$ctrl.client.email}}</b></p>
<p><span translate>Salesperson</span>: <b>{{$ctrl.client.salesPerson}}</b></p>
<p><span translate>Channel</span>: <b>{{$ctrl.client.contactChannel}}</b></p>
<p><vn-label translate>Comercial Name</vn-label> {{$ctrl.summary.name}}</p>
<p><vn-label translate>Contact</vn-label> {{$ctrl.summary.contact}}</p>
<p><vn-label translate>Phone</vn-label> {{$ctrl.summary.phone}}</p>
<p><vn-label translate>Mobile</vn-label> {{$ctrl.summary.mobile}}</p>
<p><vn-label translate>Email</vn-label> {{$ctrl.summary.email}}</p>
<p><vn-label translate>Salesperson</vn-label> {{$ctrl.summary.salesPerson.name}}</p>
<p><vn-label translate>Channel</vn-label> {{$ctrl.summary.contactChannel.name}}</p>
</vn-one>
<vn-one margin-medium>
<h5 translate>Fiscal data</h5>
<p><span translate>Social name</span>: <b>{{$ctrl.client.socialName}}</b></p>
<p><span translate>NIF / CIF</span>: <b>{{$ctrl.client.fi}}</b></p>
<p><span translate>Fiscal address</span>: <b>{{$ctrl.client.street}}</b></p>
<p><span translate>City</span>: <b>{{$ctrl.client.city}}</b></p>
<p><span translate>Postcode</span>: <b>{{$ctrl.client.postcode}}</b></p>
<p><span translate>Province</span>: <b>{{$ctrl.client.province}}</b></p>
<p><span translate>Country</span>: <b>{{$ctrl.client.country}}</b></p>
<p><vn-label translate>Social name</vn-label> {{$ctrl.summary.socialName}}</p>
<p><vn-label translate>NIF / CIF</vn-label> {{$ctrl.summary.fi}}</p>
<p><vn-label translate>Street</vn-label> {{$ctrl.summary.street}}</p>
<p><vn-label translate>City</vn-label> {{$ctrl.summary.city}}</p>
<p><vn-label translate>Postcode</vn-label> {{$ctrl.summary.postcode}}</p>
<p><vn-label translate>Province</vn-label> {{$ctrl.summary.province.name}}</p>
<p><vn-label translate>Country</vn-label> {{$ctrl.summary.country.country}}</p>
<p>
<vn-check
label="Is equalizated"
field="$ctrl.summary.isEqualizated"
disabled="true">
</vn-check>
</p>
<p>
<vn-check
label="Active"
field="$ctrl.summary.isActive"
disabled="true">
</vn-check>
</p>
<p>
<vn-check
label="Invoice by address"
field="$ctrl.summary.hasToInvoiceByAddress"
disabled="true">
</vn-check>
</p>
<p>
<vn-check
label="Verified data"
field="$ctrl.summary.isTaxDataChecked"
disabled="true">
</vn-check>
</p>
<p>
<vn-check
label="Has to invoice"
field="$ctrl.summary.hasToInvoice"
disabled="true">
</vn-check>
</p>
<p>
<vn-check
label="Invoice by mail"
field="$ctrl.summary.isToBeMailed"
disabled="true">
</vn-check>
</p>
<p>
<vn-check
label="Vies"
field="$ctrl.summary.isVies"
disabled="true">
</vn-check>
</p>
</vn-one>
<vn-one margin-medium>
<h5 translate>Pay method</h5>
<p><span translate>Pay method</span>: <b>{{$ctrl.client.payMethodFk}}</b></p>
<p><vn-label translate>Pay method</vn-label> {{$ctrl.summary.payMethod.name}}</p>
<p><vn-label translate>IBAN</vn-label> {{$ctrl.summary.iban}}</p>
<p><vn-label translate>Due day</vn-label> {{$ctrl.summary.dueDay}}</p>
<p>
<vn-check
label="Received core VNH"
field="$ctrl.summary.hasCoreVnh"
disabled="true">
</vn-check>
</p>
<p>
<vn-check
label="Received core VNL"
field="$ctrl.summary.hasCoreVnl"
disabled="true">
</vn-check>
</p>
<p>
<vn-check
label="Received B2B VNL"
field="$ctrl.summary.hasSepaVnl"
disabled="true">
</vn-check>
</p>
</vn-one>
</vn-horizontal>
<vn-horizontal vn-one>
<vn-one margin-medium>
<h5 translate>Address</h5>
<h5 translate>Default address</h5>
<p>{{$ctrl.address.nickname}}</p>
<p><span>{{$ctrl.address.street}}</span></p>
<p><span>{{$ctrl.address.city}}</span></p>
</vn-one>
<vn-one margin-medium>
<h5 translate>Credit</h5>
<h5 translate>Web access</h5>
<p><vn-label translate>User</vn-label> {{$ctrl.summary.account.name}}</p>
<p>
<vn-check
label="Enable web access"
field="$ctrl.summary.account.active"
disabled="true">
</vn-check>
</p>
</vn-one>
<vn-one margin-medium>
<h5 translate>Greuge</h5>
<h5 translate>Recovery</h5>
<vn-vertical ng-if="$ctrl.recovery">
<p><vn-label translate>Since</vn-label> {{$ctrl.recovery.started}}</p>
<p><vn-label translate>To</vn-label> {{$ctrl.recovery.finished}}</p>
<p><vn-label translate>Amount</vn-label> {{$ctrl.recovery.amount | currency:'€':2}}</p>
<p><vn-label translate>Period</vn-label> {{$ctrl.recovery.period}}</p>
</vn-vertical>
</vn-one>
</vn-horizontal>
<vn-horizontal vn-one>
<vn-one margin-medium>
<h5 translate>Total greuge</h5>
<p><vn-label translate>Total</vn-label> {{$ctrl.greuge.sumAmount | currency:'€':2}}</p>
</vn-one>
<vn-one margin-medium>
<h5 translate>Credit</h5>
<p>
<vn-label translate>Credit</vn-label>
{{$ctrl.summary.credit | currency:'€':2}}
</p>
<p>
<vn-label translate>Secured credit</vn-label>
<b ng-if="!$ctrl.summary.creditInsurance">-</b>
<b ng-if="$ctrl.summary.creditInsurance">{{$ctrl.summary.creditInsurance | currency:'€':2}}
</p>
</vn-one>
</vn-horizontal>
</vn-vertical>
</vn-card>
</vn-vertical>

View File

@ -1,24 +1,92 @@
import ngModule from '../module';
class ClientSummary {
constructor($http) {
this.$http = $http;
}
getRelations() {
let filter = {
include: ['account', 'salesPerson', 'province']
};
let url = `/client/api/Clients/${this.client.id}?filter=${JSON.stringify(filter)}`;
this.$http.get(encodeURIComponent(url)).then(res => {
if (res.data)
this.client = res.data;
set client(value) {
if (!value)
return;
let filter = {
include: [
{
relation: 'account',
scope: {
fields: ['name', 'active']
}
},
{
relation: 'salesPerson',
scope: {
fields: ['name']
}
},
{
relation: 'country',
scope: {
fields: ['country']
}
},
{
relation: 'province',
scope: {
fields: ['name']
}
},
{
relation: 'contactChannel',
scope: {
fields: ['name']
}
},
{
relation: 'payMethod',
scope: {
fields: ['name']
}
},
{
relation: 'addresses',
scope: {
where: {isDefaultAddress: true},
fields: ['nickname', 'street', 'city', 'postalCode']
}
}
]
};
let clientSummary = `/client/api/Clients/${value.id}?filter=${JSON.stringify(filter)}`;
this.$http.get(encodeURIComponent(clientSummary)).then(res => {
if (res.data) {
this.summary = res.data;
this.address = res.data.addresses[0];
}
});
let greugeSum = `/client/api/Greuges/${value.id}/sumAmount`;
this.$http.get(encodeURIComponent(greugeSum)).then(res => {
if (res.data)
this.greuge = res.data;
});
let recoveryFilter = {
where: {
and: [{clientFk: value.id}, {or: [{finished: null}, {finished: {gt: Date.now()}}]}]
},
limit: 1
};
let recovery = `/client/api/Recoveries?filter=${JSON.stringify(recoveryFilter)}`;
this.$http.get(encodeURIComponent(recovery)).then(res => {
if (res.data)
this.recovery = res.data[0];
});
}
$onChanges(changesObj) {
if (this.client && this.client.id && !this.client.salesPerson) {
this.getRelations();
}
}
}
ClientSummary.$inject = ['$http'];

View File

@ -0,0 +1,2 @@
Default address: Consignatario pred.
Total greuge: Greuge total

View File

@ -12,16 +12,18 @@
<vn-check
vn-one
label="Enable web access"
field="$ctrl.account.active">
field="$ctrl.account.active"
vn-acl="employee"
acl-conditional-to-employee="{{$ctrl.canEnableCheckBox}}">
</vn-check>
</vn-horizontal>
<vn-horizontal>
<vn-textfield
vn-focus
vn-one
margin-medium-top
label="User"
field="$ctrl.account.name"
vn-focus>
field="$ctrl.account.name">
</vn-textfield>
</vn-horizontal>
</vn-card>
@ -47,7 +49,7 @@
</vn-textfield>
</tpl-body>
<tpl-buttons>
<button response="CANCEL" translate>Cancel</button>
<input type="button" response="CANCEL" translate-attr="{value: 'Cancel'}"/>
<button response="ACCEPT" translate>Change password</button>
</tpl-buttons>
</vn-dialog>

View File

@ -6,21 +6,30 @@ export default class Controller {
this.$http = $http;
this.vnApp = vnApp;
this.canChangePassword = false;
this.canEnableCheckBox = true;
}
$onChanges() {
if (this.client) {
this.account = this.client.account;
this.isCustomer();
this.checkConditions();
}
}
isCustomer() {
if (this.client && this.client.id) {
if (this.client.id) {
this.$http.get(`/client/api/Clients/${this.client.id}/hasCustomerRole`).then(res => {
this.canChangePassword = (res.data) ? res.data.isCustomer : false;
this.canChangePassword = res.data && res.data.isCustomer;
});
}
}
checkConditions() {
if (this.client.id) {
this.$http.get(`/client/api/Clients/${this.client.id}/isValidClient`).then(res => {
this.canEnableCheckBox = res.data;
});
} else {
this.canChangePassword = false;
}
}
@ -31,7 +40,7 @@ export default class Controller {
}
onPassChange(response) {
if (response == 'ACCEPT' && this.canChangePassword)
if (response == 'ACCEPT')
try {
if (!this.newPassword)
throw new Error(`Passwords can't be empty`);

View File

@ -1,22 +1,23 @@
<vn-vertical ng-click="$ctrl.showDropDown = true" tabindex="0">
<vn-textfield vn-auto
label="{{$ctrl.label}}"
model="$ctrl.displayValue"
readonly="$ctrl.readonly"
tab-index="-1">
</vn-textfield>
<vn-drop-down vn-auto
items="$ctrl.items"
show="$ctrl.showDropDown"
selected="$ctrl.field"
filter="true"
load-more="$ctrl.getItems()"
show-load-more="$ctrl.maxRow"
remove-load-more="$ctrl.removeLoadMore"
filter-action="$ctrl.findItems(search)"
item-width="$ctrl.width"
multiple="$ctrl.multiple"
parent = "$ctrl.element">
<vn-item ng-transclude="tplItem">{{$parent.item[$ctrl.showField]}}</vn-item>
<div>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input
type="button"
class="mdl-textfield__input"
ng-click="$ctrl.onMouseDown($event)"
ng-keydown="$ctrl.onKeyDown($event)">
</input>
<div class="icons">
<vn-icon
icon="clear"
class="clear"
ng-click="$ctrl.onClearClick($event)"
translate-attr="{title: 'Clear'}">
</vn-icon>
</div>
<label class="mdl-textfield__label" translate>{{::$ctrl.label}}</label>
</div>
<vn-drop-down
vn-id="drop-down"
on-select="$ctrl.onDropDownSelect(value)">
</vn-drop-down>
</vn-vertical>
</div>

482
client/core/src/components/autocomplete/autocomplete.js Normal file → Executable file
View File

@ -1,381 +1,255 @@
import ngModule from '../../module';
import Component from '../../lib/component';
import copyObject from '../../lib/copy';
import './style.scss';
class Autocomplete extends Component {
constructor($element, $scope, $http, $timeout, $filter) {
super($element);
this.$element = $element;
this.$scope = $scope;
/**
* Input with option selector.
*
* @property {String} valueField The data field name that should be shown
* @property {String} showFiled The data field name that should be used as value
* @property {Array} data Static data for the autocomplete
* @property {Object} intialData A initial data to avoid the server request used to get the selection
* @property {Boolean} multiple Wether to allow multiple selection
*/
export default class Autocomplete extends Component {
constructor($element, $scope, $http, $transclude) {
super($element, $scope);
this.$http = $http;
this.$timeout = $timeout;
this.$filter = $filter;
this.$transclude = $transclude;
this._showDropDown = false;
this.finding = false;
this.findMore = false;
this._value = null;
this._field = null;
this._preLoad = false;
this.maxRow = 10;
this.showField = 'name';
this._field = undefined;
this._selection = null;
this.valueField = 'id';
this.items = copyObject(this.data) || [];
this.displayValueMultiCheck = [];
this.showField = 'name';
this._multiField = [];
this.readonly = true;
this.removeLoadMore = false;
this.form = null;
this.findForm = false;
}
get showDropDown() {
return this._showDropDown;
}
set showDropDown(value) {
if (value && this.url && !this._preLoad) {
this._preLoad = true;
this.getItems();
}
if (value && !this.width) {
let rectangle = this.$element[0].getBoundingClientRect();
this.width = Math.round(rectangle.width) - 10;
}
this._showDropDown = value;
}
get displayValue() {
return this._value;
}
set displayValue(value) {
let val = (value === undefined || value === '') ? null : value;
if (this.multiple && val) {
let index = this.displayValueMultiCheck.indexOf(val);
if (index === -1)
this.displayValueMultiCheck.push(val);
else
this.displayValueMultiCheck.splice(index, 1);
this._value = this.displayValueMultiCheck.join(', ');
} else {
this._value = val;
}
if (value === null) {
this.field = null;
if (this.multiple && this.items.length) {
this.displayValueMultiCheck = [];
this.items.map(item => {
item.checked = false;
return item;
});
}
}
this.input = this.element.querySelector('.mdl-textfield__input');
componentHandler.upgradeElement(
this.element.querySelector('.mdl-textfield'));
}
/**
* @type {any} The autocomplete value.
*/
get field() {
return this.multiple ? this._multiField : this._field;
return this._field;
}
set field(value) {
if (!angular.equals(value, this.field)) {
this.finding = true;
if (value && value.hasOwnProperty(this.valueField)) {
this._field = value[this.valueField];
if (this.multiple) {
this.setMultiField(value[this.valueField]);
}
this.setDirtyForm();
} else {
this.setValue(value);
}
if (angular.equals(value, this._field))
return;
if (value && value.hasOwnProperty(this.showField))
this.displayValue = value[this.showField];
this._field = value;
this.refreshSelection();
this.finding = false;
if (this.onChange)
this.onChange({item: this._field});
}
if (this.onChange)
this.onChange(value);
}
set initialData(value) {
if (value && value.hasOwnProperty(this.valueField)) {
this._field = value[this.valueField];
if (this.multiple) {
this._multiField = [value[this.valueField]];
}
if (value.hasOwnProperty(this.showField)) {
this.displayValue = value[this.showField];
}
}
/**
* @type {Object} The selected data object, you can use this property
* to prevent requests to display the initial value.
*/
get selection() {
return this._selection;
}
setMultiField(val) {
if (val && typeof val === 'object' && val[this.valueField]) {
val = val[this.valueField];
}
if (val === null) {
this._multiField = [];
} else {
let index = this._multiField.indexOf(val);
if (index === -1) {
this._multiField.push(val);
} else {
this._multiField.splice(index, 1);
}
}
set selection(value) {
this._selection = value;
this.refreshDisplayed();
}
setValue(value) {
if (value) {
let data = this.items;
selectionIsValid(selection) {
return selection
&& selection[this.valueField] == this._field
&& selection[this.showField] != null;
}
if (data && data.length)
refreshSelection() {
if (this.selectionIsValid(this._selection))
return;
let value = this._field;
if (value && this.valueField && this.showField) {
if (this.selectionIsValid(this.initialData)) {
this.selection = this.initialData;
return;
}
let data = this.data;
if (!data && this.$.dropDown)
data = this.$.dropDown.$.model.data;
if (data)
for (let i = 0; i < data.length; i++)
if (data[i][this.valueField] === value) {
this.showItem(data[i]);
this.selection = data[i];
return;
}
this.requestItem(value);
} else {
this._field = null;
this.setMultiField(null);
this.displayValue = '';
}
if (this.url) {
this.requestSelection(value);
return;
}
} else
this.selection = null;
}
requestItem(value) {
if (!value) return;
requestSelection(value) {
let where = {};
where[this.valueField] = value;
if (this.multiple)
where[this.valueField] = {inq: this.field};
else
where[this.valueField] = value;
let filter = {
fields: this.getRequestFields(),
fields: this.getFields(),
where: where
};
let json = JSON.stringify(filter);
let json = encodeURIComponent(JSON.stringify(filter));
this.$http.get(`${this.url}?filter=${json}`).then(
json => this.onItemRequest(json.data),
json => this.onItemRequest(null)
json => this.onSelectionRequest(json.data),
() => this.onSelectionRequest(null)
);
}
onItemRequest(data) {
if (data && data.length > 0)
this.showItem(data[0]);
else
this.showItem(null);
onSelectionRequest(data) {
if (data && data.length > 0) {
if (this.multiple)
this.selection = data;
else
this.selection = data[0];
} else
this.selection = null;
}
showItem(item) {
this.displayValue = item ? item[this.showField] : '';
this.field = item;
refreshDisplayed() {
let display = '';
if (this._selection && this.showField) {
if (this.multiple && Array.isArray(this._selection)) {
for (var item of this._selection) {
if (display.length > 0) display += ', ';
display += item[this.showField];
}
} else {
display = this._selection[this.showField];
}
}
this.input.value = display;
this.mdlUpdate();
}
getRequestFields() {
let fields = {};
fields[this.valueField] = true;
fields[this.showField] = true;
getFields() {
let fields = [];
fields.push(this.valueField);
fields.push(this.showField);
if (this._selectFields)
for (let field of this._selectFields)
fields[field] = true;
if (this.selectFields)
for (let field of this.selectFields)
fields.push(field);
return fields;
}
getOrder() {
return this.order ? this.order : `${this.showField} ASC`;
mdlUpdate() {
let field = this.element.querySelector('.mdl-textfield');
let mdlField = field.MaterialTextfield;
if (mdlField) mdlField.updateClasses_();
}
findItems(search) {
if (this.url && search && !this.finding) {
this.maxRow = false;
let filter = {};
if (this.filterSearch) {
let toSearch = this.filterSearch.replace(/search/g, search);
filter = this.$scope.$eval(toSearch);
} else {
filter = {where: {name: {regexp: search}}};
if (this.filter && this.filter.where) {
Object.assign(filter.where, this.filter.where);
}
}
filter.order = this.getOrder();
let json = JSON.stringify(filter);
this.finding = true;
this.$http.get(`${this.url}?filter=${json}`).then(
json => {
this.items = [];
json.data.forEach(
el => {
if (this.multiple) {
el.checked = this.field.indexOf(el[this.valueField]) !== -1;
}
this.items.push(el);
}
);
this.finding = false;
},
() => {
this.finding = false;
}
);
} else if (search && !this.url && this.data) {
this.items = this.$filter('filter')(this.data, search);
} else if (!search && !this.finding) {
this.maxRow = 10;
this.items = [];
this.getItems();
}
setValue(value) {
this.field = value;
if (this.form) this.form.$setDirty();
}
getItems() {
if (this.url === undefined) {
this.items = copyObject(this.data);
this.maxRow = false;
this.removeLoadMore = true;
} else {
let filter = {};
if (!this.finding) {
this.finding = true;
if (this.maxRow) {
if (this.items) {
filter.skip = this.items.length;
}
filter.limit = this.maxRow;
filter.order = this.getOrder();
}
if (this.filter) {
Object.assign(filter, this.filter);
}
let json = JSON.stringify(filter);
this.removeLoadMore = false;
this.$http.get(`${this.url}?filter=${json}`).then(
json => {
if (json.data.length) {
json.data.forEach(
el => {
if (this.multiple) {
el.checked = this.field.indexOf(el[this.valueField]) !== -1;
}
this.items.push(el);
}
);
if (filter.skip === 0 && this.maxRow && json.data.length < this.maxRow) {
this.removeLoadMore = true;
}
} else {
this.maxRow = false;
}
this.finding = false;
},
() => {
this.finding = false;
}
);
}
}
}
_parentForm() {
this.findForm = true;
let formScope = this.$scope;
while (formScope && !formScope.form && formScope.$id > 1) {
formScope = formScope.$parent;
}
this.form = formScope ? formScope.form || null : null;
}
setDirtyForm() {
if (!this.form && !this.findForm) {
this._parentForm();
}
if (this.form) {
this.form.$setDirty();
}
onDropDownSelect(value) {
this.setValue(value);
this.field = value;
}
$onInit() {
this.findMore = this.url && this.maxRow;
this.mouseFocus = false;
this.focused = false;
onClearClick(event) {
event.preventDefault();
this.setValue(null);
}
this.$element.bind('mouseover', e => {
this.$timeout(() => {
this.mouseFocus = true;
this.showDropDown = this.focused;
});
onKeyDown(event) {
if (event.defaultPrevented) return;
switch (event.keyCode) {
case 38: // Up
case 40: // Down
case 13: // Enter
this.showDropDown();
break;
default:
if (event.key.length == 1)
this.showDropDown(event.key);
else
return;
}
event.preventDefault();
}
onMouseDown(event) {
event.preventDefault();
this.showDropDown();
}
showDropDown(search) {
Object.assign(this.$.dropDown.$.model, {
url: this.url,
staticData: this.data
});
this.$element.bind('mouseout', () => {
this.$timeout(() => {
this.mouseFocus = false;
this.showDropDown = this.focused;
});
});
this.$element.bind('focusin', e => {
this.$timeout(() => {
this.focused = true;
this.showDropDown = true;
});
});
this.$element.bind('focusout', e => {
this.$timeout(() => {
this.focused = false;
this.showDropDown = this.mouseFocus;
});
Object.assign(this.$.dropDown, {
valueField: this.valueField,
showField: this.showField,
selectFields: this.getFields(),
where: this.where,
order: this.order,
parent: this.input,
multiple: this.multiple,
limit: this.limit,
$transclude: this.$transclude
});
this.$.dropDown.show(search);
}
$onDestroy() {
this.$element.unbind('mouseover');
this.$element.unbind('mouseout');
this.$element.unbind('focusin');
this.$element.unbind('focusout');
}
$onChanges(objectChange) {
if (objectChange.data && objectChange.data.currentValue && objectChange.data.currentValue.length) {
this.items = copyObject(objectChange.data.currentValue);
this.maxRow = false;
this.removeLoadMore = true;
}
}
}
Autocomplete.$inject = ['$element', '$scope', '$http', '$timeout', '$filter'];
Autocomplete.$inject = ['$element', '$scope', '$http', '$transclude'];
ngModule.component('vnAutocomplete', {
template: require('./autocomplete.html'),
controller: Autocomplete,
bindings: {
url: '@?',
data: '<?',
showField: '@?',
valueField: '@?',
selectFields: '@?',
initialData: '<?',
onChange: '&?',
data: '<?',
field: '=',
label: '@',
multiple: '@?',
selectFields: '<?',
where: '@?',
order: '@?',
filter: '<?',
filterSearch: '@?'
label: '@',
initialData: '<?',
field: '=?',
limit: '<?',
showFilter: '<?',
selection: '<?',
multiple: '<?',
onChange: '&?'
},
transclude: {
tplItem: '?tplItem'
},
require: {
form: '?^form'
}
});

View File

@ -1,208 +1,74 @@
import './autocomplete.js';
import template from './autocomplete.html';
describe('Component vnAutocomplete', () => {
let $componentController;
let $element;
let $scope;
let $httpBackend;
let $timeout;
let $element;
let controller;
let data = {id: 1, name: 'Bruce Wayne'};
beforeEach(() => {
angular.mock.module('client');
});
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_, _$timeout_) => {
$componentController = _$componentController_;
$scope = $rootScope.$new();
$element = angular.element(`<div>${template}</div>`);
$httpBackend = _$httpBackend_;
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
$timeout = _$timeout_;
$element = angular.element('<div></div>');
controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout});
controller = _$componentController_('vnAutocomplete', {$element, $scope, $httpBackend, $transclude: null});
}));
describe('showDropDown() setter', () => {
it(`should set _showDropDown value`, () => {
controller._showDropDown = '';
controller.showDropDown = 'some value';
describe('field() setter/getter', () => {
it(`should set field controllers property`, () => {
controller.field = data.id;
expect(controller._showDropDown).toEqual('some value');
expect(controller.field).toEqual(data.id);
});
it(`should set _showDropDown value`, () => {
controller._showDropDown = '';
controller.showDropDown = 'some value';
it(`should set selection finding an existing item in the initialData property`, () => {
controller.valueField = 'id';
controller.showField = 'name';
controller.initialData = data;
controller.field = data.id;
expect(controller._showDropDown).toEqual('some value');
});
});
describe('displayValue() setter', () => {
it(`should display value in a formated way`, () => {
let value = 'some value';
controller.displayValue = value;
expect(controller._value).toEqual(value);
expect(controller.selection).toEqual(data);
});
describe('when the autocomeplete is multiple', () => {
it(`should display values separated with commas`, () => {
controller.multiple = true;
controller.displayValue = 'some value';
controller.displayValue = 'another value';
it(`should set selection finding an existing item in the data property`, () => {
controller.valueField = 'id';
controller.showField = 'name';
controller.data = [data];
controller.field = data.id;
expect(controller._value).toEqual('some value, another value');
});
});
});
describe('field() setter', () => {
describe('when value is an object', () => {
it(`should set _field controllers property`, () => {
controller.field = {id: 1, name: 'Bruce Wayne'};
expect(controller._field).toEqual(1);
});
it(`should set _multifield controllers property `, () => {
controller.multiple = true;
controller.field = {id: 1, name: 'Bruce Wayne'};
expect(controller._field).toEqual(1);
expect(controller._multiField[0]).toEqual(1);
controller.field = {id: 1, name: 'Bruce Wayne'};
expect(controller._multiField).toEqual([]);
expect(controller._field).toEqual(1);
});
it(`should set _multifield value and remove it if called a second type with same value`, () => {
controller.multiple = true;
controller.field = {id: 1, name: 'Bruce Wayne'};
expect(controller._field).toEqual(1);
expect(controller._multiField[0]).toEqual(1);
controller.field = {id: 1, name: 'Bruce Wayne'};
expect(controller._multiField).toEqual([]);
expect(controller._field).toEqual(1);
});
it(`should set displayValue finding an existing item in the controller.items property`, () => {
controller.items = [{id: 1, name: 'test1'}, {id: 2, name: 'Bruce Wayne'}];
controller.field = {id: 2, name: 'Bruce Wayne'};
expect(controller.displayValue).toEqual('Bruce Wayne');
});
expect(controller.selection).toEqual(data);
});
describe('when value is a number', () => {
it(`should set _field controller property finding an existing item in the controller.items property`, () => {
controller.items = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce Wayne'}];
controller.field = 2;
it(`should set selection to null when can't find an existing item in the data property`, () => {
controller.valueField = 'id';
controller.showField = 'name';
controller.field = data.id;
expect(controller._field).toEqual(2);
});
it(`should set _multifield value and remove it if called a second type with same value finding an existing item in the controller.items property`, () => {
controller.items = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce Wayne'}];
controller.multiple = true;
controller.field = 2;
expect(controller._multiField[0]).toEqual(2);
controller.field = 2;
expect(controller._multiField).toEqual([]);
});
it(`should perform a query if the item id isn't present in the controller.items property`, () => {
controller.url = 'test.com';
$httpBackend.expectGET(`${controller.url}?filter={"fields":{"id":true,"name":true},"where":{"id":3}}`);
controller.items = [{id: 1, name: 'test1'}, {id: 2, name: 'Bruce Wayne'}];
controller.field = 3;
$httpBackend.flush();
});
it(`should set displayValue finding an existing item in the controller.items property`, () => {
controller.items = [{id: 1, name: 'test1'}, {id: 2, name: 'Bruce Wayne'}];
controller.field = 2;
expect(controller.displayValue).toEqual('Bruce Wayne');
});
it(`should set field performing a query as the item id isn't present in the controller.items property`, () => {
controller.url = 'test.com';
$httpBackend.expectGET(`${controller.url}?filter={"fields":{"id":true,"name":true},"where":{"id":3}}`);
controller.items = [{id: 1, name: 'test1'}, {id: 2, name: 'Bruce Wayne'}];
controller.field = 3;
$httpBackend.flush();
});
expect(controller.selection).toEqual(null);
});
});
describe('findItems()', () => {
it(`should perform a search and store the result in controller items`, () => {
let controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout});
controller.url = 'test.com';
let search = 'The Joker';
let json = JSON.stringify({where: {name: {regexp: search}}, order: controller.getOrder()});
$httpBackend.whenGET(`${controller.url}?filter=${json}`).respond([{id: 3, name: 'The Joker'}]);
$httpBackend.expectGET(`${controller.url}?filter=${json}`);
controller.findItems(search);
it(`should perform a query if the item id isn't present in the data property`, () => {
controller.valueField = 'id';
controller.showField = 'name';
controller.url = 'localhost';
controller.field = data.id;
let filter = {
fields: ['id', 'name'],
where: {id: data.id}
};
let json = encodeURIComponent(JSON.stringify(filter));
$httpBackend.expectGET(`localhost?filter=${json}`);
controller.field = data.id;
$httpBackend.flush();
expect(controller.items[0]).toEqual({id: 3, name: 'The Joker'});
});
it(`should perform a search and store the result in controller items with filterSearch`, () => {
let controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout});
controller.url = 'test.com';
let search = 'The Joker';
controller.filterSearch = "{where: {name: {regexp: 'search'}}}";
let json = JSON.stringify({where: {name: {regexp: search}}, order: controller.getOrder()});
$httpBackend.whenGET(`${controller.url}?filter=${json}`).respond([{id: 3, name: 'The Joker'}]);
$httpBackend.expectGET(`${controller.url}?filter=${json}`);
controller.findItems(search);
$httpBackend.flush();
expect(controller.items[0]).toEqual({id: 3, name: 'The Joker'});
});
it(`should perform a search with multiple true and store the result in controller items with the checked property defined`, () => {
controller.url = 'test.com';
let search = 'Joker';
controller.multiple = true;
let json = JSON.stringify({where: {name: {regexp: search}}, order: controller.getOrder()});
$httpBackend.whenGET(`${controller.url}?filter=${json}`).respond([{id: 3, name: 'The Joker'}, {id: 4, name: 'Joker'}]);
$httpBackend.expectGET(`${controller.url}?filter=${json}`);
controller.findItems(search);
$httpBackend.flush();
expect(controller.items).toEqual([{id: 3, name: 'The Joker', checked: false}, {id: 4, name: 'Joker', checked: false}]);
});
it(`should call getItems function if there's no search value`, () => {
controller.url = 'test.com';
spyOn(controller, 'getItems');
controller.findItems();
expect(controller.getItems).toHaveBeenCalledWith();
});
});
describe('getItems()', () => {
it(`should perfom a query to fill the items without filter`, () => {
controller.url = 'test.com';
$httpBackend.whenGET(`${controller.url}?filter={"skip":0,"limit":10,"order":"name ASC"}`).respond([{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce Wayne'}]);
$httpBackend.expectGET(`${controller.url}?filter={"skip":0,"limit":10,"order":"name ASC"}`);
controller.getItems();
$httpBackend.flush();
expect(controller.items).toEqual([{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce Wayne'}]);
});
});
});

69
client/core/src/components/autocomplete/style.scss Normal file → Executable file
View File

@ -1,3 +1,47 @@
vn-autocomplete > div > .mdl-textfield {
position: relative;
width: 100%;
& > input {
cursor: pointer;
height: 26px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
&:focus {
outline: none;
}
&::-moz-focus-inner {
border: 0;
}
}
& > .icons {
display: none;
position: absolute;
right: 0;
top: 1.3em;
height: 1em;
color: #888;
border-radius: .2em;
background-color: rgba(255, 255, 255, .8);
& > vn-icon {
cursor: pointer;
font-size: 18px;
&:hover {
color: #333;
}
}
}
&:hover > .icons,
& > input:focus + .icons {
display: block;
}
}
ul.vn-autocomplete {
list-style-type: none;
padding: 1em;
@ -14,7 +58,7 @@ ul.vn-autocomplete {
&.active,
&:hover {
background-color: rgba(1,1,1,.1);
background-color: rgba(1, 1, 1, .1);
}
&.load-more {
color: #ffa410;
@ -22,27 +66,4 @@ ul.vn-autocomplete {
padding: .4em .8em;
}
}
}
vn-autocomplete {
position: relative;
vn-vertical {
outline:none;
}
.mdl-chip__action {
position: absolute;
top: 0px;
right: -6px;
margin: 22px 0px;
background: transparent;
}
.material-icons {
font-size: 18px;
}
vn-drop-down{
margin-top: 47px;
}
vn-drop-down .dropdown-body .filter vn-icon {
margin-left: -26px;
}
}

View File

@ -37,14 +37,16 @@ export default class Dialog extends Component {
show() {
if (this.shown) return;
this.shown = true;
this.keypressHandler = e => this.onKeypress(e);
this.document.addEventListener('keypress', this.keypressHandler);
this.keyDownHandler = e => this.onkeyDown(e);
this.document.addEventListener('keydown', this.keyDownHandler);
this.element.style.display = 'flex';
this.transitionTimeout =
setTimeout(() => this.$element.addClass('shown'), 30);
this.transitionTimeout = setTimeout(() => this.$element.addClass('shown'), 30);
if (this.onOpen)
this.onOpen();
let firstFocusable = this.element.querySelector('input, textarea');
if (firstFocusable) firstFocusable.focus();
}
/**
* Hides the dialog calling the response handler.
@ -68,7 +70,7 @@ export default class Dialog extends Component {
realHide() {
if (!this.shown) return;
this.element.style.display = 'none';
this.document.removeEventListener('keypress', this.keypressHandler);
this.document.removeEventListener('keydown', this.keyDownHandler);
this.lastEvent = null;
this.shown = false;
this.transitionTimeout =
@ -94,7 +96,7 @@ export default class Dialog extends Component {
if (event != this.lastEvent)
this.hide();
}
onKeypress(event) {
onkeyDown(event) {
if (event.keyCode == 27) // Esc
this.hide();
}

View File

@ -28,7 +28,10 @@
display: block;
width: 20em;
}
button {
button,
input[type="button"],
input[type="submit"],
input[type="reset"] {
text-transform: uppercase;
background-color: transparent;
border: none;
@ -55,7 +58,10 @@
margin-top: 1.5em;
text-align: right;
button {
button,
input[type="button"],
input[type="submit"],
input[type="reset"] {
color: #ffa410;
font-family: vn-font-bold;
padding: .7em;

61
client/core/src/components/drop-down/drop-down.html Normal file → Executable file
View File

@ -1,28 +1,35 @@
<vn-vertical class="dropdown-body" ng-if="$ctrl.show">
<vn-auto ng-show="$ctrl.filter" class="filter">
<vn-horizontal>
<input vn-one placeholder="{{'Search' | translate}}" type="text" ng-model="$ctrl.search"/>
<vn-icon vn-none icon="clear" ng-click="$ctrl.clearSearch()"></vn-icon>
</vn-horizontal>
</vn-auto>
<vn-auto>
<ul class="dropdown">
<li
ng-repeat="item in $ctrl.itemsFiltered track by $index"
ng-click="$ctrl.selectItem(item)"
ng-class="{'active': $index === $ctrl.activeOption, 'checked': item.checked}"
ng-mouseover="$ctrl.activeOption = $index"
>
<input type="checkbox" ng-checked="item.checked" ng-if="$ctrl.multiple">
<div ng-transclude="vnItem">{{item.name}}</div>
</li>
<li
ng-if="$ctrl.loadMore&&!$ctrl.removeLoadMore"
class="dropdown__loadMore"
ng-class="{'active': $ctrl.itemsFiltered.length === $ctrl.activeOption, 'noMore' : !$ctrl.showLoadMore}"
ng-click="$ctrl.loadItems()"
translate="{{$ctrl.showLoadMore ? 'Show More' : 'No more results'}}"
></li>
<div
class="body"
ng-mousedown="$ctrl.onMouseDown($event)">
<div ng-show="$ctrl.showFilter" class="filter">
<input
type="text"
ng-model="$ctrl.search"
tabindex="-1"
class="search"
ng-blur="$ctrl.onFocusOut()"
translate-attr="{placeholder: 'Search'}"/>
<vn-icon
icon="clear"
ng-click="$ctrl.onClearClick()"
translate-attr="{title: 'Clear'}">
</vn-icon>
</div>
<vn-model
vn-id="model"
on-data-change="$ctrl.onModelDataChange()">
</vn-model>
<div class="list" tabindex="-1">
<ul
class="dropdown"
ng-click="$ctrl.onContainerClick($event)">
</ul>
</vn-auto>
</vn-vertical>
<div
ng-if="$ctrl.statusText"
ng-click="$ctrl.onLoadMoreClick($event)"
class="status"
translate>
{{$ctrl.statusText}}
</div>
</div>
</div>

592
client/core/src/components/drop-down/drop-down.js Normal file → Executable file
View File

@ -1,44 +1,48 @@
import ngModule from '../../module';
import validKey from '../../lib/key-codes';
import Component from '../../lib/component';
import './style.scss';
import './model';
export default class DropDown {
constructor($element, $filter, $timeout) {
this.$element = $element;
this.$filter = $filter;
export default class DropDown extends Component {
constructor($element, $scope, $transclude, $timeout, $http, $translate) {
super($element, $scope);
this.$transclude = $transclude;
this.$timeout = $timeout;
this.$translate = $translate;
this._search = null;
this.itemsFiltered = [];
this.valueField = 'id';
this.showField = 'name';
this._search = undefined;
this._shown = false;
this._activeOption = -1;
this._focusingFilter = false;
this._tryToShow = 0;
this.showLoadMore = true;
this.showFilter = true;
this.input = this.element.querySelector('.search');
this.body = this.element.querySelector('.body');
this.container = this.element.querySelector('ul');
this.list = this.element.querySelector('.list');
this.docKeyDownHandler = e => this.onDocKeyDown(e);
this.docFocusInHandler = e => this.onDocFocusIn(e);
this.element.addEventListener('mousedown',
e => this.onBackgroundMouseDown(e));
this.element.addEventListener('focusin',
e => this.onFocusIn(e));
this.list.addEventListener('scroll',
e => this.onScroll(e));
}
get container() {
return this.$element[0].querySelector('ul.dropdown');
get shown() {
return this._shown;
}
get show() {
return this._show;
}
set show(value) {
let oldValue = this.show;
// It wait up to 1 second if the dropdown opens but there is no data to show
if (value && !oldValue && !this.itemsFiltered.length && this._tryToShow < 4) {
this.$timeout(() => {
this._tryToShow++;
this.show = true;
if (this.activeOption === -1) {
this.activeOption = 0;
}
}, 250);
} else {
this._tryToShow = 0;
this._show = value;
this._toggleDropDown(value, oldValue);
}
set shown(value) {
if (value)
this.show();
else
this.hide();
}
get search() {
@ -46,242 +50,390 @@ export default class DropDown {
}
set search(value) {
let val = (value === undefined || value === '') ? null : value;
this._search = val;
value = value == '' || value == null ? null : value;
if (value === this._search) return;
if (this.filterAction)
this.onFilterRest();
else
this.filterItems();
this._search = value;
this.$.model.clear();
this.$timeout.cancel(this.searchTimeout);
this.searchTimeout = this.$timeout(() => {
this.refreshModel();
this.searchTimeout = null;
}, 350);
this.buildList();
}
get statusText() {
let model = this.$.model;
let data = model.data;
let statusText = null;
if (model.isLoading || this.searchTimeout)
statusText = 'Loading...';
else if (data == null)
statusText = 'No data';
else if (model.moreRows)
statusText = 'Load More';
else if (data.length === 0)
statusText = 'No results found';
return statusText;
}
get model() {
return this.$.model;
}
get activeOption() {
return this._activeOption;
}
set activeOption(value) {
if (value < 0) {
value = 0;
} else if (value >= this.itemsFiltered.length) {
value = this.showLoadMore ? this.itemsFiltered.length : this.itemsFiltered.length - 1;
}
this.$timeout(() => {
this._activeOption = value;
if (value && value >= this.itemsFiltered.length - 3 && !this.removeLoadMore) {
this.loadItems();
}
});
/**
* Shows the drop-down. If a parent is specified it is shown in a visible
* relative position to it.
*
* @param {String} search The initial search term or %null
*/
show(search) {
if (this._shown) return;
this._shown = true;
this._activeOption = -1;
this.search = search;
this.buildList();
this.element.style.display = 'block';
this.list.scrollTop = 0;
this.$timeout(() => this.$element.addClass('shown'), 40);
this.document.addEventListener('keydown', this.docKeyDownHandler);
this.document.addEventListener('focusin', this.docFocusInHandler);
this.relocate();
this.input.focus();
}
_toggleDropDown(value, oldValue) {
this.$timeout(() => {
this._eventScroll(value);
this._calculatePosition(value, oldValue);
});
/**
* Hides the drop-down.
*/
hide() {
if (!this._shown) return;
this._shown = false;
this.element.style.display = '';
this.$element.removeClass('shown');
this.document.removeEventListener('keydown', this.docKeyDownHandler);
this.document.removeEventListener('focusin', this.docFocusInHandler);
if (this.parent)
this.parent.focus();
}
_eventScroll(add, num) {
let count = num || 0;
if (add) {
if (this.container) {
this.container.addEventListener('scroll', e => this.loadFromScroll(e));
// this.$timeout(() => { // falla al entrar por primera vez xq pierde el foco y cierra el dropdown
// this._setFocusInFilterInput();
// });
} else if (count < 4) {
count++;
this.$timeout(() => { // wait angular ngIf
this._eventScroll(add, count);
}, 250);
}
} else if (this.container) {
this.container.removeEventListener('scroll', e => this.loadFromScroll(e));
/**
* Repositions the drop-down to a correct location relative to the parent.
*/
relocate() {
if (!this.parent) return;
let style = this.body.style;
style.width = '';
style.height = '';
let parentRect = this.parent.getBoundingClientRect();
let bodyRect = this.body.getBoundingClientRect();
let top = parentRect.top + parentRect.height;
let height = bodyRect.height;
let width = Math.max(bodyRect.width, parentRect.width);
let margin = 10;
if (top + height + margin > window.innerHeight)
top = Math.max(parentRect.top - height, margin);
style.top = `${top}px`;
style.left = `${parentRect.left}px`;
style.width = `${width}px`;
if (height + margin * 2 > window.innerHeight)
style.height = `${window.innerHeight - margin * 2}px`;
}
/**
* Activates a option and scrolls the drop-down to that option.
*
* @param {Number} option The option index
*/
moveToOption(option) {
this.activateOption(option);
let list = this.list;
let li = this.activeLi;
if (!li) return;
let liRect = li.getBoundingClientRect();
let listRect = list.getBoundingClientRect();
if (liRect.bottom > listRect.bottom)
list.scrollTop += liRect.bottom - listRect.bottom;
else if (liRect.top < listRect.top)
list.scrollTop -= listRect.top - liRect.top;
}
/**
* Activates a option.
*
* @param {Number} option The option index
*/
activateOption(option) {
this._activeOption = option;
if (this.activeLi)
this.activeLi.className = '';
let data = this.$.model.data;
if (option >= 0 && data && option < data.length) {
this.activeLi = this.container.children[option];
this.activeLi.className = 'active';
}
}
_setFocusInFilterInput() {
let inputFilterSearch = this.$element[0].querySelector('input');
this._focusingFilter = true;
if (inputFilterSearch)
this.$timeout(() => {
inputFilterSearch.focus();
this._focusingFilter = false;
}, 250);
}
/**
* Selects an option.
*
* @param {Number} option The option index
*/
selectOption(option) {
if (option != -1) {
let data = this.$.model.data;
let item = data ? data[option] : null;
let value = item ? item[this.valueField] : null;
_background(create) {
let el = document.getElementById('ddBack');
if (el) {
el.parentNode.removeChild(el);
}
if (this.multiple) {
if (!Array.isArray(this.selection)) {
this.selection = [];
this.field = [];
}
if (create) {
el = document.createElement('div');
el.id = 'ddBack';
document.body.appendChild(el);
}
}
_calculatePosition(value, oldValue) {
if (value && !oldValue) {
if (this.parent === undefined) {
this.parent = this.$element.parent().parent();
this.selection.push(item);
this.field.push(value);
} else {
this.selection = item;
this.field = value;
}
let parentRect = this.parent.getBoundingClientRect();
let elemetRect = this.$element[0].getBoundingClientRect();
let instOffset = parentRect.bottom + elemetRect.height;
if (instOffset >= window.innerHeight) {
this._background(true);
this.$element.addClass('fixed-dropDown');
this.$element.css('top', `${(parentRect.top - elemetRect.height)}px`);
this.$element.css('left', `${(parentRect.x)}px`);
this.$element.css('height', `${elemetRect.height}px`);
}
} else if (!value && oldValue) {
this.$element.removeAttr('style');
if (this.itemWidth) {
this.$element.css('width', this.itemWidth + 'px');
}
this.$element.removeClass('fixed-dropDown');
this._background();
if (this.onSelect)
this.onSelect({value: value});
}
if (!this.multiple)
this.hide();
}
filterItems() {
this.itemsFiltered = this.search ? this.$filter('filter')(this.items, this.search) : this.items;
refreshModel() {
this.$.model.filter = {
fields: this.selectFields,
where: this.getWhere(this._search),
order: this.getOrder(),
limit: this.limit || 8
};
this.$.model.refresh(this._search);
}
onFilterRest() {
if (this.filterAction) {
this.filterAction({search: this.search});
getWhere(search) {
if (search == '' || search == null)
return undefined;
if (this.where) {
let jsonFilter = this.where.replace(/search/g, search);
return this.$.$eval(jsonFilter);
}
let where = {};
where[this.showField] = {regexp: search};
return where;
}
clearSearch() {
getOrder() {
if (this.order)
return this.order;
else if (this.showField)
return `${this.showField} ASC`;
return undefined;
}
onMouseDown(event) {
this.lastMouseEvent = event;
}
onBackgroundMouseDown(event) {
if (event != this.lastMouseEvent)
this.hide();
}
onFocusIn(event) {
this.lastFocusEvent = event;
}
onDocFocusIn(event) {
if (event !== this.lastFocusEvent)
this.hide();
}
onClearClick() {
this.search = null;
}
selectOption() {
if (this.activeOption >= 0 && this.activeOption < this.items.length && this.items[this.activeOption]) {
this.selected = this.items[this.activeOption];
this.show = false;
this.clearSearch();
} else if (this.showLoadMore && this.activeOption === this.items.length) {
this.loadMore();
}
onScroll() {
let list = this.list;
let shouldLoad =
list.scrollTop + list.clientHeight >= (list.scrollHeight - 40)
&& !this.$.model.isLoading;
if (shouldLoad)
this.$.model.loadMore();
}
onKeydown(event) {
if (this.show) {
if (event.keyCode === 13) { // Enter
this.$timeout(() => {
this.selectOption();
});
event.preventDefault();
} else if (event.keyCode === 27) { // Escape
this.clearSearch();
} else if (event.keyCode === 38) { // Arrow up
this.activeOption--;
this.$timeout(() => {
this.setScrollPosition();
}, 100);
} else if (event.keyCode === 40) { // Arrow down
this.activeOption++;
this.$timeout(() => {
this.setScrollPosition();
}, 100);
} else if (event.keyCode === 35) { // End
this.activeOption = this.itemsFiltered.length - 1;
this.$timeout(() => {
this.setScrollPosition();
}, 100);
} else if (event.keyCode === 36) { // Start
this.activeOption = 0;
this.$timeout(() => {
this.setScrollPosition();
}, 100);
} else if (this.filter) {
let oldValue = this.search || '';
if (validKey(event)) {
this.search = oldValue + String.fromCharCode(event.keyCode);
} else if (event.keyCode === 8) { // backSpace
this.search = oldValue.slice(0, -1);
}
} /* else {
console.error(`Error: keyCode ${event.keyCode} not supported`);
} */
}
onLoadMoreClick(event) {
event.preventDefault();
this.$.model.loadMore();
}
setScrollPosition() {
let child = this.$element[0].querySelector('ul.dropdown li.active');
if (child) {
let childRect = child.getBoundingClientRect();
let containerRect = this.container.getBoundingClientRect();
if (typeof child.scrollIntoView === 'function' && (childRect.top > containerRect.top + containerRect.height || childRect.top < containerRect.top)) {
child.scrollIntoView();
onContainerClick(event) {
if (event.defaultPrevented) return;
let index = getPosition(this.container, event);
if (index != -1) this.selectOption(index);
}
onModelDataChange() {
this.buildList();
}
onDocKeyDown(event) {
if (event.defaultPrevented) return;
let data = this.$.model.data;
let option = this.activeOption;
let nOpts = data ? data.length - 1 : 0;
switch (event.keyCode) {
case 13: // Enter
this.selectOption(option);
break;
case 27: // Escape
this.hide();
break;
case 38: // Up
this.moveToOption(option <= 0 ? nOpts : option - 1);
break;
case 40: // Down
this.moveToOption(option >= nOpts ? 0 : option + 1);
break;
case 35: // End
this.moveToOption(nOpts);
break;
case 36: // Start
this.moveToOption(0);
break;
default:
return;
}
event.preventDefault();
this.$.$applyAsync();
}
buildList() {
this.destroyScopes();
this.scopes = [];
let hasTemplate = this.$transclude &&
this.$transclude.isSlotFilled('tplItem');
let fragment = this.document.createDocumentFragment();
let data = this.$.model.data;
if (data) {
for (let i = 0; i < data.length; i++) {
let li = this.document.createElement('li');
fragment.appendChild(li);
if (this.multiple) {
let check = this.document.createElement('input');
check.type = 'checkbox';
li.appendChild(check);
if (this.field && this.field.indexOf(data[i][this.valueField]) != -1)
check.checked = true;
}
if (hasTemplate) {
this.$transclude((clone, scope) => {
Object.assign(scope, data[i]);
li.appendChild(clone[0]);
this.scopes[i] = scope;
}, null, 'tplItem');
} else {
let text = this.document.createTextNode(data[i][this.showField]);
li.appendChild(text);
}
}
}
this.container.innerHTML = '';
this.container.appendChild(fragment);
this.activateOption(this._activeOption);
this.relocate();
}
selectItem(item) {
this.selected = item;
if (this.multiple) {
item.checked = !item.checked;
this.show = true;
} else {
this.show = false;
}
}
loadItems() {
if (this.showLoadMore && this.loadMore) {
this.loadMore();
}
this.show = true;
}
loadFromScroll(e) {
let containerRect = e.target.getBoundingClientRect();
if (e.target.scrollHeight - e.target.scrollTop - containerRect.height <= 50) {
this.loadItems();
}
}
$onChanges(changesObj) {
if (changesObj.show && changesObj.itemWidth && changesObj.itemWidth.currentValue) {
this.$element.css('width', changesObj.itemWidth.currentValue + 'px');
}
if (changesObj.items) {
this.filterItems();
}
}
$onInit() {
if (this.parent)
this.parent.addEventListener('keydown', e => this.onKeydown(e));
destroyScopes() {
if (this.scopes)
for (let scope of this.scopes)
scope.$destroy();
}
$onDestroy() {
if (this.parent)
this.parent.removeEventListener('keydown', e => this.onKeydown(e));
this.destroyScopes();
}
}
DropDown.$inject = ['$element', '$scope', '$transclude', '$timeout', '$http', '$translate'];
DropDown.$inject = ['$element', '$filter', '$timeout'];
/**
* Gets the position of an event element relative to a parent.
*
* @param {HTMLElement} parent The parent element
* @param {Event} event The event object
* @return {Number} The element index
*/
function getPosition(parent, event) {
let target = event.target;
let children = parent.children;
if (target === parent)
return -1;
while (target.parentNode !== parent)
target = target.parentNode;
for (let i = 0; i < children.length; i++)
if (children[i] === target)
return i;
return -1;
}
ngModule.component('vnDropDown', {
template: require('./drop-down.html'),
controller: DropDown,
bindings: {
items: '<',
show: '<',
filter: '@?',
selected: '=',
search: '=?',
loadMore: '&?',
removeLoadMore: '<?',
filterAction: '&?',
showLoadMore: '<?',
itemWidth: '<?',
field: '=?',
data: '<?',
selection: '=?',
search: '<?',
limit: '<?',
showFilter: '<?',
parent: '<?',
multiple: '<?'
multiple: '<?',
onSelect: '&?'
},
transclude: {
vnItem: '?vnItem'
tplItem: '?tplItem'
}
});

View File

@ -1,9 +1,13 @@
import './drop-down.js';
import template from './drop-down.html';
describe('Component vnDropDown', () => {
let $componentController;
let $timeout;
let $element;
let $scope;
let $httpBackend;
let $q;
let $filter;
let controller;
@ -11,337 +15,34 @@ describe('Component vnDropDown', () => {
angular.mock.module('client');
});
beforeEach(angular.mock.inject((_$componentController_, _$timeout_, _$filter_, _$httpBackend_) => {
_$httpBackend_.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$timeout_, _$httpBackend_, _$q_, _$filter_) => {
$componentController = _$componentController_;
$element = angular.element('<div><ul><li></li></ul></div>');
$element = angular.element(`<div>${template}</div>`);
$timeout = _$timeout_;
$q = _$q_;
$filter = _$filter_;
controller = $componentController('vnDropDown', {$element, $timeout, $filter});
$scope = $rootScope.$new();
$httpBackend = _$httpBackend_;
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
$scope.model = $componentController('vnModel', {$httpBackend, $q, $filter});
controller = $componentController('vnDropDown', {$element, $scope, $transclude: null, $timeout, $httpBackend, $translate: null});
controller.parent = angular.element('<vn-parent></vn-parent>')[0];
}));
describe('show() setter', () => {
describe('show() method', () => {
it(`should define controllers _show using the value received as argument`, () => {
controller._show = 'old value';
controller.show = 'new value';
controller.show();
expect(controller._show).toEqual('new value');
expect(controller.shown).toEqual(true);
});
});
describe('search()', () => {
it(`should set controllers _search property with the value received`, () => {
controller.search = 'some filter valiue';
describe('hide() method', () => {
it(`should define controllers _show using the value received as argument`, () => {
controller.hide();
expect(controller._search).toEqual('some filter valiue');
});
it(`should set controllers _search property to null as the value received is an empty string`, () => {
controller.search = '';
expect(controller._search).toEqual(null);
});
it(`should call onFilterRest() if controllers filterAction is defined`, () => {
controller.filterAction = true;
spyOn(controller, 'onFilterRest');
controller.search = 'some filter valiue';
expect(controller.onFilterRest).toHaveBeenCalledWith();
});
it(`should call filterItems() if controllers filterAction is undefined`, () => {
controller.filterAction = undefined;
spyOn(controller, 'filterItems');
controller.search = 'some filter valiue';
expect(controller.filterItems).toHaveBeenCalledWith();
});
});
describe('activeOption() setter', () => {
it(`should set _activeOption as items.length if showLoadMore is defined if activeOption is bigger than items.length then call loadItems()`, () => {
spyOn(controller, 'loadItems');
controller.showLoadMore = true;
controller.itemsFiltered = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}];
controller.activeOption = 10;
$timeout.flush();
expect(controller.activeOption).toEqual(4);
expect(controller.loadItems).toHaveBeenCalledWith();
});
it(`should set _activeOption as activeOption if showLoadMore is defined if activeOption is smaller than items.length then call loadItems()`, () => {
spyOn(controller, 'loadItems');
controller.showLoadMore = true;
controller.itemsFiltered = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}];
controller.activeOption = 2;
$timeout.flush();
expect(controller.activeOption).toEqual(2);
expect(controller.loadItems).toHaveBeenCalledWith();
});
it(`should set _activeOption as items.length -1 if showLoadMore is not defined then call loadItems()`, () => {
spyOn(controller, 'loadItems');
controller.showLoadMore = undefined;
controller.itemsFiltered = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}];
controller.activeOption = 10;
$timeout.flush();
expect(controller.activeOption).toEqual(3);
expect(controller.loadItems).toHaveBeenCalledWith();
});
it(`should define _activeOption as activeOption and never call loadItems()`, () => {
spyOn(controller, 'loadItems');
controller.itemsFiltered = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}, {id: 5, name: 'Doctor X'}];
controller.activeOption = 1;
$timeout.flush();
expect(controller.activeOption).toEqual(1);
expect(controller.loadItems).not.toHaveBeenCalledWith();
});
});
describe('filterItems() setter', () => {
it(`should set _itemsFiltered using the value of items`, () => {
controller.items = [{id: 1, name: 'Batman'}];
controller.filterItems();
expect(controller.itemsFiltered).toEqual(controller.items);
});
it(`should set _itemsFiltered with the filtered value of items`, () => {
controller.items = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}];
controller.search = 'Batman';
controller.filterItems();
expect(controller.itemsFiltered).toEqual([Object({id: 1, name: 'Batman'})]);
});
it(`should set _itemsFiltered an empty array`, () => {
controller.items = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}];
controller.search = 'the Joker';
expect(controller.itemsFiltered.length).toEqual(0);
});
});
describe('onFilterRest()', () => {
it(`should call the filterAction() with a constructed object as argument`, () => {
controller.filterAction = () => {};
controller.search = 'Batman';
spyOn(controller, 'filterAction');
controller.onFilterRest();
expect(controller.filterAction).toHaveBeenCalledWith({search: controller.search});
});
});
describe('$onChanges()', () => {
it(`should set the width css of the $element`, () => {
let argumentObject = {show: true, itemWidth: {currentValue: 100}};
spyOn(controller.$element, 'css');
controller.$onChanges(argumentObject);
expect(controller.$element.css).toHaveBeenCalledWith('width', '100px');
});
it(`should set the width css of the $element`, () => {
let argumentObject = {items: {id: 1, name: 'Batman'}};
spyOn(controller, 'filterItems');
controller.$onChanges(argumentObject);
expect(controller.filterItems).toHaveBeenCalledWith();
});
});
describe('clearSearch()', () => {
it(`should set the controllers search property to null`, () => {
controller.search = true;
controller.clearSearch();
expect(controller.search).toEqual(null);
});
});
describe('selectOption()', () => {
it(`should set controllers selected and show properties then call clearSearch() as _activeOption is smaller than items.length`, () => {
spyOn(controller, 'clearSearch');
controller.items = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}];
controller._activeOption = 0;
controller.selectOption();
expect(controller.selected).toEqual(controller.items[controller._activeOption]);
expect(controller._show).toEqual(false);
expect(controller.clearSearch).toHaveBeenCalledWith();
});
it(`should not set controllers selected, show and never call clearSearch() as _activeOption is bigger than items.length`, () => {
spyOn(controller, 'clearSearch');
controller.items = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}];
controller._activeOption = 100;
controller.selectOption();
expect(controller.selected).not.toBeDefined();
expect(controller._show).not.toBeDefined();
expect(controller.clearSearch).not.toHaveBeenCalledWith();
});
it(`should call loadMore() if the activeValue equals items.length`, () => {
controller.loadMore = () => {};
spyOn(controller, 'loadMore');
controller.items = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}];
controller._activeOption = 4;
controller.showLoadMore = 4;
controller.selectOption();
expect(controller.loadMore).toHaveBeenCalledWith();
});
});
describe('onKeydown()', () => {
it(`should call selectOption() and preventDefault() if Enter key is pressed`, () => {
spyOn(controller, 'selectOption');
controller._show = true;
controller.element = document.createElement('div');
let event = {target: controller.element, preventDefault: () => {}};
event.keyCode = 13;
spyOn(event, 'preventDefault');
controller.onKeydown(event);
$timeout.flush();
expect(controller.selectOption).toHaveBeenCalledWith();
expect(event.preventDefault).toHaveBeenCalledWith();
});
it(`should call clearSearch() Esc key is pressed`, () => {
spyOn(controller, 'clearSearch');
controller._show = true;
controller.element = document.createElement('div');
let event = {target: controller.element};
event.keyCode = 27;
controller.onKeydown(event);
expect(controller.clearSearch).toHaveBeenCalledWith();
});
it(`should call clearSearch() Esc key is pressed and take off 1 from _activeOption`, () => {
controller.itemsFiltered = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}];
spyOn(controller, 'setScrollPosition');
controller._show = true;
controller.element = document.createElement('div');
let event = {target: controller.element};
event.keyCode = 38;
controller._activeOption = 1;
controller.onKeydown(event);
$timeout.flush();
expect(controller.setScrollPosition).toHaveBeenCalledWith();
expect(controller._activeOption).toEqual(0);
});
it(`should call clearSearch() Esc key is pressed and add up 1 to _activeOption`, () => {
controller.itemsFiltered = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}];
spyOn(controller, 'setScrollPosition');
controller._show = true;
controller.element = document.createElement('div');
let event = {target: controller.element};
event.keyCode = 40;
controller._activeOption = 1;
controller.onKeydown(event);
$timeout.flush();
expect(controller.setScrollPosition).toHaveBeenCalledWith();
expect(controller._activeOption).toEqual(2);
});
});
describe('setScrollPosition()', () => {
it(`should call child.scrollIntoView if defined `, () => {
$element[0].firstChild.setAttribute('class', 'dropdown');
$element[0].firstChild.firstChild.setAttribute('class', 'active');
let child = $element[0].firstChild.firstChild;
spyOn(child, 'getBoundingClientRect').and.returnValue({top: 100});
let container = $element[0].firstChild;
spyOn(container, 'getBoundingClientRect').and.returnValue({top: 10, height: 70});
child.scrollIntoView = () => {};
spyOn(child, 'scrollIntoView');
controller._activeOption = 0;
controller.setScrollPosition();
expect(child.scrollIntoView).toHaveBeenCalledWith();
});
});
describe('selectItem()', () => {
it(`should pass item to selected and set controller._show to false`, () => {
let item = {id: 1, name: 'Batman'};
controller.selectItem(item);
expect(controller.selected).toEqual(item);
expect(controller._show).toEqual(false);
});
it(`should pass item to selected and set controller._show to true if the controller.multiple is defined`, () => {
let item = {id: 1, name: 'Batman'};
controller.multiple = true;
controller.selectItem(item);
expect(controller.selected).toEqual(item);
expect(controller._show).not.toBeDefined();
});
});
describe('loadItems()', () => {
it(`should set controller.show to true`, () => {
controller.show = false;
controller.itemsFiltered = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}];
controller.loadItems();
expect(controller.show).toEqual(true);
});
it(`should call loadMore() and then set controller._show to true if there are items`, () => {
controller.showLoadMore = () => {};
controller.loadMore = () => {};
spyOn(controller, 'loadMore');
controller.itemsFiltered = [{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce'}, {id: 3, name: 'Logan'}, {id: 4, name: 'Wolverine'}];
controller.loadItems();
expect(controller._show).toEqual(true);
expect(controller.loadMore).toHaveBeenCalledWith();
});
it(`should call loadMore() and then set controller._show to undefined if there are not items`, () => {
controller.showLoadMore = () => {};
controller.loadMore = () => {};
spyOn(controller, 'loadMore');
controller.itemsFiltered = [];
controller.loadItems();
expect(controller._show).not.toBeDefined();
expect(controller.loadMore).toHaveBeenCalledWith();
});
});
describe('$onInit()', () => {
it(`should add an event listener to the parent element`, () => {
spyOn(controller.parent, 'addEventListener');
controller.$onInit();
expect(controller.parent.addEventListener).toHaveBeenCalledWith('keydown', jasmine.any(Function));
});
});
describe('$onDestroy()', () => {
it(`should remove an event listener from the parent element`, () => {
spyOn(controller.parent, 'removeEventListener');
controller.$onDestroy();
expect(controller.parent.removeEventListener).toHaveBeenCalledWith('keydown', jasmine.any(Function));
expect(controller.shown).toEqual(false);
});
});
});

View File

@ -0,0 +1,107 @@
import ngModule from '../../module';
export default class Model {
constructor($http, $q, $filter) {
this.$http = $http;
this.$q = $q;
this.$filter = $filter;
this.filter = null;
this.clear();
}
get isLoading() {
return this.canceler != null;
}
loadMore() {
if (this.moreRows) {
let filter = Object.assign({}, this.myFilter);
filter.skip += filter.limit;
this.sendRequest(filter, true);
}
}
clear() {
this.cancelRequest();
this.data = null;
this.moreRows = false;
this.dataChanged();
}
refresh(search) {
if (this.url) {
let filter = Object.assign({}, this.filter);
if (filter.limit)
filter.skip = 0;
this.clear();
this.sendRequest(filter);
} else if (this.staticData) {
if (search)
this.data = this.$filter('filter')(this.staticData, search);
else
this.data = this.staticData;
this.dataChanged();
}
}
cancelRequest() {
if (this.canceler) {
this.canceler.resolve();
this.canceler = null;
this.request = null;
}
}
sendRequest(filter, append) {
this.cancelRequest();
this.canceler = this.$q.defer();
let options = {timeout: this.canceler.promise};
let json = encodeURIComponent(JSON.stringify(filter));
this.request = this.$http.get(`${this.url}?filter=${json}`, options).then(
json => this.onRemoteDone(json, filter, append),
json => this.onRemoteError(json)
);
}
onRemoteDone(json, filter, append) {
let data = json.data;
if (append)
this.data = this.data.concat(data);
else
this.data = data;
this.myFilter = filter;
this.moreRows = filter.limit && data.length == filter.limit;
this.onRequestEnd();
this.dataChanged();
}
onRemoteError(json) {
this.onRequestEnd();
}
onRequestEnd() {
this.request = null;
this.canceler = null;
}
dataChanged() {
if (this.onDataChange)
this.onDataChange();
}
}
Model.$inject = ['$http', '$q', '$filter'];
ngModule.component('vnModel', {
controller: Model,
bindings: {
url: '@?',
staticData: '<?',
data: '=?',
limit: '<?',
onDataChange: '&?'
}
});

161
client/core/src/components/drop-down/style.scss Normal file → Executable file
View File

@ -1,80 +1,95 @@
vn-drop-down {
position: absolute;
z-index: 10;
padding: 0 15px;
margin-left: -15px;
background: transparent;
max-height: 446px;
overflow: hidden;
.dropdown-body{
background: white;
border: 1px solid #A7A7A7;
.filter{
padding: 5px 9px 5px 5px;
input{
height: 25px;
padding-left: 5px;
}
vn-icon{
font-size: 16px;
margin-left: -20px;
margin-top: 7px;
cursor: pointer;
&:hover{
color: red;
}
}
}
ul{
padding: 0;
margin: 0;
background: white;
max-height: 378px;
overflow-y: auto;
li {
outline: none;
list-style-type: none;
padding: 5px 10px;
cursor: pointer;
white-space: nowrap;
&.dropdown__loadMore{
color: rgb(255,171,64);
font-weight: 700;
}
&.dropdown__loadMore.noMore{
color:#424242;
font-weight: 700;
opacity: 0.7;
}
input[type=checkbox]{
float: left;
margin: 5px 5px 0 0;
}
}
li.active{
background-color: #3D3A3B;
color: white;
}
}
}
}
#ddBack {
position: fixed;
z-index: 9998;
display: none;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: transparent;
}
vn-drop-down.fixed-dropDown {
position: fixed;
margin: 0;
padding: 0;
.dropdown-body{
height: 100%;
ul{
border-bottom: 1px solid #A7A7A7;
right: 0;
bottom: 0;
&.shown {
& > .body {
transform: translateY(0);
opacity: 1;
}
}
}
& > .body {
position: fixed;
box-shadow: 0 .1em .4em rgba(1, 1, 1, .4);
border-radius: .1em;
background-color: white;
display: flex;
flex-direction: column;
transform: translateY(-.4em);
opacity: 0;
transition-property: opacity, transform;
transition-duration: 250ms;
transition-timing-function: ease-in-out;
& > .filter {
position: relative;
& > .search {
display: block;
width: 100%;
box-sizing: border-box;
border: none;
border-bottom: 1px solid #ccc;
padding: .6em;
}
& > vn-icon[icon=clear] {
display: none;
cursor: pointer;
position: absolute;
right: .5em;
top: .6em;
height: 1em;
color: #888;
border-radius: 50%;
background-color: rgba(255, 255, 255, .8);
font-size: 18px;
&:hover {
color: #333;
}
}
&:hover > vn-icon[icon=clear] {
display: block;
}
}
& > .list {
max-height: 12.8em;
overflow: auto;
ul {
padding: 0;
margin: 0;
}
li, .status {
outline: none;
list-style-type: none;
padding: .6em;
cursor: pointer;
white-space: nowrap;
transition: background-color 250ms ease-out;
display: flex;
& > input[type=checkbox] {
margin: 0;
margin-right: .6em;
}
&:hover {
background-color: rgba(0, 0, 0, .1);
}
&.active {
background-color: #3D3A3B;
color: white;
}
}
.status {
color: #ffab40;
font-weight: bold;
}
}
}
}

View File

@ -15,6 +15,7 @@ export default class Controller extends Component {
this.button = $element[0].querySelector('button');
this.textNode = this.snackbar.querySelector('.text');
}
/**
* Shows a notification.
*
@ -29,14 +30,13 @@ export default class Controller extends Component {
this.button.textContent =
data.actionText || this.$translate.instant('Hide');
this.documentClickHandler = e => this.onDocumentClick(e);
document.addEventListener('click', this.documentClickHandler);
this.timeoutId = setTimeout(() => this.hide(),
data.timeout || 6000);
this.timeoutId = setTimeout(() =>
this.hide(), data.timeout || 6000);
this.transitionTimeout =
setTimeout(() => this.$snackbar.addClass('shown'), 30);
this.transitionTimeout = setTimeout(() =>
this.$snackbar.addClass('shown'), 30);
}
/**
* Shows an error.
*
@ -46,38 +46,38 @@ export default class Controller extends Component {
this.$snackbar.addClass('error');
this.show(data);
}
/**
* Hides the snackbar.
*/
hide() {
if (!this.shown) return;
clearTimeout(this.timeoutId);
document.removeEventListener('click', this.documentClickHandler);
this.shown = false;
this.hideTimeout = setTimeout(() => this.onTransitionEnd(), 250);
this.transitionTimeout =
setTimeout(() => this.$snackbar.removeClass('shown'), 30);
}
onTransitionEnd() {
this.$snackbar.removeClass('error');
this.textNode.textContent = '';
this.button.textContent = '';
this.actionHandler = null;
}
onDocumentClick(event) {
if (event === this.event) return;
this.hide();
}
onSnackbarClick(event) {
this.event = event;
}
onButtonClick() {
if (this.actionHandler)
this.actionHandler();
else
this.hide();
}
clearTimeouts() {
clearTimeout(this.timeoutId);
clearTimeout(this.hideTimeout);
@ -86,6 +86,7 @@ export default class Controller extends Component {
this.hideTimeout = null;
this.transitionTimeout = null;
}
$onDestroy() {
this.clearTimeouts();
}

View File

@ -32,7 +32,7 @@ function put(mgPut) {
}
ngModule.factory('vnPut', put);
put.$inject = ['mgPatch'];
patch.$inject = ['mgPatch'];
function patch(mgPatch) {
return Object.assign({}, mgPatch, {
success: 'vnSuccessFactoryCreate'

View File

@ -12,17 +12,21 @@
<vn-auto style="position: relative" pad-medium text-center>
<img
ng-src="http://verdnatura.es/vn-image-data/catalog/200x200/{{::$ctrl.item.image}}"
zoom-image="http://verdnatura.es/vn-image-data/catalog/900x900/{{::$ctrl.item.image}}" on-error-src/>
<a href="https://www.verdnatura.es/#!form=admin/items&filter={{::$ctrl.item.id}}" target="_blank"><vn-float-button icon="edit"
style="position: absolute; bottom: 1em; right: 1em;"
vn-visible-by="administrative"></vn-float-button>
zoom-image="http://verdnatura.es/vn-image-data/catalog/900x900/{{::$ctrl.item.image}}"
on-error-src/>
<a href="https://www.verdnatura.es/#!form=admin/items&filter={{::$ctrl.item.id}}" target="_blank">
<vn-float-button
icon="edit"
style="position: absolute; margin: 1em; bottom: 0; right: 0;"
vn-visible-by="administrative">
</vn-float-button>
</a>
</vn-auto>
<vn-auto pad-medium>
<h6>{{$ctrl.item.name}}</h6>
<div><vn-label translate>Id</vn-label> {{$ctrl.item.id}}</div>
<div ng-repeat="itemTag in $ctrl.itemTags | limitTo:4">
<div><vn-label translate>{{$ctrl.tags[itemTag.tagFk].name}}</vn-label>: {{itemTag.value}}</div>
<div><vn-label translate>{{$ctrl.tags[itemTag.tagFk].name}}</vn-label> {{itemTag.value}}</div>
</div>
</vn-auto>
</vn-vertical>

View File

@ -32,14 +32,20 @@
</vn-one>
<vn-one margin-medium>
<vn-vertical>
<h5 translate>Tags</h5>
<p ng-repeat="tag in $ctrl.tags track by tag.id">
<span translate>{{tag.tag.name}}</span>: <b>{{tag.value}}</b>
<h5 translate>Tax</h5>
<p ng-repeat="tax in $ctrl.taxes track by $index">
<span translate>{{tax.country.country}}</span>: <b>{{tax.taxClass.description}}</b>
</p>
</vn-vertical>
</vn-one>
</vn-horizontal>
<vn-horizontal>
<vn-one margin-medium>
<h5 translate>Tags</h5>
<p ng-repeat="tag in $ctrl.tags track by tag.id">
<span translate>{{tag.tag.name}}</span>: <b>{{tag.value}}</b>
</p>
</vn-one>
<vn-one margin-medium>
<vn-vertical>
<h5 translate>Nicho</h5>

View File

@ -17,6 +17,25 @@ class ItemSummary {
});
}
_getTaxes() {
let filter = {
fields: ['id', 'countryFk', 'taxClassFk'],
include: [{
relation: 'country',
scope: {fields: ['country']}
}, {
relation: 'taxClass',
scope: {fields: ['id', 'description']}
}]
};
let urlFilter = encodeURIComponent(JSON.stringify(filter));
let url = `/item/api/Items/${this.item.id}/taxes?filter=${urlFilter}`;
this.$http.get(url).then(json => {
this.taxes = json.data;
});
}
_getBotanical() {
let filter = {
where: {itemFk: this.item.id},
@ -58,6 +77,7 @@ class ItemSummary {
this._getTags();
this._getBarcodes();
this._getNiches();
this._getTaxes();
if (!this.item.botanical)
this._getBotanical();
}

View File

@ -1,5 +1,5 @@
<vn-horizontal>
<ul style="list-style-type: none; margin: 0; padding: 0; width: 100%; color: #666;">
<ul style="list-style-type: none; margin: 0; padding: 0; width: 100%;">
<vn-menu-item ng-repeat="item in $ctrl.items" item="::item"></vn-menu-item>
</ul>
</vn-horizontal>

View File

@ -1,5 +1,5 @@
import ngModule from '../../module';
import './style.css';
import './style.scss';
export default class LeftMenu {
constructor(aclService, $state) {

View File

@ -1,7 +1,9 @@
<li ng-class="{active: $ctrl.item.active}">
<a ui-sref="{{::$ctrl.item.href}}" style="display: block; text-decoration: none; color: inherit; padding: .5em 2em;">
<i class="material-icons" style="float: right; margin-left: .4em;">keyboard_arrow_right</i>
<i class="material-icons" style="vertical-align: middle; margin-right: .4em;">{{::$ctrl.item.icon}}</i>
<a ui-sref="{{::$ctrl.item.href}}"
class="vn-clickable"
style="display: block; text-decoration: none; padding: .5em 2em;">
<vn-icon icon="keyboard_arrow_right" class="material-icons" style="float: right; margin-left: .4em;"></vn-icon>
<vn-icon icon="{{::$ctrl.item.icon}}" class="material-icons" style="vertical-align: middle; margin-right: .4em;"></vn-icon>
<span translate>{{::$ctrl.item.description}}</span>
</a>
</li>

View File

@ -1,7 +0,0 @@
vn-menu-item a:hover {
color: white !important;
background-color: #424242;
}
vn-menu-item li.active{
background-color: #E6E6E6;
}

View File

@ -0,0 +1,7 @@
vn-menu-item {
& > li.active {
background-color: #424242;
color: white;
}
}

View File

@ -1,4 +1,8 @@
<div style="position: fixed; top: 0; right: 0; padding: .8em 1.5em; z-index: 10;">
<div
id="user">
<h6>{{currentUserName}}</h6>
</div>
<vn-icon
id="apps"
icon="apps"

View File

@ -2,20 +2,32 @@ import ngModule from '../../module';
import './style.scss';
export default class MainMenu {
constructor($translate, $window, modulesFactory) {
constructor($translate, $scope, $http, $window, modulesFactory) {
this.$ = $scope;
this.$http = $http;
this.$translate = $translate;
this.$window = $window;
this.modules = modulesFactory.getModules();
this.langs = $translate.getAvailableLanguageKeys();
}
getCurrentUserName() {
this.$http.get('/auth/api/Accounts/getCurrentUserName')
.then(json => {
this.$.currentUserName = json.data;
});
}
onLogoutClick() {
this.$window.location = '/logout';
}
onChangeLangClick(lang) {
this.$translate.use(lang);
}
$onInit() {
this.getCurrentUserName();
}
}
MainMenu.$inject = ['$translate', '$window', 'modulesFactory'];
MainMenu.$inject = ['$translate', '$scope', '$http', '$window', 'modulesFactory'];
ngModule.component('vnMainMenu', {
template: require('./main-menu.html'),

View File

@ -1,4 +1,11 @@
vn-main-menu {
#user {
display: inline-block;
padding-right: 0.2em;
margin-bottom: 8px;
height: 2.5em;
vertical-align: middle;
}
& > div > vn-icon {
font-size: 2.2em;
cursor: pointer;

View File

@ -26,11 +26,11 @@ html [bg-dark-menu], .bg-dark-menu {
background-color: darken($bg-dark-menu, 35%);
}
/* Color para items seleccionados */
.bg-dark-item{
.bg-dark-item {
background-color: $bg-dark-bar;
color: $color-white;
}
/* Color para items inactivos */
.bg-opacity-item{
.bg-opacity-item {
opacity: 0.6;
}

View File

@ -24,15 +24,6 @@ html [fixed-bottom-right] {
bottom: 2em;
right: 2em;
}
vn-label {
font-size: .9em;
color: #666;
}
vn-button-bar {
display: block;
margin-top: $margin-small;
}
html [text-center], .text-center {
text-align: center;
}
@ -105,6 +96,33 @@ html [noDrop], .noDrop{
cursor: no-drop;
}
a {
color: inherit;
}
.vn-clickable {
cursor: pointer;
transition: background-color 250ms ease-out;
&:hover {
background-color: rgba(0, 0, 0, .1);
}
}
button {
@extend .vn-clickable;
}
vn-label {
font-size: .9em;
color: #666;
}
vn-button-bar {
display: block;
margin-top: $margin-small;
}
vn-main-block {
display:block;
max-width: 1920px;
@ -118,8 +136,9 @@ vn-main-block {
padding-bottom: 1em;
}
}
.vn-descriptor {
& .header {
.header {
background: #ffa410;
color: white;
justify-content: space-between;
@ -130,20 +149,33 @@ vn-main-block {
font-size: 2.5em;
}
& > a {
@extend .vn-clickable;
display: flex;
align-items: center;
padding: .5em;
color: white;
text-decoration: none;
transition: background-color 250ms ease-out;
&:hover {
background-color: rgba(1, 1, 1, 0.1);
}
& > vn-icon {
font-size: 1.8em;
}
}
}
.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 {
@ -154,19 +186,12 @@ vn-main-block {
.vn-list-item {
@extend .pad-medium;
@extend .border-solid-bottom;
@extend .vn-clickable;
display: block;
text-decoration: none;
color: inherit;
&:hover {
color: white;
background-color: #424242;
vn-label {
color: #aaa;
}
}
& > vn-horizontal > .buttons {
align-items: center;
@ -174,6 +199,7 @@ vn-main-block {
opacity: .4;
color: #ffa410;
margin-left: .5em;
transition: opacity 250ms ease-out;
&:hover {
opacity: 1;
@ -181,3 +207,13 @@ vn-main-block {
}
}
}
/** START - FORM ELEMENTS DISABLED **/
fieldset[disabled] .mdl-textfield .mdl-textfield__input, .mdl-textfield.is-disabled .mdl-textfield__input,
fieldset[disabled] .mdl-checkbox .mdl-checkbox__label, .mdl-checkbox.is-disabled .mdl-checkbox__label{
border: none !important;
color: inherit !important;
}
fieldset[disabled] .mdl-textfield .mdl-textfield__label, .mdl-textfield.is-disabled.is-disabled .mdl-textfield__label {
color: rgb(255,171,64) !important;
}
/** END - FORM ELEMENTS DISABLED **/

View File

@ -3,6 +3,7 @@
.summary{
h5 {
border-bottom: 2px solid $color-orange;
margin: 0 0 5px 0
}
h5.tittle {
border: none;
@ -10,24 +11,55 @@
color: $color-white;
}
p {
margin: 0 0 5px 0;
margin: 0 0 5px 0
}
p:after {
content: ' ';
overflow: hidden;
display: block;
clear: both
}
}
.vn-dialog.dialog-summary {
vn-card {
border: none;
box-shadow: none;
}
.vn-dialog.dialog-summary > div {
border: none;
background: transparent;
box-shadow: none;
}
.vn-dialog.dialog-summary > div > button.close > vn-icon {
color: $color-orange;
}
.vn-dialog.dialog-summary tpl-body {
width:auto;
background-color: transparent;
}
.vn-dialog.dialog-summary form {
min-width: 680px;
margin-left: -20px;
vn-vertical {
padding: 0 !important
}
& > div > button.close > vn-icon {
color: $color-orange;
}
& > div {
padding: 0
}
tpl-body {
width:auto;
background-color: transparent;
padding: 0 2em
}
.body {
overflow: auto;
margin-top: 2em;
max-height: 700px;
}
form {
min-width: 680px;
}
.buttons {
margin: 0
}
vn-check label span {
font-size: .9em
}
}

View File

@ -148,14 +148,16 @@ Nightmare.action('waitForNumberOfElements', function(selector, count, done) {
});
Nightmare.action('waitForTextInElement', function(selector, name, done) {
this.wait((resultSelector, expectedText) => {
this.wait(selector)
.wait((resultSelector, expectedText) => {
return document.querySelector(resultSelector).innerText.toLowerCase().includes(expectedText.toLowerCase());
}, selector, name)
.then(done);
});
Nightmare.action('waitForTextInInput', function(selector, name, done) {
this.wait((resultSelector, expectedText) => {
this.wait(selector)
.wait((resultSelector, expectedText) => {
return document.querySelector(resultSelector).value.toLowerCase().includes(expectedText.toLowerCase());
}, selector, name)
.then(done);

View File

@ -25,8 +25,8 @@ export default {
socialName: `${components.vnTextfield}[name="socialName"]`,
userName: `${components.vnTextfield}[name="userName"]`,
email: `${components.vnTextfield}[name="email"]`,
salesPersonInput: `${components.vnAutocomplete}[field="$ctrl.client.salesPersonFk"] > vn-vertical > ${components.vnTextfield}`,
salesBruceBannerOption: `${components.vnAutocomplete}[field="$ctrl.client.salesPersonFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
salesPersonInput: `vn-autocomplete[field="$ctrl.client.salesPersonFk"] input`,
salesBruceBannerOption: `vn-autocomplete[field="$ctrl.client.salesPersonFk"] vn-drop-down ul > li:nth-child(1)`,
createButton: `${components.vnSubmit}`
},
clientBasicData: {
@ -37,10 +37,10 @@ export default {
mobileInput: `${components.vnTextfield}[name="mobile"]`,
faxInput: `${components.vnTextfield}[name="fax"]`,
emailInput: `${components.vnTextfield}[name="email"]`,
salesPersonInput: `${components.vnAutocomplete}[field="$ctrl.client.salesPersonFk"] > vn-vertical > ${components.vnTextfield}`,
salesPersonOptionOne: `${components.vnAutocomplete}[field="$ctrl.client.salesPersonFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
channelInput: `${components.vnAutocomplete}[field="$ctrl.client.contactChannelFk"] > vn-vertical > ${components.vnTextfield}`,
channelMetropolisOption: `${components.vnAutocomplete}[field="$ctrl.client.contactChannelFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(3)`,
salesPersonInput: `${components.vnAutocomplete}[field="$ctrl.client.salesPersonFk"] input`,
salesPersonOptionOne: `${components.vnAutocomplete}[field="$ctrl.client.salesPersonFk"] vn-drop-down ul > li:nth-child(1)`,
channelInput: `${components.vnAutocomplete}[field="$ctrl.client.contactChannelFk"] input`,
channelMetropolisOption: `${components.vnAutocomplete}[field="$ctrl.client.contactChannelFk"] vn-drop-down ul > li:nth-child(3)`,
saveButton: `${components.vnSubmit}`
},
clientFiscalData: {
@ -52,10 +52,10 @@ export default {
addressInput: `${components.vnTextfield}[name="street"]`,
cityInput: `${components.vnTextfield}[name="city"]`,
postcodeInput: `${components.vnTextfield}[name="postcode"]`,
provinceInput: `${components.vnAutocomplete}[field="$ctrl.client.provinceFk"] > vn-vertical > ${components.vnTextfield}`,
provinceFifthOption: `${components.vnAutocomplete}[field="$ctrl.client.provinceFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(5)`,
countryInput: `${components.vnAutocomplete}[field="$ctrl.client.countryFk"] > vn-vertical > ${components.vnTextfield}`,
countryThirdOption: `${components.vnAutocomplete}[field="$ctrl.client.countryFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(3)`,
provinceInput: `${components.vnAutocomplete}[field="$ctrl.client.provinceFk"] input`,
provinceFifthOption: `${components.vnAutocomplete}[field="$ctrl.client.provinceFk"] vn-drop-down ul > li:nth-child(5)`,
countryInput: `${components.vnAutocomplete}[field="$ctrl.client.countryFk"] input`,
countryThirdOption: `${components.vnAutocomplete}[field="$ctrl.client.countryFk"] vn-drop-down ul > li:nth-child(3)`,
activeCheckboxLabel: `${components.vnCheck}[label='Active'] > label`,
invoiceByAddressCheckboxInput: `${components.vnCheck}[label='Invoice by address'] > label > input`,
verifiedDataCheckboxInput: `${components.vnCheck}[label='Verified data'] > label > input`,
@ -66,9 +66,9 @@ export default {
},
clientPayMethod: {
payMethodButton: `${components.vnMenuItem}[ui-sref="clientCard.billingData"]`,
payMethodInput: `${components.vnAutocomplete}[field="$ctrl.client.payMethodFk"] > vn-vertical > ${components.vnTextfield}`,
payMethodIBANOption: `${components.vnAutocomplete}[field="$ctrl.client.payMethodFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(5)`,
payMethodOptionOne: `${components.vnAutocomplete}[field="$ctrl.client.payMethodFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
payMethodInput: `${components.vnAutocomplete}[field="$ctrl.client.payMethodFk"] input`,
payMethodIBANOption: `${components.vnAutocomplete}[field="$ctrl.client.payMethodFk"] vn-drop-down ul > li:nth-child(5)`,
payMethodOptionOne: `${components.vnAutocomplete}[field="$ctrl.client.payMethodFk"] vn-drop-down ul > li:nth-child(2)`,
IBANInput: `${components.vnTextfield}[name="iban"]`,
dueDayInput: `${components.vnTextfield}[name="dueDay"]`,
cancelNotificationButton: 'vn-client-billing-data > vn-confirm button[response=CANCEL]',
@ -85,10 +85,10 @@ export default {
streetAddressInput: `${components.vnTextfield}[name="street"]`,
postcodeInput: `${components.vnTextfield}[name="postalCode"]`,
cityInput: `${components.vnTextfield}[name="city"]`,
provinceInput: `${components.vnAutocomplete}[field="$ctrl.address.provinceFk"] > vn-vertical > ${components.vnTextfield}`,
provinceSecondOption: `${components.vnAutocomplete}[field="$ctrl.address.provinceFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
agencyInput: `${components.vnAutocomplete}[field="$ctrl.address.agencyModeFk"] > vn-vertical > ${components.vnTextfield}`,
agenctySecondOption: `${components.vnAutocomplete}[field="$ctrl.address.agencyModeFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
provinceInput: `${components.vnAutocomplete}[field="$ctrl.address.provinceFk"] input`,
provinceSecondOption: `${components.vnAutocomplete}[field="$ctrl.address.provinceFk"] vn-drop-down ul > li:nth-child(2)`,
agencyInput: `${components.vnAutocomplete}[field="$ctrl.address.agencyModeFk"] input`,
agenctySecondOption: `${components.vnAutocomplete}[field="$ctrl.address.agencyModeFk"] vn-drop-down ul > li:nth-child(2)`,
phoneInput: `${components.vnTextfield}[name="phone"]`,
mobileInput: `${components.vnTextfield}[name="mobile"]`,
defaultAddress: 'vn-client-addresses > vn-vertical > vn-card > div > vn-horizontal:nth-child(2) > vn-one > vn-horizontal > vn-one > div:nth-child(2)',
@ -97,16 +97,16 @@ 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) > vn-vertical > ${components.vnTextfield}`,
firstObservationTypeSelectOptionOne: `${components.vnAutocomplete}[field="observation.observationTypeFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
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`,
secondObservationTypeSelect: `${components.vnAutocomplete}[field="observation.observationTypeFk"]:nth-child(2) > vn-vertical > ${components.vnTextfield}`,
secondObservationTypeSelectOptionTwo: `${components.vnAutocomplete}[field="observation.observationTypeFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
secondObservationTypeSelect: `${components.vnAutocomplete}[field="observation.observationTypeFk"]:nth-child(2) input`,
secondObservationTypeSelectOptionTwo: `${components.vnAutocomplete}[field="observation.observationTypeFk"] vn-drop-down ul > li:nth-child(2)`,
secondObservationDescriptionInput: `vn-horizontal:nth-child(4) > vn-textfield[label="Description"] > div > input`,
thirdObservationTypeSelect: `${components.vnAutocomplete}[field="observation.observationTypeFk"]:nth-child(3) > vn-vertical > ${components.vnTextfield}`,
thirdObservationTypeSelectOptionThree: `${components.vnAutocomplete}[field="observation.observationTypeFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(3)`,
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: {
@ -127,15 +127,15 @@ export default {
addCreditFloatButton: `${components.vnFloatButton}`,
creditInput: `${components.vnTextfield}[name="credit"]`,
saveButton: `${components.vnSubmit}`,
firstCreditText: 'vn-client-credit-list .list-element > vn-one'
firstCreditText: 'vn-client-credit-list .list-element'
},
clientGreuge: {
greugeButton: `${components.vnMenuItem}[ui-sref="clientCard.greuge.list"]`,
addGreugeFloatButton: `${components.vnFloatButton}`,
amountInput: `${components.vnTextfield}[name="amount"]`,
descriptionInput: `${components.vnTextfield}[name="description"]`,
typeInput: `${components.vnAutocomplete}[field="$ctrl.greuge.greugeTypeFk"] > vn-vertical > ${components.vnTextfield}`,
typeSecondOption: `${components.vnAutocomplete}[field="$ctrl.greuge.greugeTypeFk"] > vn-vertical > vn-drop-down > vn-vertical > vn-auto:nth-child(2) > ul > li`,
typeInput: `${components.vnAutocomplete}[field="$ctrl.greuge.greugeTypeFk"] input`,
typeSecondOption: `${components.vnAutocomplete}[field="$ctrl.greuge.greugeTypeFk"] vn-drop-down ul > li`,
saveButton: `${components.vnSubmit}`,
firstGreugeText: 'vn-client-greuge-list .list-element'
},
@ -159,54 +159,54 @@ export default {
},
itemCreateView: {
name: `${components.vnTextfield}[name="name"]`,
typeSelect: `${components.vnAutocomplete}[field="$ctrl.item.typeFk"] > vn-vertical > ${components.vnTextfield}`,
typeSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.item.typeFk"] > vn-vertical > vn-drop-down > vn-vertical > vn-auto > ul > li:nth-child(2)`,
intrastatSelect: `${components.vnAutocomplete}[field="$ctrl.item.intrastatFk"] > vn-vertical > ${components.vnTextfield}`,
intrastatSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.item.intrastatFk"] > vn-vertical > vn-drop-down > vn-vertical > vn-auto > ul > li:nth-child(2)`,
originSelect: `${components.vnAutocomplete}[field="$ctrl.item.originFk"] > vn-vertical > ${components.vnTextfield}`,
originSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.item.originFk"] > vn-vertical > vn-drop-down > vn-vertical > vn-auto > ul > li:nth-child(2)`,
expenceSelect: `${components.vnAutocomplete}[field="$ctrl.item.expenceFk"] > vn-vertical > ${components.vnTextfield}`,
expenceSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.item.expenceFk"] > vn-vertical > vn-drop-down > vn-vertical > vn-auto > ul > li:nth-child(2)`,
typeSelect: `${components.vnAutocomplete}[field="$ctrl.item.typeFk"] input`,
typeSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.item.typeFk"] vn-drop-down ul > li:nth-child(2)`,
intrastatSelect: `${components.vnAutocomplete}[field="$ctrl.item.intrastatFk"] input`,
intrastatSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.item.intrastatFk"] vn-drop-down ul > li:nth-child(2)`,
originSelect: `${components.vnAutocomplete}[field="$ctrl.item.originFk"] input`,
originSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.item.originFk"] vn-drop-down ul > li:nth-child(2)`,
expenceSelect: `${components.vnAutocomplete}[field="$ctrl.item.expenceFk"] input`,
expenceSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.item.expenceFk"] vn-drop-down ul > li:nth-child(2)`,
createButton: `${components.vnSubmit}`
},
itemBasicData: {
goToItemIndexButton: 'vn-item-descriptor [ui-sref="item.index"]',
basicDataButton: `${components.vnMenuItem}[ui-sref="item.card.data"]`,
typeSelect: `${components.vnAutocomplete}[field="$ctrl.item.typeFk"] > vn-vertical > ${components.vnTextfield}`,
typeSelectOptionTwo: `${components.vnAutocomplete}[field="$ctrl.item.typeFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
intrastatSelect: `${components.vnAutocomplete}[field="$ctrl.item.intrastatFk"] > vn-vertical > ${components.vnTextfield}`,
intrastatSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.item.intrastatFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
typeSelect: `${components.vnAutocomplete}[field="$ctrl.item.typeFk"] input`,
typeSelectOptionTwo: `${components.vnAutocomplete}[field="$ctrl.item.typeFk"] vn-drop-down ul > li:nth-child(2)`,
intrastatSelect: `${components.vnAutocomplete}[field="$ctrl.item.intrastatFk"] input`,
intrastatSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.item.intrastatFk"] vn-drop-down ul > li:nth-child(1)`,
nameInput: `vn-horizontal:nth-child(2) > ${components.vnTextfield}`,
relevancyInput: `vn-horizontal:nth-child(3) > ${components.vnTextfield}`,
originSelect: `${components.vnAutocomplete}[field="$ctrl.item.originFk"] > vn-vertical > ${components.vnTextfield}`,
originSelectOptionTwo: `${components.vnAutocomplete}[field="$ctrl.item.originFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
expenceSelect: `${components.vnAutocomplete}[field="$ctrl.item.expenceFk"] > vn-vertical > ${components.vnTextfield}`,
expenceSelectOptionTwo: `${components.vnAutocomplete}[field="$ctrl.item.expenceFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
originSelect: `${components.vnAutocomplete}[field="$ctrl.item.originFk"] input`,
originSelectOptionTwo: `${components.vnAutocomplete}[field="$ctrl.item.originFk"] vn-drop-down ul > li:nth-child(2)`,
expenceSelect: `${components.vnAutocomplete}[field="$ctrl.item.expenceFk"] input`,
expenceSelectOptionTwo: `${components.vnAutocomplete}[field="$ctrl.item.expenceFk"] vn-drop-down ul > li:nth-child(2)`,
submitBasicDataButton: `${components.vnSubmit}`
},
itemTags: {
goToItemIndexButton: 'vn-item-descriptor [ui-sref="item.index"]',
tagsButton: `${components.vnMenuItem}[ui-sref="item.card.tags"]`,
firstTagSelect: `vn-item-tags vn-horizontal:nth-child(2) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > ${components.vnTextfield}`,
firstTagSelectOptionOne: `vn-item-tags vn-horizontal:nth-child(2) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
firstTagSelect: `vn-item-tags vn-horizontal:nth-child(2) > ${components.vnAutocomplete}[field="itemTag.tagFk"] input`,
firstTagSelectOptionOne: `vn-item-tags vn-horizontal:nth-child(2) > ${components.vnAutocomplete}[field="itemTag.tagFk"] vn-drop-down ul > li:nth-child(1)`,
firstValueInput: `vn-item-tags vn-horizontal:nth-child(2) > vn-textfield[label="Value"] > div > input`,
firstRelevancyInput: `vn-horizontal:nth-child(2) > vn-textfield[label="Relevancy"] > div > input`,
secondTagSelect: `vn-item-tags vn-horizontal:nth-child(3) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > ${components.vnTextfield}`,
secondTagSelectOptionOne: `vn-item-tags vn-horizontal:nth-child(3) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
secondTagSelect: `vn-item-tags vn-horizontal:nth-child(3) > ${components.vnAutocomplete}[field="itemTag.tagFk"] input`,
secondTagSelectOptionOne: `vn-item-tags vn-horizontal:nth-child(3) > ${components.vnAutocomplete}[field="itemTag.tagFk"] vn-drop-down ul > li:nth-child(1)`,
secondValueInput: `vn-item-tags vn-horizontal:nth-child(3) > vn-textfield[label="Value"] > div > input`,
secondRelevancyInput: `vn-horizontal:nth-child(3) > vn-textfield[label="Relevancy"] > div > input`,
thirdTagSelect: `vn-item-tags vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > ${components.vnTextfield}`,
thirdTagSelectOptionOne: `vn-item-tags vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
thirdTagSelect: `vn-item-tags vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemTag.tagFk"] input`,
thirdTagSelectOptionOne: `vn-item-tags vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemTag.tagFk"] vn-drop-down ul > li:nth-child(1)`,
thirdValueInput: `vn-item-tags vn-horizontal:nth-child(4) > vn-textfield[label="Value"] > div > input`,
thirdRelevancyInput: `vn-horizontal:nth-child(4) > vn-textfield[label="Relevancy"] > div > input`,
fourthTagSelect: `vn-item-tags vn-horizontal:nth-child(5) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > ${components.vnTextfield}`,
fourthTagSelectOptionOne: `vn-item-tags vn-horizontal:nth-child(5) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
fourthTagSelect: `vn-item-tags vn-horizontal:nth-child(5) > ${components.vnAutocomplete}[field="itemTag.tagFk"] input`,
fourthTagSelectOptionOne: `vn-item-tags vn-horizontal:nth-child(5) > ${components.vnAutocomplete}[field="itemTag.tagFk"] vn-drop-down ul > li:nth-child(1)`,
fourthValueInput: `vn-item-tags vn-horizontal:nth-child(5) > vn-textfield[label="Value"] > div > input`,
fourthRelevancyInput: `vn-horizontal:nth-child(5) > vn-textfield[label="Relevancy"] > div > input`,
fifthRemoveTagButton: `vn-item-tags vn-horizontal:nth-child(6) > ${components.vnIcon}[icon="remove_circle_outline"]`,
fifthTagSelect: `vn-item-tags vn-horizontal:nth-child(6) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > ${components.vnTextfield}`,
fifthTagSelectOptionFive: `vn-item-tags vn-horizontal:nth-child(6) > ${components.vnAutocomplete}[field="itemTag.tagFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(5)`,
fifthTagSelect: `vn-item-tags vn-horizontal:nth-child(6) > ${components.vnAutocomplete}[field="itemTag.tagFk"] input`,
fifthTagSelectOptionFive: `vn-item-tags vn-horizontal:nth-child(6) > ${components.vnAutocomplete}[field="itemTag.tagFk"] vn-drop-down ul > li:nth-child(5)`,
fifthValueInput: `vn-item-tags vn-horizontal:nth-child(6) > vn-textfield[label="Value"] > div > input`,
fifthRelevancyInput: `vn-horizontal:nth-child(6) > vn-textfield[label="Relevancy"] > div > input`,
addItemTagButton: `${components.vnIcon}[icon="add_circle"]`,
@ -214,12 +214,12 @@ export default {
},
itemTax: {
taxButton: `${components.vnMenuItem}[ui-sref="item.card.tax"]`,
firstClassSelect: `vn-horizontal:nth-child(2) > ${components.vnAutocomplete}[field="tax.taxClassFk"] > vn-vertical > ${components.vnTextfield}`,
firstClassSelectOptionTwo: `vn-horizontal:nth-child(2) > ${components.vnAutocomplete} > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
secondClassSelect: `vn-horizontal:nth-child(3) > ${components.vnAutocomplete}[field="tax.taxClassFk"] > vn-vertical > ${components.vnTextfield}`,
secondClassSelectOptionOne: `vn-horizontal:nth-child(3) > ${components.vnAutocomplete} > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
thirdClassSelect: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="tax.taxClassFk"] > vn-vertical > ${components.vnTextfield}`,
thirdClassSelectOptionTwo: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete} > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
firstClassSelect: `vn-horizontal:nth-child(2) > ${components.vnAutocomplete}[field="tax.taxClassFk"] input`,
firstClassSelectOptionTwo: `vn-horizontal:nth-child(2) > ${components.vnAutocomplete} vn-drop-down ul > li:nth-child(2)`,
secondClassSelect: `vn-horizontal:nth-child(3) > ${components.vnAutocomplete}[field="tax.taxClassFk"] input`,
secondClassSelectOptionOne: `vn-horizontal:nth-child(3) > ${components.vnAutocomplete} vn-drop-down ul > li:nth-child(1)`,
thirdClassSelect: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="tax.taxClassFk"] input`,
thirdClassSelectOptionTwo: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete} vn-drop-down ul > li:nth-child(2)`,
submitTaxButton: `${components.vnSubmit}`
},
itemBarcodes: {
@ -232,31 +232,34 @@ export default {
itemNiches: {
nicheButton: `${components.vnMenuItem}[ui-sref="item.card.niche"]`,
addNicheButton: `${components.vnIcon}[icon="add_circle"]`,
firstWarehouseSelect: `${components.vnAutocomplete}[field="itemNiche.warehouseFk"] > vn-vertical > ${components.vnTextfield}`,
firstWarehouseSelectSecondOption: `${components.vnAutocomplete}[field="itemNiche.warehouseFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
thirdWarehouseSelect: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemNiche.warehouseFk"] > vn-vertical > ${components.vnTextfield}`,
thirdWarehouseSelectFourthOption: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemNiche.warehouseFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(4)`,
firstWarehouseSelect: `${components.vnAutocomplete}[field="itemNiche.warehouseFk"] input`,
firstWarehouseSelectSecondOption: `${components.vnAutocomplete}[field="itemNiche.warehouseFk"] vn-drop-down ul > li:nth-child(2)`,
secondWarehouseSelect: `vn-horizontal:nth-child(3) > ${components.vnAutocomplete}[field="itemNiche.warehouseFk"] input`,
thirdWarehouseSelect: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemNiche.warehouseFk"] input`,
thirdWarehouseSelectFourthOption: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="itemNiche.warehouseFk"] vn-drop-down ul > li:nth-child(4)`,
secondNicheRemoveButton: `vn-horizontal:nth-child(3) > vn-one > ${components.vnIcon}[icon="remove_circle_outline"]`,
firstCodeInput: `vn-horizontal:nth-child(2) > ${components.vnTextfield}`,
secondCodeInput: `vn-horizontal:nth-child(3) > ${components.vnTextfield}`,
thirdCodeInput: `vn-horizontal:nth-child(4) > ${components.vnTextfield}`,
submitNichesButton: `${components.vnSubmit}`
},
itemBotanical: {
botanicalButton: `${components.vnMenuItem}[ui-sref="item.card.botanical"]`,
botanicalInput: `vn-horizontal:nth-child(2) > ${components.vnTextfield}`,
genusSelect: `${components.vnAutocomplete}[field="$ctrl.botanical.genusFk"] > vn-vertical > ${components.vnTextfield}`,
genusSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.botanical.genusFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
genusSelectOptionTwo: `${components.vnAutocomplete}[field="$ctrl.botanical.genusFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
speciesSelect: `${components.vnAutocomplete}[field="$ctrl.botanical.specieFk"] > vn-vertical > ${components.vnTextfield}`,
speciesSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.botanical.specieFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(1)`,
speciesSelectOptionTwo: `${components.vnAutocomplete}[field="$ctrl.botanical.specieFk"] > vn-vertical > vn-drop-down > vn-vertical:not(.ng-hide) > vn-auto:nth-child(2) > ul > li:nth-child(2)`,
genusSelect: `${components.vnAutocomplete}[field="$ctrl.botanical.genusFk"] input`,
genusSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.botanical.genusFk"] vn-drop-down ul > li:nth-child(1)`,
genusSelectOptionTwo: `${components.vnAutocomplete}[field="$ctrl.botanical.genusFk"] vn-drop-down ul > li:nth-child(2)`,
speciesSelect: `${components.vnAutocomplete}[field="$ctrl.botanical.specieFk"] input`,
speciesSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.botanical.specieFk"] vn-drop-down ul > li:nth-child(1)`,
speciesSelectOptionTwo: `${components.vnAutocomplete}[field="$ctrl.botanical.specieFk"] vn-drop-down ul > li:nth-child(2)`,
submitBotanicalButton: `${components.vnSubmit}`
},
itemSummary: {
basicData: `${components.vnItemSummary} > vn-horizontal:nth-child(1) > vn-one:nth-child(2) > vn-vertical > p:nth-child(2)`,
tags: `${components.vnItemSummary} > vn-horizontal:nth-child(1) > vn-one:nth-child(3) > vn-vertical > p`,
niche: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(1) > vn-vertical > p:nth-child(2)`,
botanical: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(2) > vn-vertical > p`,
barcode: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(3) > vn-vertical > p`
vat: `${components.vnItemSummary} > vn-horizontal:nth-child(1) > vn-one:nth-child(3) > vn-vertical > p`,
tags: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(1) > p`,
niche: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(2) > vn-vertical > p:nth-child(2)`,
botanical: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(3) > vn-vertical > p`,
barcode: `${components.vnItemSummary} > vn-horizontal:nth-child(2) > vn-one:nth-child(4) > vn-vertical > p`
}
};

View File

@ -50,76 +50,13 @@ describe('create client path', () => {
});
});
it('should receive an error when clicking the create button having all the form fields empty but name', () => {
it('should receive an error when clicking the create button having name and Business name fields empty', () => {
return nightmare
.type(selectors.createClientView.name, 'Carol Danvers')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the create button having all the form fields empty but Tax Number', () => {
return nightmare
.clearInput(selectors.createClientView.name)
.type(selectors.createClientView.taxNumber, '16195279J')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the create button having all the form fields empty but Business Name', () => {
return nightmare
.clearInput(selectors.createClientView.taxNumber)
.type(selectors.createClientView.socialName, 'Avengers team')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the create button having all the form fields empty but User Name', () => {
return nightmare
.clearInput(selectors.createClientView.socialName)
.type(selectors.createClientView.userName, 'CaptainMarvel')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the create button having all the form fields empty but email while email have incorrect format', () => {
return nightmare
.clearInput(selectors.createClientView.userName)
.type(selectors.createClientView.email, 'I will save the Avengers!')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Some fields are invalid');
});
});
it('should receive an error when clicking the create button having all the form fields empty but email', () => {
return nightmare
.clearInput(selectors.createClientView.email)
.type(selectors.createClientView.email, 'CarolDanvers@verdnatura.es')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the create button having all the form fields empty but sales person', () => {
return nightmare
.waitToClick(selectors.createClientView.salesPersonInput)
.waitToClick(selectors.createClientView.salesBruceBannerOption)
.wait(200)
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
@ -127,15 +64,23 @@ describe('create client path', () => {
});
});
it(`should create a new user with all it's data`, () => {
it(`should attempt to create a new user with all it's data but wrong email`, () => {
return nightmare
.wait(selectors.createClientView.email)
.clearInput(selectors.createClientView.email)
.type(selectors.createClientView.name, 'Carol Danvers')
.type(selectors.createClientView.taxNumber, '16195279J')
.type(selectors.createClientView.socialName, 'AVG tax')
.type(selectors.createClientView.userName, 'CaptainMarvel')
.type(selectors.createClientView.email, 'CarolDanvers@verdnatura.es')
.clearInput(selectors.createClientView.email)
.type(selectors.createClientView.email, 'incorrect email format')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it(`should create a new user with all correct data`, () => {
return nightmare
.clearInput(selectors.createClientView.email)
.type(selectors.createClientView.email, 'caroldanvers@verdnatura.es')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {

View File

@ -44,11 +44,23 @@ describe('Edit basicData path', () => {
});
});
it('should edit the name', () => {
it('should edit the client basic data', () => {
return nightmare
.wait(selectors.clientBasicData.nameInput)
.clearInput(selectors.clientBasicData.nameInput)
.type(selectors.clientBasicData.nameInput, 'Ororo Munroe')
.clearInput(selectors.clientBasicData.contactInput)
.type(selectors.clientBasicData.contactInput, 'Black Panther')
.clearInput(selectors.clientBasicData.phoneInput)
.type(selectors.clientBasicData.phoneInput, '123456789')
.clearInput(selectors.clientBasicData.mobileInput)
.type(selectors.clientBasicData.mobileInput, '987654321')
.clearInput(selectors.clientBasicData.emailInput)
.type(selectors.clientBasicData.emailInput, 'Storm@verdnatura.es')
.waitToClick(selectors.clientBasicData.salesPersonInput)
.waitToClick(selectors.clientBasicData.salesPersonOptionOne)
.waitToClick(selectors.clientBasicData.channelInput)
.waitToClick(selectors.clientBasicData.channelMetropolisOption)
.click(selectors.clientBasicData.saveButton)
.waitForSnackbar()
.then(result => {
@ -68,144 +80,48 @@ describe('Edit basicData path', () => {
});
});
it('should edit the contact name', () => {
return nightmare
.wait(selectors.clientBasicData.contactInput)
.clearInput(selectors.clientBasicData.contactInput)
.type(selectors.clientBasicData.contactInput, 'Black Panther')
.click(selectors.clientBasicData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the contact name have been edited', () => {
return nightmare
.click(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.addressInput)
.click(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.contactInput)
.getInputValue(selectors.clientBasicData.contactInput)
.then(result => {
expect(result).toEqual('Black Panther');
});
});
it('should add the landline phone number', () => {
return nightmare
.wait(selectors.clientBasicData.phoneInput)
.clearInput(selectors.clientBasicData.phoneInput)
.type(selectors.clientBasicData.phoneInput, '123456789')
.click(selectors.clientBasicData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the landline phone number have been added', () => {
return nightmare
.click(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.addressInput)
.click(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.phoneInput)
.getInputValue(selectors.clientBasicData.phoneInput)
.then(result => {
expect(result).toEqual('123456789');
});
});
it('should add the mobile phone number', () => {
return nightmare
.wait(selectors.clientBasicData.mobileInput)
.clearInput(selectors.clientBasicData.mobileInput)
.type(selectors.clientBasicData.mobileInput, '987654321')
.click(selectors.clientBasicData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the mobile phone number have been added', () => {
return nightmare
.click(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.addressInput)
.click(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.mobileInput)
.getInputValue(selectors.clientBasicData.mobileInput)
.then(result => {
expect(result).toEqual('987654321');
});
});
it('should edit the email', () => {
return nightmare
.wait(selectors.clientBasicData.emailInput)
.clearInput(selectors.clientBasicData.emailInput)
.type(selectors.clientBasicData.emailInput, 'Storm@verdnatura.es')
.click(selectors.clientBasicData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the email have been edited', () => {
return nightmare
.click(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.addressInput)
.click(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.emailInput)
.getInputValue(selectors.clientBasicData.emailInput)
.then(result => {
expect(result).toEqual('Storm@verdnatura.es');
});
});
it('should select the sales person first option', () => {
return nightmare
.waitToClick(selectors.clientBasicData.salesPersonInput)
.waitToClick(selectors.clientBasicData.salesPersonOptionOne)
.wait(200)
.waitToClick(selectors.clientBasicData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the sales person have been selected', () => {
return nightmare
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.addressInput)
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(200)
.getInputValue(selectors.clientBasicData.salesPersonInput)
.then(result => {
expect(result).toEqual('accessory accessory');
});
});
it('should select the channel', () => {
return nightmare
.waitToClick(selectors.clientBasicData.channelInput)
.waitToClick(selectors.clientBasicData.channelMetropolisOption)
.wait(400)
.waitToClick(selectors.clientBasicData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the channel have been selected', () => {
return nightmare
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.addressInput)
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(400)
.getInputValue(selectors.clientBasicData.channelInput)
.then(result => {
expect(result).toEqual('Metropolis newspaper');

View File

@ -50,7 +50,6 @@ describe('Edit fiscalData path', () => {
return nightmare
.waitToClick(selectors.clientAddresses.firstEditButton)
.wait(selectors.clientAddresses.equalizationTaxCheckboxLabel)
.wait(200)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientAddresses.equalizationTaxCheckboxLabel)
@ -64,7 +63,6 @@ describe('Edit fiscalData path', () => {
.waitToClick(selectors.clientAddresses.addressesButton)
.waitToClick(selectors.clientAddresses.secondEditButton)
.wait(selectors.clientAddresses.equalizationTaxCheckboxLabel)
.wait(200)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientAddresses.equalizationTaxCheckboxLabel)
@ -84,58 +82,29 @@ describe('Edit fiscalData path', () => {
});
});
it('should edit the social name', () => {
it('should edit the clients fiscal data', () => {
return nightmare
.wait(selectors.clientFiscalData.socialNameInput)
.clearInput(selectors.clientFiscalData.socialNameInput)
.type(selectors.clientFiscalData.socialNameInput, 'Hulk edited')
.click(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the social name have been edited', () => {
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('Hulk edited');
});
});
it('should edit the fiscal id', () => {
return nightmare
.wait(selectors.clientFiscalData.fiscalIdInput)
.type(selectors.clientFiscalData.socialNameInput, 'SMASH!')
.clearInput(selectors.clientFiscalData.fiscalIdInput)
.type(selectors.clientFiscalData.fiscalIdInput, '94980061C')
.click(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the fiscal id have been edited', () => {
return nightmare
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.fiscalIdInput)
.getInputValue(selectors.clientFiscalData.fiscalIdInput)
.then(result => {
expect(result).toEqual('94980061C');
});
});
it('should check the Equalization tax checkbox', () => {
return nightmare
.waitToClick(selectors.clientFiscalData.equalizationTaxCheckboxLabel)
.waitToClick(selectors.clientFiscalData.saveButton)
.clearInput(selectors.clientFiscalData.addressInput)
.type(selectors.clientFiscalData.addressInput, 'Somewhere edited')
.clearInput(selectors.clientFiscalData.cityInput)
.type(selectors.clientFiscalData.cityInput, 'N/A')
.clearInput(selectors.clientFiscalData.postcodeInput)
.type(selectors.clientFiscalData.postcodeInput, '12345')
.waitToClick(selectors.clientFiscalData.provinceInput)
.waitToClick(selectors.clientFiscalData.provinceFifthOption)
.waitToClick(selectors.clientFiscalData.activeCheckboxLabel)
.waitToClick(selectors.clientFiscalData.invoiceByAddressCheckboxInput)
.waitToClick(selectors.clientFiscalData.verifiedDataCheckboxInput)
.waitToClick(selectors.clientFiscalData.hasToInvoiceCheckboxLabel)
.waitToClick(selectors.clientFiscalData.invoiceByMailCheckboxLabel)
.waitToClick(selectors.clientFiscalData.viesCheckboxInput)
.click(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
@ -151,21 +120,7 @@ describe('Edit fiscalData path', () => {
});
});
it('should confirm Equalization tax checkbox is checked', () => {
return nightmare
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.equalizationTaxCheckboxLabel)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientFiscalData.equalizationTaxCheckboxLabel)
.then(value => {
expect(value).toBeTruthy();
});
});
describe('Confirm all addresses have now EQtax checked', () => {
describe('confirm all addresses have now EQtax checked', () => {
it(`should click on the addresses button to access to the client's addresses`, () => {
return nightmare
.waitToClick(selectors.clientAddresses.addressesButton)
@ -180,7 +135,6 @@ describe('Edit fiscalData path', () => {
return nightmare
.waitToClick(selectors.clientAddresses.firstEditButton)
.wait(selectors.clientAddresses.equalizationTaxCheckboxLabel)
.wait(200)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientAddresses.equalizationTaxCheckboxLabel)
@ -194,7 +148,6 @@ describe('Edit fiscalData path', () => {
.waitToClick(selectors.clientAddresses.addressesButton)
.waitToClick(selectors.clientAddresses.secondEditButton)
.wait(selectors.clientAddresses.equalizationTaxCheckboxLabel)
.wait(200)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientAddresses.equalizationTaxCheckboxLabel)
@ -204,119 +157,68 @@ describe('Edit fiscalData path', () => {
});
});
it('should go to fiscal data then edit the address', () => {
it('should navigate back to fiscal data to confirm it have been edited', () => {
return nightmare
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.addressInput)
.clearInput(selectors.clientFiscalData.addressInput)
.type(selectors.clientFiscalData.addressInput, 'Somewhere edited')
.click(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.wait(selectors.clientFiscalData.socialNameInput)
.getInputValue(selectors.clientFiscalData.socialNameInput)
.then(result => {
expect(result).toEqual('Data saved!');
expect(result).toEqual('SMASH!');
});
});
it('should confirm the fiscal id have been edited', () => {
return nightmare
.getInputValue(selectors.clientFiscalData.fiscalIdInput)
.then(result => {
expect(result).toEqual('94980061C');
});
});
it('should confirm Equalization tax checkbox is checked', () => {
return nightmare
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientFiscalData.equalizationTaxCheckboxLabel)
.then(value => {
expect(value).toBeTruthy();
});
});
it('should confirm the address have been edited', () => {
return nightmare
.click(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.click(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.addressInput)
.getInputValue(selectors.clientFiscalData.addressInput)
.then(result => {
expect(result).toEqual('Somewhere edited');
});
});
it('should edit the city', () => {
return nightmare
.wait(selectors.clientFiscalData.cityInput)
.clearInput(selectors.clientFiscalData.cityInput)
.type(selectors.clientFiscalData.cityInput, 'N/A')
.click(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the city have been edited', () => {
return nightmare
.click(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.click(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.cityInput)
.getInputValue(selectors.clientFiscalData.cityInput)
.then(result => {
expect(result).toEqual('N/A');
});
});
it('should edit the postcode', () => {
return nightmare
.wait(selectors.clientFiscalData.postcodeInput)
.clearInput(selectors.clientFiscalData.postcodeInput)
.type(selectors.clientFiscalData.postcodeInput, '12345')
.click(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the postcode have been edited', () => {
return nightmare
.click(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.click(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.postcodeInput)
.getInputValue(selectors.clientFiscalData.postcodeInput)
.then(result => {
expect(result).toEqual('12345');
});
});
it(`should edit the province`, () => {
return nightmare
.waitToClick(selectors.clientFiscalData.provinceInput)
.waitToClick(selectors.clientFiscalData.provinceFifthOption)
.wait(200)
.waitToClick(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it(`should confirm the province have been selected`, () => {
return nightmare
.click(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.click(selectors.clientFiscalData.fiscalDataButton)
.wait(200)
.getInputValue(selectors.clientFiscalData.provinceInput)
.then(result => {
expect(result).toEqual('Province two');
});
});
it('should uncheck the active checkbox', () => {
return nightmare
.waitToClick(selectors.clientFiscalData.activeCheckboxLabel)
.waitToClick(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm active checkbox is unchecked', () => {
return nightmare
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.activeCheckboxLabel)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientFiscalData.activeCheckboxLabel)
@ -325,22 +227,8 @@ describe('Edit fiscalData path', () => {
});
});
it('should uncheck the invoice by address checkbox', () => {
return nightmare
.waitToClick(selectors.clientFiscalData.invoiceByAddressCheckboxInput)
.waitToClick(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm invoice by address checkbox is unchecked', () => {
return nightmare
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.invoiceByAddressCheckboxInput)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientFiscalData.invoiceByAddressCheckboxInput)
@ -349,22 +237,8 @@ describe('Edit fiscalData path', () => {
});
});
it('should check 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 checked', () => {
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)
@ -373,22 +247,8 @@ describe('Edit fiscalData path', () => {
});
});
it('should uncheck the Has to invoice checkbox', () => {
return nightmare
.waitToClick(selectors.clientFiscalData.hasToInvoiceCheckboxLabel)
.waitToClick(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm Has to invoice checkbox is unchecked', () => {
return nightmare
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.hasToInvoiceCheckboxLabel)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientFiscalData.hasToInvoiceCheckboxLabel)
@ -397,22 +257,8 @@ describe('Edit fiscalData path', () => {
});
});
it('should uncheck the Invoice by mail checkbox', () => {
return nightmare
.waitToClick(selectors.clientFiscalData.invoiceByMailCheckboxLabel)
.waitToClick(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm Invoice by mail checkbox is unchecked', () => {
return nightmare
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.invoiceByMailCheckboxLabel)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientFiscalData.invoiceByMailCheckboxLabel)
@ -421,22 +267,8 @@ describe('Edit fiscalData path', () => {
});
});
it('should check the Vies checkbox', () => {
return nightmare
.waitToClick(selectors.clientFiscalData.viesCheckboxInput)
.waitToClick(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm Vies checkbox is checked', () => {
return nightmare
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.waitToClick(selectors.clientFiscalData.fiscalDataButton)
.wait(selectors.clientFiscalData.viesCheckboxInput)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientFiscalData.viesCheckboxInput)

View File

@ -45,36 +45,15 @@ describe('Edit pay method path', () => {
});
});
it(`should edit the Pay method to any without IBAN`, () => {
return nightmare
.waitToClick(selectors.clientPayMethod.payMethodInput)
.waitToClick(selectors.clientPayMethod.payMethodOptionOne)
.wait(200)
.waitToClick(selectors.clientPayMethod.saveButton)
.waitToClick(selectors.clientPayMethod.cancelNotificationButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it(`should confirm the Pay method have been selected`, () => {
return nightmare
.click(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.click(selectors.clientPayMethod.payMethodButton)
.wait(200)
.getInputValue(selectors.clientPayMethod.payMethodInput)
.then(result => {
expect(result).toEqual('PayMethod one');
});
});
it(`should receive an error when changing payMethod to IBAN without an IBAN entered`, () => {
it(`should attempt to edit the Pay method without an IBAN but fail`, () => {
return nightmare
.waitToClick(selectors.clientPayMethod.payMethodInput)
.waitToClick(selectors.clientPayMethod.payMethodIBANOption)
.wait(200)
.clearInput(selectors.clientPayMethod.dueDayInput)
.type(selectors.clientPayMethod.dueDayInput, '60')
.waitToClick(selectors.clientPayMethod.receivedCoreVNHCheckbox)
.waitToClick(selectors.clientPayMethod.receivedCoreVNLCheckbox)
.waitToClick(selectors.clientPayMethod.receivedB2BVNLCheckbox)
.waitToClick(selectors.clientPayMethod.saveButton)
.waitToClick(selectors.clientPayMethod.cancelNotificationButton)
.waitForSnackbar()
@ -97,56 +76,22 @@ describe('Edit pay method path', () => {
it(`should confirm the IBAN pay method is sucessfully saved`, () => {
return nightmare
.click(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.click(selectors.clientPayMethod.payMethodButton)
.wait(200)
.getInputValue(selectors.clientPayMethod.payMethodInput)
.then(result => {
expect(result).toEqual('PayMethod with IBAN');
});
});
it(`should edit the due day`, () => {
return nightmare
.clearInput(selectors.clientPayMethod.dueDayInput)
.type(selectors.clientPayMethod.dueDayInput, '60')
.waitToClick(selectors.clientPayMethod.saveButton)
.waitToClick(selectors.clientPayMethod.cancelNotificationButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the due day have been edited', () => {
return nightmare
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.waitToClick(selectors.clientPayMethod.payMethodButton)
.wait(selectors.clientPayMethod.dueDayInput)
.getInputValue(selectors.clientPayMethod.dueDayInput)
.then(result => {
expect(result).toEqual('60');
});
});
it('should uncheck the Received core VNH checkbox', () => {
return nightmare
.waitToClick(selectors.clientPayMethod.receivedCoreVNHCheckbox)
.waitToClick(selectors.clientPayMethod.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm Received core VNH checkbox is unchecked', () => {
return nightmare
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.waitToClick(selectors.clientPayMethod.payMethodButton)
.wait(selectors.clientPayMethod.receivedCoreVNHCheckbox)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientPayMethod.receivedCoreVNHCheckbox)
@ -155,22 +100,8 @@ describe('Edit pay method path', () => {
});
});
it('should uncheck the Received core VNL checkbox', () => {
return nightmare
.waitToClick(selectors.clientPayMethod.receivedCoreVNLCheckbox)
.waitToClick(selectors.clientPayMethod.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm Received core VNL checkbox is unchecked', () => {
return nightmare
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.waitToClick(selectors.clientPayMethod.payMethodButton)
.wait(selectors.clientPayMethod.receivedCoreVNLCheckbox)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientPayMethod.receivedCoreVNLCheckbox)
@ -179,22 +110,8 @@ describe('Edit pay method path', () => {
});
});
it('should uncheck the Received B2B VNL checkbox', () => {
return nightmare
.waitToClick(selectors.clientPayMethod.receivedB2BVNLCheckbox)
.waitToClick(selectors.clientPayMethod.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm Received B2B VNL checkbox is unchecked', () => {
return nightmare
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.waitToClick(selectors.clientPayMethod.payMethodButton)
.wait(selectors.clientPayMethod.receivedB2BVNLCheckbox)
.evaluate(selector => {
return document.querySelector(selector).checked;
}, selectors.clientPayMethod.receivedB2BVNLCheckbox)

View File

@ -55,97 +55,18 @@ describe('Add address path', () => {
});
});
it('should check the default checkbox then receive an error after clicking save button as the form is empty', () => {
it('should receive an error after clicking save button as consignee, street and town fields are empty', () => {
return nightmare
.waitToClick(selectors.clientAddresses.defaultCheckboxInput)
.waitToClick(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the save button having all the form fields empty but consignee', () => {
return nightmare
.type(selectors.clientAddresses.consigneeInput, 'Bruce Bunner')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the save button having all the form fields empty but Street', () => {
return nightmare
.clearInput(selectors.clientAddresses.consigneeInput)
.type(selectors.clientAddresses.streetAddressInput, '320 Park Avenue New York')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the save button having all the form fields empty but postcode', () => {
return nightmare
.clearInput(selectors.clientAddresses.streetAddressInput)
.type(selectors.clientAddresses.postcodeInput, '10022')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the save button having all the form fields empty but city', () => {
return nightmare
.clearInput(selectors.clientAddresses.postcodeInput)
.type(selectors.clientAddresses.cityInput, 'New York')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the save button having all the form fields empty but province', () => {
return nightmare
.clearInput(selectors.clientAddresses.cityInput)
.waitToClick(selectors.clientAddresses.provinceInput)
.waitToClick(selectors.clientAddresses.provinceSecondOption)
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the save button having all the form fields empty but province and agency', () => {
return nightmare
.waitToClick(selectors.clientAddresses.agencyInput)
.waitToClick(selectors.clientAddresses.agenctySecondOption)
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the save button having all the form fields empty but province, agency and phone', () => {
return nightmare
.type(selectors.clientAddresses.phoneInput, '999887744')
.click(selectors.createClientView.createButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it('should receive an error when clicking the save button having all the form fields empty but province, agency and mobile', () => {
return nightmare
.clearInput(selectors.clientAddresses.phoneInput)
.type(selectors.clientAddresses.mobileInput, '999887744')
.click(selectors.createClientView.createButton)
.waitToClick(selectors.clientFiscalData.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
@ -156,9 +77,7 @@ describe('Add address path', () => {
return nightmare
.type(selectors.clientAddresses.consigneeInput, 'Bruce Bunner')
.type(selectors.clientAddresses.streetAddressInput, '320 Park Avenue New York')
.type(selectors.clientAddresses.postcodeInput, '10022')
.type(selectors.clientAddresses.cityInput, 'New York')
.type(selectors.clientAddresses.phoneInput, '999887744')
.click(selectors.clientAddresses.saveButton)
.waitForSnackbar()
.then(result => {
@ -203,7 +122,7 @@ describe('Add address path', () => {
.waitToClick(selectors.clientAddresses.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
expect(result).toContain('Error:');
});
});
});

View File

@ -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!');
// });
// });
// });

View File

@ -45,17 +45,19 @@ describe('Edit web access path', () => {
});
});
it(`should click on the Enable web access checkbox to uncheck it`, () => {
it(`should uncheck the Enable web access checkbox and update the name`, () => {
return nightmare
.waitToClick(selectors.clientWebAccess.enableWebAccessCheckbox)
.waitToClick(selectors.clientFiscalData.saveButton)
.clearInput(selectors.clientWebAccess.userNameInput)
.type(selectors.clientWebAccess.userNameInput, 'Hulk')
.waitToClick(selectors.clientWebAccess.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain(`Data saved!`);
});
});
it('should confirm Enable web access checkbox is unchecked', () => {
it('should confirm web access is unchecked and name updated', () => {
return nightmare
.waitToClick(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
@ -66,29 +68,9 @@ describe('Edit web access path', () => {
}, selectors.clientWebAccess.enableWebAccessCheckbox)
.then(value => {
expect(value).toBeFalsy();
});
});
it('should edit the User name', () => {
return nightmare
.wait(selectors.clientWebAccess.userNameInput)
.clearInput(selectors.clientWebAccess.userNameInput)
.type(selectors.clientWebAccess.userNameInput, 'Hulk')
.click(selectors.clientWebAccess.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toEqual('Data saved!');
});
});
it('should confirm the User name have been edited', () => {
return nightmare
.click(selectors.clientBasicData.basicDataButton)
.wait(selectors.clientBasicData.nameInput)
.click(selectors.clientWebAccess.webAccessButton)
.wait(selectors.clientWebAccess.userNameInput)
.waitForTextInInput(selectors.clientWebAccess.userNameInput, 'Hulk')
.getInputValue(selectors.clientWebAccess.userNameInput)
return nightmare
.getInputValue(selectors.clientWebAccess.userNameInput);
})
.then(result => {
expect(result).toEqual('Hulk');
});

View File

@ -72,6 +72,7 @@ describe('Add credit path', () => {
.getInnerText(selectors.clientCredit.firstCreditText)
.then(value => {
expect(value).toContain(999);
expect(value).toContain('developer');
});
});
});

View File

@ -55,39 +55,8 @@ describe('Add greuge path', () => {
});
});
it(`should receive an error if all fields are empty but date on submit`, () => {
return nightmare
.click(selectors.clientCredit.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it(`should receive an error if all fields are empty but date and amount on submit`, () => {
return nightmare
.type(selectors.clientGreuge.amountInput, 999)
.click(selectors.clientGreuge.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it(`should receive an error if all fields are empty but date and description on submit`, () => {
return nightmare
.clearInput(selectors.clientGreuge.amountInput)
.type(selectors.clientGreuge.descriptionInput, 'new armor for Batman!')
.click(selectors.clientGreuge.saveButton)
.waitForSnackbar()
.then(result => {
expect(result).toContain('Some fields are invalid');
});
});
it(`should receive an error if all fields are empty but date and type on submit`, () => {
return nightmare
.clearInput(selectors.clientGreuge.descriptionInput)
.waitToClick(selectors.clientGreuge.typeInput)
.waitToClick(selectors.clientGreuge.typeSecondOption)
.click(selectors.clientGreuge.saveButton)
@ -99,7 +68,6 @@ describe('Add greuge path', () => {
it(`should create a new greuge with all its data`, () => {
return nightmare
.clearInput(selectors.clientGreuge.amountInput)
.type(selectors.clientGreuge.amountInput, 999)
.type(selectors.clientGreuge.descriptionInput, 'new armor for Batman!')
.click(selectors.clientGreuge.saveButton)

View File

@ -1,7 +1,7 @@
import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/helpers';
describe('mandate path', () => {
describe('lock verified data path', () => {
const nightmare = createNightmare();
describe('as salesPerson', () => {
@ -203,80 +203,80 @@ describe('mandate path', () => {
expect(result).toEqual('administrative was here');
});
});
});
describe('as salesPerson second run', () => {
beforeAll(() => {
return nightmare
.waitToClick(selectors.globalItems.logOutButton)
.waitForLogin('salesPerson');
describe('as salesPerson second 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 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 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 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 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 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 disabled once again for salesPerson', () => {
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 verified data button is disabled once again for salesPerson', () => {
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 have been disabled 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).toContain('is-disabled');
});
it('should confirm the form have been disabled 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).toContain('is-disabled');
});
});
});

View File

@ -1,7 +1,7 @@
import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/helpers';
describe('mandate path', () => {
describe('invoice path', () => {
const nightmare = createNightmare();
beforeAll(() => {
@ -51,7 +51,6 @@ describe('mandate path', () => {
.getInnerText(selectors.clientInvoices.firstInvoiceText)
.then(value => {
expect(value).toContain('V1800001');
expect(value).toContain('02/03/2018');
expect(value).toContain('350.50');
});
});

View File

@ -48,6 +48,7 @@ describe('Item summary path', () => {
it(`should check the item summary preview shows fields from basic data`, () => {
return nightmare
.waitForTextInElement(selectors.itemSummary.basicData, 'Name: Gem of Time')
.getInnerText(selectors.itemSummary.basicData)
.then(result => {
expect(result).toContain('Name: Gem of Time');
@ -56,7 +57,7 @@ describe('Item summary path', () => {
it(`should check the item summary preview shows fields from tags`, () => {
return nightmare
.wait(200)
.waitForTextInElement(selectors.itemSummary.tags, 'Color: Yellow')
.getInnerText(selectors.itemSummary.tags)
.then(result => {
expect(result).toContain('Color: Yellow');
@ -65,6 +66,7 @@ describe('Item summary path', () => {
it(`should check the item summary preview shows fields from niche`, () => {
return nightmare
.waitForTextInElement(selectors.itemSummary.niche, 'Warehouse One: A1')
.getInnerText(selectors.itemSummary.niche)
.then(result => {
expect(result).toContain('Warehouse One: A1');
@ -73,6 +75,7 @@ describe('Item summary path', () => {
it(`should check the item summary preview shows fields from botanical`, () => {
return nightmare
.waitForTextInElement(selectors.itemSummary.botanical, 'Botanical: Hedera helix')
.getInnerText(selectors.itemSummary.botanical)
.then(result => {
expect(result).toContain('Botanical: Hedera helix');
@ -81,6 +84,7 @@ describe('Item summary path', () => {
it(`should check the item summary preview shows fields from barcode`, () => {
return nightmare
.waitForTextInElement(selectors.itemSummary.barcode, '1')
.getInnerText(selectors.itemSummary.barcode)
.then(result => {
expect(result).toContain('1');
@ -108,6 +112,7 @@ describe('Item summary path', () => {
it(`should check the item summary shows fields from all its sections`, () => {
return nightmare
.waitForTextInElement(selectors.itemSummary.basicData, 'Name: Gem of Time')
.getInnerText(selectors.itemSummary.basicData)
.then(result => {
expect(result).toContain('Name: Gem of Time');

View File

@ -69,7 +69,6 @@ describe('edit item basic data path', () => {
.click(selectors.itemNiches.firstCodeInput)
.wait(selectors.itemNiches.firstCodeInput)
.waitToClick(selectors.itemBasicData.basicDataButton)
.wait(200)
.getInputValue(selectors.itemBasicData.nameInput)
.then(result => {
expect(result).toEqual('Rose of Purity');

View File

@ -63,7 +63,7 @@ describe('add item tax path', () => {
.click(selectors.itemTags.tagsButton)
.wait(selectors.itemTags.firstTagSelect)
.waitToClick(selectors.itemTax.taxButton)
.wait(200)
.waitForTextInInput(selectors.itemTax.firstClassSelect, 'general')
.getInputValue(selectors.itemTax.firstClassSelect)
.then(result => {
expect(result).toEqual('General VAT');

View File

@ -71,7 +71,7 @@ describe('create item tags path', () => {
.click(selectors.itemBasicData.basicDataButton)
.wait(selectors.itemBasicData.nameInput)
.click(selectors.itemTags.tagsButton)
.wait(200)
.waitForTextInInput(selectors.itemTags.firstTagSelect, 'Owner')
.getInputValue(selectors.itemTags.firstTagSelect)
.then(result => {
expect(result).toEqual('Owner');
@ -80,6 +80,7 @@ describe('create item tags path', () => {
it(`should confirm the first value is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.firstValueInput, 'Thanos')
.getInputValue(selectors.itemTags.firstValueInput)
.then(result => {
expect(result).toEqual('Thanos');
@ -88,6 +89,7 @@ describe('create item tags path', () => {
it(`should confirm the first relevancy is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.firstRelevancyInput, '1')
.getInputValue(selectors.itemTags.firstRelevancyInput)
.then(result => {
expect(result).toEqual('1');
@ -96,6 +98,7 @@ describe('create item tags path', () => {
it(`should confirm the second select is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.secondTagSelect, 'Color')
.getInputValue(selectors.itemTags.secondTagSelect)
.then(result => {
expect(result).toEqual('Color');
@ -104,6 +107,7 @@ describe('create item tags path', () => {
it(`should confirm the second value is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.secondValueInput, 'Dark Blue')
.getInputValue(selectors.itemTags.secondValueInput)
.then(result => {
expect(result).toEqual('Dark Blue');
@ -112,6 +116,7 @@ describe('create item tags path', () => {
it(`should confirm the second relevancy is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.secondRelevancyInput, '2')
.getInputValue(selectors.itemTags.secondRelevancyInput)
.then(result => {
expect(result).toEqual('2');
@ -120,6 +125,7 @@ describe('create item tags path', () => {
it(`should confirm the third select is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.thirdTagSelect, 'Shape')
.getInputValue(selectors.itemTags.thirdTagSelect)
.then(result => {
expect(result).toEqual('Shape');
@ -128,6 +134,7 @@ describe('create item tags path', () => {
it(`should confirm the third value is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.thirdValueInput, 'round')
.getInputValue(selectors.itemTags.thirdValueInput)
.then(result => {
expect(result).toEqual('round');
@ -136,6 +143,7 @@ describe('create item tags path', () => {
it(`should confirm the third relevancy is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.thirdRelevancyInput, '3')
.getInputValue(selectors.itemTags.thirdRelevancyInput)
.then(result => {
expect(result).toEqual('3');
@ -144,6 +152,7 @@ describe('create item tags path', () => {
it(`should confirm the fourth select is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.fourthTagSelect, 'Power')
.getInputValue(selectors.itemTags.fourthTagSelect)
.then(result => {
expect(result).toEqual('Power');
@ -152,6 +161,7 @@ describe('create item tags path', () => {
it(`should confirm the fourth value is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.fourthValueInput, 'Manipulates time')
.getInputValue(selectors.itemTags.fourthValueInput)
.then(result => {
expect(result).toEqual('Manipulates time');
@ -160,6 +170,7 @@ describe('create item tags path', () => {
it(`should confirm the fourth relevancy is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.fourthRelevancyInput, '4')
.getInputValue(selectors.itemTags.fourthRelevancyInput)
.then(result => {
expect(result).toEqual('4');
@ -168,6 +179,7 @@ describe('create item tags path', () => {
it(`should confirm the fifth select is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.fifthTagSelect, 'Location')
.getInputValue(selectors.itemTags.fifthTagSelect)
.then(result => {
expect(result).toEqual('Location');
@ -176,6 +188,7 @@ describe('create item tags path', () => {
it(`should confirm the fifth value is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.fifthValueInput, 'Gamoras hideout')
.getInputValue(selectors.itemTags.fifthValueInput)
.then(result => {
expect(result).toEqual('Gamoras hideout');
@ -184,6 +197,7 @@ describe('create item tags path', () => {
it(`should confirm the fifth relevancy is the expected one`, () => {
return nightmare
.waitForTextInInput(selectors.itemTags.fifthRelevancyInput, '5')
.getInputValue(selectors.itemTags.fifthRelevancyInput)
.then(result => {
expect(result).toEqual('5');

View File

@ -49,11 +49,11 @@ describe('create item niche path', () => {
.waitToClick(selectors.itemNiches.firstWarehouseSelect)
.waitToClick(selectors.itemNiches.firstWarehouseSelectSecondOption)
.clearInput(selectors.itemNiches.firstCodeInput)
.type(selectors.itemNiches.firstCodeInput, 'New Location')
.type(selectors.itemNiches.firstCodeInput, 'A2')
.waitToClick(selectors.itemNiches.secondNicheRemoveButton)
.waitToClick(selectors.itemNiches.thirdWarehouseSelect)
.waitToClick(selectors.itemNiches.thirdWarehouseSelectFourthOption)
.type(selectors.itemNiches.thirdCodeInput, 'a code')
.type(selectors.itemNiches.thirdCodeInput, 'A4')
.click(selectors.itemNiches.submitNichesButton)
.waitForSnackbar()
.then(result => {
@ -61,15 +61,46 @@ describe('create item niche path', () => {
});
});
it(`should confirm the remaining niches are for the second third and fourth warehouses`, () => {
it(`should confirm the first niche is the expected one`, () => {
return nightmare
.click(selectors.itemBasicData.basicDataButton)
.wait(selectors.itemBasicData.nameInput)
.click(selectors.itemNiches.nicheButton)
.wait(200)
.getInputValue(selectors.itemNiches.thirdCodeInput)
.waitForTextInInput(selectors.itemNiches.firstWarehouseSelect, 'Warehouse Two')
.getInputValue(selectors.itemNiches.firstWarehouseSelect)
.then(result => {
expect(result).toEqual('a code');
expect(result).toEqual('Warehouse Two');
return nightmare
.getInputValue(selectors.itemNiches.firstCodeInput);
})
.then(result => {
expect(result).toEqual('A2');
});
});
it(`should confirm the second niche is the expected one`, () => {
return nightmare
.getInputValue(selectors.itemNiches.secondWarehouseSelect)
.then(result => {
expect(result).toEqual('Warehouse Three');
return nightmare
.getInputValue(selectors.itemNiches.secondCodeInput);
})
.then(result => {
expect(result).toEqual('A3');
});
});
it(`should confirm the third niche is the expected one`, () => {
return nightmare
.getInputValue(selectors.itemNiches.thirdWarehouseSelect)
.then(result => {
expect(result).toEqual('Warehouse Four');
return nightmare
.getInputValue(selectors.itemNiches.thirdCodeInput);
})
.then(result => {
expect(result).toEqual('A4');
});
});
});

View File

@ -57,37 +57,36 @@ describe('create item botanical path', () => {
});
});
it(`should confirm the botanical for item 5 was created`, () => {
it(`should confirm the botanical for item Mjolnir was created`, () => {
return nightmare
.click(selectors.itemBasicData.basicDataButton)
.wait(selectors.itemBasicData.nameInput)
.click(selectors.itemBotanical.botanicalButton)
.wait(200)
.waitForTextInInput(selectors.itemBotanical.botanicalInput, 'Cicuta maculata')
.getInputValue(selectors.itemBotanical.botanicalInput)
.then(result => {
expect(result).toEqual('Cicuta maculata');
});
});
it(`should confirm the Genus for item 5 was created`, () => {
it(`should confirm the Genus for item Mjolnir was created`, () => {
return nightmare
.wait(200)
.waitForTextInInput(selectors.itemBotanical.genusSelect, 'Abelia')
.getInputValue(selectors.itemBotanical.genusSelect)
.then(result => {
expect(result).toEqual('Abelia');
});
});
it(`should confirm the Species for item 5 was created`, () => {
it(`should confirm the Species for item Mjolnir was created`, () => {
return nightmare
.wait(200)
.getInputValue(selectors.itemBotanical.speciesSelect)
.then(result => {
expect(result).toEqual('dealbata');
});
});
it(`should edit botanical for the item with id Mjolnir`, () => {
it(`should edit botanical for the item Mjolnir`, () => {
return nightmare
.clearInput(selectors.itemBotanical.botanicalInput)
.type(selectors.itemBotanical.botanicalInput, 'Herp Derp')
@ -102,30 +101,29 @@ describe('create item botanical path', () => {
});
});
it(`should confirm the botanical for item 5 was edited`, () => {
it(`should confirm the botanical for item Mjolnir was edited`, () => {
return nightmare
.click(selectors.itemBasicData.basicDataButton)
.wait(selectors.itemBasicData.nameInput)
.click(selectors.itemBotanical.botanicalButton)
.wait(200)
.waitForTextInInput(selectors.itemBotanical.botanicalInput, 'Herp Derp')
.getInputValue(selectors.itemBotanical.botanicalInput)
.then(result => {
expect(result).toEqual('Herp Derp');
});
});
it(`should confirm the Genus for item 5 was edited`, () => {
it(`should confirm the Genus for item Mjolnir was edited`, () => {
return nightmare
.wait(200)
.waitForTextInInput(selectors.itemBotanical.genusSelect, 'Abies')
.getInputValue(selectors.itemBotanical.genusSelect)
.then(result => {
expect(result).toEqual('Abies');
});
});
it(`should confirm the Species for item 5 was edited`, () => {
it(`should confirm the Species for item Mjolnir was edited`, () => {
return nightmare
.wait(200)
.getInputValue(selectors.itemBotanical.speciesSelect)
.then(result => {
expect(result).toEqual('decurrens');

View File

@ -61,7 +61,7 @@ describe('create item barcodes path', () => {
.click(selectors.itemBasicData.basicDataButton)
.wait(selectors.itemBasicData.nameInput)
.click(selectors.itemBarcodes.barcodeButton)
.wait(200)
.waitForTextInInput(selectors.itemBarcodes.thirdCodeInput, '5')
.getInputValue(selectors.itemBarcodes.thirdCodeInput)
.then(result => {
expect(result).toEqual('5');

View File

@ -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');
});
});
});

View File

@ -1,7 +1,6 @@
require('require-yaml');
const gulp = require('gulp');
const runSequence = require('run-sequence');
const gulpEnv = require('gulp-env');
const fs = require('fs-extra');
const exec = require('child_process').exec;
const PluginError = require('plugin-error');
@ -28,7 +27,6 @@ let devServerPort = wpConfig.devServerPort;
let nginxDir = `${servicesDir}/nginx`;
let proxyConf = require(`${nginxDir}/config.yml`);
let proxyEnvFile = `${nginxDir}/config.${env}.yml`;
let environmentFile = './.env.json';
if (fs.existsSync(proxyEnvFile))
Object.assign(proxyConf, require(proxyEnvFile));
@ -39,24 +37,18 @@ let defaultPort = proxyConf.defaultPort;
// Development
gulp.task('default', () => {
return gulp.start('environment', 'services', 'client');
return gulp.start('services', 'client');
});
gulp.task('client', ['build-clean'], async () => {
await runSequenceP(['routes', 'locales'], 'watch', 'webpack-dev-server');
});
gulp.task('environment', () => {
gulpEnv({
file: environmentFile,
});
});
/**
* Starts all backend services, including the nginx proxy and the database.
*/
gulp.task('services', async () => {
await runSequenceP('environment', 'docker-start', 'services-only', 'nginx');
await runSequenceP('docker-start', 'services-only', 'nginx');
});
/**
@ -75,6 +67,10 @@ gulp.task('e2e', ['docker-rebuild'], async () => {
await runSequenceP('e2e-only');
});
gulp.task('smokes', ['docker-rebuild'], async () => {
await runSequenceP('smokes-only');
});
/**
* Runs the e2e tests.
*/
@ -84,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.
*/
@ -399,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', ['environment'], async () => {
gulp.task('docker', async () => {
try {
await execP('docker rm -f dblocal');
} catch (e) {}
@ -442,10 +444,10 @@ gulp.task('docker-run', async () => {
try {
await execP('docker image inspect -f "{{json .Id}}" dblocal');
} catch (err) {
await execP(`docker build -t dblocal:latest --build-arg rootPassword=${process.env.salixPassword} ./services/db`);
await execP('docker build -t dblocal:latest ./services/db');
}
await execP(`docker run -d --name dblocal -p ${process.env.salixPort}:${process.env.salixPort} dblocal`);
await execP('docker run -d --name dblocal -p 3306:3306 dblocal');
await runSequenceP('docker-wait');
});
@ -459,7 +461,6 @@ gulp.task('docker-wait', callback => {
let elapsedTime = 0;
let maxInterval = 30 * 60;
console.log('process', process.env.salixPassword);
log('Waiting for MySQL init process...');
checker();
@ -478,10 +479,8 @@ gulp.task('docker-wait', callback => {
return callback(new Error('Docker exited, please see the docker logs for more info'));
let conn = mysql.createConnection({
host: process.env.salixHost,
port: process.env.salixPort,
user: process.env.salixUser,
password: process.env.salixPassword
host: 'localhost',
user: 'root'
});
conn.on('error', () => {});
conn.connect(err => {

View File

@ -44,7 +44,6 @@
"file-loader": "^1.1.6",
"gulp": "^3.9.1",
"gulp-concat": "^2.6.0",
"gulp-env": "^0.4.0",
"gulp-extend": "^0.2.0",
"gulp-install": "^1.1.0",
"gulp-jasmine": "^3.0.0",

View File

@ -3,18 +3,16 @@ const routes = require('../routes');
const restoreFixtures = require('../../../../../services/db/testing_fixtures');
describe('Auth routes', () => {
let fixturesToApply = {tables: ['`salix`.`user`'], inserts: [
`INSERT INTO salix.user(id,username,password,email)
VALUES
(10, 'JessicaJones', 'ac754a330530832ba1bf7687f577da91', 'JessicaJones@verdnatura.es');`
]};
let sqlStatements = {deletes: `
DELETE FROM salix.user WHERE id = 102;
`, inserts: ``, updates: ``};
beforeEach(done => {
restoreFixtures(fixturesToApply, done);
beforeEach(() => {
restoreFixtures(sqlStatements);
});
afterAll(done => {
restoreFixtures(fixturesToApply, done);
afterAll(() => {
restoreFixtures(sqlStatements);
});
let User = app.models.User;
@ -33,9 +31,23 @@ describe('Auth routes', () => {
req = {body: {}};
});
describe('when the user doesnt exist but the client does and the password is correct', () => {
it('should create the user login and return the token', done => {
spyOn(User, 'upsertWithWhere').and.callThrough();
req.body.user = 'PetterParker';
req.body.password = 'nightmare';
res.json = response => {
expect(User.upsertWithWhere).toHaveBeenCalledWith(jasmine.any(Object), jasmine.any(Object), jasmine.any(Function));
expect(response.token).toBeDefined();
done();
};
loginFunction(req, res);
});
});
describe('when the user exists and the password is correct', () => {
it('should login and return the token', done => {
req.body.user = 'JessicaJones';
req.body.user = 'developer';
req.body.password = 'nightmare';
res.json = response => {
expect(response.token).toBeDefined();
@ -44,22 +56,8 @@ describe('Auth routes', () => {
loginFunction(req, res);
});
describe('when the user doesnt exist but the client does and the password is correct', () => {
it('should create the user login and return the token', done => {
spyOn(User, 'upsertWithWhere').and.callThrough();
req.body.user = 'PetterParker';
req.body.password = 'nightmare';
res.json = response => {
expect(User.upsertWithWhere).toHaveBeenCalledWith(jasmine.any(Object), jasmine.any(Object), jasmine.any(Function));
expect(response.token).toBeDefined();
done();
};
loginFunction(req, res);
});
});
it('should define the url to continue upon login', done => {
req.body.user = 'JessicaJones';
req.body.user = 'developer';
req.body.password = 'nightmare';
req.body.location = 'http://localhost:5000/auth/?apiKey=salix&continue="continueURL"';
res.json = response => {
@ -70,7 +68,7 @@ describe('Auth routes', () => {
});
it('should define the loginUrl upon login', done => {
req.body.user = 'JessicaJones';
req.body.user = 'developer';
req.body.password = 'nightmare';
req.body.location = 'http://localhost:5000/auth/?apiKey=salix';
res.json = response => {

View File

@ -14,17 +14,29 @@
"description": "Identifier"
},
"started": {
"type": "date"
"type": "date",
"required": true,
"mysql": {
"columnName": "dateStart"
}
},
"ended": {
"type": "date"
"finished": {
"type": "date",
"mysql": {
"columnName": "dateEnd"
}
}
},
"relations": {
"client": {
"type": "belongsTo",
"model": "Client",
"foreignKey": "clientFk"
"foreignKey": "client"
},
"creditInsurance": {
"type": "hasMany",
"model": "CreditInsurance",
"foreignKey": "creditClassification"
}
}
}
}

View File

@ -0,0 +1,36 @@
{
"name": "CreditInsurance",
"description": "Credit insurance",
"base": "VnModel",
"options": {
"mysql": {
"table": "creditInsurance"
}
},
"properties": {
"id": {
"id": true,
"type": "Number",
"description": "Identifier"
},
"credit": {
"type": "Number"
},
"created": {
"type": "date",
"mysql": {
"columnName": "creationDate"
}
},
"grade": {
"type": "Number"
}
},
"relations": {
"creditClassification": {
"type": "belongsTo",
"model": "CreditClassification",
"foreignKey": "creditClassification"
}
}
}

View File

@ -31,5 +31,11 @@
},
"InvoiceOut": {
"dataSource": "vn"
},
"CreditInsurance": {
"dataSource": "vn"
},
"CreditClassification": {
"dataSource": "vn"
}
}

View File

@ -22,7 +22,7 @@ USE `account`;
LOCK TABLES `role` WRITE;
/*!40000 ALTER TABLE `role` DISABLE KEYS */;
INSERT INTO `role` VALUES (0,'root','Rol con todos los privilegios',0,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(1,'employee','Empleado básico',1,'2017-05-19 07:04:58','2017-11-29 10:06:31'),(2,'customer','Privilegios básicos de un cliente',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(3,'agency','Consultar tablas de predicciones de bultos',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(5,'administrative','Tareas relacionadas con la contabilidad',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(6,'guest','Privilegios para usuarios sin cuenta',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(9,'developer','Desarrolladores del sistema',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(11,'account','Privilegios relacionados con el login',0,'2017-05-19 07:04:58','2017-09-20 17:06:35'),(13,'teamBoss','Jefe de departamento',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(15,'logistic','Departamento de compras, responsables de la logistica',1,'2017-05-19 07:04:58','2018-02-12 10:50:10'),(16,'logisticBoss','Jefe del departamento de logística',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(17,'adminBoss','Jefe del departamento de administración',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(18,'salesPerson','Departamento de ventas',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(19,'salesBoss','Jefe del departamento de ventas',1,'2017-05-19 07:04:58','2017-08-16 12:38:27'),(20,'manager','Departamento de gerencia',1,'2017-06-01 14:57:02','2017-06-01 14:57:51'),(21,'salesAssistant','Jefe auxiliar de ventas',1,'2017-08-16 12:40:52','2017-08-16 12:40:52'),(22,'teamManager','Jefe de departamento con privilegios de auxiliar de venta.',1,'2017-09-07 09:08:12','2017-09-07 09:08:12'),(30,'financialBoss','Director finaciero',1,'2017-09-21 11:05:36','2017-09-21 11:05:36'),(31,'freelancer','Trabajadores por cuenta ajena',1,'2017-10-10 12:57:26','2017-10-10 12:59:27'),(32,'ett','Trabajadores de empresa temporal',1,'2017-10-10 12:58:58','2017-10-10 12:59:20'),(33,'invoicing','Personal con acceso a facturación',0,'2018-01-29 16:43:34','2018-01-29 16:43:34'),(34,'agencyBoss','Jefe/a del departamento de agencias',1,'2018-01-29 16:44:39','2018-02-23 07:58:53'),(35,'buyer','Departamento de compras',1,'2018-02-12 10:35:42','2018-02-12 10:35:42'),(36,'replenisher','Trabajadores de camara',0,'2018-02-16 14:07:10','2018-02-23 13:30:32'),(37,'hr','Gestor/a de recursos humanos',1,'2018-02-22 17:34:53','2018-02-22 17:34:53'),(38,'hrBoss','Jefe/a de recursos humanos',1,'2018-02-22 17:35:09','2018-02-22 17:35:09'),(39,'adminAssistant','Jefe auxiliar administrativo',1,'2018-02-23 10:37:36','2018-02-23 10:38:41'),(40,'handmade','Departamento de confección',1,'2018-02-23 11:14:53','2018-02-23 11:39:12'),(41,'handmadeBoss','Jefe de departamento de confección',1,'2018-02-23 11:15:09','2018-02-23 11:39:26'),(42,'artificial','Departamento de artificial',1,'2018-02-23 11:39:59','2018-02-23 11:39:59'),(43,'artificialBoss','Jefe del departamento de artificial',1,'2018-02-23 11:40:16','2018-02-23 11:40:16'),(44,'accessory','Departamento de complementos',1,'2018-02-23 11:41:12','2018-02-23 11:41:12'),(45,'accessoryBoss','Jefe del departamento de complementos',1,'2018-02-23 11:41:23','2018-02-23 11:41:23'),(47,'cooler','Empleados de cámara',1,'2018-02-23 13:08:18','2018-02-23 13:08:18'),(48,'coolerBoss','Jefe del departamento de cámara',1,'2018-02-23 13:12:01','2018-02-23 13:12:01'),(49,'production','Empleado de producción',1,'2018-02-26 15:28:23','2018-02-26 15:28:23'),(50,'productionBoss','Jefe de producción',1,'2018-02-26 15:34:12','2018-02-26 15:34:12'),(51,'marketing','Departamento de marketing',1,'2018-03-01 07:28:39','2018-03-01 07:28:39'),(52,'marketingBoss','Jefe del departamento de marketing',1,'2018-03-01 07:28:57','2018-03-01 07:28:57');
INSERT INTO `role` VALUES (0,'root','Rol con todos los privilegios',0,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(1,'employee','Empleado básico',1,'2017-05-19 07:04:58','2017-11-29 10:06:31'),(2,'customer','Privilegios básicos de un cliente',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(3,'agency','Consultar tablas de predicciones de bultos',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(5,'administrative','Tareas relacionadas con la contabilidad',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(6,'guest','Privilegios para usuarios sin cuenta',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(9,'developer','Desarrolladores del sistema',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(11,'account','Privilegios relacionados con el login',0,'2017-05-19 07:04:58','2017-09-20 17:06:35'),(13,'teamBoss','Jefe de departamento',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(15,'logistic','Departamento de compras, responsables de la logistica',1,'2017-05-19 07:04:58','2018-02-12 10:50:10'),(16,'logisticBoss','Jefe del departamento de logística',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(17,'adminBoss','Jefe del departamento de administración',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(18,'salesPerson','Departamento de ventas',1,'2017-05-19 07:04:58','2017-05-19 07:04:58'),(19,'salesBoss','Jefe del departamento de ventas',1,'2017-05-19 07:04:58','2017-08-16 12:38:27'),(20,'manager','Departamento de gerencia',1,'2017-06-01 14:57:02','2017-06-01 14:57:51'),(21,'salesAssistant','Jefe auxiliar de ventas',1,'2017-08-16 12:40:52','2017-08-16 12:40:52'),(22,'teamManager','Jefe de departamento con privilegios de auxiliar de venta.',1,'2017-09-07 09:08:12','2017-09-07 09:08:12'),(30,'financialBoss','Director finaciero',1,'2017-09-21 11:05:36','2017-09-21 11:05:36'),(31,'freelancer','Trabajadores por cuenta ajena',1,'2017-10-10 12:57:26','2017-10-10 12:59:27'),(32,'ett','Trabajadores de empresa temporal',1,'2017-10-10 12:58:58','2017-10-10 12:59:20'),(33,'invoicing','Personal con acceso a facturación',0,'2018-01-29 16:43:34','2018-01-29 16:43:34'),(34,'agencyBoss','Jefe/a del departamento de agencias',1,'2018-01-29 16:44:39','2018-02-23 07:58:53'),(35,'buyer','Departamento de compras',1,'2018-02-12 10:35:42','2018-02-12 10:35:42'),(36,'replenisher','Trabajadores de camara',0,'2018-02-16 14:07:10','2018-02-23 13:30:32'),(37,'hr','Gestor/a de recursos humanos',1,'2018-02-22 17:34:53','2018-02-22 17:34:53'),(38,'hrBoss','Jefe/a de recursos humanos',1,'2018-02-22 17:35:09','2018-02-22 17:35:09'),(39,'adminAssistant','Jefe auxiliar administrativo',1,'2018-02-23 10:37:36','2018-02-23 10:38:41'),(40,'handmade','Departamento de confección',1,'2018-02-23 11:14:53','2018-02-23 11:39:12'),(41,'handmadeBoss','Jefe de departamento de confección',1,'2018-02-23 11:15:09','2018-02-23 11:39:26'),(42,'artificial','Departamento de artificial',1,'2018-02-23 11:39:59','2018-02-23 11:39:59'),(43,'artificialBoss','Jefe del departamento de artificial',1,'2018-02-23 11:40:16','2018-02-23 11:40:16'),(44,'accessory','Departamento de complementos',1,'2018-02-23 11:41:12','2018-02-23 11:41:12'),(45,'accessoryBoss','Jefe del departamento de complementos',1,'2018-02-23 11:41:23','2018-02-23 11:41:23'),(47,'cooler','Empleados de cámara',1,'2018-02-23 13:08:18','2018-02-23 13:08:18'),(48,'coolerBoss','Jefe del departamento de cámara',1,'2018-02-23 13:12:01','2018-02-23 13:12:01'),(49,'production','Empleado de producción',1,'2018-02-26 15:28:23','2018-02-26 15:28:23'),(50,'productionBoss','Jefe de producción',1,'2018-02-26 15:34:12','2018-02-26 15:34:12'),(51,'marketing','Departamento de marketing',1,'2018-03-01 07:28:39','2018-03-01 07:28:39'),(52,'marketingBoss','Jefe del departamento de marketing',1,'2018-03-01 07:28:57','2018-03-01 07:28:57'),(53,'creditInsurance','Gestor de seguros de cambio',0,'2018-03-05 07:44:35','2018-03-05 07:44:35'),(54,'itemPicker','Sacador en cámara',1,'2018-03-05 12:08:17','2018-03-05 12:08:17'),(55,'itemPickerBoss','Jefe de sacadores',1,'2018-03-05 12:08:31','2018-03-05 12:08:31');
/*!40000 ALTER TABLE `role` ENABLE KEYS */;
UNLOCK TABLES;
@ -32,7 +32,7 @@ UNLOCK TABLES;
LOCK TABLES `roleRole` WRITE;
/*!40000 ALTER TABLE `roleRole` DISABLE KEYS */;
INSERT INTO `roleRole` VALUES (0,0),(0,1),(0,2),(0,3),(0,5),(0,6),(0,9),(0,11),(0,13),(0,15),(0,16),(0,17),(0,18),(0,19),(0,20),(0,21),(0,22),(0,30),(0,31),(0,32),(0,33),(0,34),(0,35),(0,36),(0,37),(0,38),(0,39),(0,40),(0,41),(0,42),(0,43),(0,44),(0,45),(0,47),(0,48),(0,49),(0,50),(0,51),(0,52),(1,1),(1,2),(1,3),(1,6),(1,11),(2,2),(2,6),(2,11),(3,3),(3,6),(3,11),(5,1),(5,2),(5,3),(5,5),(5,6),(5,11),(5,13),(5,18),(5,19),(5,21),(5,33),(6,6),(9,0),(9,1),(9,2),(9,3),(9,5),(9,6),(9,9),(9,11),(9,13),(9,15),(9,16),(9,17),(9,18),(9,19),(9,20),(9,21),(9,22),(9,30),(9,31),(9,32),(9,33),(9,34),(9,35),(9,36),(9,37),(9,38),(9,39),(9,40),(9,41),(9,42),(9,43),(9,44),(9,45),(9,47),(9,48),(9,49),(9,50),(9,51),(9,52),(11,6),(11,11),(13,1),(13,2),(13,3),(13,6),(13,11),(13,13),(15,1),(15,2),(15,3),(15,6),(15,11),(15,15),(15,35),(16,1),(16,2),(16,3),(16,6),(16,11),(16,13),(16,15),(16,16),(16,35),(17,1),(17,2),(17,3),(17,5),(17,6),(17,11),(17,13),(17,17),(17,18),(17,19),(17,20),(17,21),(17,33),(17,37),(17,39),(18,1),(18,2),(18,3),(18,6),(18,11),(18,18),(19,1),(19,2),(19,3),(19,6),(19,11),(19,13),(19,18),(19,19),(19,21),(20,1),(20,2),(20,3),(20,6),(20,11),(20,13),(20,20),(21,1),(21,2),(21,3),(21,6),(21,11),(21,13),(21,18),(21,21),(22,1),(22,2),(22,3),(22,6),(22,11),(22,13),(22,18),(22,21),(22,22),(30,1),(30,2),(30,3),(30,5),(30,6),(30,11),(30,13),(30,18),(30,19),(30,20),(30,21),(30,22),(30,30),(30,33),(31,1),(31,2),(31,3),(31,6),(31,11),(31,31),(32,1),(32,2),(32,3),(32,6),(32,11),(32,32),(33,33),(34,1),(34,2),(34,3),(34,6),(34,11),(34,13),(34,33),(34,34),(35,1),(35,2),(35,3),(35,6),(35,11),(35,35),(36,1),(36,2),(36,3),(36,6),(36,11),(36,36),(36,44),(36,47),(37,1),(37,2),(37,3),(37,6),(37,11),(37,37),(38,1),(38,2),(38,3),(38,6),(38,11),(38,37),(38,38),(39,1),(39,2),(39,3),(39,5),(39,6),(39,11),(39,13),(39,18),(39,19),(39,21),(39,33),(39,39),(40,1),(40,2),(40,3),(40,6),(40,11),(40,40),(41,1),(41,2),(41,3),(41,6),(41,11),(41,13),(41,40),(41,41),(42,1),(42,2),(42,3),(42,6),(42,11),(42,42),(43,1),(43,2),(43,3),(43,6),(43,11),(43,13),(43,42),(43,43),(44,1),(44,2),(44,3),(44,6),(44,11),(44,44),(45,1),(45,2),(45,3),(45,6),(45,11),(45,13),(45,44),(45,45),(47,1),(47,2),(47,3),(47,6),(47,11),(47,47),(48,1),(48,2),(48,3),(48,6),(48,11),(48,13),(48,47),(48,48),(49,1),(49,2),(49,3),(49,6),(49,11),(49,36),(49,44),(49,47),(49,49),(50,1),(50,2),(50,3),(50,6),(50,11),(50,13),(50,36),(50,44),(50,47),(50,49),(50,50),(51,1),(51,2),(51,3),(51,6),(51,11),(51,51),(52,1),(52,2),(52,3),(52,6),(52,11),(52,13),(52,51),(52,52);
INSERT INTO `roleRole` VALUES (0,0),(0,1),(0,2),(0,3),(0,5),(0,6),(0,9),(0,11),(0,13),(0,15),(0,16),(0,17),(0,18),(0,19),(0,20),(0,21),(0,22),(0,30),(0,31),(0,32),(0,33),(0,34),(0,35),(0,36),(0,37),(0,38),(0,39),(0,40),(0,41),(0,42),(0,43),(0,44),(0,45),(0,47),(0,48),(0,49),(0,50),(0,51),(0,52),(0,53),(0,54),(0,55),(1,1),(1,2),(1,3),(1,6),(1,11),(2,2),(2,6),(2,11),(3,3),(3,6),(3,11),(5,1),(5,2),(5,3),(5,5),(5,6),(5,11),(5,13),(5,18),(5,19),(5,21),(5,33),(5,53),(6,6),(9,0),(9,1),(9,2),(9,3),(9,5),(9,6),(9,9),(9,11),(9,13),(9,15),(9,16),(9,17),(9,18),(9,19),(9,20),(9,21),(9,22),(9,30),(9,31),(9,32),(9,33),(9,34),(9,35),(9,36),(9,37),(9,38),(9,39),(9,40),(9,41),(9,42),(9,43),(9,44),(9,45),(9,47),(9,48),(9,49),(9,50),(9,51),(9,52),(9,53),(9,54),(9,55),(11,6),(11,11),(13,1),(13,2),(13,3),(13,6),(13,11),(13,13),(15,1),(15,2),(15,3),(15,6),(15,11),(15,15),(15,35),(16,1),(16,2),(16,3),(16,6),(16,11),(16,13),(16,15),(16,16),(16,35),(17,1),(17,2),(17,3),(17,5),(17,6),(17,11),(17,13),(17,17),(17,18),(17,19),(17,20),(17,21),(17,33),(17,37),(17,39),(17,53),(18,1),(18,2),(18,3),(18,6),(18,11),(18,18),(19,1),(19,2),(19,3),(19,6),(19,11),(19,13),(19,18),(19,19),(19,21),(19,53),(20,1),(20,2),(20,3),(20,6),(20,11),(20,13),(20,20),(21,1),(21,2),(21,3),(21,6),(21,11),(21,13),(21,18),(21,21),(21,53),(22,1),(22,2),(22,3),(22,6),(22,11),(22,13),(22,18),(22,21),(22,22),(22,53),(30,1),(30,2),(30,3),(30,5),(30,6),(30,11),(30,13),(30,18),(30,19),(30,20),(30,21),(30,22),(30,30),(30,33),(30,53),(31,1),(31,2),(31,3),(31,6),(31,11),(31,31),(32,1),(32,2),(32,3),(32,6),(32,11),(32,32),(33,33),(34,1),(34,2),(34,3),(34,6),(34,11),(34,13),(34,33),(34,34),(35,1),(35,2),(35,3),(35,6),(35,11),(35,35),(36,1),(36,2),(36,3),(36,6),(36,11),(36,36),(36,44),(36,47),(37,1),(37,2),(37,3),(37,6),(37,11),(37,37),(38,1),(38,2),(38,3),(38,6),(38,11),(38,37),(38,38),(39,1),(39,2),(39,3),(39,5),(39,6),(39,11),(39,13),(39,18),(39,19),(39,21),(39,33),(39,39),(39,53),(40,1),(40,2),(40,3),(40,6),(40,11),(40,40),(41,1),(41,2),(41,3),(41,6),(41,11),(41,13),(41,40),(41,41),(42,1),(42,2),(42,3),(42,6),(42,11),(42,42),(43,1),(43,2),(43,3),(43,6),(43,11),(43,13),(43,42),(43,43),(44,1),(44,2),(44,3),(44,6),(44,11),(44,44),(45,1),(45,2),(45,3),(45,6),(45,11),(45,13),(45,44),(45,45),(47,1),(47,2),(47,3),(47,6),(47,11),(47,47),(48,1),(48,2),(48,3),(48,6),(48,11),(48,13),(48,47),(48,48),(49,1),(49,2),(49,3),(49,6),(49,11),(49,36),(49,44),(49,47),(49,49),(50,1),(50,2),(50,3),(50,6),(50,11),(50,13),(50,36),(50,44),(50,47),(50,49),(50,50),(51,1),(51,2),(51,3),(51,6),(51,11),(51,51),(52,1),(52,2),(52,3),(52,6),(52,11),(52,13),(52,51),(52,52),(53,1),(53,2),(53,3),(53,6),(53,11),(53,53),(54,1),(54,2),(54,3),(54,6),(54,11),(54,54),(55,1),(55,2),(55,3),(55,6),(55,11),(55,13),(55,54),(55,55);
/*!40000 ALTER TABLE `roleRole` ENABLE KEYS */;
UNLOCK TABLES;
@ -42,7 +42,7 @@ UNLOCK TABLES;
LOCK TABLES `roleInherit` WRITE;
/*!40000 ALTER TABLE `roleInherit` DISABLE KEYS */;
INSERT INTO `roleInherit` VALUES (9,0),(5,1),(13,1),(18,1),(31,1),(32,1),(34,1),(35,1),(37,1),(40,1),(42,1),(44,1),(47,1),(51,1),(1,2),(1,3),(30,5),(39,5),(11,6),(1,11),(2,11),(3,11),(16,13),(20,13),(21,13),(22,13),(34,13),(41,13),(43,13),(45,13),(48,13),(50,13),(52,13),(16,15),(21,18),(5,19),(17,20),(30,20),(19,21),(22,21),(39,21),(30,22),(5,33),(34,33),(15,35),(49,36),(17,37),(38,37),(17,39),(41,40),(43,42),(36,44),(45,44),(36,47),(48,47),(50,49),(52,51);
INSERT INTO `roleInherit` VALUES (9,0),(5,1),(13,1),(18,1),(31,1),(32,1),(34,1),(35,1),(37,1),(40,1),(42,1),(44,1),(47,1),(51,1),(53,1),(54,1),(1,2),(1,3),(30,5),(39,5),(11,6),(1,11),(2,11),(3,11),(16,13),(20,13),(21,13),(22,13),(34,13),(41,13),(43,13),(45,13),(48,13),(50,13),(52,13),(55,13),(16,15),(21,18),(5,19),(17,20),(30,20),(19,21),(22,21),(39,21),(30,22),(5,33),(34,33),(15,35),(49,36),(17,37),(38,37),(17,39),(41,40),(43,42),(36,44),(45,44),(36,47),(48,47),(50,49),(52,51),(21,53),(30,53),(55,54);
/*!40000 ALTER TABLE `roleInherit` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@ -55,7 +55,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2018-03-01 14:14:54
-- Dump completed on 2018-03-07 9:44:56
USE `salix`;
-- MySQL dump 10.13 Distrib 5.7.17, for Win64 (x86_64)
--
@ -80,7 +80,7 @@ USE `salix`;
LOCK TABLES `ACL` WRITE;
/*!40000 ALTER TABLE `ACL` DISABLE KEYS */;
INSERT INTO `ACL` VALUES (1,'Account','*','*','ALLOW','ROLE','employee'),(3,'Address','*','*','ALLOW','ROLE','employee'),(5,'AgencyService','*','READ','ALLOW','ROLE','employee'),(7,'Client','*','*','ALLOW','ROLE','employee'),(9,'ClientObservation','*','*','ALLOW','ROLE','employee'),(11,'ContactChannel','*','READ','ALLOW','ROLE','employee'),(13,'Employee','*','READ','ALLOW','ROLE','employee'),(14,'PayMethod','*','READ','ALLOW','ROLE','employee'),(16,'FakeProduction','*','READ','ALLOW','ROLE','employee'),(17,'Warehouse','* ','READ','ALLOW','ROLE','employee'),(18,'State','*','READ','ALLOW','ROLE','employee'),(20,'TicketState','*','*','ALLOW','ROLE','employee'),(24,'Delivery','*','READ','ALLOW','ROLE','employee'),(25,'Zone','*','READ','ALLOW','ROLE','employee'),(26,'ClientCredit','*','*','ALLOW','ROLE','employee'),(27,'ClientCreditLimit','*','READ','ALLOW','ROLE','employee'),(28,'ClientObservation','*','READ','ALLOW','ROLE','employee'),(30,'GreugeType','*','READ','ALLOW','ROLE','employee'),(31,'Mandate','*','READ','ALLOW','ROLE','employee'),(32,'MandateType','*','READ','ALLOW','ROLE','employee'),(33,'Company','*','READ','ALLOW','ROLE','employee'),(34,'Greuge','*','READ','ALLOW','ROLE','employee'),(35,'AddressObservation','*','*','ALLOW','ROLE','employee'),(36,'ObservationType','*','*','ALLOW','ROLE','employee'),(37,'Greuge','*','WRITE','ALLOW','ROLE','employee'),(38,'AgencyMode','*','READ','ALLOW','ROLE','employee'),(39,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(40,'ItemBotanical','*','WRITE','ALLOW','ROLE','buyer'),(41,'ItemBotanical','*','READ','ALLOW','ROLE','employee'),(42,'ItemPlacement','*','WRITE','ALLOW','ROLE','buyer'),(43,'ItemPlacement','*','WRITE','ALLOW','ROLE','replenisher'),(44,'ItemPlacement','*','READ','ALLOW','ROLE','employee'),(45,'ItemBarcode','*','READ','ALLOW','ROLE','employee'),(46,'ItemBarcode','*','WRITE','ALLOW','ROLE','buyer'),(47,'ItemBarcode','*','WRITE','ALLOW','ROLE','replenisher'),(48,'ItemNiche','*','READ','ALLOW','ROLE','employee'),(49,'ItemNiche','*','WRITE','ALLOW','ROLE','buyer'),(50,'ItemNiche','*','WRITE','ALLOW','ROLE','replenisher'),(51,'ItemTag','*','READ','ALLOW','ROLE','employee'),(52,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(53,'Item','*','READ','ALLOW','ROLE','employee'),(54,'Item','*','WRITE','ALLOW','ROLE','buyer'),(55,'Recovery','*','READ','ALLOW','ROLE','employee'),(56,'Recovery','*','WRITE','ALLOW','ROLE','administrative');
INSERT INTO `ACL` VALUES (1,'Account','*','*','ALLOW','ROLE','employee'),(3,'Address','*','*','ALLOW','ROLE','employee'),(5,'AgencyService','*','READ','ALLOW','ROLE','employee'),(7,'Client','*','*','ALLOW','ROLE','employee'),(9,'ClientObservation','*','*','ALLOW','ROLE','employee'),(11,'ContactChannel','*','READ','ALLOW','ROLE','employee'),(13,'Employee','*','READ','ALLOW','ROLE','employee'),(14,'PayMethod','*','READ','ALLOW','ROLE','employee'),(16,'FakeProduction','*','READ','ALLOW','ROLE','employee'),(17,'Warehouse','* ','READ','ALLOW','ROLE','employee'),(18,'State','*','READ','ALLOW','ROLE','employee'),(20,'TicketState','*','*','ALLOW','ROLE','employee'),(24,'Delivery','*','READ','ALLOW','ROLE','employee'),(25,'Zone','*','READ','ALLOW','ROLE','employee'),(26,'ClientCredit','*','*','ALLOW','ROLE','employee'),(27,'ClientCreditLimit','*','READ','ALLOW','ROLE','employee'),(28,'ClientObservation','*','READ','ALLOW','ROLE','employee'),(30,'GreugeType','*','READ','ALLOW','ROLE','employee'),(31,'Mandate','*','READ','ALLOW','ROLE','employee'),(32,'MandateType','*','READ','ALLOW','ROLE','employee'),(33,'Company','*','READ','ALLOW','ROLE','employee'),(34,'Greuge','*','READ','ALLOW','ROLE','employee'),(35,'AddressObservation','*','*','ALLOW','ROLE','employee'),(36,'ObservationType','*','*','ALLOW','ROLE','employee'),(37,'Greuge','*','WRITE','ALLOW','ROLE','employee'),(38,'AgencyMode','*','READ','ALLOW','ROLE','employee'),(39,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(40,'ItemBotanical','*','WRITE','ALLOW','ROLE','buyer'),(41,'ItemBotanical','*','READ','ALLOW','ROLE','employee'),(42,'ItemPlacement','*','WRITE','ALLOW','ROLE','buyer'),(43,'ItemPlacement','*','WRITE','ALLOW','ROLE','replenisher'),(44,'ItemPlacement','*','READ','ALLOW','ROLE','employee'),(45,'ItemBarcode','*','READ','ALLOW','ROLE','employee'),(46,'ItemBarcode','*','WRITE','ALLOW','ROLE','buyer'),(47,'ItemBarcode','*','WRITE','ALLOW','ROLE','replenisher'),(48,'ItemNiche','*','READ','ALLOW','ROLE','employee'),(49,'ItemNiche','*','WRITE','ALLOW','ROLE','buyer'),(50,'ItemNiche','*','WRITE','ALLOW','ROLE','replenisher'),(51,'ItemTag','*','READ','ALLOW','ROLE','employee'),(52,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(53,'Item','*','READ','ALLOW','ROLE','employee'),(54,'Item','*','WRITE','ALLOW','ROLE','buyer'),(55,'Recovery','*','READ','ALLOW','ROLE','employee'),(56,'Recovery','*','WRITE','ALLOW','ROLE','administrative'),(57,'CreditClassification','*','READ','ALLOW','ROLE','employee'),(58,'CreditClassification','*','WRITE','ALLOW','ROLE','creditInsurance'),(59,'CreditInsurance','*','READ','ALLOW','ROLE','employee'),(60,'CreditInsurance','*','WRITE','ALLOW','ROLE','creditInsurance'),(61,'InvoiceOut','*','READ','ALLOW','ROLE','employee');
/*!40000 ALTER TABLE `ACL` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@ -93,7 +93,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2018-03-01 14:14:54
-- Dump completed on 2018-03-07 9:44:57
USE `vn`;
-- MySQL dump 10.13 Distrib 5.7.17, for Win64 (x86_64)
--
@ -151,4 +151,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2018-03-01 14:14:55
-- Dump completed on 2018-03-07 9:44:57

View File

@ -2,5 +2,5 @@
for file in changes/*/*.sql; do
echo "Importing $file"
mysql -u root -p$salixPassword < $file
mysql -u root < $file
done

View File

@ -1,27 +1,38 @@
INSERT INTO `util`.`config` ( `dbVersion`, `hasTriggersDisabled`, `environment`)
VALUES ('1.0.0', '0', 'development');
INSERT INTO `account`.`user`(`name`,`password`,`role`,`active`,`email`)
SELECT name, MD5('nightmare'), id, 1, CONCAT(name, '@verdnatura.es')
INSERT INTO `account`.`user`(`id`,`name`,`password`,`role`,`active`,`email`)
SELECT id,name, MD5('nightmare'), id, 1, CONCAT(name, '@verdnatura.es')
FROM `account`.`role`;
INSERT INTO `vn`.`worker`(`workerCode`, `firstName`, `name`, `userFk`)
SELECT UPPER(LPAD(role, 3, '0')), name, name, id
INSERT INTO `vn`.`worker`(`id`,`workerCode`, `firstName`, `name`, `userFk`)
SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id
FROM `vn`.`user`;
DELETE FROM `vn`.`worker` where name ='customer';
INSERT INTO `account`.`user`(`id`,`name`,`password`,`role`,`active`,`email`)
VALUES
(1, 'BruceWayne', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'BruceWayne@verdnatura.es'),
(2, 'PetterParker', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'PetterParker@verdnatura.es'),
(3, 'ClarkKent', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'ClarkKent@verdnatura.es'),
(4, 'TonyStark', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'TonyStark@verdnatura.es'),
(5, 'MaxEisenhardt', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'MaxEisenhardt@verdnatura.es'),
(6, 'DavidCharlesHaller', 'ac754a330530832ba1bf7687f577da91', 18, 1, 'DavidCharlesHaller@verdnatura.es'),
(7, 'HankPym', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'HankPym@verdnatura.es'),
(8, 'CharlesXavier', 'ac754a330530832ba1bf7687f577da91', 18, 1, 'CharlesXavier@verdnatura.es'),
(9, 'BruceBanner', 'ac754a330530832ba1bf7687f577da91', 18, 1, 'BruceBanner@verdnatura.es'),
(10, 'JessicaJones', 'ac754a330530832ba1bf7687f577da91', 9, 1, 'JessicaJones@verdnatura.es'),
(11, 'Cyborg', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'cyborg@verdnatura.es');
(101, 'BruceWayne', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'BruceWayne@verdnatura.es'),
(102, 'PetterParker', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'PetterParker@verdnatura.es'),
(103, 'ClarkKent', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'ClarkKent@verdnatura.es'),
(104, 'TonyStark', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'TonyStark@verdnatura.es'),
(105, 'MaxEisenhardt', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'MaxEisenhardt@verdnatura.es'),
(106, 'DavidCharlesHaller', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'DavidCharlesHaller@verdnatura.es'),
(107, 'HankPym', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'HankPym@verdnatura.es'),
(108, 'CharlesXavier', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'CharlesXavier@verdnatura.es'),
(109, 'BruceBanner', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'BruceBanner@verdnatura.es'),
(110, 'JessicaJones', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'JessicaJones@verdnatura.es');
INSERT INTO `vn`.`worker`(`workerCode`, `id`, `firstName`, `name`, `userFk`)
VALUES
('LGN', 106, 'David Charles', 'Haller', 106),
('ANT', 107, 'Hank', 'Pym', 107),
('DCX', 108, 'Charles', 'Xavier', 108),
('HLK', 109, 'Bruce', 'Banner', 109),
('JJJ', 110, 'Jessica', 'Jones', 110);
INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`)
VALUES
@ -109,15 +120,6 @@ INSERT INTO `vn`.`cplusTerIdNif`(`id`, `description`)
VALUES
(1, 'NIF');
INSERT INTO `vn`.`worker`(`workerCode`, `id`, `firstName`, `name`, `userFk`)
VALUES
('LGN', 1, 'David Charles', 'Haller', 6),
('ANT', 2, 'Hank', 'Pym', 7),
('DCX', 3, 'Charles', 'Xavier', 8),
('HLK', 4, 'Bruce', 'Banner', 9),
('JJJ', 5, 'Jessica', 'Jones', 10),
('VSC', 20, 'Victor', 'Stone', 11);
INSERT INTO `vn`.`contactChannel`(`id`, `name`)
VALUES
(1, 'Rumors on the streets'),
@ -128,84 +130,85 @@ INSERT INTO `vn`.`contactChannel`(`id`, `name`)
INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city`,`postcode`,`phone`,`mobile`,`fax`,`isRelevant`,`email`,`iban`,`dueDay`,`accountingAccount`,`isEqualizated`,`provinceFk`,`hasToInvoice`,`credit`,`countryFk`,`isActive`,`gestdocFk`,`quality`,`payMethodFk`,`created`,`isToBeMailed`,`contactChannelFk`,`hasSepaVnl`,`hasCoreVnl`,`hasCoreVnh`,`riskCalculated`,`clientTypeFk`,`mailAddress`,`cplusTerIdNifFk`,`hasToInvoiceByAddress`,`isTaxDataChecked`,`isFreezed`,`creditInsurance`,`isCreatedAsServed`,`hasInvoiceSimplified`,`salesPersonFk`,`isVies`,`eypbc`)
VALUES
(1, 'Bruce Wayne', '74451390E', 'Batman', 'Alfred', '1007 Mountain Drive, Gotham', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceWayne@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 1, 0, 1),
(2, 'Petter Parker', '87945234L', 'Spider-Man', 'Aunt May', '20 Ingram Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'PetterParker@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 1, NULL, 0, 0, 1, 0, 1),
(3, 'Clark Kent', '06815934E', 'Super-Man', 'lois lane', '344 Clinton Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'ClarkKent@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 1, 0, 1),
(4, 'Tony Stark', '06089160W', 'Iron-Man', 'Pepper Potts', '10880 Malibu Point', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'TonyStark@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 1, 0, 1),
(5, 'Max Eisenhardt', '39182496H', 'Magneto', 'Rogue', 'Unknown Whereabouts', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'MaxEisenhardt@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 3, 0, 1),
(6, 'DavidCharlesHaller', '53136686Q', 'Legion', 'Charles Xavier', 'Evil hideout', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'DavidCharlesHaller@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 3, 0, 1),
(7, 'Hank Pym', '09854837G', 'Ant-Man', 'Hawk', 'Anthill', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'HankPym@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 3, 0, 1),
(8, 'Charles Xavier', '22641921P', 'Professor X', 'Beast', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'CharlesXavier@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 4, 0, 1),
(9, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceBanner@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 1, NULL, 0, 0, 4, 0, 1),
(10, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'JessicaJones@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 4, 0, 1);
(101, 'Bruce Wayne', '74451390E', 'Batman', 'Alfred', '1007 Mountain Drive, Gotham', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceWayne@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 18, 0, 1),
(102, 'Petter Parker', '87945234L', 'Spider-Man', 'Aunt May', '20 Ingram Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'PetterParker@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 1, NULL, 0, 0, 18, 0, 1),
(103, 'Clark Kent', '06815934E', 'Super-Man', 'lois lane', '344 Clinton Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'ClarkKent@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 18, 0, 1),
(104, 'Tony Stark', '06089160W', 'Iron-Man', 'Pepper Potts', '10880 Malibu Point', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'TonyStark@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 18, 0, 1),
(105, 'Max Eisenhardt', '39182496H', 'Magneto', 'Rogue', 'Unknown Whereabouts', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'MaxEisenhardt@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 18, 0, 1),
(106, 'DavidCharlesHaller', '53136686Q', 'Legion', 'Charles Xavier', 'Evil hideout', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'DavidCharlesHaller@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1),
(107, 'Hank Pym', '09854837G', 'Ant-Man', 'Hawk', 'Anthill', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'HankPym@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1),
(108, 'Charles Xavier', '22641921P', 'Professor X', 'Beast', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'CharlesXavier@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1),
(109, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceBanner@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 1, NULL, 0, 0, 19, 0, 1),
(110, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'JessicaJones@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 0, 1, NULL, 0, 0, 19, 0, 1);
INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `isDefaultAddress`, `clientFk`, `agencyModeFk`, `longitude`, `latitude`, `isEqualizated`)
VALUES
(101, '01', 'Somewhere in Thailand', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(102, '02', 'Somewhere in Poland', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(103, '03', 'Somewhere in Japan', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(104, '04', 'Somewhere in Spain', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(105, '05', 'Somewhere in Potugal', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(106, '06', 'Somewhere in UK', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(107, '07', 'Somewhere in Valencia', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(108, '08', 'Somewhere in Silla', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(109, '09', 'Somewhere in London', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(110, '10', 'Somewhere in Algemesi', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(111, '11', 'Somewhere in Carlet', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(112, '12', 'Somewhere in Campanar', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(113, '13', 'Somewhere in Malilla', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(114, '14', 'Somewhere in France', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(115, '15', 'Somewhere in Birmingham', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(116, '16', 'Somewhere in Scotland', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(117, '17', 'Somewhere in nowhere', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(118, '18', 'Somewhere over the rainbow', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(119, '19', 'Somewhere in Alberic', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(120, '20', 'Somewhere in Montortal', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(121, 'my other address', 'NY roofs', 'Silla', 46460, 1, NULL, NULL, 1, 1, 2, 2, NULL, NULL, 0),
(122, 'my other address', 'The phone box', 'Silla', 46460, 1, NULL, NULL, 1, 1, 3, 2, NULL, NULL, 0),
(123, 'my other address', 'Stark tower', 'Silla', 46460, 1, NULL, NULL, 1, 1, 4, 2, NULL, NULL, 0),
(124, 'my other address', 'The plastic cell', 'Silla', 46460, 1, NULL, NULL, 1, 1, 5, 2, NULL, NULL, 0),
(125, 'my other address', 'Many places', 'Silla', 46460, 1, NULL, NULL, 1, 1, 6, 2, NULL, NULL, 0),
(126, 'my other address', 'Your pocket', 'Silla', 46460, 1, NULL, NULL, 1, 1, 7, 2, NULL, NULL, 0),
(127, 'my other address', 'Cerebro', 'Silla', 46460, 1, NULL, NULL, 1, 1, 8, 2, NULL, NULL, 0),
(128, 'my other address', 'Luke Cages Bar', 'Silla', 46460, 1, NULL, NULL, 1, 1, 10, 2, NULL, NULL, 0);
(101, '01', 'Somewhere in Thailand', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(102, '02', 'Somewhere in Poland', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(103, '03', 'Somewhere in Japan', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(104, '04', 'Somewhere in Spain', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(105, '05', 'Somewhere in Potugal', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(106, '06', 'Somewhere in UK', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(107, '07', 'Somewhere in Valencia', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(108, '08', 'Somewhere in Silla', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(109, '09', 'Somewhere in London', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(110, '10', 'Somewhere in Algemesi', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(111, '11', 'Somewhere in Carlet', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(112, '12', 'Somewhere in Campanar', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(113, '13', 'Somewhere in Malilla', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(114, '14', 'Somewhere in France', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(115, '15', 'Somewhere in Birmingham', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(116, '16', 'Somewhere in Scotland', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(117, '17', 'Somewhere in nowhere', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(118, '18', 'Somewhere over the rainbow', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(119, '19', 'Somewhere in Alberic', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(120, '20', 'Somewhere in Montortal', 'Silla', 46460, 1, NULL, NULL, 1, 0, 109, 2, NULL, NULL, 0),
(121, 'my other address', 'the bat cave', 'Silla', 46460, 1, NULL, NULL, 1, 0, 101, 2, NULL, NULL, 0),
(122, 'my other address', 'NY roofs', 'Silla', 46460, 1, NULL, NULL, 1, 0, 102, 2, NULL, NULL, 0),
(123, 'my other address', 'The phone box', 'Silla', 46460, 1, NULL, NULL, 1, 0, 103, 2, NULL, NULL, 0),
(124, 'my other address', 'Stark tower', 'Silla', 46460, 1, NULL, NULL, 1, 0, 104, 2, NULL, NULL, 0),
(125, 'my other address', 'The plastic cell', 'Silla', 46460, 1, NULL, NULL, 1, 0, 105, 2, NULL, NULL, 0),
(126, 'my other address', 'Many places', 'Silla', 46460, 1, NULL, NULL, 1, 0, 106, 2, NULL, NULL, 0),
(127, 'my other address', 'Your pocket', 'Silla', 46460, 1, NULL, NULL, 1, 0, 107, 2, NULL, NULL, 0),
(128, 'my other address', 'Cerebro', 'Silla', 46460, 1, NULL, NULL, 1, 0, 108, 2, NULL, NULL, 0),
(129, 'my other address', 'Luke Cages Bar', 'Silla', 46460, 1, NULL, NULL, 1, 0, 110, 2, NULL, NULL, 0);
INSERT INTO `vn`.`clientCredit`(`id`, `clientFk`, `workerFk`, `amount`, `created`)
VALUES
(1, 1, 1, 1000, DATE_ADD(CURDATE(), INTERVAL 1 MONTH)),
(2, 1, 2, 900, DATE_ADD(CURDATE(), INTERVAL 2 MONTH)),
(3, 1, 3, 800, DATE_ADD(CURDATE(), INTERVAL 3 MONTH)),
(4, 1, 4, 700, DATE_ADD(CURDATE(), INTERVAL 4 MONTH)),
(5, 1, 5, 600, DATE_ADD(CURDATE(), INTERVAL 5 MONTH)),
(6, 1, 1, 500, DATE_ADD(CURDATE(), INTERVAL 6 MONTH)),
(7, 1, 2, 400, DATE_ADD(CURDATE(), INTERVAL 7 MONTH)),
(8, 1, 3, 300, DATE_ADD(CURDATE(), INTERVAL 8 MONTH)),
(9, 1, 4, 200, DATE_ADD(CURDATE(), INTERVAL 9 MONTH)),
(10, 1, 5, 100, DATE_ADD(CURDATE(), INTERVAL 10 MONTH)),
(11, 1, 1, 50, DATE_ADD(CURDATE(), INTERVAL 11 MONTH)),
(12, 2, 2, 800, CURDATE()),
(13, 3, 3, 200, CURDATE()),
(14, 4, 4, 90, CURDATE()),
(15, 5, 5, 90, CURDATE());
(1, 101, 5, 1000, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(2, 101, 5, 900, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
(3, 101, 5, 800, DATE_ADD(CURDATE(), INTERVAL -3 MONTH)),
(4, 101, 5, 700, DATE_ADD(CURDATE(), INTERVAL -4 MONTH)),
(5, 101, 5, 600, DATE_ADD(CURDATE(), INTERVAL -5 MONTH)),
(6, 101, 5, 500, DATE_ADD(CURDATE(), INTERVAL -6 MONTH)),
(7, 101, 5, 400, DATE_ADD(CURDATE(), INTERVAL -7 MONTH)),
(8, 101, 9, 300, DATE_ADD(CURDATE(), INTERVAL -8 MONTH)),
(9, 101, 9, 200, DATE_ADD(CURDATE(), INTERVAL -9 MONTH)),
(10, 101, 9, 100, DATE_ADD(CURDATE(), INTERVAL -10 MONTH)),
(11, 101, 9, 50, DATE_ADD(CURDATE(), INTERVAL -11 MONTH)),
(12, 102, 9, 800, CURDATE()),
(13, 103, 9, 200, CURDATE()),
(14, 104, 9, 90, CURDATE()),
(15, 105, 9, 90, CURDATE());
INSERT INTO `vn`.`clientCreditLimit`(`id`, `maxAmount`, `roleFk`)
VALUES
(1, 9999999, 5),
(2, 10000, 5),
(3, 600, 5);
(1, 9999999, 20),
(2, 10000, 21),
(3, 600, 13);
INSERT INTO `vn`.`clientObservation`(`id`, `clientFk`, `workerFk`, `text`, `created`)
VALUES
(1, 1, 1, 'Madness, as you know, is like gravity, all it takes is a little push', CURDATE()),
(2, 2, 1, 'With great power, comes great responsibility', CURDATE()),
(3, 3, 2, 'this is a job for Super-Man!', CURDATE()),
(4, 4, 2, 'yes... I am Iron-Man', CURDATE()),
(5, 5, 3, 'They do understand. Our mutant powers make us superior', CURDATE()),
(6, 6, 3, 'My name is Legion, for we are many!', CURDATE()),
(7, 7, 4, 'I think our first move should be calling the Avengers..', CURDATE()),
(8, 8, 4, 'Just because someone stumbles and loses their path, does not mean they are lost forever.', CURDATE()),
(9, 9, 5, 'HULK SMASH! ...', CURDATE()),
(10, 10, 5, 'They say everyone is born a hero. But if you let it, life will push you over the line until you are the villain.', CURDATE());
(1, 101, 1, 'Madness, as you know, is like gravity, all it takes is a little push', CURDATE()),
(2, 102, 1, 'With great power, comes great responsibility', CURDATE()),
(3, 103, 3, 'this is a job for Super-Man!', CURDATE()),
(4, 104, 3, 'yes... I am Iron-Man', CURDATE()),
(5, 105, 5, 'They do understand. Our mutant powers make us superior', CURDATE()),
(6, 106, 5, 'My name is Legion, for we are many!', CURDATE()),
(7, 107, 9, 'I think our first move should be calling the Avengers..', CURDATE()),
(8, 108, 9, 'Just because someone stumbles and loses their path, does not mean they are lost forever.', CURDATE()),
(9, 109, 20, 'HULK SMASH! ...', CURDATE()),
(10, 110, 20, 'They say everyone is born a hero. But if you let it, life will push you over the line until you are the villain.', CURDATE());
INSERT INTO `vn`.`observationType`(`id`,`description`)
VALUES
@ -221,11 +224,17 @@ INSERT INTO `vn`.`observationType`(`id`,`description`)
INSERT INTO `vn`.`creditClassification`(`id`, `client`, `dateStart`, `dateEnd`)
VALUES
(1, 1, CURDATE(), CURDATE()),
(2, 2, CURDATE(), CURDATE()),
(3, 3, CURDATE(), CURDATE()),
(4, 4, CURDATE(), CURDATE()),
(5, 5, CURDATE(), CURDATE());
(1, 101, CURDATE(), CURDATE()),
(2, 102, CURDATE(), CURDATE()),
(3, 103, CURDATE(), CURDATE()),
(4, 104, CURDATE(), CURDATE()),
(5, 105, CURDATE(), CURDATE());
INSERT INTO `vn`.`creditInsurance`(`id`, `creditClassification`, `credit`, `creationDate`, `grade`)
VALUES
(1, 1 , 3000, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL),
(2, 2 , 6000, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), NULL),
(3, 3, 10000 , DATE_ADD(CURDATE(), INTERVAL -3 MONTH), NULL);
INSERT INTO `vn`.`route`(`id`, `created`)
VALUES
@ -249,20 +258,20 @@ INSERT INTO `vn2008`.`empresa_grupo`(`empresa_grupo_id`, `grupo`)
INSERT INTO `vn2008`.`empresa`(`id`, `abbreviation`, `registro`, `gerente_id`, `alta`, `baja`, `logo`, `oficial`, `cyc`, `rgb`, `mail`, `cuno`, `ODBC_DATE`, `Id_Cliente`, `digito_factura`, `Id_Proveedores_account`, `morosidad`, `empresa_grupo`)
VALUES
(442, 'WAY', 'Wayne Industries, Inc. operates as a warehouse for steel products.', '2', '1989-11-19', NULL, NULL, '1', '1', '00FF00', 'BruceWayne@verdnatura.es', NULL, '1989-08-11 12:31:22', '10', '1', NULL, '1', '1');
(442, 'WAY', 'Wayne Industries, Inc. operates as a warehouse for steel products.', '20', '1989-11-19', NULL, NULL, '1', '1', '00FF00', 'BruceWayne@verdnatura.es', NULL, '1989-08-11 12:31:22', '110', '1', NULL, '1', '1');
INSERT INTO `vn`.`ticket`(`id`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `clientFk`,`nickname`, `addressFk`)
VALUES
(1, 1, 1, NULL, CURDATE(), 1, 'Batman', 101),
(2, 1, 1, NULL, CURDATE(), 1, 'Spider-Man', 102),
(3, 2, 2, NULL, CURDATE(), 2, 'Super-Man', 103),
(4, 2, 2, NULL, CURDATE(), 2, 'Iron-Man', 104),
(5, 3, 3, NULL, CURDATE(), 3, 'Magneto', 105),
(6, 3, 3, NULL, CURDATE(), 3, 'Legion', 106),
(7, 4, 4, NULL, CURDATE(), 4, 'Ant-Man', 107),
(8, 4, 4, NULL, CURDATE(), 4, 'Professor X', 108),
(9, 5, 5, NULL, CURDATE(), 5, 'Hulk', 109),
(10, 6, 5, NULL, CURDATE(), 5, 'Jessica Jones', 110);
(1, 1, 1, NULL, CURDATE(), 101, 'Batman', 101),
(2, 1, 1, NULL, CURDATE(), 101, 'Spider-Man', 102),
(3, 2, 2, NULL, CURDATE(), 102, 'Super-Man', 103),
(4, 2, 2, NULL, CURDATE(), 102, 'Iron-Man', 104),
(5, 3, 3, NULL, CURDATE(), 103, 'Magneto', 105),
(6, 3, 3, NULL, CURDATE(), 103, 'Legion', 106),
(7, 4, 4, NULL, CURDATE(), 104, 'Ant-Man', 107),
(8, 4, 4, NULL, CURDATE(), 104, 'Professor X', 108),
(9, 5, 5, NULL, CURDATE(), 105, 'Hulk', 109),
(10, 6, 5, NULL, CURDATE(), 105, 'Jessica Jones', 110);
INSERT INTO `vn`.`ticketTracking`(`id`, `ticketFk`, `stateFk`, `workerFk`, `created`)
VALUES
@ -301,18 +310,18 @@ INSERT INTO `vn`.`greugeType`(`id`, `name`)
INSERT INTO `vn`.`greuge`(`id`, `clientFk`, `description`, `amount`, `shipped`, `created`, `greugeTypeFk`, `ticketFk`)
VALUES
(1, 1, 'some diff charges', -19.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 1, 1),
(2, 1, 'more diff charges', 60, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 2, 1),
(3, 1, 'even more! diff charges', -9.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 3, 1),
(4, 1, 'insane diff charges', 60, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 4, 1),
(5, 1, 'gargantuous diff charges', -9.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 5, 1),
(6, 1, 'diff charges', 88.30, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 6, 1),
(7, 1, 'unaffordable diff charges', -39.12, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 1, 1),
(8, 1, 'some recovery charges', 29.35, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 2, 1),
(9, 1, 'some manna charges', -9.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 3, 1),
(10, 1, 'some claim charges', 13.13, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 4, 1),
(11, 1, 'some heritage charges', -15.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 5, 1),
(12, 1, 'some miscellaneous charges', 58.00, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 6, 1);
(1, 101, 'some diff charges', -19.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 1, 1),
(2, 101, 'more diff charges', 60, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 2, 1),
(3, 101, 'even more! diff charges', -9.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 3, 1),
(4, 101, 'insane diff charges', 60, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 4, 1),
(5, 101, 'gargantuous diff charges', -9.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 5, 1),
(6, 101, 'diff charges', 88.30, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 6, 1),
(7, 101, 'unaffordable diff charges', -39.12, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 1, 1),
(8, 101, 'some recovery charges', 29.35, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 2, 1),
(9, 101, 'some manna charges', -9.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 3, 1),
(10, 101, 'some claim charges', 13.13, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 4, 1),
(11, 101, 'some heritage charges', -15.99, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 5, 1),
(12, 101, 'some miscellaneous charges', 58.00, DATE_ADD(CURDATE(), INTERVAL 1 MONTH), CURDATE(), 6, 1);
INSERT INTO `vn`.`mandateType`(`id`, `name`)
VALUES
@ -321,7 +330,7 @@ INSERT INTO `vn`.`mandateType`(`id`, `name`)
INSERT INTO `vn`.`mandate`(`id`, `clientFk`, `companyFk`, `code`, `created`, `mandateTypeFk`)
VALUES
(1, 2, 442, '1-1', CURDATE(), 2);
(1, 102, 442, '1-1', CURDATE(), 2);
INSERT INTO `vn`.`itemCategory`(`id`, `name`, `display`, `color`)
VALUES
@ -418,10 +427,6 @@ INSERT INTO `vn`.`itemBotanical`(`itemFk`, `botanical`, `genusFk`, `specieFk`)
( 3, 'Cycas revoluta', 2, NULL),
( 4, 'Polygonum', NULL, NULL);
INSERT INTO `salix`.`user`(`id`,`username`,`password`,`email`)
VALUES
(10, 'JessicaJones', 'ac754a330530832ba1bf7687f577da91', 'JessicaJones@verdnatura.es');
INSERT INTO `vn`.`tag`(`id`,`name`,`isFree`,`isQuantitatif`,`sourceTable`,`unit`)
VALUES
(1, 'Color', 0, 0, null, null),
@ -444,13 +449,13 @@ INSERT INTO `vn`.`itemLog` (`id`, `originFk`, `userFk`, `action`, `description`)
INSERT INTO `vn`.`invoiceOut`(`id`, `ref`, `serial`, `amount`, `clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `pdf`)
VALUES
( 1, 'T1111111' , 'T', 500 , 1, CURDATE(), 442, CURDATE(), CURDATE(), 8, 1),
( 2, 'V2222222' , 'V', 350.50 , 2, CURDATE(), 442, CURDATE(), CURDATE(), 8, 1),
( 3, 'E3333333' , 'E', 90.30 , 3, CURDATE(), 442, CURDATE(), CURDATE(), 8, 1);
( 1, 'T1111111' , 'T', 500 , 101, CURDATE(), 442, CURDATE(), CURDATE(), 8, 1),
( 2, 'V2222222' , 'V', 350.50 , 102, CURDATE(), 442, CURDATE(), CURDATE(), 8, 1),
( 3, 'E3333333' , 'E', 90.30 , 103, CURDATE(), 442, CURDATE(), CURDATE(), 8, 1);
INSERT INTO `vn`.`recovery`(`id`, `clientFk`, `started`, `finished`, `amount`, `period`)
VALUES
( 1, '1', CURDATE(), date_add(CURDATE(),INTERVAL 1 MONTH), 50, 7),
( 2, '2', CURDATE(), date_add(CURDATE(),INTERVAL 3 MONTH), 100, 1),
( 3, '2', CURDATE(), date_add(CURDATE(),INTERVAL 1 MONTH), 50, 7),
( 4, '3', CURDATE(), NULL, 50, 7);
( 1, 101, CURDATE(), date_add(CURDATE(),INTERVAL 1 MONTH), 50, 7),
( 2, 102, CURDATE(), date_add(CURDATE(),INTERVAL 3 MONTH), 100, 1),
( 3, 102, CURDATE(), date_add(CURDATE(),INTERVAL 1 MONTH), 50, 7),
( 4, 103, CURDATE(), NULL, 50, 7);

View File

@ -1,8 +1,6 @@
FROM mysql:5.6.37
ARG rootPassword
ENV salixPassword $rootPassword
ENV MYSQL_ROOT_PASSWORD $salixPassword
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
ENV TZ GMT-1
WORKDIR /docker-entrypoint-initdb.d

View File

@ -0,0 +1,58 @@
DROP TRIGGER IF EXISTS `vn2008`.`ClientesBeforeUpdate`;
DELIMITER $$
USE `vn2008`$$
CREATE DEFINER=`root`@`%` TRIGGER `ClientesBeforeUpdate`
BEFORE UPDATE ON `Clientes`
FOR EACH ROW
BEGIN
DECLARE vText VARCHAR(255) DEFAULT NULL;
DECLARE isAlreadyUsedIf BOOLEAN;
SELECT (COUNT(*) > 1) INTO isAlreadyUsedIf
FROM Clientes
WHERE `IF` = TRIM(NEW.`IF`);
IF isAlreadyUsedIf THEN
CALL util.throw ('Error. El NIF/CIF está repetido');
END IF;
-- Comprueba que el formato de los teléfonos es válido
IF !(NEW.telefono <=> OLD.telefono) THEN
CALL pbx.phoneIsValid (NEW.telefono);
END IF;
IF !(NEW.movil <=> OLD.movil) THEN
CALL pbx.phoneIsValid (NEW.movil);
END IF;
IF !(NEW.fax <=> OLD.fax) THEN
CALL pbx.phoneIsValid (NEW.fax);
END IF;
-- Avisar al comercial si ha llegado la documentación sepa/core
IF NEW.sepavnl AND !OLD.sepavnl THEN
SET vText = 'Sepa de VNL';
END IF;
IF NEW.corevnl AND !OLD.corevnl THEN
SET vText = 'Core de VNL';
END IF;
IF vText IS NOT NULL
THEN
INSERT INTO mail(`to`, reply_to, subject, text)
SELECT
CONCAT(IF(ac.id,name, 'jgallego'), '@verdnatura.es'),
'administracion@verdnatura.es',
CONCAT('Cliente ', NEW.Id_Cliente),
CONCAT('Recibida la documentación: ', vText)
FROM Trabajadores t
LEFT JOIN account.user u ON t.user_id = u.id AND active
LEFT JOIN account.account ac ON ac.id = u.id
WHERE t.Id_Trabajador = NEW.Id_Trabajador;
END IF;
END$$
DELIMITER ;

View File

@ -16,26 +16,23 @@ let errorHandler = callback => {
};
};
let insertFixtures = (inserts, callback) => {
connection.query(inserts[0], errorHandler(callback));
// connection.query('SET FOREIGN_KEY_CHECKS = 1');
};
let truncate = (tables, callback) => {
let truncatesSQL = tables.reduce((accumulator, currentValue, i) => {
let sql = 'TRUNCATE TABLE ' + currentValue + '; ';
return (`${accumulator}${sql}`);
}, '');
connection.query(truncatesSQL.slice(0, -2), errorHandler(callback));
let insertFixtures = async function(sqlStatements) {
try {
if (sqlStatements.deletes.length)
await connection.query(sqlStatements.deletes);
if (sqlStatements.inserts.length)
await connection.query(sqlStatements.inserts);
if (sqlStatements.updates.length)
await connection.query(sqlStatements.updates);
} catch (error) {
errorHandler(error);
}
};
connection.connect();
module.exports = function restoreFixtures(fixturesToApply, callback) {
module.exports = function restoreFixtures(sqlStatements) {
connection.query('SET FOREIGN_KEY_CHECKS = 0', () => {
truncate(fixturesToApply.tables, () => {
insertFixtures(fixturesToApply.inserts, callback);
});
insertFixtures(sqlStatements);
});
};

View File

@ -40,16 +40,17 @@ module.exports = function(Client) {
delete params.phone;
}
let keys = Object.keys(params);
if (keys.length) {
keys.forEach(
key => {
let properties = Object.keys(params);
if (properties.length) {
properties.forEach(
property => {
let propertyToBeEqual = (property === 'postcode' || property === 'fi' || property === 'id');
if (filters.where.and) {
let filter = {};
filter[key] = (key === 'postcode' || key === 'fi' || key === 'id') ? params[key] : {regexp: params[key]};
filter[property] = propertyToBeEqual ? params[property] : {regexp: params[property]};
filters.where.and.push(filter);
} else {
filters.where[key] = (key === 'postcode' || key === 'fi' || key === 'id') ? params[key] : {regexp: params[key]};
filters.where[property] = propertyToBeEqual ? params[property] : {regexp: params[property]};
}
}
);

View File

@ -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];
};
};

View File

@ -0,0 +1,50 @@
module.exports = Self => {
Self.remoteMethod('isValidClient', {
description: 'Checks if the user havent got the role employee, is active and has verified data',
accessType: 'READ',
accepts: [
{
arg: 'id',
type: 'string',
required: true,
description: 'The user id',
http: {source: 'path'}
}, {
arg: 'context',
type: 'object',
required: true,
description: 'Filter defining where',
http: function(context) {
return context.req.query;
}
}
],
returns: {
type: 'boolean',
root: true
},
http: {
path: `/:id/isValidClient`,
verb: 'GET'
}
});
Self.isValidClient = async function(id) {
let query =
`SELECT r.name
FROM salix.Account A
JOIN vn.client C ON A.id = C.id
JOIN salix.RoleMapping rm ON rm.principalId = A.id
JOIN salix.Role r ON r.id = rm.roleId
WHERE A.id = ? AND C.isActive AND C.isTaxDataChecked`;
let roleNames = await Self.rawSql(query, [id]);
if (!roleNames.length) return false;
roleNames.forEach(role => {
if (role.name === 'employee')
return false;
});
return true;
};
};

View File

@ -3,58 +3,19 @@ const catchErrors = require('../../../../../../services/utils/jasmineHelpers').c
const restoreFixtures = require('../../../../../../services/db/testing_fixtures');
describe('Client addressesPropagateRe', () => {
let fixturesToApply = {tables: ['`account`.`user`', '`vn2008`.`Clientes`', '`vn2008`.`Consignatarios`'], inserts: [
`INSERT INTO account.user(id,name,password,role,active,email)
VALUES
(1, 'BruceWayne', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'BruceWayne@verdnatura.es'),
(2, 'PetterParker', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'PetterParker@verdnatura.es'),
(3, 'ClarkKent', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'ClarkKent@verdnatura.es'),
(4, 'TonyStark', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'TonyStark@verdnatura.es'),
(5, 'MaxEisenhardt', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'MaxEisenhardt@verdnatura.es'),
(6, 'DavidCharlesHaller', 'ac754a330530832ba1bf7687f577da91', 18, 1, 'DavidCharlesHaller@verdnatura.es'),
(7, 'HankPym', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'HankPym@verdnatura.es'),
(8, 'CharlesXavier', 'ac754a330530832ba1bf7687f577da91', 18, 1, 'CharlesXavier@verdnatura.es'),
(9, 'BruceBanner', 'ac754a330530832ba1bf7687f577da91', 18, 1, 'BruceBanner@verdnatura.es'),
(10, 'JessicaJones', 'ac754a330530832ba1bf7687f577da91', 9, 1, 'JessicaJones@verdnatura.es'),
(11, 'Cyborg', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'cyborg@verdnatura.es');
INSERT INTO salix.Address(id, consignee, street, city, postcode, provinceFk, phone, mobile, isEnabled, isDefaultAddress, clientFk, defaultAgencyFk, longitude, latitude, isEqualizated)
VALUES
(1, 'Bruce Wayne', 'The Bat cave', 'Silla', 46460, 1, NULL, NULL, 1, 1, 1, 2, NULL, NULL, 0),
(2, 'Petter Parker', 'NY roofs', 'Silla', 46460, 1, NULL, NULL, 1, 1, 2, 2, NULL, NULL, 0),
(3, 'Clark Kenn', 'The phone box', 'Silla', 46460, 1, NULL, NULL, 1, 1, 3, 2, NULL, NULL, 0),
(4, 'Tony Stark', 'Stark tower', 'Silla', 46460, 1, NULL, NULL, 1, 1, 4, 2, NULL, NULL, 0),
(5, 'Max Eisenhardt', 'The plastic cell', 'Silla', 46460, 1, NULL, NULL, 1, 1, 5, 2, NULL, NULL, 0),
(6, 'David Charles Haller', 'Many places', 'Silla', 46460, 1, NULL, NULL, 1, 1, 6, 2, NULL, NULL, 0),
(7, 'Hank Pym', 'Your pocket', 'Silla', 46460, 1, NULL, NULL, 1, 1, 7, 2, NULL, NULL, 0),
(8, 'Charles Xavier', 'Cerebro', 'Silla', 46460, 1, NULL, NULL, 1, 1, 8, 2, NULL, NULL, 0),
(9, 'Bruce Banner', 'Somewhere in Thailand', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(10,'Jessica Jones', 'Luke Cages Bar', 'Silla', 46460, 1, NULL, NULL, 1, 1, 10, 2, NULL, NULL, 0);
INSERT INTO vn.client(id,name,fi,socialName,contact,street,city,postcode,phone,mobile,fax,isRelevant,email,iban,dueDay,accountingAccount,isEqualizated,provinceFk,hasToInvoice,credit,countryFk,isActive,gestdocFk,quality,payMethodFk,created,isToBeMailed,contactChannelFk,hasSepaVnl,hasCoreVnl,hasCoreVnh,riskCalculated,clientTypeFk,mailAddress,cplusTerIdNifFk,hasToInvoiceByAddress,isTaxDataChecked,isFreezed,creditInsurance,isCreatedAsServed,hasInvoiceSimplified,salesPersonFk,isVies,eypbc)
VALUES
(1, 'Bruce Wayne', '74451390E', 'Batman', 'Alfred', '1007 Mountain Drive, Gotham', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceWayne@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 1, 0, 1),
(2, 'Petter Parker', '87945234L', 'Spider-Man', 'Aunt May', '20 Ingram Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'PetterParker@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 1, 0, 1),
(3, 'Clark Kent', '06815934E', 'Super-Man', 'lois lane', '344 Clinton Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'ClarkKent@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 1, 0, 1),
(4, 'Tony Stark', '06089160W', 'Iron-Man', 'Pepper Potts', '10880 Malibu Point', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'TonyStark@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 1, 0, 1),
(5, 'Max Eisenhardt', '39182496H', 'Magneto', 'Rogue', 'Unknown Whereabouts', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'MaxEisenhardt@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 3, 0, 1),
(6, 'DavidCharlesHaller', '53136686Q', 'Legion', 'Charles Xavier', 'Evil hideout', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'DavidCharlesHaller@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 3, 0, 1),
(7, 'Hank Pym', '09854837G', 'Ant-Man', 'Hawk', 'Anthill', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'HankPym@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 3, 0, 1),
(8, 'Charles Xavier', '22641921P', 'Professor X', 'Beast', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'CharlesXavier@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 4, 0, 1),
(9, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceBanner@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 4, 0, 1),
(10, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'JessicaJones@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 4, 0, 1);`
]};
beforeEach(done => {
restoreFixtures(fixturesToApply, done);
let sqlStatements = {deletes: ``, inserts: ``, updates:
`UPDATE vn.address SET isEqualizated = 0 WHERE clientFk = 101;`
};
beforeEach(() => {
restoreFixtures(sqlStatements);
});
afterAll(done => {
restoreFixtures(fixturesToApply, done);
afterAll(() => {
restoreFixtures(sqlStatements);
});
it('should propagate the isEqualizated on both addresses of Mr Wayne', done => {
let id = 1;
let id = 101;
let data = {
isEqualizated: true
};

View File

@ -3,13 +3,13 @@ const catchErrors = require('../../../../../../services/utils/jasmineHelpers').c
describe('Client card', () => {
it('should call the card() method to receive a formated card of Bruce Wayne', done => {
let id = 1;
let id = 101;
let callback = (error, result) => {
if (error) return catchErrors(done)(error);
expect(result).toEqual(jasmine.objectContaining({
id: 1,
id: 101,
name: 'Bruce Wayne'
}));
done();

View File

@ -3,58 +3,18 @@ const catchErrors = require('../../../../../../services/utils/jasmineHelpers').c
const restoreFixtures = require('../../../../../../services/db/testing_fixtures');
describe('Client Create', () => {
let fixturesToApply = {tables: ['`account`.`user`', '`vn2008`.`Clientes`', '`vn2008`.`Consignatarios`'], inserts: [
`INSERT INTO account.user(id,name,password,role,active,email)
VALUES
(1, 'BruceWayne', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'BruceWayne@verdnatura.es'),
(2, 'PetterParker', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'PetterParker@verdnatura.es'),
(3, 'ClarkKent', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'ClarkKent@verdnatura.es'),
(4, 'TonyStark', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'TonyStark@verdnatura.es'),
(5, 'MaxEisenhardt', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'MaxEisenhardt@verdnatura.es'),
(6, 'DavidCharlesHaller', 'ac754a330530832ba1bf7687f577da91', 18, 1, 'DavidCharlesHaller@verdnatura.es'),
(7, 'HankPym', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'HankPym@verdnatura.es'),
(8, 'CharlesXavier', 'ac754a330530832ba1bf7687f577da91', 18, 1, 'CharlesXavier@verdnatura.es'),
(9, 'BruceBanner', 'ac754a330530832ba1bf7687f577da91', 18, 1, 'BruceBanner@verdnatura.es'),
(10, 'JessicaJones', 'ac754a330530832ba1bf7687f577da91', 9, 1, 'JessicaJones@verdnatura.es'),
(11, 'Cyborg', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'cyborg@verdnatura.es');
INSERT INTO account.user(name, password, role, active, email)
SELECT name, MD5('nightmare'), id, 1, CONCAT(name, '@verdnatura.es')
FROM account.role;
let sqlStatements = {deletes: `
DELETE FROM vn.address WHERE nickname = "Wade";
DELETE FROM vn.client WHERE name = "Wade";
DELETE FROM account.user WHERE name = "Deadpool";
`, inserts: ``, updates: ``};
INSERT INTO salix.Address(id, consignee, street, city, postcode, provinceFk, phone, mobile, isEnabled, isDefaultAddress, clientFk, defaultAgencyFk, longitude, latitude, isEqualizated)
VALUES
(1, 'Bruce Wayne', 'The Bat cave', 'Silla', 46460, 1, NULL, NULL, 1, 1, 1, 2, NULL, NULL, 0),
(2, 'Petter Parker', 'NY roofs', 'Silla', 46460, 1, NULL, NULL, 1, 1, 2, 2, NULL, NULL, 0),
(3, 'Clark Kenn', 'The phone box', 'Silla', 46460, 1, NULL, NULL, 1, 1, 3, 2, NULL, NULL, 0),
(4, 'Tony Stark', 'Stark tower', 'Silla', 46460, 1, NULL, NULL, 1, 1, 4, 2, NULL, NULL, 0),
(5, 'Max Eisenhardt', 'The plastic cell', 'Silla', 46460, 1, NULL, NULL, 1, 1, 5, 2, NULL, NULL, 0),
(6, 'David Charles Haller', 'Many places', 'Silla', 46460, 1, NULL, NULL, 1, 1, 6, 2, NULL, NULL, 0),
(7, 'Hank Pym', 'Your pocket', 'Silla', 46460, 1, NULL, NULL, 1, 1, 7, 2, NULL, NULL, 0),
(8, 'Charles Xavier', 'Cerebro', 'Silla', 46460, 1, NULL, NULL, 1, 1, 8, 2, NULL, NULL, 0),
(9, 'Bruce Banner', 'Somewhere in Thailand', 'Silla', 46460, 1, NULL, NULL, 1, 1, 9, 2, NULL, NULL, 0),
(10,'Jessica Jones', 'Luke Cages Bar', 'Silla', 46460, 1, NULL, NULL, 1, 1, 10, 2, NULL, NULL, 0);
INSERT INTO vn.client(id,name,fi,socialName,contact,street,city,postcode,phone,mobile,fax,isRelevant,email,iban,dueDay,accountingAccount,isEqualizated,provinceFk,hasToInvoice,credit,countryFk,isActive,gestdocFk,quality,payMethodFk,created,isToBeMailed,contactChannelFk,hasSepaVnl,hasCoreVnl,hasCoreVnh,riskCalculated,clientTypeFk,mailAddress,cplusTerIdNifFk,hasToInvoiceByAddress,isTaxDataChecked,isFreezed,creditInsurance,isCreatedAsServed,hasInvoiceSimplified,salesPersonFk,isVies,eypbc)
VALUES
(1, 'Bruce Wayne', '74451390E', 'Batman', 'Alfred', '1007 Mountain Drive, Gotham', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceWayne@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 1, 0, 1),
(2, 'Petter Parker', '87945234L', 'Spider-Man', 'Aunt May', '20 Ingram Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'PetterParker@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 1, 0, 1),
(3, 'Clark Kent', '06815934E', 'Super-Man', 'lois lane', '344 Clinton Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'ClarkKent@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 1, 0, 1),
(4, 'Tony Stark', '06089160W', 'Iron-Man', 'Pepper Potts', '10880 Malibu Point', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'TonyStark@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 1, 0, 1),
(5, 'Max Eisenhardt', '39182496H', 'Magneto', 'Rogue', 'Unknown Whereabouts', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'MaxEisenhardt@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 3, 0, 1),
(6, 'DavidCharlesHaller', '53136686Q', 'Legion', 'Charles Xavier', 'Evil hideout', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'DavidCharlesHaller@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 3, 0, 1),
(7, 'Hank Pym', '09854837G', 'Ant-Man', 'Hawk', 'Anthill', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'HankPym@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 3, 0, 1),
(8, 'Charles Xavier', '22641921P', 'Professor X', 'Beast', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'CharlesXavier@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 4, 0, 1),
(9, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceBanner@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 4, 0, 1),
(10, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'JessicaJones@verdnatura.es', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1,'0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 4, 0, 1);`
]};
beforeEach(done => {
restoreFixtures(fixturesToApply, done);
beforeAll(() => {
restoreFixtures(sqlStatements);
});
afterAll(done => {
restoreFixtures(fixturesToApply, done);
afterAll(() => {
restoreFixtures(sqlStatements);
});
let newAccountData = {

View File

@ -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();
});
});
});

View File

@ -3,7 +3,7 @@ const catchErrors = require('../../../../../../services/utils/jasmineHelpers').c
describe('Client hasCustomerRole', () => {
it('should call the hasCustomerRole() method with a customer id', done => {
let id = 1;
let id = 101;
let params = {};
let callback = (error, result) => {

View File

@ -0,0 +1,57 @@
const app = require('../../../../../client/server/server');
describe('Client isValidClient', () => {
it('should call the isValidClient() method with a client id and receive true', done => {
let id = 101;
app.models.Client.isValidClient(id)
.then(result => {
expect(result).toBeTruthy();
done();
});
});
it('should call the isValidClient() method with a employee id and receive false', done => {
let id = 1;
app.models.Client.isValidClient(id)
.then(result => {
expect(result).toBeFalsy();
done();
});
});
it('should call the isValidClient() method with a unexistant id and receive false', done => {
let id = 999999;
app.models.Client.isValidClient(id)
.then(result => {
expect(result).toBeFalsy();
done();
});
});
it('should call the isValidClient() method with a invalid id and receive false', done => {
let id = 'Pepinillos';
app.models.Client.isValidClient(id)
.then(result => {
expect(result).toBeFalsy();
done();
});
});
it('should call the isValidClient() method with a customer id which isnt active and return false', done => {
let id = '106';
app.models.Client.isValidClient(id)
.then(result => {
expect(result).toBeFalsy();
done();
});
});
it('should call the isValidClient() method with a customer id which his data isnt verified and return false', done => {
let id = '110';
app.models.Client.isValidClient(id)
.then(result => {
expect(result).toBeFalsy();
done();
});
});
});

View File

@ -7,7 +7,7 @@ describe('Client listWorkers', () => {
.then(result => {
let amountOfEmployees = Object.keys(result).length;
expect(amountOfEmployees).toEqual(6);
expect(amountOfEmployees).toEqual(37);
done();
})
.catch(catchErrors(done));

View File

@ -13,4 +13,33 @@ module.exports = function(Self) {
}
next();
});
Self.remoteMethod('getCurrentUserName', {
description: 'Gets the current user name',
accepts: [
{
arg: 'context',
type: 'object',
http: function(ctx) {
return ctx;
}
}
],
returns: {
type: 'string',
root: true
},
http: {
verb: 'GET',
path: '/getCurrentUserName'
}
});
Self.getCurrentUserName = async function(ctx) {
let filter = {fields: ['name']};
let userId = ctx.req.accessToken.userId;
let account = await Self.findById(userId, filter);
return account.name;
};
};

View File

@ -12,8 +12,10 @@ module.exports = function(Self) {
require('../methods/client/listWorkers')(Self);
require('../methods/client/filter')(Self);
require('../methods/client/hasCustomerRole')(Self);
require('../methods/client/isValidClient')(Self);
require('../methods/client/activeSalesPerson')(Self);
require('../methods/client/addressesPropagateRe')(Self);
require('../methods/client/getDebt')(Self);
// Validations
@ -97,12 +99,22 @@ module.exports = function(Self) {
throw new UserError('Unable to mark the equivalence surcharge');
}
if (changes.credit !== undefined)
if (changes.credit !== undefined) {
try {
await validateCreditChange(ctx, finalState);
} catch (e) {
throw new UserError('You are not allowed to change the credit');
}
let filter = {fields: ['id'], where: {userFk: ctx.options.accessToken.userId}};
let worker = await Self.app.models.Worker.findOne(filter);
let newCredit = {
amount: changes.credit,
clientFk: finalState.id,
workerFk: worker ? worker.id : null
};
await Self.app.models.ClientCredit.create(newCredit);
}
});
async function validateCreditChange(ctx, finalState) {

View File

@ -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"
@ -147,6 +151,11 @@
"type": "hasMany",
"model": "Address",
"foreignKey": "clientFk"
},
"greuge": {
"type": "hasMany",
"model": "Greuge",
"foreignKey": "clientFk"
}
}
}

View File

@ -1,41 +1,37 @@
{
"db": {
"name": "db",
"connector": "memory"
},
"vn": {
"name": "mysql",
"connector": "mysql",
"database": "vn",
"debug": false,
"host": "${salixHost}",
"port": "${salixPort}",
"username": "${salixUser}",
"password": "${salixPassword}",
"host": "localhost",
"port": 3306,
"username": "root",
"password": "",
"connectTimeout": 20000,
"acquireTimeout": 20000
},
"salix": {
"name": "mysql",
"connector": "mysql",
"database": "salix",
"debug": false,
"host": "${salixHost}",
"port": "${salixPort}",
"username": "${salixUser}",
"password": "${salixPassword}",
"host": "localhost",
"port": 3306,
"username": "root",
"password": "",
"connectTimeout": 20000,
"acquireTimeout": 20000
},
"account": {
"name": "mysql",
"connector": "mysql",
"database": "account",
"debug": false,
"host": "${salixHost}",
"port": "${salixPort}",
"username": "${salixUser}",
"password": "${salixPassword}",
"host": "localhost",
"port": 3306,
"username": "root",
"password": "",
"connectTimeout": 20000,
"acquireTimeout": 20000
},
@ -43,10 +39,10 @@
"connector": "mysql",
"database": "edi",
"debug": false,
"host": "${salixHost}",
"port": "${salixPort}",
"username": "${salixUser}",
"password": "${salixPassword}",
"host": "localhost",
"port": 3306,
"username": "root",
"password": "",
"connectTimeout": 20000,
"acquireTimeout": 20000
}

View File

@ -9,7 +9,6 @@ module.exports = function(options) {
if (loopbackContext) {
loopbackContext.set('currentUser', req.accessToken.userId);
}
next();
};
};

View File

@ -45,9 +45,6 @@
"Country": {
"dataSource": "vn"
},
"CreditClassification": {
"dataSource": "vn"
},
"PayMethod": {
"dataSource": "vn"
},

View File

@ -1,4 +0,0 @@
2018/03/02 09:31:59 [notice] 7044#10044: signal process started
2018/03/02 09:31:59 [notice] 3892#15188: signal process started
2018/03/02 09:39:40 [notice] 8636#14980: signal process started
2018/03/02 12:40:36 [notice] 8340#13172: signal process started

38
smokes_tests.js Normal file
View File

@ -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();