diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index 25dc82324..6ef96c488 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -78,7 +78,7 @@ INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossF
INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`)
VALUES
- (1, 'España', 0, 'ES', 1, 24),
+ (1, 'España', 1, 'ES', 1, 24),
(2, 'Italia', 1, 'IT', 1, 27),
(3, 'Alemania', 1, 'DE', 1, 22),
(4, 'Rumania', 1, 'RO', 1, 24),
@@ -182,8 +182,8 @@ INSERT INTO `vn`.`province`(`id`, `name`, `countryFk`, `warehouseFk`)
(1, 'Province one', 1, NULL),
(2, 'Province two', 1, NULL),
(3, 'Province three', 1, NULL),
- (4, 'Province four', 1, NULL),
- (5, 'Province five', 2, NULL);
+ (4, 'Province four', 2, NULL),
+ (5, 'Province five', 13, NULL);
INSERT INTO `vn`.`town`(`id`, `name`, `provinceFk`)
VALUES
@@ -1966,3 +1966,8 @@ INSERT INTO `vn`.`travelThermograph`(`thermographFk`, `created`, `warehouseFk`,
INSERT INTO `vn`.`incoterms` (`code`, `name`)
VALUES
('FAS', 'Free Alongside Ship');
+
+INSERT INTO `vn`.`customsAgent` (`id`, `fiscalName`, `street`, `nif`, `phone`, `email`)
+ VALUES
+ (1, 'Agent one', '1007 Mountain Drive, Gotham', 'N1111111111', '111111111', 'agentone@gotham.com'),
+ (2, 'Agent two', '1007 Mountain Drive, Gotham', 'N2222222222', '222222222', 'agenttwo@gotham.com');
\ No newline at end of file
diff --git a/loopback/locale/en.json b/loopback/locale/en.json
index 70d06c9bd..584ecbedd 100644
--- a/loopback/locale/en.json
+++ b/loopback/locale/en.json
@@ -61,5 +61,7 @@
"MESSAGE_BOUGHT_UNITS": "Bought {{quantity}} units of {{concept}} (#{{itemId}}) for the ticket id [#{{ticketId}}]({{{url}}})",
"MESSAGE_INSURANCE_CHANGE": "I have changed the insurence credit of client [{{clientName}} (#{{clientId}})]({{{url}}}) to *{{credit}} €*",
"MESSAGE_CHANGED_PAYMETHOD": "I have changed the pay method for client [{{clientName}} (#{{clientId}})]({{{url}}})",
- "MESSAGE_CLAIM_ITEM_REGULARIZE": "I sent *{{quantity}}* units of [{{concept}} (#{{itemId}})]({{{itemUrl}}}) to {{nickname}} coming from ticket id [#{{ticketId}}]({{{ticketUrl}}})"
+ "MESSAGE_CLAIM_ITEM_REGULARIZE": "I sent *{{quantity}}* units of [{{concept}} (#{{itemId}})]({{{itemUrl}}}) to {{nickname}} coming from ticket id [#{{ticketId}}]({{{ticketUrl}}})",
+ "Customs agent is required for a non UEE member": "Customs agent is required for a non UEE member",
+ "Incoterms is required for a non UEE member": "Incoterms is required for a non UEE member"
}
\ No newline at end of file
diff --git a/modules/client/back/methods/address/createDefaultAddress.js b/modules/client/back/methods/address/createDefaultAddress.js
deleted file mode 100644
index e524a6017..000000000
--- a/modules/client/back/methods/address/createDefaultAddress.js
+++ /dev/null
@@ -1,44 +0,0 @@
-module.exports = function(Self) {
- Self.remoteMethod('createDefaultAddress', {
- description: 'Creates both client and its web account',
- accepts: {
- arg: 'data',
- type: 'object',
- http: {source: 'body'}
- },
- returns: {
- root: true,
- type: 'Object'
- },
- http: {
- verb: 'post',
- path: '/createDefaultAddress'
- }
- });
-
- Self.createDefaultAddress = async data => {
- const Address = Self.app.models.Address;
- const Client = Self.app.models.Client;
- const tx = await Address.beginTransaction({});
-
- try {
- let options = {transaction: tx};
-
- let address = data.address;
- let newAddress = await Address.create(address, options);
- let client = await Client.findById(address.clientFk, null, options);
-
- if (data.isDefaultAddress) {
- await client.updateAttributes({
- defaultAddressFk: newAddress.id
- }, options);
- }
-
- await tx.commit();
- return newAddress;
- } catch (e) {
- await tx.rollback();
- throw e;
- }
- };
-};
diff --git a/modules/client/back/methods/address/specs/createDefaultAddress.spec.js b/modules/client/back/methods/address/specs/createDefaultAddress.spec.js
deleted file mode 100644
index 452d9c9b7..000000000
--- a/modules/client/back/methods/address/specs/createDefaultAddress.spec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const app = require('vn-loopback/server/server');
-
-describe('Address createDefaultAddress', () => {
- let address;
- let client;
-
- afterAll(async done => {
- await client.updateAttributes({defaultAddressFk: 1});
- await address.destroy();
-
- done();
- });
-
- it('should verify that client defaultAddressFk is untainted', async() => {
- client = await app.models.Client.findById(101);
-
- expect(client.defaultAddressFk).toEqual(1);
- });
-
- it('should create a new address and set as a client default address', async() => {
- let data = {
- address: {
- clientFk: 101,
- nickname: 'My address',
- street: 'Wall Street',
- city: 'New York',
-
- },
- isDefaultAddress: true
- };
-
- address = await app.models.Address.createDefaultAddress(data);
- client = await app.models.Client.findById(101);
-
- expect(client.defaultAddressFk).toEqual(address.id);
- });
-});
diff --git a/modules/client/back/methods/client/createAddress.js b/modules/client/back/methods/client/createAddress.js
new file mode 100644
index 000000000..0319fc386
--- /dev/null
+++ b/modules/client/back/methods/client/createAddress.js
@@ -0,0 +1,121 @@
+const UserError = require('vn-loopback/util/user-error');
+
+module.exports = function(Self) {
+ Self.remoteMethodCtx('createAddress', {
+ description: 'Creates client address updating default address',
+ accepts: [{
+ arg: 'id',
+ type: 'Number',
+ description: 'The client id',
+ http: {source: 'path'}
+ },
+ {
+ arg: 'nickname',
+ type: 'String',
+ required: true
+ },
+ {
+ arg: 'city',
+ type: 'String',
+ required: true
+ },
+ {
+ arg: 'street',
+ type: 'String',
+ required: true
+ },
+ {
+ arg: 'phone',
+ type: 'String'
+ },
+ {
+ arg: 'mobile',
+ type: 'String'
+ },
+ {
+ arg: 'postalCode',
+ type: 'String'
+ },
+ {
+ arg: 'provinceId',
+ type: 'Number'
+ },
+ {
+ arg: 'agencyModeId',
+ type: 'Number'
+ },
+ {
+ arg: 'incotermsId',
+ type: 'String'
+ },
+ {
+ arg: 'customsAgentId',
+ type: 'Number'
+ },
+ {
+ arg: 'isActive',
+ type: 'Boolean'
+ },
+ {
+ arg: 'isDefaultAddress',
+ type: 'Boolean'
+ }],
+ returns: {
+ root: true,
+ type: 'Object'
+ },
+ http: {
+ verb: 'post',
+ path: '/:id/createAddress'
+ }
+ });
+
+ Self.createAddress = async(ctx, clientId) => {
+ const models = Self.app.models;
+ const args = ctx.args;
+ const tx = await models.Address.beginTransaction({});
+
+ try {
+ const options = {transaction: tx};
+ const province = await models.Province.findById(args.provinceId, {
+ include: {
+ relation: 'country'
+ }
+ }, options);
+
+ const isUeeMember = province.country().isUeeMember;
+ if (!isUeeMember && !args.incotermsId)
+ throw new UserError(`Incoterms is required for a non UEE member`);
+
+ if (!isUeeMember && !args.customsAgentId)
+ throw new UserError(`Customs agent is required for a non UEE member`);
+
+ const newAddress = await models.Address.create({
+ clientFk: clientId,
+ nickname: args.nickname,
+ incotermsFk: args.incotermsId,
+ customsAgentFk: args.customsAgentId,
+ city: args.city,
+ street: args.street,
+ phone: args.phone,
+ postalCode: args.postalCode,
+ provinceFk: args.provinceId,
+ agencyModeFk: args.agencyModeId,
+ isActive: args.isActive
+ }, options);
+ const client = await Self.findById(clientId, null, options);
+
+ if (args.isDefaultAddress) {
+ await client.updateAttributes({
+ defaultAddressFk: newAddress.id
+ }, options);
+ }
+
+ await tx.commit();
+ return newAddress;
+ } catch (e) {
+ await tx.rollback();
+ throw e;
+ }
+ };
+};
diff --git a/modules/client/back/methods/client/specs/createAddress.spec.js b/modules/client/back/methods/client/specs/createAddress.spec.js
new file mode 100644
index 000000000..29f9e145f
--- /dev/null
+++ b/modules/client/back/methods/client/specs/createAddress.spec.js
@@ -0,0 +1,87 @@
+const app = require('vn-loopback/server/server');
+
+describe('Address createAddress', () => {
+ const clientId = 101;
+ const provinceId = 5;
+ const incotermsId = 'FAS';
+ const customAgentOneId = 1;
+ let address;
+ let client;
+
+ afterAll(async done => {
+ await client.updateAttributes({defaultAddressFk: 1});
+ await address.destroy();
+
+ done();
+ });
+
+ it('should throw a non uee member error if no incoterms is defined', async() => {
+ const expectedResult = 'My edited address';
+ const ctx = {
+ args: {
+ provinceId: provinceId,
+ nickname: expectedResult,
+ street: 'Wall Street',
+ city: 'New York',
+ customsAgentId: customAgentOneId
+ }
+ };
+
+ try {
+ await app.models.Client.createAddress(ctx, clientId);
+ } catch (e) {
+ err = e;
+ }
+
+ expect(err).toBeDefined();
+ expect(err.message).toEqual('Incoterms is required for a non UEE member');
+ });
+
+ it('should throw a non uee member error if no customsAgent is defined', async() => {
+ const expectedResult = 'My edited address';
+ const ctx = {
+ args: {
+ provinceId: provinceId,
+ nickname: expectedResult,
+ street: 'Wall Street',
+ city: 'New York',
+ incotermsId: incotermsId
+ }
+ };
+
+
+ try {
+ await app.models.Client.createAddress(ctx, clientId);
+ } catch (e) {
+ err = e;
+ }
+
+ expect(err).toBeDefined();
+ expect(err.message).toEqual('Customs agent is required for a non UEE member');
+ });
+
+ it('should verify that client defaultAddressFk is untainted', async() => {
+ client = await app.models.Client.findById(clientId);
+
+ expect(client.defaultAddressFk).toEqual(1);
+ });
+
+ it('should create a new address and set as a client default address', async() => {
+ const ctx = {
+ args: {
+ provinceId: 1,
+ nickname: 'My address',
+ street: 'Wall Street',
+ city: 'New York',
+ incotermsId: incotermsId,
+ customsAgentId: customAgentOneId,
+ isDefaultAddress: true
+ }
+ };
+
+ address = await app.models.Client.createAddress(ctx, clientId);
+ client = await app.models.Client.findById(clientId);
+
+ expect(client.defaultAddressFk).toEqual(address.id);
+ });
+});
diff --git a/modules/client/back/methods/client/specs/updateAddress.spec.js b/modules/client/back/methods/client/specs/updateAddress.spec.js
new file mode 100644
index 000000000..a4cf07891
--- /dev/null
+++ b/modules/client/back/methods/client/specs/updateAddress.spec.js
@@ -0,0 +1,100 @@
+const app = require('vn-loopback/server/server');
+
+describe('Address updateAddress', () => {
+ const clientId = 101;
+ const addressId = 1;
+ const provinceId = 5;
+ const incotermsId = 'FAS';
+ const customAgentOneId = 1;
+ let oldAddress;
+ let address;
+
+ afterAll(async done => {
+ await address.updateAttributes({
+ nickname: oldAddress.nickname,
+ provinceFk: 1,
+ customsAgentFk: null,
+ incotermsFk: null
+ });
+
+ done();
+ });
+
+ it('should throw a non uee member error if no incoterms is defined', async() => {
+ const expectedResult = 'My edited address';
+ const ctx = {
+ args: {
+ provinceFk: provinceId,
+ nickname: expectedResult,
+ customsAgentFk: customAgentOneId
+ }
+ };
+
+ try {
+ await app.models.Client.updateAddress(ctx, clientId, addressId);
+ } catch (e) {
+ err = e;
+ }
+
+ expect(err).toBeDefined();
+ expect(err.message).toEqual('Incoterms is required for a non UEE member');
+ });
+
+ it('should throw a non uee member error if no customsAgent is defined', async() => {
+ const expectedResult = 'My edited address';
+ const ctx = {
+ args: {
+ provinceFk: provinceId,
+ nickname: expectedResult,
+ incotermsFk: incotermsId
+ }
+ };
+
+
+ try {
+ await app.models.Client.updateAddress(ctx, clientId, addressId);
+ } catch (e) {
+ err = e;
+ }
+
+ expect(err).toBeDefined();
+ expect(err.message).toEqual('Customs agent is required for a non UEE member');
+ });
+
+ it('should update the adress from a non uee member and not throw an error', async() => {
+ const expectedResult = 'My edited address';
+ const ctx = {
+ args: {
+ provinceFk: provinceId,
+ nickname: expectedResult,
+ incotermsFk: incotermsId,
+ customsAgentFk: customAgentOneId
+ }
+ };
+
+ oldAddress = await app.models.Address.findById(addressId);
+
+ await app.models.Client.updateAddress(ctx, clientId, addressId);
+
+ address = await app.models.Address.findById(addressId);
+
+ expect(address.nickname).toEqual(expectedResult);
+ });
+
+ it('should update the address', async() => {
+ const expectedResult = 'My second time edited address';
+ const ctx = {
+ args: {
+ nickname: expectedResult
+ }
+ };
+
+ oldAddress = await app.models.Address.findById(addressId);
+
+ await app.models.Client.updateAddress(ctx, clientId, addressId);
+
+ address = await app.models.Address.findById(addressId);
+
+ expect(address.nickname).toEqual(expectedResult);
+ });
+});
diff --git a/modules/client/back/methods/client/updateAddress.js b/modules/client/back/methods/client/updateAddress.js
new file mode 100644
index 000000000..b9270600f
--- /dev/null
+++ b/modules/client/back/methods/client/updateAddress.js
@@ -0,0 +1,119 @@
+const UserError = require('vn-loopback/util/user-error');
+
+module.exports = function(Self) {
+ Self.remoteMethod('updateAddress', {
+ description: 'Updates a client address updating default address',
+ accepts: [{
+ arg: 'ctx',
+ type: 'Object',
+ http: {source: 'context'}
+ },
+ {
+ arg: 'clientId',
+ type: 'Number',
+ description: 'The client id',
+ http: {source: 'path'}
+ },
+ {
+ arg: 'addressId',
+ type: 'Number',
+ description: 'The address id',
+ http: {source: 'path'}
+ },
+ {
+ arg: 'nickname',
+ type: 'String'
+ },
+ {
+ arg: 'city',
+ type: 'String'
+ },
+ {
+ arg: 'street',
+ type: 'String'
+ },
+ {
+ arg: 'phone',
+ type: 'String'
+ },
+ {
+ arg: 'mobile',
+ type: 'String'
+ },
+ {
+ arg: 'postalCode',
+ type: 'String'
+ },
+ {
+ arg: 'provinceFk',
+ type: 'Number'
+ },
+ {
+ arg: 'agencyModeFk',
+ type: 'Number'
+ },
+ {
+ arg: 'incotermsFk',
+ type: 'String'
+ },
+ {
+ arg: 'customsAgentFk',
+ type: 'Number'
+ },
+ {
+ arg: 'isActive',
+ type: 'Boolean'
+ },
+ {
+ arg: 'isEqualizated',
+ type: 'Boolean'
+ }],
+ returns: {
+ root: true,
+ type: 'Object'
+ },
+ http: {
+ verb: 'patch',
+ path: '/:clientId/updateAddress/:addressId'
+ }
+ });
+
+ Self.updateAddress = async(ctx, clientId, addressId) => {
+ const models = Self.app.models;
+ const args = ctx.args;
+ const tx = await models.Address.beginTransaction({});
+ try {
+ const options = {transaction: tx};
+ const address = await models.Address.findOne({
+ where: {
+ id: addressId,
+ clientFk: clientId
+ }
+ });
+ const provinceId = args.provinceFk || address.provinceFk;
+ const province = await models.Province.findById(provinceId, {
+ include: {
+ relation: 'country'
+ }
+ }, options);
+
+ const isUeeMember = province.country().isUeeMember;
+ const incotermsId = args.incotermsFk || address.incotermsFk;
+ if (!isUeeMember && !incotermsId)
+ throw new UserError(`Incoterms is required for a non UEE member`);
+
+ const customsAgentId = args.customsAgentFk || address.customsAgentFk;
+ if (!isUeeMember && !customsAgentId)
+ throw new UserError(`Customs agent is required for a non UEE member`);
+
+ delete args.ctx; // Remove unwanted properties
+ const updatedAddress = await address.updateAttributes(ctx.args, options);
+
+ await tx.commit();
+ return updatedAddress;
+ } catch (e) {
+ await tx.rollback();
+ throw e;
+ }
+ };
+};
diff --git a/modules/client/back/models/address.js b/modules/client/back/models/address.js
index 4e23f5d12..ffcaf39da 100644
--- a/modules/client/back/models/address.js
+++ b/modules/client/back/models/address.js
@@ -3,9 +3,6 @@ let getFinalState = require('vn-loopback/util/hook').getFinalState;
let isMultiple = require('vn-loopback/util/hook').isMultiple;
module.exports = Self => {
- // Methods
- require('../methods/address/createDefaultAddress')(Self);
-
Self.validateAsync('isEqualizated', cannotHaveET, {
message: 'Cannot check Equalization Tax in this NIF/CIF'
});
@@ -25,35 +22,6 @@ 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`
});
diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js
index 1dba6c6db..198aae2cd 100644
--- a/modules/client/back/models/client.js
+++ b/modules/client/back/models/client.js
@@ -25,6 +25,8 @@ module.exports = Self => {
require('../methods/client/uploadFile')(Self);
require('../methods/client/lastActiveTickets')(Self);
require('../methods/client/sendSms')(Self);
+ require('../methods/client/createAddress')(Self);
+ require('../methods/client/updateAddress')(Self);
// Validations
diff --git a/modules/client/back/models/specs/address.spec.js b/modules/client/back/models/specs/address.spec.js
index 49fb709bf..685acc80d 100644
--- a/modules/client/back/models/specs/address.spec.js
+++ b/modules/client/back/models/specs/address.spec.js
@@ -2,9 +2,10 @@ const app = require('vn-loopback/server/server');
describe('loopback model address', () => {
let createdAddressId;
+ const clientId = 101;
afterAll(async done => {
- let client = await app.models.Client.findById(101);
+ let client = await app.models.Client.findById(clientId);
await app.models.Address.destroyById(createdAddressId);
await client.updateAttribute('isEqualizated', false);
@@ -28,14 +29,14 @@ describe('loopback model address', () => {
});
it('should set isEqualizated to true of a given Client to trigger any new address to have it', async() => {
- let client = await app.models.Client.findById(101);
+ let client = await app.models.Client.findById(clientId);
expect(client.isEqualizated).toBeFalsy();
await client.updateAttribute('isEqualizated', true);
let newAddress = await app.models.Address.create({
- clientFk: 101,
+ clientFk: clientId,
agencyModeFk: 5,
city: 'here',
isActive: true,
@@ -44,7 +45,9 @@ describe('loopback model address', () => {
phone: '555555555',
postalCode: '46000',
provinceFk: 1,
- street: 'Test address'
+ street: 'Test address',
+ incotermsFk: 'FAS',
+ customsAgentFk: 1
});
expect(newAddress.isEqualizated).toBeTruthy();
diff --git a/modules/client/front/address/create/index.html b/modules/client/front/address/create/index.html
index 3fe51a16e..fabc12bf9 100644
--- a/modules/client/front/address/create/index.html
+++ b/modules/client/front/address/create/index.html
@@ -1,8 +1,9 @@
@@ -19,7 +20,7 @@
+ label="Default" ng-model="$ctrl.address.isDefaultAddress">
@@ -41,7 +42,7 @@
{
- if (res.data && this.data.isDefaultAddress)
+ if (this.address.isDefaultAddress)
this.client.defaultAddressFk = res.data.id;
this.$state.go('client.card.address.index');
diff --git a/modules/client/front/address/create/index.spec.js b/modules/client/front/address/create/index.spec.js
index 0b1f5c532..6bd53cb72 100644
--- a/modules/client/front/address/create/index.spec.js
+++ b/modules/client/front/address/create/index.spec.js
@@ -30,14 +30,13 @@ describe('Client', () => {
}));
it('should define and set address property', () => {
- expect(controller.data.address.clientFk).toBe(1234);
- expect(controller.data.address.isActive).toBe(true);
+ expect(controller.address.isActive).toBe(true);
});
describe('onSubmit()', () => {
it('should perform a PATCH and not set value to defaultAddressFk property', () => {
spyOn(controller.$state, 'go');
- controller.data.isDefaultAddress = false;
+ controller.address.isDefaultAddress = false;
controller.onSubmit();
expect(controller.client.defaultAddressFk).toEqual(121);
@@ -46,7 +45,7 @@ describe('Client', () => {
it('should perform a PATCH and set a value to defaultAddressFk property', () => {
spyOn(controller.$state, 'go');
- controller.data.isDefaultAddress = true;
+ controller.address.isDefaultAddress = true;
controller.onSubmit();
expect(controller.client.defaultAddressFk).toEqual(124);
diff --git a/modules/client/front/address/edit/index.html b/modules/client/front/address/edit/index.html
index 1032e25f5..ed331de2e 100644
--- a/modules/client/front/address/edit/index.html
+++ b/modules/client/front/address/edit/index.html
@@ -6,9 +6,9 @@
this.$.model.save(true))
.then(() => {
- this.$.watcher.notifySaved();
this.card.reload();
this.goToIndex();
});