Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 1798-e2e-extensions
This commit is contained in:
commit
7f745b95b8
|
@ -19,6 +19,9 @@
|
|||
},
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"isUeeMember": {
|
||||
"type": "Boolean"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
REPLACE INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('CustomsAgent', '*', '*', 'ALLOW', 'ROLE', 'employee');
|
|
@ -0,0 +1,11 @@
|
|||
CREATE TABLE `vn`.`customsAgent` (
|
||||
`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 UNIQUE KEY `nif_UNIQUE` (`nif`);
|
|
@ -0,0 +1,10 @@
|
|||
CREATE TABLE `vn`.`incoterms` (
|
||||
`code` varchar(3) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`name` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Internacional Commercial Terms';
|
||||
|
||||
ALTER TABLE `vn`.`incoterms`
|
||||
ADD PRIMARY KEY (`code`);
|
||||
|
||||
REPLACE INTO `vn`.`incoterms` (`code`, `name`) VALUES
|
||||
('FAS', 'Free Alongside Ship');
|
|
@ -0,0 +1,26 @@
|
|||
ALTER TABLE `vn`.`address`
|
||||
ADD COLUMN `customsAgentFk` INT NULL DEFAULT NULL AFTER `isEqualizated`;
|
||||
|
||||
ALTER TABLE `vn`.`address`
|
||||
ADD COLUMN `incotermsFk` VARCHAR(3) NULL DEFAULT NULL AFTER `customsAgentFk`;
|
||||
|
||||
|
||||
ALTER TABLE `vn`.`address`
|
||||
ADD INDEX `address_customsAgentFk_idx` (`customsAgentFk` ASC);
|
||||
|
||||
ALTER TABLE `vn`.`address`
|
||||
ADD INDEX `address_incotermsFk_idx` (`incotermsFk` ASC);
|
||||
|
||||
ALTER TABLE `vn`.`address`
|
||||
ADD CONSTRAINT `address_customsAgentFk`
|
||||
FOREIGN KEY (`customsAgentFk`)
|
||||
REFERENCES `vn`.`customsAgent` (`id`)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE `vn`.`address`
|
||||
ADD CONSTRAINT `address_incotermsFk`
|
||||
FOREIGN KEY (`incotermsFk`)
|
||||
REFERENCES `vn`.`incoterms` (`code`)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE;
|
|
@ -78,12 +78,13 @@ 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),
|
||||
(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);
|
||||
|
||||
|
@ -188,8 +189,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', 1, NULL);
|
||||
(4, 'Province four', 2, NULL),
|
||||
(5, 'Province five', 13, NULL);
|
||||
|
||||
INSERT INTO `vn`.`town`(`id`, `name`, `provinceFk`)
|
||||
VALUES
|
||||
|
@ -1961,3 +1962,12 @@ INSERT INTO `vn`.`travelThermograph`(`thermographFk`, `created`, `warehouseFk`,
|
|||
('TZ1905012010', CURDATE(), 1, 1, 'WARM', 'Temperature in range', 5),
|
||||
('138350-0', DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 'WARM', NULL, 5),
|
||||
('138350-0', CURDATE(), 1, NULL, 'COOL', NULL, NULL);
|
||||
|
||||
REPLACE INTO `vn`.`incoterms` (`code`, `name`)
|
||||
VALUES
|
||||
('FAS', 'Free Alongside Ship');
|
||||
|
||||
REPLACE 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');
|
|
@ -6,6 +6,7 @@ import {url as defaultURL} from './config';
|
|||
export async function getBrowser() {
|
||||
const browser = await Puppeteer.launch({
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
`--window-size=${ 1920 },${ 1080 }`
|
||||
],
|
||||
defaultViewport: null,
|
||||
|
|
|
@ -103,11 +103,13 @@ export default {
|
|||
streetAddressInput: '[ng-model="$ctrl.address.street"]',
|
||||
postcodeInput: '[ng-model="$ctrl.address.postalCode"]',
|
||||
cityInput: '[ng-model="$ctrl.address.city"]',
|
||||
provinceAutocomplete: 'vn-autocomplete[ng-model="$ctrl.address.provinceFk"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[ng-model="$ctrl.address.agencyModeFk"]',
|
||||
provinceAutocomplete: 'vn-autocomplete[ng-model="$ctrl.address.provinceId"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[ng-model="$ctrl.address.agencyModeId"]',
|
||||
phoneInput: '[ng-model="$ctrl.address.phone"]',
|
||||
mobileInput: '[ng-model="$ctrl.address.mobile"]',
|
||||
defaultAddress: 'vn-client-address-index div:nth-child(1) div[name="street"]',
|
||||
incotermsAutocomplete: 'vn-autocomplete[ng-model="$ctrl.address.incotermsId"]',
|
||||
customsAgentAutocomplete: 'vn-autocomplete[ng-model="$ctrl.address.customsAgentId"]',
|
||||
secondMakeDefaultStar: 'vn-client-address-index vn-card div:nth-child(2) vn-icon-button[icon="star_border"]',
|
||||
firstEditAddress: 'vn-client-address-index div:nth-child(1) > a',
|
||||
secondEditAddress: 'vn-client-address-index div:nth-child(2) > a',
|
||||
|
|
|
@ -74,7 +74,7 @@ describe('Client create path', async() => {
|
|||
await page.waitToClick(selectors.createClientView.createButton);
|
||||
const result = await page.waitForLastSnackbar();
|
||||
|
||||
expect(result).toEqual(`The postcode doesn't exists. Ensure you put the correct format`);
|
||||
expect(result).toEqual(`The postcode doesn't exist. Please enter a correct one`);
|
||||
});
|
||||
|
||||
it(`should check for autocompleted city, province and country`, async() => {
|
||||
|
|
|
@ -26,7 +26,7 @@ describe('Client Add address path', () => {
|
|||
|
||||
it('should receive an error after clicking save button as consignee, street and town fields are empty', async() => {
|
||||
await page.waitToClick(selectors.clientAddresses.defaultCheckboxInput);
|
||||
await page.autocompleteSearch(selectors.clientAddresses.provinceAutocomplete, 'Province one');
|
||||
await page.autocompleteSearch(selectors.clientAddresses.provinceAutocomplete, 'Province five');
|
||||
await page.write(selectors.clientAddresses.cityInput, 'Valencia');
|
||||
await page.write(selectors.clientAddresses.postcodeInput, '46000');
|
||||
await page.autocompleteSearch(selectors.clientAddresses.agencyAutocomplete, 'Entanglement');
|
||||
|
@ -38,12 +38,29 @@ describe('Client Add address path', () => {
|
|||
expect(result).toEqual('Some fields are invalid');
|
||||
});
|
||||
|
||||
it(`should create a new address with all it's data`, async() => {
|
||||
|
||||
it(`should receive an error after clicking save button as consignee, incoterms and customsAgent are empty`, async() => {
|
||||
await page.write(selectors.clientAddresses.consigneeInput, 'Bruce Bunner');
|
||||
await page.write(selectors.clientAddresses.streetAddressInput, '320 Park Avenue New York');
|
||||
await page.waitToClick(selectors.clientAddresses.saveButton);
|
||||
const result = await page.waitForLastSnackbar();
|
||||
|
||||
expect(result).toEqual('Incoterms is required for a non UEE member');
|
||||
});
|
||||
|
||||
it(`should receive an error after clicking save button as consignee, incoterms and customsAgent are empty`, async() => {
|
||||
await page.autocompleteSearch(selectors.clientAddresses.incotermsAutocomplete, 'Free Alongside Ship');
|
||||
await page.waitToClick(selectors.clientAddresses.saveButton);
|
||||
const result = await page.waitForLastSnackbar();
|
||||
|
||||
expect(result).toEqual('Customs agent is required for a non UEE member');
|
||||
});
|
||||
|
||||
it(`should create a new address with all it's data`, async() => {
|
||||
await page.autocompleteSearch(selectors.clientAddresses.customsAgentAutocomplete, 'Agent one');
|
||||
await page.waitToClick(selectors.clientAddresses.saveButton);
|
||||
const result = await page.waitForLastSnackbar();
|
||||
|
||||
expect(result).toEqual('Data saved!');
|
||||
});
|
||||
|
||||
|
|
|
@ -54,12 +54,14 @@
|
|||
"This ticket can not be modified": "This ticket can not be modified",
|
||||
"You can't delete a confirmed order": "You can't delete a confirmed order",
|
||||
"Value has an invalid format": "Value has an invalid format",
|
||||
"The postcode doesn't exists. Ensure you put the correct format": "The postcode doesn't exists. Ensure you put the correct format",
|
||||
"The postcode doesn't exist. Please enter a correct one": "The postcode doesn't exist. Please enter a correct one",
|
||||
"Can't create stowaway for this ticket": "Can't create stowaway for this ticket",
|
||||
"Has deleted the ticket id": "Has deleted the ticket id [#{{id}}]({{{url}}})",
|
||||
"Swift / BIC can't be empty": "Swift / BIC can't be empty",
|
||||
"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"
|
||||
}
|
|
@ -106,7 +106,7 @@
|
|||
"Invalid quantity": "Cantidad invalida",
|
||||
"This postal code is not valid": "This postal code is not valid",
|
||||
"is invalid": "is invalid",
|
||||
"The postcode doesn't exists. Ensure you put the correct format": "El código postal no existe. Asegúrate de ponerlo con el formato correcto",
|
||||
"The postcode doesn't exist. Please enter a correct one": "El código postal no existe. Por favor, introduce uno correcto",
|
||||
"The department name can't be repeated": "El nombre del departamento no puede repetirse",
|
||||
"This phone already exists": "Este teléfono ya existe",
|
||||
"You cannot move a parent to its own sons": "No puedes mover un elemento padre a uno de sus hijos",
|
||||
|
@ -119,6 +119,8 @@
|
|||
"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",
|
||||
"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",
|
||||
"MESSAGE_BOUGHT_UNITS": "Se ha comprado {{quantity}} unidades de {{concept}} (#{{itemId}}) para el ticket id [#{{ticketId}}]({{{url}}})",
|
||||
"MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} (#{{clientId}})]({{{url}}}) a *{{credit}} €*",
|
||||
"MESSAGE_CHANGED_PAYMETHOD": "He cambiado la forma de pago del cliente [{{clientName}} (#{{clientId}})]({{{url}}})",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -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 with no error thrown', 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);
|
||||
});
|
||||
});
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -97,5 +97,11 @@
|
|||
},
|
||||
"ClientDms": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"CustomsAgent": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Incoterms": {
|
||||
"dataSource": "vn"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,6 +22,22 @@ module.exports = Self => {
|
|||
done();
|
||||
}
|
||||
|
||||
Self.validateAsync('postalCode', hasValidPostcode, {
|
||||
message: `The postcode doesn't exist. Please enter a correct one`
|
||||
});
|
||||
|
||||
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 +55,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) {
|
||||
|
|
|
@ -73,6 +73,16 @@
|
|||
"type": "hasMany",
|
||||
"model": "AddressObservation",
|
||||
"foreignKey": "addressFk"
|
||||
},
|
||||
"incoterms": {
|
||||
"type": "belongsTo",
|
||||
"model": "Incoterms",
|
||||
"foreignKey": "incotermsFk"
|
||||
},
|
||||
"customsAgent": {
|
||||
"type": "belongsTo",
|
||||
"model": "CustomsAgent",
|
||||
"foreignKey": "customsAgentFk"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
@ -156,7 +158,7 @@ module.exports = Self => {
|
|||
}
|
||||
|
||||
Self.validateAsync('postCode', hasValidPostcode, {
|
||||
message: `The postcode doesn't exists. Ensure you put the correct format`
|
||||
message: `The postcode doesn't exist. Please enter a correct one`
|
||||
});
|
||||
|
||||
async function hasValidPostcode(err, done) {
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "CustomsAgent",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "customsAgent"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "Number",
|
||||
"description": "Identifier",
|
||||
"id": true
|
||||
},
|
||||
"fiscalName": {
|
||||
"type": "String",
|
||||
"required": true
|
||||
},
|
||||
"street": {
|
||||
"type": "String"
|
||||
},
|
||||
"nif": {
|
||||
"type": "String",
|
||||
"required": true
|
||||
},
|
||||
"phone": {
|
||||
"type": "String"
|
||||
},
|
||||
"email": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "Incoterms",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "incoterms"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "String",
|
||||
"description": "Identifier",
|
||||
"id": true
|
||||
},
|
||||
"name": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
"acls": [
|
||||
{
|
||||
"accessType": "READ",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
url="Addresses/createDefaultAddress"
|
||||
url="Clients/{{$ctrl.$params.id}}/createAddress"
|
||||
id-field="id"
|
||||
data="$ctrl.data"
|
||||
data="$ctrl.address"
|
||||
params="$ctrl.address"
|
||||
save="post"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
|
@ -19,7 +20,7 @@
|
|||
<vn-horizontal>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="Default" ng-model="$ctrl.data.isDefaultAddress">
|
||||
label="Default" ng-model="$ctrl.address.isDefaultAddress">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
|
@ -41,7 +42,7 @@
|
|||
<vn-autocomplete
|
||||
vn-one
|
||||
vn-id="province"
|
||||
ng-model="$ctrl.address.provinceFk"
|
||||
ng-model="$ctrl.address.provinceId"
|
||||
url="Provinces"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
|
@ -97,7 +98,7 @@
|
|||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-model="$ctrl.address.agencyModeFk"
|
||||
ng-model="$ctrl.address.agencyModeId"
|
||||
url="AgencyModes/isActive"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
|
@ -116,6 +117,29 @@
|
|||
rule>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
ng-model="$ctrl.address.incotermsId"
|
||||
url="Incoterms"
|
||||
show-field="name"
|
||||
value-field="code"
|
||||
label="Incoterms">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
ng-model="$ctrl.address.customsAgentId"
|
||||
url="CustomsAgents"
|
||||
show-field="fiscalName"
|
||||
value-field="id"
|
||||
label="Customs agent">
|
||||
<append>
|
||||
<vn-icon-button
|
||||
icon="add_circle"
|
||||
vn-tooltip="New customs agent"
|
||||
ng-click="$ctrl.showCustomAgent($event)">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Save"></vn-submit>
|
||||
|
@ -130,3 +154,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,17 +1,14 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from 'core/lib/component';
|
||||
|
||||
export default class Controller {
|
||||
constructor($, $state) {
|
||||
this.$ = $;
|
||||
this.$state = $state;
|
||||
this.data = {
|
||||
address: {
|
||||
clientFk: parseInt($state.params.id),
|
||||
isActive: true
|
||||
},
|
||||
export default class Controller extends Component {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
|
||||
this.address = {
|
||||
isActive: true,
|
||||
isDefaultAddress: false
|
||||
};
|
||||
this.address = this.data.address;
|
||||
}
|
||||
|
||||
get postcodeSelection() {
|
||||
|
@ -36,15 +33,27 @@ export default class Controller {
|
|||
|
||||
onSubmit() {
|
||||
this.$.watcher.submit().then(res => {
|
||||
if (res.data && this.data.isDefaultAddress)
|
||||
if (this.address.isDefaultAddress)
|
||||
this.client.defaultAddressFk = res.data.id;
|
||||
|
||||
this.$state.go('client.card.address.index');
|
||||
});
|
||||
}
|
||||
|
||||
showCustomAgent(event) {
|
||||
if (event.defaultPrevented) return;
|
||||
event.preventDefault();
|
||||
|
||||
this.$.customAgent.show();
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$state'];
|
||||
onCustomAgentAccept() {
|
||||
return this.$http.post(`CustomsAgents`, this.newCustomsAgent)
|
||||
.then(res => this.address.customsAgentFk = res.data.id);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -26,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);
|
||||
|
@ -42,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);
|
||||
|
@ -73,5 +76,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
|
|
@ -6,16 +6,16 @@
|
|||
</mg-ajax>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.address"
|
||||
url="Addresses"
|
||||
url="Clients/{{$ctrl.$params.id}}/updateAddress"
|
||||
id-field="id"
|
||||
data="$ctrl.address"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="AddressObservations"
|
||||
fields="['id', 'addressFk', 'observationTypeFk', 'description']"
|
||||
link="{addressFk: $ctrl.$stateParams.addressId}"
|
||||
link="{addressFk: $ctrl.$params.addressId}"
|
||||
data="observations"
|
||||
auto-load="true">
|
||||
</vn-crud-model>
|
||||
|
@ -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"
|
||||
|
@ -111,7 +111,6 @@
|
|||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
initial-data="$ctrl.address.agencyMode"
|
||||
ng-model="$ctrl.address.agencyModeFk"
|
||||
url="AgencyModes/isActive"
|
||||
show-field="name"
|
||||
|
@ -131,6 +130,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">
|
||||
<append>
|
||||
<vn-icon-button
|
||||
icon="add_circle"
|
||||
vn-tooltip="New customs agent"
|
||||
ng-click="$ctrl.showCustomAgent($event)">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-title>Notes</vn-title>
|
||||
<div name="observations">
|
||||
<vn-horizontal ng-repeat="observation in observations">
|
||||
|
@ -178,3 +200,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);
|
||||
|
@ -25,17 +20,26 @@ export default class Controller {
|
|||
}
|
||||
|
||||
onSubmit() {
|
||||
this.$.watcher.check();
|
||||
this.$.watcher.realSubmit()
|
||||
this.$.watcher.submit()
|
||||
.then(() => this.$.model.save(true))
|
||||
.then(() => {
|
||||
this.$.watcher.notifySaved();
|
||||
this.card.reload();
|
||||
this.goToIndex();
|
||||
});
|
||||
}
|
||||
|
||||
showCustomAgent(event) {
|
||||
if (event.defaultPrevented) return;
|
||||
event.preventDefault();
|
||||
|
||||
this.$.customAgent.show();
|
||||
}
|
||||
|
||||
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