diff --git a/db/changes/233601/00-aclWorker.sql b/db/changes/233601/00-aclWorker.sql
new file mode 100644
index 000000000..e79d8f738
--- /dev/null
+++ b/db/changes/233601/00-aclWorker.sql
@@ -0,0 +1,3 @@
+INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
+ VALUES
+ ('Worker', 'search', 'READ', 'ALLOW', 'ROLE', 'employee');
diff --git a/db/changes/233601/00-department.sql b/db/changes/233601/00-department.sql
new file mode 100644
index 000000000..777d26b9f
--- /dev/null
+++ b/db/changes/233601/00-department.sql
@@ -0,0 +1,3 @@
+UPDATE `vn`.`department`
+ SET code='VN'
+WHERE name='VERDNATURA';
diff --git a/e2e/helpers/extensions.js b/e2e/helpers/extensions.js
index fe3ef08bd..b6ea32a6c 100644
--- a/e2e/helpers/extensions.js
+++ b/e2e/helpers/extensions.js
@@ -632,6 +632,7 @@ let actions = {
await this.write(selector, value.toString());
break;
case 'vn-autocomplete':
+ case 'vn-worker-autocomplete':
if (value)
await this.autocompleteSearch(selector, value.toString());
else
@@ -667,6 +668,7 @@ let actions = {
switch (tagName) {
case 'vn-textfield':
case 'vn-autocomplete':
+ case 'vn-worker-autocomplete':
case 'vn-input-time':
case 'vn-datalist':
el = await input.$('input');
diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index 93288efa7..fe3633723 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -187,7 +187,7 @@ export default {
country: 'vn-client-create vn-autocomplete[ng-model="$ctrl.client.countryFk"]',
userName: 'vn-client-create vn-textfield[ng-model="$ctrl.client.userName"]',
email: 'vn-client-create vn-textfield[ng-model="$ctrl.client.email"]',
- salesPerson: 'vn-client-create vn-autocomplete[ng-model="$ctrl.client.salesPersonFk"]',
+ salesPerson: 'vn-client-create vn-worker-autocomplete[ng-model="$ctrl.client.salesPersonFk"]',
saveNewProvicenButton: '#saveProvince',
saveNewCityButton: '#saveCity',
saveNewPoscode: '#savePostcode',
@@ -199,7 +199,7 @@ export default {
email: 'vn-client-basic-data vn-textfield[ng-model="$ctrl.client.email"]',
phone: 'vn-client-basic-data vn-textfield[ng-model="$ctrl.client.phone"]',
mobile: 'vn-client-basic-data vn-textfield[ng-model="$ctrl.client.mobile"]',
- salesPerson: 'vn-client-basic-data vn-autocomplete[ng-model="$ctrl.client.salesPersonFk"]',
+ salesPerson: 'vn-client-basic-data vn-worker-autocomplete[ng-model="$ctrl.client.salesPersonFk"]',
channel: 'vn-client-basic-data vn-autocomplete[ng-model="$ctrl.client.contactChannelFk"]',
transferor: 'vn-client-basic-data vn-autocomplete[ng-model="$ctrl.client.transferorFk"]',
businessType: 'vn-client-basic-data vn-autocomplete[ng-model="$ctrl.client.businessTypeFk"]',
@@ -735,7 +735,7 @@ export default {
},
createStateView: {
state: 'vn-autocomplete[ng-model="$ctrl.stateFk"]',
- worker: 'vn-autocomplete[ng-model="$ctrl.workerFk"]',
+ worker: 'vn-worker-autocomplete[ng-model="$ctrl.workerFk"]',
saveStateButton: `button[type=submit]`
},
claimsIndex: {
@@ -781,12 +781,12 @@ export default {
firstClaimReason: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimReasonFk"]',
firstClaimResult: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimResultFk"]',
firstClaimResponsible: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimResponsibleFk"]',
- firstClaimWorker: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.workerFk"]',
+ firstClaimWorker: 'vn-claim-development vn-horizontal:nth-child(1) vn-worker-autocomplete[ng-model="claimDevelopment.workerFk"]',
firstClaimRedelivery: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimRedeliveryFk"]',
secondClaimReason: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimReasonFk"]',
secondClaimResult: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimResultFk"]',
secondClaimResponsible: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimResponsibleFk"]',
- secondClaimWorker: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.workerFk"]',
+ secondClaimWorker: 'vn-claim-development vn-horizontal:nth-child(2) vn-worker-autocomplete[ng-model="claimDevelopment.workerFk"]',
secondClaimRedelivery: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimRedeliveryFk"]',
saveDevelopmentButton: 'button[type=submit]'
},
@@ -854,7 +854,7 @@ export default {
},
createRouteView: {
- worker: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.workerFk"]',
+ worker: 'vn-route-create vn-worker-autocomplete[ng-model="$ctrl.route.workerFk"]',
createdDatePicker: 'vn-route-create vn-date-picker[ng-model="$ctrl.route.created"]',
vehicleAuto: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.vehicleFk"]',
agency: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.agencyModeFk"]',
@@ -976,7 +976,7 @@ export default {
street: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.street"]',
user: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.name"]',
email: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.email"]',
- boss: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.bossFk"]',
+ boss: 'vn-worker-create vn-worker-autocomplete[ng-model="$ctrl.worker.bossFk"]',
role: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.roleFk"]',
iban: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.iban"]',
createButton: 'vn-worker-create vn-submit[label="Create"]',
diff --git a/e2e/paths/05-ticket/05_tracking_state.spec.js b/e2e/paths/05-ticket/05_tracking_state.spec.js
index 949c9a8e6..9ac373287 100644
--- a/e2e/paths/05-ticket/05_tracking_state.spec.js
+++ b/e2e/paths/05-ticket/05_tracking_state.spec.js
@@ -59,7 +59,7 @@ describe('Ticket Create new tracking state path', () => {
const result = await page
.waitToGetProperty(selectors.createStateView.worker, 'value');
- expect(result).toEqual('salesPersonNick');
+ expect(result).toEqual('salesPerson');
});
it(`should succesfully create a valid state`, async() => {
diff --git a/front/core/components/autocomplete/index.html b/front/core/components/autocomplete/index.html
index 69aac4d43..527ca77e7 100755
--- a/front/core/components/autocomplete/index.html
+++ b/front/core/components/autocomplete/index.html
@@ -18,7 +18,7 @@
+
-
\ No newline at end of file
+
diff --git a/front/core/components/autocomplete/index.js b/front/core/components/autocomplete/index.js
index 2539c4ef4..c78c29398 100755
--- a/front/core/components/autocomplete/index.js
+++ b/front/core/components/autocomplete/index.js
@@ -17,10 +17,9 @@ import './style.scss';
* @event change Thrown when value is changed
*/
export default class Autocomplete extends Field {
- constructor($element, $, $compile, $transclude) {
- super($element, $, $compile);
+ constructor($element, $, $transclude) {
+ super($element, $, $transclude);
this.$transclude = $transclude;
- this.$compile = $compile;
this._selection = null;
this.input = this.element.querySelector('input');
}
@@ -153,7 +152,14 @@ export default class Autocomplete extends Field {
filter.include = this.include;
let json = encodeURIComponent(JSON.stringify(filter));
- this.$http.get(`${this.url}?filter=${json}`).then(
+
+ let url;
+ if (this.url.includes('?'))
+ url = `${this.url}&filter=${json}`;
+ else
+ url = `${this.url}?filter=${json}`;
+
+ this.$http.get(url).then(
json => this.onSelectionRequest(json.data),
() => this.onSelectionRequest()
);
@@ -282,7 +288,7 @@ export default class Autocomplete extends Field {
this.refreshSelection();
}
}
-Autocomplete.$inject = ['$element', '$scope', '$compile', '$transclude'];
+Autocomplete.$inject = ['$element', '$scope', '$transclude'];
ngModule.vnComponent('vnAutocomplete', {
template: require('./index.html'),
diff --git a/front/core/components/drop-down/index.html b/front/core/components/drop-down/index.html
index ab868f7b5..692b0c87c 100644
--- a/front/core/components/drop-down/index.html
+++ b/front/core/components/drop-down/index.html
@@ -13,12 +13,12 @@
class="dropdown"
ng-click="$ctrl.onContainerClick($event)">
-
{{$ctrl.statusText}}
-
\ No newline at end of file
+
diff --git a/front/core/components/field/index.js b/front/core/components/field/index.js
index 7ce840555..ff92b6b87 100644
--- a/front/core/components/field/index.js
+++ b/front/core/components/field/index.js
@@ -3,8 +3,8 @@ import FormInput from '../form-input';
import './style.scss';
export default class Field extends FormInput {
- constructor($element, $scope) {
- super($element, $scope);
+ constructor($element, $scope, $transclude) {
+ super($element, $scope, $transclude);
this.prefix = null;
this.suffix = null;
@@ -197,7 +197,7 @@ export default class Field extends FormInput {
});
}
}
-Field.$inject = ['$element', '$scope'];
+Field.$inject = ['$element', '$scope', '$transclude'];
ngModule.vnComponent('vnField', {
template: require('./index.html'),
diff --git a/front/core/components/index.js b/front/core/components/index.js
index e1b58374e..eb40d5e1f 100644
--- a/front/core/components/index.js
+++ b/front/core/components/index.js
@@ -51,6 +51,7 @@ import './textarea';
import './th';
import './treeview';
import './wday-picker';
+import './worker-autocomplete';
import './datalist';
import './contextmenu';
import './rating';
diff --git a/front/core/components/worker-autocomplete/index.html b/front/core/components/worker-autocomplete/index.html
new file mode 100755
index 000000000..95631e8aa
--- /dev/null
+++ b/front/core/components/worker-autocomplete/index.html
@@ -0,0 +1,8 @@
+
+
+ {{name}}
+
+
+ {{nickname}}, {{code}}
+
+
diff --git a/front/core/components/worker-autocomplete/index.js b/front/core/components/worker-autocomplete/index.js
new file mode 100755
index 000000000..70ca69e6e
--- /dev/null
+++ b/front/core/components/worker-autocomplete/index.js
@@ -0,0 +1,40 @@
+import ngModule from '../../module';
+import Autocomplete from '../autocomplete';
+
+export default class WorkerAutocomplete extends Autocomplete {
+ constructor(...args) {
+ super(...args);
+ }
+
+ $onInit() {
+ super.$onInit();
+
+ let url = 'Workers/search';
+ if (this.departments) {
+ const parameter = encodeURIComponent(JSON.stringify(this.departments));
+ url = `Workers/search?departmentCodes=${parameter}`;
+ }
+ Object.assign(this, {
+ label: 'Worker',
+ url,
+ searchFunction: function({$search}) {
+ return {and: [
+ {'active': {neq: false}},
+ {or: [
+ {'name': $search},
+ {'nickname': {like: '%' + $search + '%'}},
+ {'code': {like: $search + '%'}}
+ ]}
+ ]};
+ },
+ });
+ }
+}
+
+ngModule.vnComponent('vnWorkerAutocomplete', {
+ slotTemplate: require('./index.html'),
+ controller: WorkerAutocomplete,
+ bindings: {
+ departments: ''
+ },
+});
diff --git a/loopback/util/specs/validateIban.spec.js b/loopback/util/specs/validateIban.spec.js
index a5d08d4c4..dd096c1b5 100644
--- a/loopback/util/specs/validateIban.spec.js
+++ b/loopback/util/specs/validateIban.spec.js
@@ -1,21 +1,45 @@
const validateIban = require('../validateIban');
describe('IBAN validation', () => {
- it('should return false for non-IBAN input', () => {
- let isValid = validateIban('Pepinillos');
+ it('should return false for invalid Spanish IBAN format', () => {
+ let isValid = validateIban('ES00 9999 0000 9999 0000 9999', 'ES');
expect(isValid).toBeFalsy();
});
- it('should return false for invalid spanish IBAN input', () => {
- let isValid = validateIban('ES00 9999 0000 9999 0000 9999');
-
- expect(isValid).toBeFalsy();
- });
-
- it('should return true for valid spanish IBAN', () => {
- let isValid = validateIban('ES91 2100 0418 4502 0005 1332');
+ it('should return true for valid Spanish IBAN', () => {
+ let isValid = validateIban('ES91 2100 0418 4502 0005 1332', 'ES');
expect(isValid).toBeTruthy();
});
+
+ it('should return false for invalid Spanish IBAN with incorrect length', () => {
+ let isValid = validateIban('ES91210004184502000513', 'ES');
+
+ expect(isValid).toBeFalsy();
+ });
+
+ it('should return false for invalid Spanish IBAN with incorrect module97 result', () => {
+ let isValid = validateIban('ES9121000418450200051331', 'ES');
+
+ expect(isValid).toBeFalsy();
+ });
+
+ it('should return true for a non-Spanish countryCode', () => {
+ let isValid = validateIban('DE89370400440532013000', 'AT');
+
+ expect(isValid).toBeTruthy();
+ });
+
+ it('should return true for null IBAN', () => {
+ let isValid = validateIban(null, 'ES');
+
+ expect(isValid).toBeTruthy();
+ });
+
+ it('should return false for non-string IBAN', () => {
+ let isValid = validateIban(12345, 'ES');
+
+ expect(isValid).toBeFalsy();
+ });
});
diff --git a/loopback/util/validateIban.js b/loopback/util/validateIban.js
index 3ca09ef95..ed3e00426 100644
--- a/loopback/util/validateIban.js
+++ b/loopback/util/validateIban.js
@@ -1,6 +1,7 @@
-module.exports = function(iban) {
+module.exports = function(iban, countryCode) {
if (iban == null) return true;
if (typeof iban != 'string') return false;
+ if (countryCode?.toLowerCase() != 'es') return true;
iban = iban.toUpperCase();
iban = trim(iban);
diff --git a/modules/claim/front/basic-data/index.html b/modules/claim/front/basic-data/index.html
index 16e134c60..10aa7623a 100644
--- a/modules/claim/front/basic-data/index.html
+++ b/modules/claim/front/basic-data/index.html
@@ -25,15 +25,13 @@
-
-
+
-
+
-
-
+
-->
-
\ No newline at end of file
+
diff --git a/modules/claim/front/search-panel/index.html b/modules/claim/front/search-panel/index.html
index 151a06c8e..fbc527d60 100644
--- a/modules/claim/front/search-panel/index.html
+++ b/modules/claim/front/search-panel/index.html
@@ -22,26 +22,18 @@
-
- {{firstName}} {{name}}
-
-
+
- {{firstName}} {{name}}
-
+
{
});
async function ibanNeedsValidation(err, done) {
- const filter = {
- fields: ['code'],
- where: {id: this.countryFk}
- };
- const country = await Self.app.models.Country.findOne(filter);
- const code = country ? country.code.toLowerCase() : null;
- if (code != 'es')
+ if (!this.bankEntityFk)
return done();
- if (!validateIban(this.iban))
+ const bankEntity = await Self.app.models.BankEntity.findById(this.bankEntityFk);
+ const filter = {
+ fields: ['code'],
+ where: {id: bankEntity.countryFk}
+ };
+ const country = await Self.app.models.Country.findOne(filter);
+
+ if (!validateIban(this.iban, country?.code))
err();
done();
}
diff --git a/modules/client/front/basic-data/index.html b/modules/client/front/basic-data/index.html
index a5c866979..e48b39fdc 100644
--- a/modules/client/front/basic-data/index.html
+++ b/modules/client/front/basic-data/index.html
@@ -14,13 +14,13 @@
-
@@ -59,18 +59,15 @@
-
-
-
+
- {{nickname}}
diff --git a/modules/client/front/create/index.html b/modules/client/front/create/index.html
index 3e7fdd949..e6bf561ef 100644
--- a/modules/client/front/create/index.html
+++ b/modules/client/front/create/index.html
@@ -15,18 +15,15 @@
rule
vn-focus>
-
- {{firstName}} {{lastName}}
-
+ departments="['VT']"
+ show-field="nickname">
+
-
- {{code}} - {{town.name}} ({{town.province.name}},
+ {{code}} - {{town.name}} ({{town.province.name}},
{{town.province.country.country}})
@@ -82,7 +79,7 @@
- {{name}}, {{province.name}}
+ {{name}}, {{province.name}}
({{province.country.country}})
@@ -150,4 +147,4 @@
-
\ No newline at end of file
+
diff --git a/modules/client/front/search-panel/index.html b/modules/client/front/search-panel/index.html
index a02f93882..2105d3a65 100644
--- a/modules/client/front/search-panel/index.html
+++ b/modules/client/front/search-panel/index.html
@@ -14,17 +14,12 @@
vn-one label="Name"
ng-model="filter.name">
-
- {{firstName}} {{name}}
-
+
diff --git a/modules/item/front/fixed-price-search-panel/index.html b/modules/item/front/fixed-price-search-panel/index.html
index ebe210277..347e65571 100644
--- a/modules/item/front/fixed-price-search-panel/index.html
+++ b/modules/item/front/fixed-price-search-panel/index.html
@@ -54,11 +54,10 @@
vn-id="buyer"
disabled="false"
ng-model="$ctrl.filter.buyerFk"
- url="Workers/activeWithRole"
+ url="TicketRequests/getItemTypeWorker"
show-field="nickname"
search-function="{firstName: $search}"
value-field="id"
- where="{role: {inq: ['logistic', 'buyer']}}"
label="Buyer"
on-change="$ctrl.addFilters()">
diff --git a/modules/item/front/index/index.js b/modules/item/front/index/index.js
index 10bd4bbb7..2bcc2302a 100644
--- a/modules/item/front/index/index.js
+++ b/modules/item/front/index/index.js
@@ -44,8 +44,7 @@ class Controller extends Section {
{
field: 'buyerFk',
autocomplete: {
- url: 'Workers/activeWithRole',
- where: `{role: {inq: ['logistic', 'buyer']}}`,
+ url: 'TicketRequests/getItemTypeWorker',
searchFunction: '{firstName: $search}',
showField: 'nickname',
valueField: 'id',
diff --git a/modules/item/front/request-search-panel/index.html b/modules/item/front/request-search-panel/index.html
index 9d35fbca4..6a51a429d 100644
--- a/modules/item/front/request-search-panel/index.html
+++ b/modules/item/front/request-search-panel/index.html
@@ -22,12 +22,11 @@
- {{nickname}}
+ label="Atender">
@@ -46,18 +45,13 @@
-
- {{firstName}} {{lastName}}
-
+ departments="['VT']"
+ label="Salesperson">
+
-
-
\ No newline at end of file
+
diff --git a/modules/route/front/basic-data/index.html b/modules/route/front/basic-data/index.html
index ade9230e8..7f9aef0d0 100644
--- a/modules/route/front/basic-data/index.html
+++ b/modules/route/front/basic-data/index.html
@@ -8,20 +8,11 @@