added incoterms & customs agent to address forms
gitea/salix/2003-adress_validate_uee_members This commit has test failures
Details
gitea/salix/2003-adress_validate_uee_members This commit has test failures
Details
This commit is contained in:
parent
deada69ca4
commit
25ffa839a2
|
@ -19,6 +19,9 @@
|
|||
},
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"isUeeMember": {
|
||||
"type": "Boolean"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Thermograph', '*', '*', 'ALLOW', 'ROLE', 'buyer');
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('TravelThermograph', '*', '*', 'ALLOW', 'ROLE', 'buyer');
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Entry', '*', '*', 'ALLOW', 'ROLE', 'buyer');
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('CustomsAgent', '*', '*', 'ALLOW', 'ROLE', 'employee');
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
CREATE TABLE `vn`.`customsAgent` (
|
||||
`id` int(11) NOT NULL,
|
||||
`fiscalName` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`street` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`nif` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`phone` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`email` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`fiscalName` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`street` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`nif` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`phone` varchar(16) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`email` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
ALTER TABLE `vn`.`customsAgent`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `nif_UNIQUE` (`nif`);
|
||||
COMMIT;
|
|
@ -84,6 +84,7 @@ INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`,
|
|||
(4, 'Rumania', 1, 'RO', 1, 24),
|
||||
(5, 'Holanda', 1, 'NL', 1, 18),
|
||||
(8, 'Portugal', 1, 'PT', 1, 27),
|
||||
(13,'Ecuador', 0, 'EC', 1, 24),
|
||||
(19,'Francia', 1, 'FR', 1, 27),
|
||||
(30,'Canarias', 1, 'IC', 1, 24);
|
||||
|
||||
|
@ -182,7 +183,7 @@ INSERT INTO `vn`.`province`(`id`, `name`, `countryFk`, `warehouseFk`)
|
|||
(2, 'Province two', 1, NULL),
|
||||
(3, 'Province three', 1, NULL),
|
||||
(4, 'Province four', 1, NULL),
|
||||
(5, 'Province five', 1, NULL);
|
||||
(5, 'Province five', 2, NULL);
|
||||
|
||||
INSERT INTO `vn`.`town`(`id`, `name`, `provinceFk`)
|
||||
VALUES
|
||||
|
|
|
@ -118,5 +118,7 @@
|
|||
"You should specify at least a start or end date": "Debes especificar al menos una fecha de inicio o de fín",
|
||||
"Start date should be lower than end date": "La fecha de inicio debe ser menor que la fecha de fín",
|
||||
"You should mark at least one week day": "Debes marcar al menos un día de la semana",
|
||||
"Swift / BIC can't be empty": "Swift / BIC no puede estar vacío"
|
||||
"Swift / BIC can't be empty": "Swift / BIC no puede estar vacío",
|
||||
"Customs agent is required for a non UEE member": "El agente de aduanas es requerido para los clientes extracomunitarios",
|
||||
"Incoterms is required for a non UEE member": "El incoterms es requerido para los clientes extracomunitarios"
|
||||
}
|
|
@ -25,6 +25,51 @@ module.exports = Self => {
|
|||
done();
|
||||
}
|
||||
|
||||
Self.validateAsync('customsAgentFk', validateCustomsAgent,
|
||||
{message: 'Customs agent is required for a non UEE member'}
|
||||
);
|
||||
|
||||
async function validateCustomsAgent(err, done) {
|
||||
if (!await isUeeMember(this.provinceFk) && !this.customsAgentFk) err();
|
||||
done();
|
||||
}
|
||||
|
||||
Self.validateAsync('incotermsFk', validateIncoterms,
|
||||
{message: 'Incoterms is required for a non UEE member'}
|
||||
);
|
||||
|
||||
async function validateIncoterms(err, done) {
|
||||
if (!await isUeeMember(this.provinceFk) && !this.incotermsFk) err();
|
||||
done();
|
||||
}
|
||||
|
||||
async function isUeeMember(provinceId) {
|
||||
const models = Self.app.models;
|
||||
const province = await models.Province.findById(provinceId, {
|
||||
include: {
|
||||
relation: 'country'
|
||||
}
|
||||
});
|
||||
|
||||
return province.country().isUeeMember;
|
||||
}
|
||||
|
||||
Self.validateAsync('postalCode', hasValidPostcode, {
|
||||
message: `The postcode doesn't exists. Ensure you put the correct format`
|
||||
});
|
||||
|
||||
async function hasValidPostcode(err, done) {
|
||||
if (!this.postalCode)
|
||||
return done();
|
||||
|
||||
const models = Self.app.models;
|
||||
const postcode = await models.Postcode.findById(this.postalCode);
|
||||
|
||||
if (!postcode) err();
|
||||
done();
|
||||
}
|
||||
|
||||
|
||||
Self.beforeRemote('findById', function(ctx, modelInstance, next) {
|
||||
ctx.args.filter = {
|
||||
include: [{
|
||||
|
@ -42,21 +87,6 @@ module.exports = Self => {
|
|||
next();
|
||||
});
|
||||
|
||||
Self.validateAsync('postalCode', hasValidPostcode, {
|
||||
message: `The postcode doesn't exists. Ensure you put the correct format`
|
||||
});
|
||||
|
||||
async function hasValidPostcode(err, done) {
|
||||
if (!this.postalCode)
|
||||
return done();
|
||||
|
||||
const models = Self.app.models;
|
||||
const postcode = await models.Postcode.findById(this.postalCode);
|
||||
|
||||
if (!postcode) err();
|
||||
done();
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
Self.observe('before save', async function(ctx) {
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
},
|
||||
"incoterms": {
|
||||
"type": "belongsTo",
|
||||
"model": "Incoterm",
|
||||
"model": "Incoterms",
|
||||
"foreignKey": "incotermsFk"
|
||||
},
|
||||
"customsAgent": {
|
||||
|
|
|
@ -15,5 +15,13 @@
|
|||
"name": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
"acls": [
|
||||
{
|
||||
"accessType": "READ",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -116,6 +116,29 @@
|
|||
rule>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
ng-model="$ctrl.address.incotermsFk"
|
||||
url="Incoterms"
|
||||
show-field="name"
|
||||
value-field="code"
|
||||
label="Incoterms">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
ng-model="$ctrl.address.customsAgentFk"
|
||||
url="CustomsAgents"
|
||||
show-field="fiscalName"
|
||||
value-field="id"
|
||||
label="Customs agent">
|
||||
</vn-autocomplete>
|
||||
<vn-icon-button
|
||||
vn-auto
|
||||
class="vn-my-md"
|
||||
icon="add_circle"
|
||||
vn-tooltip="New customs agent"
|
||||
ng-click="customAgent.show()">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Save"></vn-submit>
|
||||
|
@ -130,3 +153,38 @@
|
|||
<vn-client-postcode vn-id="postcode"
|
||||
on-response="$ctrl.onResponse($response)">
|
||||
</vn-client-postcode>
|
||||
|
||||
<!-- Create custom agent dialog -->
|
||||
<vn-dialog class="edit"
|
||||
vn-id="customAgent"
|
||||
on-accept="$ctrl.onCustomAgentAccept()">
|
||||
<tpl-body>
|
||||
<h5 class="vn-py-sm" translate>New customs agent</h5>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one vn-focus
|
||||
label="NIF"
|
||||
ng-model="$ctrl.newCustomsAgent.nif"
|
||||
required="true">
|
||||
</vn-textfield>
|
||||
<vn-textfield vn-one
|
||||
label="Fiscal name"
|
||||
ng-model="$ctrl.newCustomsAgent.fiscalName"
|
||||
required="true">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one
|
||||
label="Street"
|
||||
ng-model="$ctrl.newCustomsAgent.street">
|
||||
</vn-textfield>
|
||||
<vn-textfield vn-one
|
||||
label="Phone"
|
||||
ng-model="$ctrl.newCustomsAgent.phone">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="accept" translate>Create</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
|
@ -1,12 +1,13 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from 'core/lib/component';
|
||||
|
||||
export default class Controller extends Component {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
|
||||
export default class Controller {
|
||||
constructor($, $state) {
|
||||
this.$ = $;
|
||||
this.$state = $state;
|
||||
this.data = {
|
||||
address: {
|
||||
clientFk: parseInt($state.params.id),
|
||||
clientFk: parseInt(this.$params.id),
|
||||
isActive: true
|
||||
},
|
||||
isDefaultAddress: false
|
||||
|
@ -42,9 +43,14 @@ export default class Controller {
|
|||
this.$state.go('client.card.address.index');
|
||||
});
|
||||
}
|
||||
|
||||
onCustomAgentAccept() {
|
||||
return this.$http.post(`CustomsAgents`, this.newCustomsAgent)
|
||||
.then(res => this.address.customsAgentFk = res.data.id);
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$state'];
|
||||
Controller.$inject = ['$element', '$scope'];
|
||||
|
||||
ngModule.component('vnClientAddressCreate', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -3,17 +3,21 @@ import watcher from 'core/mocks/watcher';
|
|||
|
||||
describe('Client', () => {
|
||||
describe('Component vnClientAddressCreate', () => {
|
||||
let $scope;
|
||||
let controller;
|
||||
let $componentController;
|
||||
let $httpBackend;
|
||||
let $element;
|
||||
let $state;
|
||||
|
||||
beforeEach(ngModule('client'));
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, _$state_) => {
|
||||
$componentController = _$componentController_;
|
||||
beforeEach(angular.mock.inject(($componentController, $rootScope, _$state_, _$httpBackend_) => {
|
||||
$scope = $rootScope.$new();
|
||||
$httpBackend = _$httpBackend_;
|
||||
$state = _$state_;
|
||||
$state.params.id = '1234';
|
||||
controller = $componentController('vnClientAddressCreate', {$state});
|
||||
$element = angular.element('<vn-client-address-create></vn-client-address-create>');
|
||||
controller = $componentController('vnClientAddressCreate', {$element, $scope});
|
||||
controller.$.watcher = watcher;
|
||||
controller.$.watcher.submit = () => {
|
||||
return {
|
||||
|
@ -73,5 +77,16 @@ describe('Client', () => {
|
|||
expect(controller.address.provinceFk).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onCustomAgentAccept()', () => {
|
||||
it(`should create a new customs agent and then set the customsAgentFk property on the address`, () => {
|
||||
const expectedResult = {id: 1, fiscalName: 'Customs agent one'};
|
||||
$httpBackend.when('POST', 'CustomsAgents').respond(200, expectedResult);
|
||||
controller.onCustomAgentAccept();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.address.customsAgentFk).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
Street address: Dirección postal
|
||||
Default: Predeterminado
|
||||
Consignee: Consignatario
|
||||
Postcode: Código postal
|
||||
Town/City: Ciudad
|
||||
Province: Provincia
|
||||
Agency: Agencia
|
||||
Phone: Teléfono
|
||||
Mobile: Móvil
|
|
@ -99,8 +99,8 @@
|
|||
ng-model="$ctrl.address.postalCode"
|
||||
rule>
|
||||
</vn-textfield>
|
||||
<!--
|
||||
<vn-icon-button
|
||||
|
||||
<!-- <vn-icon-button
|
||||
vn-auto
|
||||
class="vn-my-md"
|
||||
icon="add_circle"
|
||||
|
@ -131,6 +131,29 @@
|
|||
rule>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
ng-model="$ctrl.address.incotermsFk"
|
||||
url="Incoterms"
|
||||
show-field="name"
|
||||
value-field="code"
|
||||
label="Incoterms">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
ng-model="$ctrl.address.customsAgentFk"
|
||||
url="CustomsAgents"
|
||||
show-field="fiscalName"
|
||||
value-field="id"
|
||||
label="Customs agent">
|
||||
</vn-autocomplete>
|
||||
<vn-icon-button
|
||||
vn-auto
|
||||
class="vn-my-md"
|
||||
icon="add_circle"
|
||||
vn-tooltip="New customs agent"
|
||||
ng-click="customAgent.show()">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
<vn-title>Notes</vn-title>
|
||||
<div name="observations">
|
||||
<vn-horizontal ng-repeat="observation in observations">
|
||||
|
@ -178,3 +201,37 @@
|
|||
on-response="$ctrl.onResponse($response)">
|
||||
</vn-client-postcode>
|
||||
|
||||
<!-- Create custom agent dialog -->
|
||||
<vn-dialog class="edit"
|
||||
vn-id="customAgent"
|
||||
on-accept="$ctrl.onCustomAgentAccept()">
|
||||
<tpl-body>
|
||||
<h5 class="vn-py-sm" translate>New customs agent</h5>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one vn-focus
|
||||
label="NIF"
|
||||
ng-model="$ctrl.newCustomsAgent.nif"
|
||||
required="true">
|
||||
</vn-textfield>
|
||||
<vn-textfield vn-one
|
||||
label="Fiscal name"
|
||||
ng-model="$ctrl.newCustomsAgent.fiscalName"
|
||||
required="true">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one
|
||||
label="Street"
|
||||
ng-model="$ctrl.newCustomsAgent.street">
|
||||
</vn-textfield>
|
||||
<vn-textfield vn-one
|
||||
label="Phone"
|
||||
ng-model="$ctrl.newCustomsAgent.phone">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="accept" translate>Create</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
|
@ -1,12 +1,7 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from 'core/lib/component';
|
||||
|
||||
export default class Controller {
|
||||
constructor($scope, $state) {
|
||||
this.$ = $scope;
|
||||
this.$state = $state;
|
||||
this.$stateParams = $state.params;
|
||||
}
|
||||
|
||||
export default class Controller extends Component {
|
||||
removeObservation(index) {
|
||||
this.$.watcher.setDirty();
|
||||
this.$.model.remove(index);
|
||||
|
@ -34,8 +29,12 @@ export default class Controller {
|
|||
this.goToIndex();
|
||||
});
|
||||
}
|
||||
|
||||
onCustomAgentAccept() {
|
||||
return this.$http.post(`CustomsAgents`, this.newCustomsAgent)
|
||||
.then(res => this.address.customsAgentFk = res.data.id);
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$scope', '$state'];
|
||||
|
||||
ngModule.component('vnClientAddressEdit', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -2,15 +2,22 @@ import './index';
|
|||
|
||||
describe('Client', () => {
|
||||
describe('Component vnClientAddressEdit', () => {
|
||||
let $state;
|
||||
let $scope;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
let $element;
|
||||
let $state;
|
||||
|
||||
beforeEach(ngModule('client'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, _$state_) => {
|
||||
beforeEach(angular.mock.inject(($componentController, $rootScope, _$state_, _$httpBackend_) => {
|
||||
$scope = $rootScope.$new();
|
||||
$httpBackend = _$httpBackend_;
|
||||
$state = _$state_;
|
||||
$state.params.addressId = '1';
|
||||
controller = $componentController('vnClientAddressEdit', {$state});
|
||||
$element = angular.element('<vn-client-address-edit></vn-client-address-edit>');
|
||||
controller = $componentController('vnClientAddressEdit', {$element, $scope});
|
||||
controller.address = {id: 1, customsAgentFk: null};
|
||||
controller.$.watcher = {
|
||||
setDirty: () => {},
|
||||
setPristine: () => {},
|
||||
|
@ -55,5 +62,16 @@ describe('Client', () => {
|
|||
expect(controller.$state.go).toHaveBeenCalledWith('client.card.address.index');
|
||||
});
|
||||
});
|
||||
|
||||
describe('onCustomAgentAccept()', () => {
|
||||
it(`should create a new customs agent and then set the customsAgentFk property on the address`, () => {
|
||||
const expectedResult = {id: 1, fiscalName: 'Customs agent one'};
|
||||
$httpBackend.when('POST', 'CustomsAgents').respond(200, expectedResult);
|
||||
controller.onCustomAgentAccept();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.address.customsAgentFk).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
Enabled: Activo
|
||||
Is equalizated: Recargo de equivalencia
|
||||
Observation type: Tipo de observación
|
||||
Description: Descripción
|
||||
The observation type must be unique: El tipo de observación ha de ser único
|
||||
Remove note: Quitar nota
|
||||
Add note: Añadir nota
|
|
@ -1,2 +0,0 @@
|
|||
Set as default: Establecer como predeterminado
|
||||
Active first to set as default: Active primero para marcar como predeterminado
|
|
@ -0,0 +1,27 @@
|
|||
# Index
|
||||
Set as default: Establecer como predeterminado
|
||||
Active first to set as default: Active primero para marcar como predeterminado
|
||||
# Edit
|
||||
Enabled: Activo
|
||||
Is equalizated: Recargo de equivalencia
|
||||
Observation type: Tipo de observación
|
||||
Description: Descripción
|
||||
The observation type must be unique: El tipo de observación ha de ser único
|
||||
Remove note: Quitar nota
|
||||
Add note: Añadir nota
|
||||
Customs agent: Agente de aduanas
|
||||
New customs agent: Nuevo agente de aduanas
|
||||
# Create
|
||||
Street address: Dirección postal
|
||||
Default: Predeterminado
|
||||
Consignee: Consignatario
|
||||
Postcode: Código postal
|
||||
Town/City: Ciudad
|
||||
Province: Provincia
|
||||
Agency: Agencia
|
||||
Phone: Teléfono
|
||||
Mobile: Móvil
|
||||
|
||||
# Common
|
||||
Fiscal name: Nombre fiscal
|
||||
Street: Dirección fiscal
|
Loading…
Reference in New Issue