merge
gitea/salix/test This commit looks good
Details
gitea/salix/test This commit looks good
Details
This commit is contained in:
commit
67733e6e08
|
@ -68,7 +68,6 @@ pipeline {
|
||||||
environment {
|
environment {
|
||||||
NODE_ENV = ""
|
NODE_ENV = ""
|
||||||
FIREFOX_BIN = "/opt/firefox/firefox-bin"
|
FIREFOX_BIN = "/opt/firefox/firefox-bin"
|
||||||
DB_HOST = "${env.DOCKER_HOST_2}"
|
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
nodejs('node-lts') {
|
nodejs('node-lts') {
|
||||||
|
|
|
@ -19,8 +19,8 @@ module.exports = Self => {
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.remoteMethod('getCurrentUserName', {
|
Self.remoteMethod('getCurrentUserData', {
|
||||||
description: 'Gets the current user name',
|
description: 'Gets the current user data',
|
||||||
accepts: [
|
accepts: [
|
||||||
{
|
{
|
||||||
arg: 'context',
|
arg: 'context',
|
||||||
|
@ -31,21 +31,22 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: 'string',
|
type: 'object',
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
verb: 'GET',
|
verb: 'GET',
|
||||||
path: '/getCurrentUserName'
|
path: '/getCurrentUserData'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getCurrentUserName = async function(ctx) {
|
Self.getCurrentUserData = async function(ctx) {
|
||||||
let filter = {fields: ['name']};
|
let filter = {fields: ['name']};
|
||||||
let userId = ctx.req.accessToken.userId;
|
let userId = ctx.req.accessToken.userId;
|
||||||
let account = await Self.findById(userId, filter);
|
let account = await Self.findById(userId, filter);
|
||||||
|
let worker = await Self.app.models.Worker.findOne({where: {userFk: userId}, fields: ['id']});
|
||||||
|
|
||||||
return account.name;
|
return {accountName: account.name, workerId: worker.id};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||||
|
VALUES
|
||||||
|
('Dms', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('ClaimDms', 'removeFile', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('ClaimDms', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Claim', 'uploadFile', 'WRITE', 'ALLOW', 'ROLE', 'employee');
|
|
@ -0,0 +1,15 @@
|
||||||
|
CREATE TABLE `vn`.`claimDms` (
|
||||||
|
`claimFk` INT UNSIGNED NOT NULL,
|
||||||
|
`dmsFk` INT NOT NULL,
|
||||||
|
PRIMARY KEY (`claimFk`, `dmsFk`),
|
||||||
|
INDEX `dmsFk_idx` (`dmsFk` ASC),
|
||||||
|
CONSTRAINT `claimFk`
|
||||||
|
FOREIGN KEY (`claimFk`)
|
||||||
|
REFERENCES `vn2008`.`cl_main` (`id`)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT `dmsFk`
|
||||||
|
FOREIGN KEY (`dmsFk`)
|
||||||
|
REFERENCES `vn2008`.`gestdoc` (`id`)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE);
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE `vn`.`claimLog`
|
||||||
|
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT ;
|
File diff suppressed because one or more lines are too long
|
@ -133,19 +133,13 @@ INSERT INTO `vn`.`payDem`(`id`, `payDem`)
|
||||||
(1, 10),
|
(1, 10),
|
||||||
(2, 20);
|
(2, 20);
|
||||||
|
|
||||||
INSERT INTO `vn2008`.`zones`(`zone_id`, `name`, `printingOrder`)
|
INSERT INTO `vn`.`province`(`id`, `name`, `countryFk`, `warehouseFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'zone one', 1),
|
(1, 'Province one', 1, NULL),
|
||||||
(2, 'zone two', 2),
|
(2, 'Province two', 1, NULL),
|
||||||
(3, 'zone three', 3);
|
(3, 'Province three', 1, NULL),
|
||||||
|
(4, 'Province four', 1, NULL),
|
||||||
INSERT INTO `vn`.`province`(`id`, `name`, `countryFk`, `warehouseFk`, `zoneFk`)
|
(5, 'Province five', 1, NULL);
|
||||||
VALUES
|
|
||||||
(1, 'Province one', 1, NULL, 1),
|
|
||||||
(2, 'Province two', 1, NULL, 2),
|
|
||||||
(3, 'Province three', 1, NULL, 3),
|
|
||||||
(4, 'Province four', 1, NULL, 2),
|
|
||||||
(5, 'Province five', 1, NULL, 1);
|
|
||||||
|
|
||||||
INSERT INTO `vn`.`town`(`id`, `name`, `provinceFk`)
|
INSERT INTO `vn`.`town`(`id`, `name`, `provinceFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -404,6 +398,18 @@ INSERT INTO `vn`.`invoiceOutTax` (`invoiceOutFk`, `taxableBase`, `vat`, `pgcFk`)
|
||||||
(4, 8.07, 0.81, 4770000010),
|
(4, 8.07, 0.81, 4770000010),
|
||||||
(5, 8.07, 0.81, 4770000010);
|
(5, 8.07, 0.81, 4770000010);
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`expence`(`id`, `taxTypeFk`, `name`, `isWithheld`)
|
||||||
|
VALUES
|
||||||
|
(2000000000, 1, 'Inmovilizado pendiente', 0),
|
||||||
|
(2000000000, 3, 'Compra de bienes de inmovilizado', 0),
|
||||||
|
(4751000000, 0, 'Retenciones', 1),
|
||||||
|
(4751000000, 1, 'Retenciones', 1),
|
||||||
|
(4751000000, 6, 'Retencion', 0),
|
||||||
|
(6210000567, 0, 'Alquiler VNH', 0),
|
||||||
|
(7001000000, 1, 'Mercaderia', 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO `vn`.`invoiceOutExpence`(`id`, `invoiceOutFk`, `amount`, `expenceFk`, `created`)
|
INSERT INTO `vn`.`invoiceOutExpence`(`id`, `invoiceOutFk`, `amount`, `expenceFk`, `created`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1, 813.06, 2000000000, CURDATE()),
|
(1, 1, 813.06, 2000000000, CURDATE()),
|
||||||
|
@ -435,8 +441,8 @@ INSERT INTO `vn`.`zone` (`id`, `name`, `hour`, `warehouseFk`, `agencyModeFk`, `t
|
||||||
(4, 'Zone 247 B', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 2, 7, 1, 2, 0),
|
(4, 'Zone 247 B', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 2, 7, 1, 2, 0),
|
||||||
(5, 'Zone expensive A', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 8, 1, 1000, 0),
|
(5, 'Zone expensive A', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 8, 1, 1000, 0),
|
||||||
(6, 'Zone expensive B', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 2, 8, 1, 1000, 0),
|
(6, 'Zone expensive B', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 2, 8, 1, 1000, 0),
|
||||||
(7, 'Zone refund', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 10, 0, 0, 0),
|
(7, 'Zone refund', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 23, 0, 0, 0),
|
||||||
(8, 'Zone others', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 23, 0, 0, 0),
|
(8, 'Zone others', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 10, 0, 0, 0),
|
||||||
(9, 'Zone superMan', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 2, 0, 0, 0),
|
(9, 'Zone superMan', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 2, 0, 0, 0),
|
||||||
(10, 'Zone teleportation', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 3, 3, 0, 0, 0),
|
(10, 'Zone teleportation', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 3, 3, 0, 0, 0),
|
||||||
(11, 'Zone pickup C', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 5, 1, 0, 0, 0),
|
(11, 'Zone pickup C', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 5, 1, 0, 0, 0),
|
||||||
|
@ -467,8 +473,8 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF
|
||||||
(20, 1, 5, 5, 3, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
(20, 1, 5, 5, 3, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||||
(21, NULL, 5, 5, NULL, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Holland', 102, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
(21, NULL, 5, 5, NULL, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Holland', 102, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||||
(22, NULL, 5, 5, NULL, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Japan', 103, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
(22, NULL, 5, 5, NULL, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Japan', 103, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||||
(23, NULL, 23, 1, NULL, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'address 21', 121, NULL, 0, 8, CURDATE()),
|
(23, NULL, 10, 1, NULL, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'address 21', 121, NULL, 0, 8, CURDATE()),
|
||||||
(24 ,NULL, 23, 1, NULL, CURDATE(), CURDATE(), 101, 'Bruce Wayne', 1, NULL, 0, 8, CURDATE());
|
(24 ,NULL, 10, 1, NULL, CURDATE(), CURDATE(), 101, 'Bruce Wayne', 1, NULL, 0, 8, CURDATE());
|
||||||
|
|
||||||
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
|
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1082,14 +1088,6 @@ INSERT INTO `vn2008`.`tblContadores`(`id`,`FechaInventario`)
|
||||||
VALUES
|
VALUES
|
||||||
(1,DATE_ADD(CURDATE(),INTERVAL -1 MONTH));
|
(1,DATE_ADD(CURDATE(),INTERVAL -1 MONTH));
|
||||||
|
|
||||||
INSERT INTO `vn2008`.`Estados` (`Id_Estado`, `Estado`)
|
|
||||||
VALUES
|
|
||||||
('1', 'En Espera');
|
|
||||||
|
|
||||||
INSERT INTO `vn2008`.`Informes` (`Id_Informe`, `Informe`)
|
|
||||||
VALUES
|
|
||||||
('30', 'Generar factura PDF');
|
|
||||||
|
|
||||||
INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`)
|
INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'AGENCY', 'Agencia'),
|
(1, 'AGENCY', 'Agencia'),
|
||||||
|
@ -1508,7 +1506,7 @@ INSERT INTO `vn`.`workCenter` (`id`, `name`, `warehouseFk`)
|
||||||
('1', 'Silla', '1'),
|
('1', 'Silla', '1'),
|
||||||
('5', 'Madrid', '5');
|
('5', 'Madrid', '5');
|
||||||
|
|
||||||
INSERT INTO `vn2008`.`workcenter_holiday` (`workcenter_id`, `day`, `year`)
|
INSERT INTO `vn`.`workCenterHoliday` (`workCenterFk`, `days`, `year`)
|
||||||
VALUES
|
VALUES
|
||||||
('1', '27.5', YEAR(CURDATE())),
|
('1', '27.5', YEAR(CURDATE())),
|
||||||
('5', '22', YEAR(CURDATE())),
|
('5', '22', YEAR(CURDATE())),
|
||||||
|
@ -1551,6 +1549,17 @@ INSERT INTO `vn`.`sharingCart`(`id`, `workerFk`, `started`, `ended`, `workerSubs
|
||||||
VALUES
|
VALUES
|
||||||
(1, 18, DATE_ADD(CURDATE(), INTERVAL -5 DAY), DATE_ADD(CURDATE(), INTERVAL +15 DAY), 19, DATE_ADD(CURDATE(), INTERVAL -5 DAY));
|
(1, 18, DATE_ADD(CURDATE(), INTERVAL -5 DAY), DATE_ADD(CURDATE(), INTERVAL +15 DAY), 19, DATE_ADD(CURDATE(), INTERVAL -5 DAY));
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`zoneGeo`(`id`, `name`, `lft`, `rgt`, `depth`, `sons`)
|
||||||
|
VALUES
|
||||||
|
(1, 'Origin', 1, 16, 0, 5),
|
||||||
|
(2, 'España', 2, 9, 1, 3),
|
||||||
|
(6, 'Valencia', 3, 8, 2, 2),
|
||||||
|
(7, 'Silla', 4, 7, 3, 1),
|
||||||
|
(8, '46460', 5, 6, 4, 0),
|
||||||
|
(3, 'Francia', 10, 11, 1, 0),
|
||||||
|
(4, 'Holanda', 12, 13, 1, 0),
|
||||||
|
(5, 'Portugal', 14, 15, 1, 0);
|
||||||
|
|
||||||
INSERT INTO `vn`.`zoneIncluded` (`zoneFk`, `geoFk`, `isIncluded`)
|
INSERT INTO `vn`.`zoneIncluded` (`zoneFk`, `geoFk`, `isIncluded`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 3, 0),
|
(1, 3, 0),
|
||||||
|
@ -1828,13 +1837,14 @@ INSERT INTO `vn`.`dmsType`(`id`, `name`, `path`, `readRoleFk`, `writeRoleFk`, `c
|
||||||
(16, 'Logistica', 'logistica', NULL, NULL, 'logistics'),
|
(16, 'Logistica', 'logistica', NULL, NULL, 'logistics'),
|
||||||
(17, 'cmr', 'cmr', NULL, NULL, 'cmr'),
|
(17, 'cmr', 'cmr', NULL, NULL, 'cmr'),
|
||||||
(18, 'dua', 'dua', NULL, NULL, 'dua'),
|
(18, 'dua', 'dua', NULL, NULL, 'dua'),
|
||||||
(19, 'inmovilizado', 'inmovilizado', NULL, NULL, 'fixedAssets');
|
(19, 'inmovilizado', 'inmovilizado', NULL, NULL, 'fixedAssets'),
|
||||||
|
(20, 'Reclamación', 'reclamacion', 1, 1, 'claim');
|
||||||
|
|
||||||
INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `warehouseFk`, `companyFk`, `hardCopyNumber`, `hasFile`, `reference`, `description`, `created`)
|
INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `warehouseFk`, `companyFk`, `hardCopyNumber`, `hasFile`, `reference`, `description`, `created`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 14, '1.txt', 'text/plain', 5, 1, 442, NULL, FALSE, 'Ticket:11', 'Ticket:11 dms for the ticket', CURDATE()),
|
(1, 14, '1.txt', 'text/plain', 5, 1, 442, NULL, FALSE, 'Ticket:11', 'Ticket:11 dms for the ticket', CURDATE()),
|
||||||
(2, 5, '2.txt', 'text/plain', 5, 1, 442, 1, TRUE, 'Client:101', 'Client:101 dms for the client', CURDATE()),
|
(2, 5, '2.txt', 'text/plain', 5, 1, 442, 1, TRUE, 'Client:104', 'Client:104 dms for the client', CURDATE()),
|
||||||
(3, 5, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Client: 101', 'Client:101 readme', CURDATE());
|
(3, 5, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Client: 104', 'Client:104 readme', CURDATE());
|
||||||
|
|
||||||
INSERT INTO `vn`.`ticketDms`(`ticketFk`, `dmsFk`)
|
INSERT INTO `vn`.`ticketDms`(`ticketFk`, `dmsFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1842,8 +1852,8 @@ INSERT INTO `vn`.`ticketDms`(`ticketFk`, `dmsFk`)
|
||||||
|
|
||||||
INSERT INTO `vn`.`clientDms`(`clientFk`, `dmsFk`)
|
INSERT INTO `vn`.`clientDms`(`clientFk`, `dmsFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(101, 2),
|
(104, 2),
|
||||||
(101, 3);
|
(104, 3);
|
||||||
|
|
||||||
INSERT INTO `vn`.`device` (`sn`, `model`, `userFk`)
|
INSERT INTO `vn`.`device` (`sn`, `model`, `userFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -41,7 +41,6 @@ TABLES=(
|
||||||
cplusTaxBreak
|
cplusTaxBreak
|
||||||
pgc
|
pgc
|
||||||
tag
|
tag
|
||||||
zoneGeo
|
|
||||||
)
|
)
|
||||||
dump_tables ${TABLES[@]}
|
dump_tables ${TABLES[@]}
|
||||||
|
|
||||||
|
@ -57,14 +56,12 @@ TABLES=(
|
||||||
container
|
container
|
||||||
department
|
department
|
||||||
escritos
|
escritos
|
||||||
Gastos
|
|
||||||
Grupos
|
Grupos
|
||||||
iva_group_codigo
|
iva_group_codigo
|
||||||
Monedas
|
Monedas
|
||||||
state
|
state
|
||||||
tarifa_componentes
|
tarifa_componentes
|
||||||
tarifa_componentes_series
|
tarifa_componentes_series
|
||||||
Tintas
|
|
||||||
)
|
)
|
||||||
dump_tables ${TABLES[@]}
|
dump_tables ${TABLES[@]}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,10 @@ module.exports = function createNightmare(width = 1280, height = 720) {
|
||||||
}).viewport(width, height);
|
}).viewport(width, height);
|
||||||
|
|
||||||
nightmare.on('console', (type, message, ...args) => {
|
nightmare.on('console', (type, message, ...args) => {
|
||||||
if (type === 'error')
|
if (type === 'error') {
|
||||||
|
console[type](message, ...args);
|
||||||
throw new Error(message);
|
throw new Error(message);
|
||||||
else
|
} else
|
||||||
console[type](message, ...args);
|
console[type](message, ...args);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -106,10 +106,10 @@ export default {
|
||||||
agencyAutocomplete: 'vn-autocomplete[field="$ctrl.address.agencyModeFk"]',
|
agencyAutocomplete: 'vn-autocomplete[field="$ctrl.address.agencyModeFk"]',
|
||||||
phoneInput: `${components.vnTextfield}[name="phone"]`,
|
phoneInput: `${components.vnTextfield}[name="phone"]`,
|
||||||
mobileInput: `${components.vnTextfield}[name="mobile"]`,
|
mobileInput: `${components.vnTextfield}[name="mobile"]`,
|
||||||
defaultAddress: 'vn-client-address-index vn-horizontal:nth-child(1) div[name="street"]',
|
defaultAddress: 'vn-client-address-index div:nth-child(1) div[name="street"]',
|
||||||
secondMakeDefaultStar: 'vn-client-address-index vn-card vn-horizontal:nth-child(2) vn-icon-button[icon="star_border"]',
|
secondMakeDefaultStar: 'vn-client-address-index vn-card div:nth-child(2) vn-icon-button[icon="star_border"]',
|
||||||
firstEditButton: 'vn-client-address-index vn-icon-button[icon="edit"]',
|
firstEditAddress: 'vn-client-address-index div:nth-child(1) > a',
|
||||||
secondEditButton: 'vn-client-address-index vn-horizontal:nth-child(2) vn-icon-button[icon="edit"]',
|
secondEditAddress: 'vn-client-address-index div:nth-child(2) > a',
|
||||||
activeCheckbox: 'vn-check[label="Enabled"] md-checkbox',
|
activeCheckbox: 'vn-check[label="Enabled"] md-checkbox',
|
||||||
equalizationTaxCheckbox: 'vn-client-address-edit vn-check[label="Is equalizated"] md-checkbox',
|
equalizationTaxCheckbox: 'vn-client-address-edit vn-check[label="Is equalizated"] md-checkbox',
|
||||||
firstObservationTypeAutocomplete: 'vn-client-address-edit [name=observations] :nth-child(1) [field="observation.observationTypeFk"]',
|
firstObservationTypeAutocomplete: 'vn-client-address-edit [name=observations] :nth-child(1) [field="observation.observationTypeFk"]',
|
||||||
|
@ -174,6 +174,12 @@ export default {
|
||||||
confirmFirstPaymentButton: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon-button[icon="done_all"]',
|
confirmFirstPaymentButton: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon-button[icon="done_all"]',
|
||||||
firstPaymentConfirmed: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon[icon="check"][aria-hidden="false"]'
|
firstPaymentConfirmed: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon[icon="check"][aria-hidden="false"]'
|
||||||
},
|
},
|
||||||
|
dms: {
|
||||||
|
deleteFileButton: 'vn-client-dms-index vn-table vn-tr:nth-child(1) vn-icon-button[icon="delete"]',
|
||||||
|
firstDocWorker: 'vn-client-dms-index vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(8) > span',
|
||||||
|
firstDocWorkerDescriptor: 'vn-client-dms-index > vn-worker-descriptor-popover > vn-popover',
|
||||||
|
acceptDeleteButton: 'vn-client-dms-index > vn-confirm button[response="ACCEPT"]'
|
||||||
|
},
|
||||||
itemsIndex: {
|
itemsIndex: {
|
||||||
searchIcon: 'vn-item-index vn-searchbar vn-icon[icon="search"]',
|
searchIcon: 'vn-item-index vn-searchbar vn-icon[icon="search"]',
|
||||||
createItemButton: `${components.vnFloatButton}`,
|
createItemButton: `${components.vnFloatButton}`,
|
||||||
|
@ -320,16 +326,20 @@ export default {
|
||||||
advancedSearchInvoiceOut: 'vn-ticket-index vn-searchbar vn-ticket-search-panel vn-textfield[model="filter.refFk"] input',
|
advancedSearchInvoiceOut: 'vn-ticket-index vn-searchbar vn-ticket-search-panel vn-textfield[model="filter.refFk"] input',
|
||||||
newTicketButton: 'vn-ticket-index > a',
|
newTicketButton: 'vn-ticket-index > a',
|
||||||
searchResult: 'vn-ticket-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
|
searchResult: 'vn-ticket-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
|
||||||
|
searchWeeklyResult: 'vn-ticket-weekly-index vn-table vn-tbody > vn-tr',
|
||||||
searchResultDate: 'vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(5)',
|
searchResultDate: 'vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(5)',
|
||||||
searchTicketInput: `vn-ticket-index ${components.vnTextfield}`,
|
searchTicketInput: `vn-ticket-index ${components.vnTextfield}`,
|
||||||
|
searchWeeklyTicketInput: `vn-ticket-weekly-index ${components.vnTextfield}`,
|
||||||
|
searchWeeklyClearInput: 'vn-ticket-weekly-index vn-searchbar i[class="material-icons clear"]',
|
||||||
advancedSearchButton: 'vn-ticket-index vn-searchbar > vn-popover vn-ticket-search-panel vn-submit[label="Search"] input',
|
advancedSearchButton: 'vn-ticket-index vn-searchbar > vn-popover vn-ticket-search-panel vn-submit[label="Search"] input',
|
||||||
searchButton: 'vn-ticket-index vn-searchbar vn-icon[icon="search"]',
|
searchButton: 'vn-ticket-index vn-searchbar vn-icon[icon="search"]',
|
||||||
|
searchWeeklyButton: 'vn-ticket-weekly-index vn-searchbar vn-icon[icon="search"]',
|
||||||
moreMenu: 'vn-ticket-index vn-icon-menu[vn-id="more-button"] > div > vn-icon',
|
moreMenu: 'vn-ticket-index vn-icon-menu[vn-id="more-button"] > div > vn-icon',
|
||||||
moreMenuTurns: 'vn-ticket-index vn-icon-menu vn-drop-down > vn-popover li:nth-child(2)',
|
moreMenuWeeklyTickets: 'vn-ticket-index vn-icon-menu vn-drop-down > vn-popover li:nth-child(2)',
|
||||||
sixthWeeklyTicketTurn: 'vn-ticket-weekly vn-table vn-tr:nth-child(6) vn-autocomplete[field="weekly.weekDay"] input',
|
sixthWeeklyTicket: 'vn-ticket-weekly-index vn-table vn-tr:nth-child(6) vn-autocomplete[field="weekly.weekDay"] input',
|
||||||
weeklyTicket: 'vn-ticket-weekly vn-table > div > vn-tbody > vn-tr',
|
weeklyTicket: 'vn-ticket-weekly-index vn-table > div > vn-tbody > vn-tr',
|
||||||
sixthWeeklyTicketDeleteIcon: 'vn-ticket-weekly vn-tr:nth-child(6) vn-icon-button[icon="delete"]',
|
firstWeeklyTicketDeleteIcon: 'vn-ticket-weekly-index vn-tr:nth-child(1) vn-icon-button[icon="delete"]',
|
||||||
acceptDeleteTurn: 'vn-ticket-weekly > vn-confirm[vn-id="deleteWeekly"] button[response="ACCEPT"]'
|
acceptDeleteTurn: 'vn-ticket-weekly-index > vn-confirm[vn-id="deleteWeekly"] button[response="ACCEPT"]'
|
||||||
},
|
},
|
||||||
createTicketView: {
|
createTicketView: {
|
||||||
clientAutocomplete: 'vn-ticket-create vn-autocomplete[field="$ctrl.clientFk"]',
|
clientAutocomplete: 'vn-ticket-create vn-autocomplete[field="$ctrl.clientFk"]',
|
||||||
|
@ -349,12 +359,16 @@ export default {
|
||||||
moreMenuAddToTurn: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Add turn"]',
|
moreMenuAddToTurn: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Add turn"]',
|
||||||
moreMenuDeleteTicket: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Delete ticket"]',
|
moreMenuDeleteTicket: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Delete ticket"]',
|
||||||
moreMenuMakeInvoice: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Make invoice"]',
|
moreMenuMakeInvoice: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Make invoice"]',
|
||||||
|
moreMenuChangeShippedHour: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Change shipped hour"]',
|
||||||
|
changeShippedHourInput: 'vn-ticket-descriptor > vn-dialog.ng-isolate-scope.vn-dialog.shown vn-input-time input',
|
||||||
addStowawayDialogFirstTicket: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog vn-table vn-tbody vn-tr',
|
addStowawayDialogFirstTicket: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog vn-table vn-tbody vn-tr',
|
||||||
shipButton: 'vn-ticket-descriptor > div > div.body > div.quicklinks vn-icon[icon="icon-stowaway"]',
|
shipButton: 'vn-ticket-descriptor > div > div.body > div.quicklinks vn-icon[icon="icon-stowaway"]',
|
||||||
thursdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(4)',
|
thursdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(4)',
|
||||||
saturdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(6)',
|
saturdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(6)',
|
||||||
closeStowawayDialog: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog > div > button[class="close"]',
|
closeStowawayDialog: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog > div > button[class="close"]',
|
||||||
acceptDeleteButton: 'vn-ticket-descriptor button[response="ACCEPT"]',
|
acceptDeleteButton: 'vn-ticket-descriptor button[response="ACCEPT"]',
|
||||||
|
acceptChangeHourButton: 'vn-ticket-descriptor vn-dialog[vn-id="changeShippedDialog"] button[response="ACCEPT"]',
|
||||||
|
descriptorDeliveryDate: 'vn-ticket-descriptor > div > div.body > div.attributes > vn-label-value:nth-child(6) > section > span',
|
||||||
acceptInvoiceOutButton: 'vn-ticket-descriptor vn-confirm[vn-id="makeInvoiceConfirmation"] button[response="ACCEPT"]',
|
acceptInvoiceOutButton: 'vn-ticket-descriptor vn-confirm[vn-id="makeInvoiceConfirmation"] button[response="ACCEPT"]',
|
||||||
acceptDeleteStowawayButton: 'vn-ticket-descriptor > vn-remove-stowaway button[response="ACCEPT"]'
|
acceptDeleteStowawayButton: 'vn-ticket-descriptor > vn-remove-stowaway button[response="ACCEPT"]'
|
||||||
},
|
},
|
||||||
|
@ -393,6 +407,8 @@ export default {
|
||||||
moreMenuUnmarkReseved: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] vn-drop-down > vn-popover ul > li[name="Unmark as reserved"]',
|
moreMenuUnmarkReseved: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] vn-drop-down > vn-popover ul > li[name="Unmark as reserved"]',
|
||||||
moreMenuUpdateDiscount: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] vn-drop-down > vn-popover ul > li[name="Update discount"]',
|
moreMenuUpdateDiscount: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] vn-drop-down > vn-popover ul > li[name="Update discount"]',
|
||||||
moreMenuUpdateDiscountInput: 'vn-ticket-sale vn-dialog form vn-ticket-sale-edit-discount vn-input-number[model="$ctrl.newDiscount"] input',
|
moreMenuUpdateDiscountInput: 'vn-ticket-sale vn-dialog form vn-ticket-sale-edit-discount vn-input-number[model="$ctrl.newDiscount"] input',
|
||||||
|
transferQuantityInput: 'vn-ticket-sale vn-popover.transfer.ng-isolate-scope.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text',
|
||||||
|
transferQuantityCell: 'vn-ticket-sale vn-popover.transfer.ng-isolate-scope.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable',
|
||||||
firstSaleClaimIcon: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) vn-icon[icon="icon-claims"]',
|
firstSaleClaimIcon: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) vn-icon[icon="icon-claims"]',
|
||||||
firstSaleDescriptorImage: 'vn-ticket-sale vn-item-descriptor-popover > vn-popover vn-item-descriptor img',
|
firstSaleDescriptorImage: 'vn-ticket-sale vn-item-descriptor-popover > vn-popover vn-item-descriptor img',
|
||||||
firstSaleText: 'vn-table div > vn-tbody > vn-tr:nth-child(1)',
|
firstSaleText: 'vn-table div > vn-tbody > vn-tr:nth-child(1)',
|
||||||
|
@ -416,13 +432,15 @@ export default {
|
||||||
secondSaleDiscount: 'vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(8)',
|
secondSaleDiscount: 'vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(8)',
|
||||||
secondSaleImport: 'vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(9)',
|
secondSaleImport: 'vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(9)',
|
||||||
secondSaleText: 'vn-table div > vn-tbody > vn-tr:nth-child(2)',
|
secondSaleText: 'vn-table div > vn-tbody > vn-tr:nth-child(2)',
|
||||||
|
secondSaleQuantity: 'vn-input-number[model="sale.quantity"]:nth-child(2) input',
|
||||||
|
secondSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(2) > vn-td-editable:nth-child(5)',
|
||||||
totalImport: 'vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-horizontal > vn-one > p:nth-child(3) > strong',
|
totalImport: 'vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-horizontal > vn-one > p:nth-child(3) > strong',
|
||||||
selectAllSalesCheckbox: 'vn-ticket-sale vn-thead vn-check md-checkbox',
|
selectAllSalesCheckbox: 'vn-ticket-sale vn-thead vn-check md-checkbox',
|
||||||
secondSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(2) vn-check[field="sale.checked"] md-checkbox',
|
secondSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(2) vn-check[field="sale.checked"] md-checkbox',
|
||||||
thirdSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(3) vn-check[field="sale.checked"] md-checkbox',
|
thirdSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(3) vn-check[field="sale.checked"] md-checkbox',
|
||||||
deleteSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="delete"]',
|
deleteSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="delete"]',
|
||||||
transferSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="call_split"]',
|
transferSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="call_split"]',
|
||||||
moveToTicketInput: 'vn-ticket-sale vn-popover.transfer vn-textfield[model="$ctrl.receiverTicketId"] input',
|
moveToTicketInput: 'vn-ticket-sale vn-popover.transfer vn-textfield[model="$ctrl.transfer.ticketId"] input',
|
||||||
moveToTicketInputClearButton: 'vn-popover.shown i[title="Clear"]',
|
moveToTicketInputClearButton: 'vn-popover.shown i[title="Clear"]',
|
||||||
moveToTicketButton: 'vn-ticket-sale vn-popover.transfer vn-icon[icon="arrow_forward_ios"]',
|
moveToTicketButton: 'vn-ticket-sale vn-popover.transfer vn-icon[icon="arrow_forward_ios"]',
|
||||||
moveToNewTicketButton: 'vn-ticket-sale vn-popover.transfer vn-button[label="New ticket"]',
|
moveToNewTicketButton: 'vn-ticket-sale vn-popover.transfer vn-button[label="New ticket"]',
|
||||||
|
@ -520,7 +538,7 @@ export default {
|
||||||
saveButton: `${components.vnSubmit}`
|
saveButton: `${components.vnSubmit}`
|
||||||
},
|
},
|
||||||
claimDetail: {
|
claimDetail: {
|
||||||
secondItemDiscount: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(7) > span',
|
secondItemDiscount: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(6) > span',
|
||||||
discountInput: 'vn-claim-detail vn-popover vn-input-number[model="$ctrl.newDiscount"] > div > div > div.infix > input',
|
discountInput: 'vn-claim-detail vn-popover vn-input-number[model="$ctrl.newDiscount"] > div > div > div.infix > input',
|
||||||
discoutPopoverMana: 'vn-claim-detail > vn-popover > div > div.content > div > vn-horizontal > h5',
|
discoutPopoverMana: 'vn-claim-detail > vn-popover > div > div.content > div > vn-horizontal > h5',
|
||||||
addItemButton: 'vn-claim-detail a vn-float-button',
|
addItemButton: 'vn-claim-detail a vn-float-button',
|
||||||
|
@ -528,7 +546,7 @@ export default {
|
||||||
claimDetailLine: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr',
|
claimDetailLine: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr',
|
||||||
firstItemQuantityInput: 'vn-claim-detail vn-tr:nth-child(1) vn-input-number[model="saleClaimed.quantity"] input',
|
firstItemQuantityInput: 'vn-claim-detail vn-tr:nth-child(1) vn-input-number[model="saleClaimed.quantity"] input',
|
||||||
totalClaimed: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-horizontal > div > vn-label-value:nth-child(2) > section > span',
|
totalClaimed: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-horizontal > div > vn-label-value:nth-child(2) > section > span',
|
||||||
secondItemDeleteButton: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(9) > vn-icon-button > button > vn-icon > i'
|
secondItemDeleteButton: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(8) > vn-icon-button > button > vn-icon > i'
|
||||||
},
|
},
|
||||||
claimDevelopment: {
|
claimDevelopment: {
|
||||||
addDevelopmentButton: 'vn-claim-development > vn-vertical > vn-card > div > vn-vertical > vn-one > vn-icon-button > button > vn-icon',
|
addDevelopmentButton: 'vn-claim-development > vn-vertical > vn-card > div > vn-vertical > vn-one > vn-icon-button > button > vn-icon',
|
||||||
|
@ -562,6 +580,10 @@ export default {
|
||||||
searchButton: 'vn-order-index vn-searchbar vn-icon[icon="search"]',
|
searchButton: 'vn-order-index vn-searchbar vn-icon[icon="search"]',
|
||||||
createOrderButton: `${components.vnFloatButton}`,
|
createOrderButton: `${components.vnFloatButton}`,
|
||||||
},
|
},
|
||||||
|
orderDescriptor: {
|
||||||
|
returnToModuleIndexButton: 'vn-order-descriptor a[ui-sref="order.index"]',
|
||||||
|
acceptNavigationButton: 'vn-order-basic-data vn-confirm button[response=ACCEPT]'
|
||||||
|
},
|
||||||
createOrderView: {
|
createOrderView: {
|
||||||
clientAutocomplete: 'vn-autocomplete[label="Client"]',
|
clientAutocomplete: 'vn-autocomplete[label="Client"]',
|
||||||
addressAutocomplete: 'vn-autocomplete[label="Address"]',
|
addressAutocomplete: 'vn-autocomplete[label="Address"]',
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe('Client Edit fiscalData path', () => {
|
||||||
// Confirms all addresses have EQtax false for future propagation test step 1
|
// Confirms all addresses have EQtax false for future propagation test step 1
|
||||||
it(`should click on the 1st edit icon to check EQtax isnt checked`, async() => {
|
it(`should click on the 1st edit icon to check EQtax isnt checked`, async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.clientAddresses.firstEditButton)
|
.waitToClick(selectors.clientAddresses.firstEditAddress)
|
||||||
.checkboxState(selectors.clientAddresses.equalizationTaxCheckbox);
|
.checkboxState(selectors.clientAddresses.equalizationTaxCheckbox);
|
||||||
|
|
||||||
expect(result).toBe('unchecked');
|
expect(result).toBe('unchecked');
|
||||||
|
@ -24,7 +24,7 @@ describe('Client Edit fiscalData path', () => {
|
||||||
it(`should go back to addresses then select the second one and confirm the EQtax isnt checked`, async() => {
|
it(`should go back to addresses then select the second one and confirm the EQtax isnt checked`, async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.clientAddresses.addressesButton)
|
.waitToClick(selectors.clientAddresses.addressesButton)
|
||||||
.waitToClick(selectors.clientAddresses.secondEditButton)
|
.waitToClick(selectors.clientAddresses.secondEditAddress)
|
||||||
.checkboxState(selectors.clientAddresses.equalizationTaxCheckbox);
|
.checkboxState(selectors.clientAddresses.equalizationTaxCheckbox);
|
||||||
|
|
||||||
expect(result).toBe('unchecked');
|
expect(result).toBe('unchecked');
|
||||||
|
@ -67,6 +67,7 @@ describe('Client Edit fiscalData path', () => {
|
||||||
.write(selectors.clientFiscalData.fiscalIdInput, 'INVALID!')
|
.write(selectors.clientFiscalData.fiscalIdInput, 'INVALID!')
|
||||||
.clearInput(selectors.clientFiscalData.addressInput)
|
.clearInput(selectors.clientFiscalData.addressInput)
|
||||||
.write(selectors.clientFiscalData.addressInput, 'Somewhere edited')
|
.write(selectors.clientFiscalData.addressInput, 'Somewhere edited')
|
||||||
|
.autocompleteSearch(selectors.clientFiscalData.cityAutocomplete, 'Valencia')
|
||||||
.autocompleteSearch(selectors.clientFiscalData.postcodeAutocomplete, '46000')
|
.autocompleteSearch(selectors.clientFiscalData.postcodeAutocomplete, '46000')
|
||||||
.waitToClick(selectors.clientFiscalData.activeCheckbox)
|
.waitToClick(selectors.clientFiscalData.activeCheckbox)
|
||||||
.waitToClick(selectors.clientFiscalData.frozenCheckbox)
|
.waitToClick(selectors.clientFiscalData.frozenCheckbox)
|
||||||
|
@ -80,7 +81,7 @@ describe('Client Edit fiscalData path', () => {
|
||||||
.waitForLastSnackbar();
|
.waitForLastSnackbar();
|
||||||
|
|
||||||
expect(result).toEqual('Invalid Tax number');
|
expect(result).toEqual('Invalid Tax number');
|
||||||
}, 15000);
|
});
|
||||||
|
|
||||||
it(`should edit the fiscal this time with a valid fiscal id`, async() => {
|
it(`should edit the fiscal this time with a valid fiscal id`, async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
|
@ -134,7 +135,7 @@ describe('Client Edit fiscalData path', () => {
|
||||||
// confirm all addresses have now EQtax checked step 2
|
// confirm all addresses have now EQtax checked step 2
|
||||||
it(`should click on the 1st edit icon to confirm EQtax is checked`, async() => {
|
it(`should click on the 1st edit icon to confirm EQtax is checked`, async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.clientAddresses.firstEditButton)
|
.waitToClick(selectors.clientAddresses.firstEditAddress)
|
||||||
.checkboxState(selectors.clientAddresses.equalizationTaxCheckbox);
|
.checkboxState(selectors.clientAddresses.equalizationTaxCheckbox);
|
||||||
|
|
||||||
expect(result).toBe('checked');
|
expect(result).toBe('checked');
|
||||||
|
@ -144,7 +145,7 @@ describe('Client Edit fiscalData path', () => {
|
||||||
it(`should go back to addresses then select the second one and confirm the EQtax is checked`, async() => {
|
it(`should go back to addresses then select the second one and confirm the EQtax is checked`, async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.clientAddresses.addressesButton)
|
.waitToClick(selectors.clientAddresses.addressesButton)
|
||||||
.waitToClick(selectors.clientAddresses.secondEditButton)
|
.waitToClick(selectors.clientAddresses.secondEditAddress)
|
||||||
.checkboxState(selectors.clientAddresses.equalizationTaxCheckbox);
|
.checkboxState(selectors.clientAddresses.equalizationTaxCheckbox);
|
||||||
|
|
||||||
expect(result).toBe('checked');
|
expect(result).toBe('checked');
|
||||||
|
@ -289,7 +290,7 @@ describe('Client Edit fiscalData path', () => {
|
||||||
// confirm invoice by address checkbox gets checked if the EQtax differs between addresses step 2
|
// confirm invoice by address checkbox gets checked if the EQtax differs between addresses step 2
|
||||||
it(`should click on the 1st edit icon to access the address details and uncheck EQtax checkbox`, async() => {
|
it(`should click on the 1st edit icon to access the address details and uncheck EQtax checkbox`, async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.clientAddresses.firstEditButton)
|
.waitToClick(selectors.clientAddresses.firstEditAddress)
|
||||||
.waitToClick(selectors.clientAddresses.equalizationTaxCheckbox)
|
.waitToClick(selectors.clientAddresses.equalizationTaxCheckbox)
|
||||||
.waitToClick(selectors.clientAddresses.saveButton)
|
.waitToClick(selectors.clientAddresses.saveButton)
|
||||||
.waitForLastSnackbar();
|
.waitForLastSnackbar();
|
||||||
|
|
|
@ -68,7 +68,7 @@ describe('Client Add address path', () => {
|
||||||
|
|
||||||
it(`should click on the addresses button confirm the new address exists and it's the default one`, async() => {
|
it(`should click on the addresses button confirm the new address exists and it's the default one`, async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.clientAddresses.addressesButton)
|
// .waitToClick(selectors.clientAddresses.addressesButton)
|
||||||
.waitToGetProperty(selectors.clientAddresses.defaultAddress, 'innerText');
|
.waitToGetProperty(selectors.clientAddresses.defaultAddress, 'innerText');
|
||||||
|
|
||||||
expect(result).toContain('320 Park Avenue New York');
|
expect(result).toContain('320 Park Avenue New York');
|
||||||
|
@ -86,7 +86,7 @@ describe('Client Add address path', () => {
|
||||||
it(`should click on the edit icon of the default address`, async() => {
|
it(`should click on the edit icon of the default address`, async() => {
|
||||||
const url = await nightmare
|
const url = await nightmare
|
||||||
.waitForTextInElement(selectors.clientAddresses.defaultAddress, 'Somewhere in Thailand')
|
.waitForTextInElement(selectors.clientAddresses.defaultAddress, 'Somewhere in Thailand')
|
||||||
.waitToClick(selectors.clientAddresses.firstEditButton)
|
.waitToClick(selectors.clientAddresses.firstEditAddress)
|
||||||
.waitForURL('/edit')
|
.waitForURL('/edit')
|
||||||
.parsedUrl();
|
.parsedUrl();
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe('Client add address notes path', () => {
|
||||||
it(`should click on the edit icon of the default address`, async() => {
|
it(`should click on the edit icon of the default address`, async() => {
|
||||||
const url = await nightmare
|
const url = await nightmare
|
||||||
.waitForTextInElement(selectors.clientAddresses.defaultAddress, '20 Ingram Street')
|
.waitForTextInElement(selectors.clientAddresses.defaultAddress, '20 Ingram Street')
|
||||||
.waitToClick(selectors.clientAddresses.firstEditButton)
|
.waitToClick(selectors.clientAddresses.firstEditAddress)
|
||||||
.waitForURL('/edit')
|
.waitForURL('/edit')
|
||||||
.parsedUrl();
|
.parsedUrl();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import selectors from '../../helpers/selectors.js';
|
||||||
|
import createNightmare from '../../helpers/nightmare';
|
||||||
|
|
||||||
|
describe('Client DMS', () => {
|
||||||
|
const nightmare = createNightmare();
|
||||||
|
|
||||||
|
describe('as salesPerson', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
nightmare
|
||||||
|
.loginAndModule('salesPerson', 'client')
|
||||||
|
.accessToSearchResult('Tony Stark')
|
||||||
|
.accessToSection('client.card.dms.index');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete de first file', async() => {
|
||||||
|
let result = await nightmare
|
||||||
|
.waitToClick(selectors.dms.deleteFileButton)
|
||||||
|
.waitToClick(selectors.dms.acceptDeleteButton)
|
||||||
|
.waitForLastSnackbar();
|
||||||
|
|
||||||
|
expect(result).toEqual('Data saved!');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should click on the first document line worker name making the descriptor visible`, async() => {
|
||||||
|
const visible = await nightmare
|
||||||
|
.waitToClick(selectors.dms.firstDocWorker)
|
||||||
|
.waitForClassPresent(selectors.dms.firstDocWorkerDescriptor, 'shown')
|
||||||
|
.isVisible(selectors.dms.firstDocWorkerDescriptor);
|
||||||
|
|
||||||
|
expect(visible).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -11,6 +11,7 @@ describe('Item summary path', () => {
|
||||||
|
|
||||||
it('should search for an item', async() => {
|
it('should search for an item', async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
|
.clearInput(selectors.itemsIndex.searchItemInput)
|
||||||
.write(selectors.itemsIndex.searchItemInput, 'Ranged weapon longbow 2m')
|
.write(selectors.itemsIndex.searchItemInput, 'Ranged weapon longbow 2m')
|
||||||
.waitToClick(selectors.itemsIndex.searchButton)
|
.waitToClick(selectors.itemsIndex.searchButton)
|
||||||
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1)
|
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1)
|
||||||
|
|
|
@ -11,6 +11,7 @@ describe('Item Create/Clone path', () => {
|
||||||
|
|
||||||
it(`should search for the item Infinity Gauntlet to confirm it isn't created yet`, async() => {
|
it(`should search for the item Infinity Gauntlet to confirm it isn't created yet`, async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
|
.clearInput(selectors.itemsIndex.searchItemInput)
|
||||||
.write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet')
|
.write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet')
|
||||||
.waitToClick(selectors.itemsIndex.searchButton)
|
.waitToClick(selectors.itemsIndex.searchButton)
|
||||||
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 0)
|
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 0)
|
||||||
|
@ -95,6 +96,7 @@ describe('Item Create/Clone path', () => {
|
||||||
|
|
||||||
it(`should search for the item Infinity Gauntlet`, async() => {
|
it(`should search for the item Infinity Gauntlet`, async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
|
.clearInput(selectors.itemsIndex.searchItemInput)
|
||||||
.write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet')
|
.write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet')
|
||||||
.waitToClick(selectors.itemsIndex.searchButton)
|
.waitToClick(selectors.itemsIndex.searchButton)
|
||||||
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1)
|
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1)
|
||||||
|
@ -117,6 +119,7 @@ describe('Item Create/Clone path', () => {
|
||||||
it('should search for the item Infinity Gauntlet and find two', async() => {
|
it('should search for the item Infinity Gauntlet and find two', async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.itemTags.goToItemIndexButton)
|
.waitToClick(selectors.itemTags.goToItemIndexButton)
|
||||||
|
.clearInput(selectors.itemsIndex.searchItemInput)
|
||||||
.write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet')
|
.write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet')
|
||||||
.waitToClick(selectors.itemsIndex.searchButton)
|
.waitToClick(selectors.itemsIndex.searchButton)
|
||||||
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 2)
|
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 2)
|
||||||
|
|
|
@ -11,6 +11,7 @@ describe('Item regularize path', () => {
|
||||||
|
|
||||||
it('should edit the user local warehouse', async() => {
|
it('should edit the user local warehouse', async() => {
|
||||||
let result = await nightmare
|
let result = await nightmare
|
||||||
|
.waitForSpinnerLoad()
|
||||||
.waitToClick(selectors.globalItems.userMenuButton)
|
.waitToClick(selectors.globalItems.userMenuButton)
|
||||||
.autocompleteSearch(selectors.globalItems.userLocalWarehouse, 'Warehouse Four')
|
.autocompleteSearch(selectors.globalItems.userLocalWarehouse, 'Warehouse Four')
|
||||||
.waitForLastSnackbar();
|
.waitForLastSnackbar();
|
||||||
|
@ -28,6 +29,7 @@ describe('Item regularize path', () => {
|
||||||
|
|
||||||
it('should search for the item', async() => {
|
it('should search for the item', async() => {
|
||||||
const resultCount = await nightmare
|
const resultCount = await nightmare
|
||||||
|
.clearInput(selectors.itemsIndex.searchItemInput)
|
||||||
.write(selectors.itemsIndex.searchItemInput, 'Ranged weapon pistol 9mm')
|
.write(selectors.itemsIndex.searchItemInput, 'Ranged weapon pistol 9mm')
|
||||||
.waitToClick(selectors.itemsIndex.searchButton)
|
.waitToClick(selectors.itemsIndex.searchButton)
|
||||||
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1)
|
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1)
|
||||||
|
@ -133,6 +135,7 @@ describe('Item regularize path', () => {
|
||||||
|
|
||||||
it('should search for the item once again', async() => {
|
it('should search for the item once again', async() => {
|
||||||
const resultCount = await nightmare
|
const resultCount = await nightmare
|
||||||
|
.clearInput(selectors.itemsIndex.searchItemInput)
|
||||||
.write(selectors.itemsIndex.searchItemInput, 'Ranged weapon pistol 9mm')
|
.write(selectors.itemsIndex.searchItemInput, 'Ranged weapon pistol 9mm')
|
||||||
.waitToClick(selectors.itemsIndex.searchButton)
|
.waitToClick(selectors.itemsIndex.searchButton)
|
||||||
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1)
|
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1)
|
||||||
|
|
|
@ -30,17 +30,6 @@ describe('Ticket Create new tracking state path', () => {
|
||||||
expect(result).toEqual('State cannot be blank');
|
expect(result).toEqual('State cannot be blank');
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should attempt create a new state then clear and save it`, async() => {
|
|
||||||
let result = await nightmare
|
|
||||||
.autocompleteSearch(selectors.createStateView.stateAutocomplete, '¿Fecha?')
|
|
||||||
.waitToClick(selectors.createStateView.clearStateInputButton)
|
|
||||||
.waitToClick(selectors.createStateView.saveStateButton)
|
|
||||||
.waitForLastSnackbar();
|
|
||||||
|
|
||||||
expect(result).toEqual('State cannot be blank');
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it(`should create a new state`, async() => {
|
it(`should create a new state`, async() => {
|
||||||
let result = await nightmare
|
let result = await nightmare
|
||||||
.autocompleteSearch(selectors.createStateView.stateAutocomplete, '¿Fecha?')
|
.autocompleteSearch(selectors.createStateView.stateAutocomplete, '¿Fecha?')
|
||||||
|
@ -77,18 +66,16 @@ describe('Ticket Create new tracking state path', () => {
|
||||||
expect(result).toEqual(`You don't have enough privileges`);
|
expect(result).toEqual(`You don't have enough privileges`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should attempt to create an state for the type salesPerson has rights but fail as worker is blank`, async() => {
|
it(`should make sure the worker gets autocomplete uppon selecting the assigned state`, async() => {
|
||||||
let result = await nightmare
|
let result = await nightmare
|
||||||
.autocompleteSearch(selectors.createStateView.stateAutocomplete, 'asignado')
|
.autocompleteSearch(selectors.createStateView.stateAutocomplete, 'asignado')
|
||||||
.waitToClick(selectors.createStateView.saveStateButton)
|
.waitToGetProperty(`${selectors.createStateView.workerAutocomplete} input`, 'value');
|
||||||
.waitForLastSnackbar();
|
|
||||||
|
|
||||||
expect(result).toEqual(`Worker cannot be blank`);
|
expect(result).toEqual('salesPersonNick');
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should create a new state with all it's data`, async() => {
|
it(`should succesfully create a valid state`, async() => {
|
||||||
let result = await nightmare
|
let result = await nightmare
|
||||||
.autocompleteSearch(selectors.createStateView.workerAutocomplete, 'replenisher')
|
|
||||||
.waitToClick(selectors.createStateView.saveStateButton)
|
.waitToClick(selectors.createStateView.saveStateButton)
|
||||||
.waitForLastSnackbar();
|
.waitForLastSnackbar();
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,58 @@ describe('Ticket Edit basic data path', () => {
|
||||||
.accessToSection('ticket.card.basicData.stepOne');
|
.accessToSection('ticket.card.basicData.stepOne');
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should edit the ticket agency then click next`, async() => {
|
it(`should confirm the zone autocomplete is disabled unless your role is productionBoss`, async() => {
|
||||||
|
const disabled = await nightmare
|
||||||
|
.wait(selectors.ticketBasicData.zoneAutocomplete)
|
||||||
|
.evaluate(selector => {
|
||||||
|
return document.querySelector(selector).disabled;
|
||||||
|
}, `${selectors.ticketBasicData.zoneAutocomplete} input`);
|
||||||
|
|
||||||
|
expect(disabled).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should now log as productionBoss to perform the rest of the tests`, async() => {
|
||||||
|
await nightmare
|
||||||
|
.loginAndModule('productionBoss', 'ticket')
|
||||||
|
.accessToSearchResult(11)
|
||||||
|
.accessToSection('ticket.card.basicData.stepOne');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should confirm the zone autocomplete is enabled for the role productionBoss`, async() => {
|
||||||
|
const disabled = await nightmare
|
||||||
|
.wait(selectors.ticketBasicData.zoneAutocomplete)
|
||||||
|
.evaluate(selector => {
|
||||||
|
return document.querySelector(selector).disabled;
|
||||||
|
}, `${selectors.ticketBasicData.zoneAutocomplete} input`);
|
||||||
|
|
||||||
|
expect(disabled).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should check the zone is for Silla247`, async() => {
|
||||||
|
let zone = await nightmare
|
||||||
|
.waitToGetProperty(`${selectors.ticketBasicData.zoneAutocomplete} input`, 'value');
|
||||||
|
|
||||||
|
expect(zone).toContain('Zone 247 A');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should edit the ticket agency then check there are no zones for it`, async() => {
|
||||||
|
let zone = await nightmare
|
||||||
|
.autocompleteSearch(selectors.ticketBasicData.agencyAutocomplete, 'Entanglement')
|
||||||
|
.getProperty(`${selectors.ticketBasicData.zoneAutocomplete} input`, 'value');
|
||||||
|
|
||||||
|
expect(zone.length).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should edit the ticket zone then check the agency is for the new zone`, async() => {
|
||||||
|
let zone = await nightmare
|
||||||
|
.autocompleteSearch(selectors.ticketBasicData.zoneAutocomplete, 'Zone expensive A')
|
||||||
|
.waitToGetProperty(`${selectors.ticketBasicData.agencyAutocomplete} input`, 'value');
|
||||||
|
|
||||||
|
expect(zone).toContain('Silla247Expensive');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should click next`, async() => {
|
||||||
let url = await nightmare
|
let url = await nightmare
|
||||||
.autocompleteSearch(selectors.ticketBasicData.agencyAutocomplete, 'Silla247Expensive')
|
|
||||||
.waitToGetProperty(`${selectors.ticketBasicData.zoneAutocomplete} input`, 'value')
|
|
||||||
.waitToClick(selectors.ticketBasicData.nextStepButton)
|
.waitToClick(selectors.ticketBasicData.nextStepButton)
|
||||||
.waitForURL('data/step-two')
|
.waitForURL('data/step-two')
|
||||||
.parsedUrl();
|
.parsedUrl();
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import selectors from '../../helpers/selectors.js';
|
import selectors from '../../helpers/selectors.js';
|
||||||
import createNightmare from '../../helpers/nightmare';
|
import createNightmare from '../../helpers/nightmare';
|
||||||
|
|
||||||
describe('Ticket Edit sale path', () => {
|
// #1632 [e2e] ticket.sale - Transferir líneas
|
||||||
|
xdescribe('Ticket Edit sale path', () => {
|
||||||
const nightmare = createNightmare();
|
const nightmare = createNightmare();
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
|
@ -257,12 +258,14 @@ describe('Ticket Edit sale path', () => {
|
||||||
expect(result).toEqual(3);
|
expect(result).toEqual(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should select the third sale and transfer it to a valid ticket', async() => {
|
it('should select the second sale and transfer it to a valid ticket', async() => {
|
||||||
const targetTicketId = 12;
|
const targetTicketId = 12;
|
||||||
|
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.ticketSales.thirdSaleCheckbox)
|
.waitToClick(selectors.ticketSales.secondSaleCheckbox)
|
||||||
.waitToClick(selectors.ticketSales.transferSaleButton)
|
.waitToClick(selectors.ticketSales.transferSaleButton)
|
||||||
|
.focusElement(selectors.ticketSales.transferQuantityCell)
|
||||||
|
.write(selectors.ticketSales.transferQuantityInput, '10\u000d')
|
||||||
.write(selectors.ticketSales.moveToTicketInput, targetTicketId)
|
.write(selectors.ticketSales.moveToTicketInput, targetTicketId)
|
||||||
.waitToClick(selectors.ticketSales.moveToTicketButton)
|
.waitToClick(selectors.ticketSales.moveToTicketButton)
|
||||||
.waitForURL(`ticket/${targetTicketId}/sale`)
|
.waitForURL(`ticket/${targetTicketId}/sale`)
|
||||||
|
@ -276,7 +279,14 @@ describe('Ticket Edit sale path', () => {
|
||||||
.wait(selectors.ticketSales.secondSaleText)
|
.wait(selectors.ticketSales.secondSaleText)
|
||||||
.waitToGetProperty(selectors.ticketSales.secondSaleText, 'innerText');
|
.waitToGetProperty(selectors.ticketSales.secondSaleText, 'innerText');
|
||||||
|
|
||||||
expect(result).toContain(`Ranged weapon longbow 2m`);
|
expect(result).toContain(`Melee weapon heavy shield`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should confirm the transfered quantity is the correct one', async() => {
|
||||||
|
const result = await nightmare
|
||||||
|
.waitToGetProperty(selectors.ticketSales.secondSaleQuantityCell, 'innerText');
|
||||||
|
|
||||||
|
expect(result).toContain('10');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should go back to the original ticket sales section', async() => {
|
it('should go back to the original ticket sales section', async() => {
|
||||||
|
@ -290,12 +300,19 @@ describe('Ticket Edit sale path', () => {
|
||||||
expect(url.hash).toContain('/sale');
|
expect(url.hash).toContain('/sale');
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should confirm the original ticket has only two lines now`, async() => {
|
it(`should confirm the original ticket has still three lines`, async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.wait(selectors.ticketSales.saleLine)
|
.wait(selectors.ticketSales.saleLine)
|
||||||
.countElement(selectors.ticketSales.saleLine);
|
.countElement(selectors.ticketSales.saleLine);
|
||||||
|
|
||||||
expect(result).toEqual(2);
|
expect(result).toEqual(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should confirm the second sale quantity is now half of it's original value after the transfer`, async() => {
|
||||||
|
const result = await nightmare
|
||||||
|
.waitToGetProperty(selectors.ticketSales.secondSaleQuantityCell, 'innerText');
|
||||||
|
|
||||||
|
expect(result).toContain('10');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should go back to the receiver ticket sales section', async() => {
|
it('should go back to the receiver ticket sales section', async() => {
|
||||||
|
@ -324,11 +341,12 @@ describe('Ticket Edit sale path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should confirm the original ticket received the line', async() => {
|
it('should confirm the original ticket received the line', async() => {
|
||||||
|
const expectedLines = 4;
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitForNumberOfElements(selectors.ticketSales.saleLine, 3)
|
.waitForNumberOfElements(selectors.ticketSales.saleLine, expectedLines)
|
||||||
.countElement(selectors.ticketSales.saleLine);
|
.countElement(selectors.ticketSales.saleLine);
|
||||||
|
|
||||||
expect(result).toEqual(3);
|
expect(result).toEqual(expectedLines);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should throw an error when attempting to create a ticket for an inactive client`, async() => {
|
it(`should throw an error when attempting to create a ticket for an inactive client`, async() => {
|
||||||
|
@ -357,7 +375,7 @@ describe('Ticket Edit sale path', () => {
|
||||||
const senderTicketId = 13;
|
const senderTicketId = 13;
|
||||||
|
|
||||||
const url = await nightmare
|
const url = await nightmare
|
||||||
.waitToClick(selectors.ticketSales.firstSaleCheckbox)
|
.waitToClick(selectors.ticketSales.selectAllSalesCheckbox)
|
||||||
.waitToClick(selectors.ticketSales.transferSaleButton)
|
.waitToClick(selectors.ticketSales.transferSaleButton)
|
||||||
.waitToClick(selectors.ticketSales.moveToNewTicketButton)
|
.waitToClick(selectors.ticketSales.moveToNewTicketButton)
|
||||||
.waitToClick(selectors.ticketSales.acceptDeleteTicketButton)
|
.waitToClick(selectors.ticketSales.acceptDeleteTicketButton)
|
||||||
|
|
|
@ -9,10 +9,10 @@ describe('Ticket descriptor path', () => {
|
||||||
.loginAndModule('employee', 'ticket');
|
.loginAndModule('employee', 'ticket');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should count the mount of tickets in the turns section', async() => {
|
it('should count the amount of tickets in the turns section', async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.ticketsIndex.moreMenu)
|
.waitToClick(selectors.ticketsIndex.moreMenu)
|
||||||
.waitToClick(selectors.ticketsIndex.moreMenuTurns)
|
.waitToClick(selectors.ticketsIndex.moreMenuWeeklyTickets)
|
||||||
.wait(selectors.ticketsIndex.weeklyTicket)
|
.wait(selectors.ticketsIndex.weeklyTicket)
|
||||||
.countElement(selectors.ticketsIndex.weeklyTicket);
|
.countElement(selectors.ticketsIndex.weeklyTicket);
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ describe('Ticket descriptor path', () => {
|
||||||
|
|
||||||
it('should search for the ticket 11', async() => {
|
it('should search for the ticket 11', async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.write(selectors.ticketsIndex.searchTicketInput, 'id:11')
|
.write(selectors.ticketsIndex.searchTicketInput, 11)
|
||||||
.waitToClick(selectors.ticketsIndex.searchButton)
|
.waitToClick(selectors.ticketsIndex.searchButton)
|
||||||
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
|
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
|
||||||
.countElement(selectors.ticketsIndex.searchResult);
|
.countElement(selectors.ticketsIndex.searchResult);
|
||||||
|
@ -73,8 +73,8 @@ describe('Ticket descriptor path', () => {
|
||||||
it('should confirm the ticket 11 was added on thursday', async() => {
|
it('should confirm the ticket 11 was added on thursday', async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.ticketsIndex.moreMenu)
|
.waitToClick(selectors.ticketsIndex.moreMenu)
|
||||||
.waitToClick(selectors.ticketsIndex.moreMenuTurns)
|
.waitToClick(selectors.ticketsIndex.moreMenuWeeklyTickets)
|
||||||
.waitToGetProperty(selectors.ticketsIndex.sixthWeeklyTicketTurn, 'value');
|
.waitToGetProperty(selectors.ticketsIndex.sixthWeeklyTicket, 'value');
|
||||||
|
|
||||||
expect(result).toEqual('Thursday');
|
expect(result).toEqual('Thursday');
|
||||||
});
|
});
|
||||||
|
@ -92,7 +92,7 @@ describe('Ticket descriptor path', () => {
|
||||||
|
|
||||||
it('should now search for the ticket 11', async() => {
|
it('should now search for the ticket 11', async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.write(selectors.ticketsIndex.searchTicketInput, 'id:11')
|
.write(selectors.ticketsIndex.searchTicketInput, 11)
|
||||||
.waitToClick(selectors.ticketsIndex.searchButton)
|
.waitToClick(selectors.ticketsIndex.searchButton)
|
||||||
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
|
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
|
||||||
.countElement(selectors.ticketsIndex.searchResult);
|
.countElement(selectors.ticketsIndex.searchResult);
|
||||||
|
@ -133,17 +133,25 @@ describe('Ticket descriptor path', () => {
|
||||||
it('should confirm the ticket 11 was added on saturday', async() => {
|
it('should confirm the ticket 11 was added on saturday', async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.ticketsIndex.moreMenu)
|
.waitToClick(selectors.ticketsIndex.moreMenu)
|
||||||
.waitToClick(selectors.ticketsIndex.moreMenuTurns)
|
.waitToClick(selectors.ticketsIndex.moreMenuWeeklyTickets)
|
||||||
.waitToGetProperty(selectors.ticketsIndex.sixthWeeklyTicketTurn, 'value');
|
.waitToGetProperty(selectors.ticketsIndex.sixthWeeklyTicket, 'value');
|
||||||
|
|
||||||
expect(result).toEqual('Saturday');
|
expect(result).toEqual('Saturday');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test #1450 here
|
it('should now search for the weekly ticket 11', async() => {
|
||||||
|
const result = await nightmare
|
||||||
|
.write(selectors.ticketsIndex.searchWeeklyTicketInput, 11)
|
||||||
|
.waitToClick(selectors.ticketsIndex.searchWeeklyButton)
|
||||||
|
.waitForNumberOfElements(selectors.ticketsIndex.searchWeeklyResult, 1)
|
||||||
|
.countElement(selectors.ticketsIndex.searchWeeklyResult);
|
||||||
|
|
||||||
|
expect(result).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
it('should delete the weekly ticket 11', async() => {
|
it('should delete the weekly ticket 11', async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.ticketsIndex.sixthWeeklyTicketDeleteIcon)
|
.waitToClick(selectors.ticketsIndex.firstWeeklyTicketDeleteIcon)
|
||||||
.waitToClick(selectors.ticketsIndex.acceptDeleteTurn)
|
.waitToClick(selectors.ticketsIndex.acceptDeleteTurn)
|
||||||
.waitForLastSnackbar();
|
.waitForLastSnackbar();
|
||||||
|
|
||||||
|
@ -152,7 +160,10 @@ describe('Ticket descriptor path', () => {
|
||||||
|
|
||||||
it('should confirm the sixth weekly ticket was deleted', async() => {
|
it('should confirm the sixth weekly ticket was deleted', async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.countElement(selectors.ticketsIndex.weeklyTicket);
|
.waitToClick('vn-ticket-weekly-index vn-searchbar i[class="material-icons clear"]')
|
||||||
|
.waitToClick(selectors.ticketsIndex.searchWeeklyButton)
|
||||||
|
.waitForNumberOfElements(selectors.ticketsIndex.searchWeeklyResult, 5)
|
||||||
|
.countElement(selectors.ticketsIndex.searchWeeklyResult);
|
||||||
|
|
||||||
expect(result).toEqual(5);
|
expect(result).toEqual(5);
|
||||||
});
|
});
|
|
@ -30,6 +30,33 @@ describe('Ticket descriptor path', () => {
|
||||||
expect(url.hash).toContain('/summary');
|
expect(url.hash).toContain('/summary');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should open the change shipped hours dialog by using the more menu option', async() => {
|
||||||
|
const visible = await nightmare
|
||||||
|
.waitToClick(selectors.ticketDescriptor.moreMenu)
|
||||||
|
.waitToClick(selectors.ticketDescriptor.moreMenuChangeShippedHour)
|
||||||
|
.wait(selectors.ticketDescriptor.changeShippedHourInput)
|
||||||
|
.isVisible(selectors.ticketDescriptor.changeShippedHourInput);
|
||||||
|
|
||||||
|
|
||||||
|
expect(visible).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should update the shipped hour`, async() => {
|
||||||
|
const result = await nightmare
|
||||||
|
.write(selectors.ticketDescriptor.changeShippedHourInput, '0815')
|
||||||
|
.waitToClick(selectors.ticketDescriptor.acceptChangeHourButton)
|
||||||
|
.waitForLastSnackbar();
|
||||||
|
|
||||||
|
expect(result).toEqual('Shipped hour updated');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should confirm the ticket descriptor shows the correct shipping hour`, async() => {
|
||||||
|
const result = await nightmare
|
||||||
|
.waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText');
|
||||||
|
|
||||||
|
expect(result).toContain('08:15');
|
||||||
|
});
|
||||||
|
|
||||||
it('should delete the ticket using the descriptor more menu', async() => {
|
it('should delete the ticket using the descriptor more menu', async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitToClick(selectors.ticketDescriptor.moreMenu)
|
.waitToClick(selectors.ticketDescriptor.moreMenu)
|
||||||
|
|
|
@ -69,14 +69,6 @@ describe('Ticket Summary path', () => {
|
||||||
expect(exists).toBeTruthy();
|
expect(exists).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click on the SET OK button and throw a privileges error', async() => {
|
|
||||||
let result = await nightmare
|
|
||||||
.waitToClick(selectors.ticketSummary.setOk)
|
|
||||||
.waitForLastSnackbar();
|
|
||||||
|
|
||||||
expect(result).toEqual(`You don't have enough privileges`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log in as production then navigate to the summary of the same ticket', async() => {
|
it('should log in as production then navigate to the summary of the same ticket', async() => {
|
||||||
let url = await nightmare
|
let url = await nightmare
|
||||||
.loginAndModule('production', 'ticket')
|
.loginAndModule('production', 'ticket')
|
||||||
|
|
|
@ -7,7 +7,7 @@ describe('Claim action path', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
nightmare
|
nightmare
|
||||||
.loginAndModule('administrative', 'claim')
|
.loginAndModule('administrative', 'claim')
|
||||||
.accessToSearchResult(4)
|
.accessToSearchResult(2)
|
||||||
.accessToSection('claim.card.action');
|
.accessToSection('claim.card.action');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@ describe('Order edit basic data path', () => {
|
||||||
it('should now navigate to order index', async() => {
|
it('should now navigate to order index', async() => {
|
||||||
const orderId = 16;
|
const orderId = 16;
|
||||||
const url = await nightmare
|
const url = await nightmare
|
||||||
.waitToClick(selectors.globalItems.returnToModuleIndexButton)
|
.waitToClick(selectors.orderDescriptor.returnToModuleIndexButton)
|
||||||
.waitToClick(selectors.globalItems.acceptButton)
|
.waitToClick(selectors.orderDescriptor.acceptNavigationButton)
|
||||||
.wait(selectors.ordersIndex.createOrderButton)
|
.wait(selectors.ordersIndex.createOrderButton)
|
||||||
.accessToSearchResult(orderId)
|
.accessToSearchResult(orderId)
|
||||||
.accessToSection('order.card.basicData')
|
.accessToSection('order.card.basicData')
|
||||||
|
|
|
@ -18,7 +18,10 @@
|
||||||
ng-blur="$ctrl.hasFocus = false"
|
ng-blur="$ctrl.hasFocus = false"
|
||||||
tabindex="{{$ctrl.input.tabindex}}"
|
tabindex="{{$ctrl.input.tabindex}}"
|
||||||
accept="{{$ctrl.accept}}"/>
|
accept="{{$ctrl.accept}}"/>
|
||||||
<label class="label" translate>{{$ctrl.label}}</label>
|
<label class="label">
|
||||||
|
<span translate>{{::$ctrl.label}}</span>
|
||||||
|
<span translate ng-show="::$ctrl.required">*</span>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="underline"></div>
|
<div class="underline"></div>
|
||||||
<div class="selected underline"></div>
|
<div class="selected underline"></div>
|
||||||
|
|
|
@ -122,6 +122,7 @@ ngModule.component('vnInputFile', {
|
||||||
name: '@?',
|
name: '@?',
|
||||||
disabled: '<?',
|
disabled: '<?',
|
||||||
multiple: '<?',
|
multiple: '<?',
|
||||||
|
required: '@?',
|
||||||
accept: '@?',
|
accept: '@?',
|
||||||
rule: '@?',
|
rule: '@?',
|
||||||
files: '=model',
|
files: '=model',
|
||||||
|
|
|
@ -73,6 +73,14 @@ export default class Popover extends Component {
|
||||||
if (this._shown) return;
|
if (this._shown) return;
|
||||||
|
|
||||||
if (parent) this.parent = parent;
|
if (parent) this.parent = parent;
|
||||||
|
|
||||||
|
let isDescriptorMoreMenu = parent && parent.attributes[0].nodeValue == 'more-button';
|
||||||
|
const leftMenu = this.document.querySelector('div[class="menu left"]');
|
||||||
|
if (isDescriptorMoreMenu && leftMenu) {
|
||||||
|
leftMenu.style.overflow = 'hidden';
|
||||||
|
this.restoreOverflow = true;
|
||||||
|
}
|
||||||
|
|
||||||
this._shown = true;
|
this._shown = true;
|
||||||
this.element.style.display = 'block';
|
this.element.style.display = 'block';
|
||||||
this.$timeout.cancel(this.showTimeout);
|
this.$timeout.cancel(this.showTimeout);
|
||||||
|
@ -96,6 +104,11 @@ export default class Popover extends Component {
|
||||||
hide() {
|
hide() {
|
||||||
if (!this._shown) return;
|
if (!this._shown) return;
|
||||||
|
|
||||||
|
if (this.restoreOverflow) {
|
||||||
|
const leftMenu = this.document.querySelector('div[class="menu left"]');
|
||||||
|
leftMenu.style.overflow = 'auto';
|
||||||
|
this.restoreOverflow = false;
|
||||||
|
}
|
||||||
this._shown = false;
|
this._shown = false;
|
||||||
this.$element.removeClass('shown');
|
this.$element.removeClass('shown');
|
||||||
this.$timeout.cancel(this.showTimeout);
|
this.$timeout.cancel(this.showTimeout);
|
||||||
|
|
|
@ -28,7 +28,6 @@ export default class Controller extends Component {
|
||||||
() => this.onStateChange());
|
() => this.onStateChange());
|
||||||
|
|
||||||
this._filter = null;
|
this._filter = null;
|
||||||
this.searchString = '';
|
|
||||||
this.autoLoad = false;
|
this.autoLoad = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +57,10 @@ export default class Controller extends Component {
|
||||||
this.doSearch();
|
this.doSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get shownFilter() {
|
||||||
|
return this._filter != null ? this._filter : this.suggestedFilter;
|
||||||
|
}
|
||||||
|
|
||||||
openPanel(event) {
|
openPanel(event) {
|
||||||
if (event.defaultPrevented) return;
|
if (event.defaultPrevented) return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -65,7 +68,8 @@ export default class Controller extends Component {
|
||||||
this.$panelScope = this.$.$new();
|
this.$panelScope = this.$.$new();
|
||||||
this.$panel = this.$compile(`<${this.panel}/>`)(this.$panelScope);
|
this.$panel = this.$compile(`<${this.panel}/>`)(this.$panelScope);
|
||||||
let panel = this.$panel.isolateScope().$ctrl;
|
let panel = this.$panel.isolateScope().$ctrl;
|
||||||
panel.filter = this._filter;
|
if (this.shownFilter)
|
||||||
|
panel.filter = JSON.parse(JSON.stringify(this.shownFilter));
|
||||||
panel.onSubmit = filter => this.onPanelSubmit(filter);
|
panel.onSubmit = filter => this.onPanelSubmit(filter);
|
||||||
|
|
||||||
this.$.popover.parent = this.element;
|
this.$.popover.parent = this.element;
|
||||||
|
@ -94,13 +98,12 @@ export default class Controller extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
doSearch() {
|
doSearch() {
|
||||||
let filter = this._filter;
|
this.searchString = this.getStringFromObject(this.shownFilter);
|
||||||
|
|
||||||
|
let filter = this._filter;
|
||||||
if (filter == null && this.autoload)
|
if (filter == null && this.autoload)
|
||||||
filter = {};
|
filter = {};
|
||||||
|
|
||||||
this.searchString = this.getStringFromObject(filter);
|
|
||||||
|
|
||||||
if (this.onSearch)
|
if (this.onSearch)
|
||||||
this.onSearch({$params: filter});
|
this.onSearch({$params: filter});
|
||||||
|
|
||||||
|
@ -214,6 +217,7 @@ ngModule.component('vnSearchbar', {
|
||||||
template: require('./searchbar.html'),
|
template: require('./searchbar.html'),
|
||||||
bindings: {
|
bindings: {
|
||||||
filter: '<?',
|
filter: '<?',
|
||||||
|
suggestedFilter: '<?',
|
||||||
onSearch: '&?',
|
onSearch: '&?',
|
||||||
panel: '@',
|
panel: '@',
|
||||||
model: '<?',
|
model: '<?',
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
tabindex="{{$ctrl.input.tabindex}}"/>
|
tabindex="{{$ctrl.input.tabindex}}"/>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span translate>{{::$ctrl.label}}</span>
|
<span translate>{{::$ctrl.label}}</span>
|
||||||
<span translate vn-tooltip="Required" ng-show="::$ctrl.required">*</span>
|
<span translate ng-show="::$ctrl.required">*</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="underline"></div>
|
<div class="underline"></div>
|
||||||
|
|
|
@ -16,9 +16,10 @@ export default class MainMenu {
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentUserName() {
|
getCurrentUserName() {
|
||||||
this.$http.get('/api/Accounts/getCurrentUserName')
|
this.$http.get('/api/Accounts/getCurrentUserData')
|
||||||
.then(json => {
|
.then(json => {
|
||||||
this.$.currentUserName = json.data;
|
this.$.currentUserName = json.data.accountName;
|
||||||
|
window.localStorage.currentUserWorkerId = json.data.workerId;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ describe('Component vnMainMenu', () => {
|
||||||
|
|
||||||
describe('getCurrentUserName()', () => {
|
describe('getCurrentUserName()', () => {
|
||||||
it(`should set the user name property in the controller`, () => {
|
it(`should set the user name property in the controller`, () => {
|
||||||
$httpBackend.when('GET', `/api/Accounts/getCurrentUserName`).respond('Batman');
|
$httpBackend.when('GET', `/api/Accounts/getCurrentUserData`).respond({accountName: 'Batman'});
|
||||||
$httpBackend.expect('GET', `/api/Accounts/getCurrentUserName`);
|
$httpBackend.expect('GET', `/api/Accounts/getCurrentUserData`);
|
||||||
controller.getCurrentUserName();
|
controller.getCurrentUserName();
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
|
11
gulpfile.js
11
gulpfile.js
|
@ -23,9 +23,6 @@ let containerId = 'salix-db';
|
||||||
let dataSources = require('./loopback/server/datasources.json');
|
let dataSources = require('./loopback/server/datasources.json');
|
||||||
let dbConf = dataSources.vn;
|
let dbConf = dataSources.vn;
|
||||||
|
|
||||||
if (process.env.DB_HOST)
|
|
||||||
dbConf.host = process.env.DB_HOST;
|
|
||||||
|
|
||||||
let backSources = [
|
let backSources = [
|
||||||
'!node_modules',
|
'!node_modules',
|
||||||
'loopback',
|
'loopback',
|
||||||
|
@ -423,9 +420,11 @@ async function docker() {
|
||||||
containerId = result.stdout;
|
containerId = result.stdout;
|
||||||
|
|
||||||
if (argv['random']) {
|
if (argv['random']) {
|
||||||
let inspect = await execP(`docker inspect -f "{{json .NetworkSettings.Ports}}" ${containerId}`);
|
let inspect = await execP(`docker inspect -f "{{json .NetworkSettings}}" ${containerId}`);
|
||||||
let ports = JSON.parse(inspect.stdout);
|
let netSettings = JSON.parse(inspect.stdout);
|
||||||
dbConf.port = ports['3306/tcp'][0]['HostPort'];
|
|
||||||
|
dbConf.host = netSettings.Gateway;
|
||||||
|
dbConf.port = netSettings.Ports['3306/tcp'][0]['HostPort'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runChown) await dockerWait();
|
if (runChown) await dockerWait();
|
||||||
|
|
|
@ -49,5 +49,9 @@
|
||||||
"This client can't be invoiced": "This client can't be invoiced",
|
"This client can't be invoiced": "This client can't be invoiced",
|
||||||
"The introduced hour already exists": "The introduced hour already exists",
|
"The introduced hour already exists": "The introduced hour already exists",
|
||||||
"Invalid parameters to create a new ticket": "Invalid parameters to create a new ticket",
|
"Invalid parameters to create a new ticket": "Invalid parameters to create a new ticket",
|
||||||
"Concept cannot be blank": "Concept cannot be blank"
|
"Concept cannot be blank": "Concept cannot be blank",
|
||||||
|
"Ticket id cannot be blank": "Ticket id cannot be blank",
|
||||||
|
"Weekday cannot be blank": "Weekday cannot be blank",
|
||||||
|
"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"
|
||||||
}
|
}
|
|
@ -97,5 +97,9 @@
|
||||||
"This postcode already exists": "Este código postal ya existe",
|
"This postcode already exists": "Este código postal ya existe",
|
||||||
"Concept cannot be blank": "El concepto no puede quedar en blanco",
|
"Concept cannot be blank": "El concepto no puede quedar en blanco",
|
||||||
"File doesn't exists": "El archivo no existe",
|
"File doesn't exists": "El archivo no existe",
|
||||||
"You don't have privileges to change the zone": "No tienes permisos para cambiar la zona"
|
"You don't have privileges to change the zone": "No tienes permisos para cambiar la zona",
|
||||||
|
"This ticket is already on weekly tickets": "Este ticket ya está en tickets programados",
|
||||||
|
"Ticket id cannot be blank": "El id de ticket no puede quedar en blanco",
|
||||||
|
"Weekday cannot be blank": "El día de la semana no puede quedar en blanco",
|
||||||
|
"You can't delete a confirmed order": "No puedes borrar un pedido confirmado"
|
||||||
}
|
}
|
|
@ -20,11 +20,16 @@
|
||||||
"connector": "loopback-component-storage",
|
"connector": "loopback-component-storage",
|
||||||
"provider": "filesystem",
|
"provider": "filesystem",
|
||||||
"root": "./e2e/dms",
|
"root": "./e2e/dms",
|
||||||
"maxFileSize": "10485760",
|
"maxFileSize": "52428800",
|
||||||
"allowedContentTypes": [
|
"allowedContentTypes": [
|
||||||
|
"application/x-7z-compressed",
|
||||||
|
"application/x-zip-compressed",
|
||||||
|
"application/x-rar-compressed",
|
||||||
|
"application/octet-stream",
|
||||||
"application/pdf",
|
"application/pdf",
|
||||||
"application/zip",
|
"application/zip",
|
||||||
"application/rar",
|
"application/rar",
|
||||||
|
"multipart/x-zip",
|
||||||
"image/png",
|
"image/png",
|
||||||
"image/jpeg",
|
"image/jpeg",
|
||||||
"image/jpg"
|
"image/jpg"
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('allowedContentTypes', {
|
||||||
|
description: 'Returns a list of allowed contentTypes',
|
||||||
|
accessType: 'READ',
|
||||||
|
returns: {
|
||||||
|
type: ['Object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/allowedContentTypes`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.allowedContentTypes = async() => {
|
||||||
|
const storageConnector = Self.app.dataSources.storage.connector;
|
||||||
|
const allowedContentTypes = storageConnector.allowedContentTypes;
|
||||||
|
const modelAllowedContentTypes = Self.definition.settings.allowedContentTypes;
|
||||||
|
|
||||||
|
return modelAllowedContentTypes || allowedContentTypes;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('removeFile', {
|
||||||
|
description: 'Removes a ticket document',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: {
|
||||||
|
arg: 'id',
|
||||||
|
type: 'Number',
|
||||||
|
description: 'The document id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
returns: {
|
||||||
|
type: 'Object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/:id/removeFile`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.removeFile = async(ctx, id) => {
|
||||||
|
const models = Self.app.models;
|
||||||
|
const targetClaimDms = await models.ClaimDms.findById(id);
|
||||||
|
const targetDms = await models.Dms.findById(targetClaimDms.dmsFk);
|
||||||
|
const trashDmsType = await models.DmsType.findOne({where: {code: 'trash'}});
|
||||||
|
|
||||||
|
await models.Dms.removeFile(ctx, targetClaimDms.dmsFk);
|
||||||
|
await targetClaimDms.destroy();
|
||||||
|
|
||||||
|
return targetDms.updateAttribute('dmsTypeFk', trashDmsType.id);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
|
describe('TicketDms removeFile()', () => {
|
||||||
|
const ticketDmsId = 1;
|
||||||
|
it(`should return an error for a user without enough privileges`, async() => {
|
||||||
|
let clientId = 101;
|
||||||
|
let ctx = {req: {accessToken: {userId: clientId}}};
|
||||||
|
|
||||||
|
let error;
|
||||||
|
await app.models.TicketDms.removeFile(ctx, ticketDmsId).catch(e => {
|
||||||
|
error = e;
|
||||||
|
}).finally(() => {
|
||||||
|
expect(error.message).toEqual(`You don't have enough privileges`);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(error).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,78 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('uploadFile', {
|
||||||
|
description: 'Upload and attach a document',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'Number',
|
||||||
|
description: 'The claim id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'warehouseId',
|
||||||
|
type: 'Number',
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'companyId',
|
||||||
|
type: 'Number',
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'dmsTypeId',
|
||||||
|
type: 'Number',
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'reference',
|
||||||
|
type: 'String',
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'description',
|
||||||
|
type: 'String',
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'hasFile',
|
||||||
|
type: 'Boolean',
|
||||||
|
description: ''
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: 'Object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/:id/uploadFile`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.uploadFile = async(ctx, id) => {
|
||||||
|
const models = Self.app.models;
|
||||||
|
const promises = [];
|
||||||
|
const tx = await Self.beginTransaction({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const uploadedFiles = await models.Dms.uploadFile(ctx, options);
|
||||||
|
uploadedFiles.forEach(dms => {
|
||||||
|
const newClaimDms = models.ClaimDms.create({
|
||||||
|
claimFk: id,
|
||||||
|
dmsFk: dms.id
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
promises.push(newClaimDms);
|
||||||
|
});
|
||||||
|
const resolvedPromises = await Promise.all(promises);
|
||||||
|
|
||||||
|
await tx.commit();
|
||||||
|
|
||||||
|
return resolvedPromises;
|
||||||
|
} catch (err) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -31,5 +31,11 @@
|
||||||
},
|
},
|
||||||
"ClaimState": {
|
"ClaimState": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"ClaimDms": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"ClaimLog": {
|
||||||
|
"dataSource": "vn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
require('../methods/claim-dms/removeFile')(Self);
|
||||||
|
require('../methods/claim-dms/allowedContentTypes')(Self);
|
||||||
|
};
|
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
"name": "ClaimDms",
|
||||||
|
"base": "Loggable",
|
||||||
|
"log": {
|
||||||
|
"model": "ClaimLog",
|
||||||
|
"relation": "claim"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "claimDms"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"allowedContentTypes": [
|
||||||
|
"image/png",
|
||||||
|
"image/jpeg",
|
||||||
|
"image/jpg"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"dmsFk": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"claim": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Claim",
|
||||||
|
"foreignKey": "claimFk"
|
||||||
|
},
|
||||||
|
"dms": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Dms",
|
||||||
|
"foreignKey": "dmsFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
{
|
||||||
|
"name": "ClaimLog",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "claimLog"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"id": true,
|
||||||
|
"type": "Number",
|
||||||
|
"forceId": false
|
||||||
|
},
|
||||||
|
"originFk": {
|
||||||
|
"type": "Number",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"userFk": {
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"type": "String",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"changedModel": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"oldInstance": {
|
||||||
|
"type": "Object"
|
||||||
|
},
|
||||||
|
"newInstance": {
|
||||||
|
"type": "Object"
|
||||||
|
},
|
||||||
|
"creationDate": {
|
||||||
|
"type": "Date"
|
||||||
|
},
|
||||||
|
"changedModelId": {
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"changedModelValue": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"user": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Account",
|
||||||
|
"foreignKey": "userFk"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"order": ["creationDate DESC", "id DESC"]
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
|
require('../methods/claim/filter')(Self);
|
||||||
require('../methods/claim/getSummary')(Self);
|
require('../methods/claim/getSummary')(Self);
|
||||||
require('../methods/claim/createFromSales')(Self);
|
require('../methods/claim/createFromSales')(Self);
|
||||||
require('../methods/claim/updateClaim')(Self);
|
require('../methods/claim/updateClaim')(Self);
|
||||||
require('../methods/claim/regularizeClaim')(Self);
|
require('../methods/claim/regularizeClaim')(Self);
|
||||||
require('../methods/claim/filter')(Self);
|
require('../methods/claim/uploadFile')(Self);
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,11 +18,13 @@
|
||||||
<vn-tool-bar margin-medium-bottom>
|
<vn-tool-bar margin-medium-bottom>
|
||||||
<vn-button
|
<vn-button
|
||||||
label="Import claim"
|
label="Import claim"
|
||||||
vn-http-click="$ctrl.importToNewRefundTicket()"
|
disabled="$ctrl.claim.claimStateFk == $ctrl.resolvedState"
|
||||||
|
vn-http-click="$ctrl.importToNewRefundTicket()"p
|
||||||
vn-tooltip="Imports claim details">
|
vn-tooltip="Imports claim details">
|
||||||
</vn-button>
|
</vn-button>
|
||||||
<vn-button
|
<vn-button
|
||||||
label="Import ticket"
|
label="Import ticket"
|
||||||
|
disabled="$ctrl.claim.claimStateFk == $ctrl.resolvedState"
|
||||||
ng-click="$ctrl.showLastTickets($event)"
|
ng-click="$ctrl.showLastTickets($event)"
|
||||||
vn-tooltip="Imports ticket lines">
|
vn-tooltip="Imports ticket lines">
|
||||||
</vn-button>
|
</vn-button>
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
<vn-table model="model">
|
<vn-table model="model">
|
||||||
<vn-thead>
|
<vn-thead>
|
||||||
<vn-tr>
|
<vn-tr>
|
||||||
<vn-th number>Id</vn-th>
|
|
||||||
<vn-th center>Landed</vn-th>
|
<vn-th center>Landed</vn-th>
|
||||||
<vn-th number>Quantity</vn-th>
|
<vn-th number>Quantity</vn-th>
|
||||||
<vn-th>Claimed</vn-th>
|
<vn-th>Claimed</vn-th>
|
||||||
|
@ -35,13 +34,6 @@
|
||||||
</vn-thead>
|
</vn-thead>
|
||||||
<vn-tbody>
|
<vn-tbody>
|
||||||
<vn-tr ng-repeat="saleClaimed in $ctrl.salesClaimed" vn-repeat-last>
|
<vn-tr ng-repeat="saleClaimed in $ctrl.salesClaimed" vn-repeat-last>
|
||||||
<vn-td number>
|
|
||||||
<span
|
|
||||||
ng-click="$ctrl.showDescriptor($event, saleClaimed.sale.itemFk)"
|
|
||||||
class="link">
|
|
||||||
{{::saleClaimed.sale.itemFk | zeroFill:6}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td center>{{::saleClaimed.sale.ticket.landed | dateTime:'dd/MM/yyyy'}}</vn-td>
|
<vn-td center>{{::saleClaimed.sale.ticket.landed | dateTime:'dd/MM/yyyy'}}</vn-td>
|
||||||
<vn-td number>{{::saleClaimed.sale.quantity}}</vn-td>
|
<vn-td number>{{::saleClaimed.sale.quantity}}</vn-td>
|
||||||
<vn-td>
|
<vn-td>
|
||||||
|
@ -50,7 +42,13 @@
|
||||||
on-change="$ctrl.setClaimedQuantity(saleClaimed.id, saleClaimed.quantity)">
|
on-change="$ctrl.setClaimedQuantity(saleClaimed.id, saleClaimed.quantity)">
|
||||||
</vn-input-number>
|
</vn-input-number>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td expand>{{::saleClaimed.sale.concept}}</vn-td>
|
<vn-td expand title="{{::saleClaimed.sale.concept}}">
|
||||||
|
<span
|
||||||
|
class="link"
|
||||||
|
ng-click="$ctrl.showDescriptor($event, saleClaimed.sale.itemFk)">
|
||||||
|
{{::saleClaimed.sale.concept}}
|
||||||
|
</span>
|
||||||
|
</vn-td>
|
||||||
<vn-td number>{{::saleClaimed.sale.price | currency: 'EUR':2}}</vn-td>
|
<vn-td number>{{::saleClaimed.sale.price | currency: 'EUR':2}}</vn-td>
|
||||||
<vn-td number>
|
<vn-td number>
|
||||||
<span class="link"
|
<span class="link"
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
<vn-watcher
|
||||||
|
vn-id="watcher"
|
||||||
|
data="$ctrl.dms">
|
||||||
|
</vn-watcher>
|
||||||
|
<form name="form" ng-submit="$ctrl.onSubmit()" margin-medium enctype="multipart/form-data">
|
||||||
|
<div compact>
|
||||||
|
<vn-card pad-large>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield vn-one vn-focus
|
||||||
|
label="Reference"
|
||||||
|
field="$ctrl.dms.reference">
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
label="Company"
|
||||||
|
field="$ctrl.dms.companyId"
|
||||||
|
url="/api/Companies"
|
||||||
|
show-field="code"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
label="Warehouse"
|
||||||
|
field="$ctrl.dms.warehouseId"
|
||||||
|
url="/api/Warehouses"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
label="Type"
|
||||||
|
field="$ctrl.dms.dmsTypeId"
|
||||||
|
url="/api/DmsTypes"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textarea vn-one
|
||||||
|
label="Description"
|
||||||
|
field="$ctrl.dms.description">
|
||||||
|
</vn-textarea>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-input-file vn-one
|
||||||
|
label="File"
|
||||||
|
model="$ctrl.dms.files"
|
||||||
|
on-change="$ctrl.onFileChange(files)"
|
||||||
|
accept="{{$ctrl.allowedContentTypes}}"
|
||||||
|
multiple="true">
|
||||||
|
<t-right-icons>
|
||||||
|
<vn-icon vn-none
|
||||||
|
color-secondary
|
||||||
|
title="{{$ctrl.contentTypesInfo}}"
|
||||||
|
icon="info">
|
||||||
|
</vn-icon>
|
||||||
|
</t-right-icons>
|
||||||
|
</vn-input-file>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-vertical>
|
||||||
|
<vn-check
|
||||||
|
label="Generate identifier for original file"
|
||||||
|
field="$ctrl.dms.hasFile">
|
||||||
|
</vn-check>
|
||||||
|
</vn-vertical>
|
||||||
|
</vn-card>
|
||||||
|
<vn-button-bar>
|
||||||
|
<vn-submit label="Upload"></vn-submit>
|
||||||
|
<vn-button ui-sref="claim.card.dms.index" label="Cancel"></vn-button>
|
||||||
|
</vn-button-bar>
|
||||||
|
</div>
|
||||||
|
</form>
|
|
@ -0,0 +1,115 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
constructor($scope, $http, $state, $translate, vnApp) {
|
||||||
|
this.$ = $scope;
|
||||||
|
this.$http = $http;
|
||||||
|
this.$state = $state;
|
||||||
|
this.$translate = $translate;
|
||||||
|
this.vnApp = vnApp;
|
||||||
|
this.dms = {
|
||||||
|
files: [],
|
||||||
|
hasFile: false,
|
||||||
|
hasFileAttached: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get claim() {
|
||||||
|
return this._claim;
|
||||||
|
}
|
||||||
|
|
||||||
|
set claim(value) {
|
||||||
|
this._claim = value;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
this.setDefaultParams();
|
||||||
|
this.getAllowedContentTypes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getAllowedContentTypes() {
|
||||||
|
this.$http.get('/api/claimDms/allowedContentTypes').then(res => {
|
||||||
|
const contentTypes = res.data.join(', ');
|
||||||
|
this.allowedContentTypes = contentTypes;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get contentTypesInfo() {
|
||||||
|
return this.$translate.instant('ContentTypesInfo', {
|
||||||
|
allowedContentTypes: this.allowedContentTypes
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setDefaultParams() {
|
||||||
|
const params = {filter: {
|
||||||
|
where: {code: 'claim'}
|
||||||
|
}};
|
||||||
|
this.$http.get('/api/DmsTypes/findOne', {params}).then(res => {
|
||||||
|
const dmsTypeId = res.data && res.data.id;
|
||||||
|
const companyId = window.localStorage.defaultCompanyFk;
|
||||||
|
const warehouseId = window.localStorage.defaultWarehouseFk;
|
||||||
|
const defaultParams = {
|
||||||
|
reference: this.claim.id,
|
||||||
|
warehouseId: warehouseId,
|
||||||
|
companyId: companyId,
|
||||||
|
dmsTypeId: dmsTypeId,
|
||||||
|
description: this.$translate.instant('FileDescription', {
|
||||||
|
claimId: this.claim.id,
|
||||||
|
clientId: this.claim.client.id,
|
||||||
|
clientName: this.claim.client.name
|
||||||
|
}).toUpperCase()
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dms = Object.assign(this.dms, defaultParams);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
const query = `/api/claims/${this.claim.id}/uploadFile`;
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
url: query,
|
||||||
|
params: this.dms,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': undefined
|
||||||
|
},
|
||||||
|
transformRequest: files => {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
for (let i = 0; i < files.length; i++)
|
||||||
|
formData.append(files[i].name, files[i]);
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
},
|
||||||
|
data: this.dms.files
|
||||||
|
};
|
||||||
|
this.$http(options).then(res => {
|
||||||
|
if (res) {
|
||||||
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||||
|
this.$.watcher.updateOriginalData();
|
||||||
|
this.$state.go('claim.card.dms.index');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onFileChange(files) {
|
||||||
|
let hasFileAttached = false;
|
||||||
|
if (files.length > 0)
|
||||||
|
hasFileAttached = true;
|
||||||
|
|
||||||
|
this.$.$applyAsync(() => {
|
||||||
|
this.dms.hasFileAttached = hasFileAttached;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.$inject = ['$scope', '$http', '$state', '$translate', 'vnApp'];
|
||||||
|
|
||||||
|
ngModule.component('vnClaimDmsCreate', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: Controller,
|
||||||
|
bindings: {
|
||||||
|
claim: '<'
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,81 @@
|
||||||
|
import './index';
|
||||||
|
|
||||||
|
describe('Claim', () => {
|
||||||
|
describe('Component vnClaimDmsCreate', () => {
|
||||||
|
let controller;
|
||||||
|
let $scope;
|
||||||
|
let $httpBackend;
|
||||||
|
let $httpParamSerializer;
|
||||||
|
|
||||||
|
beforeEach(ngModule('claim'));
|
||||||
|
|
||||||
|
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
|
||||||
|
$scope = $rootScope.$new();
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
$httpParamSerializer = _$httpParamSerializer_;
|
||||||
|
controller = $componentController('vnClaimDmsCreate', {$scope});
|
||||||
|
controller._claim = {
|
||||||
|
id: 15,
|
||||||
|
client: {id: 101, name: 'Bruce wayne'},
|
||||||
|
ticketFk: 16
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('claim() setter', () => {
|
||||||
|
it('should set the claim data and then call setDefaultParams() and getAllowedContentTypes()', () => {
|
||||||
|
spyOn(controller, 'setDefaultParams');
|
||||||
|
spyOn(controller, 'getAllowedContentTypes');
|
||||||
|
controller._claim = undefined;
|
||||||
|
controller.claim = {
|
||||||
|
id: 15,
|
||||||
|
client: {id: 101, name: 'Bruce wayne'},
|
||||||
|
ticketFk: 16
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(controller.claim).toBeDefined();
|
||||||
|
expect(controller.setDefaultParams).toHaveBeenCalledWith();
|
||||||
|
expect(controller.getAllowedContentTypes).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setDefaultParams()', () => {
|
||||||
|
it('should perform a GET query and define the dms property on controller', () => {
|
||||||
|
const params = {filter: {
|
||||||
|
where: {code: 'claim'}
|
||||||
|
}};
|
||||||
|
let serializedParams = $httpParamSerializer(params);
|
||||||
|
$httpBackend.when('GET', `/api/DmsTypes/findOne?${serializedParams}`).respond({id: 14, code: 'claim'});
|
||||||
|
$httpBackend.expect('GET', `/api/DmsTypes/findOne?${serializedParams}`);
|
||||||
|
controller.setDefaultParams();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.dms).toBeDefined();
|
||||||
|
expect(controller.dms.reference).toEqual(15);
|
||||||
|
expect(controller.dms.dmsTypeId).toEqual(14);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onFileChange()', () => {
|
||||||
|
it('should set dms hasFileAttached property to true if has any files', () => {
|
||||||
|
const files = [{id: 1, name: 'MyFile'}];
|
||||||
|
controller.onFileChange(files);
|
||||||
|
$scope.$apply();
|
||||||
|
|
||||||
|
expect(controller.dms.hasFileAttached).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getAllowedContentTypes()', () => {
|
||||||
|
it('should make an HTTP GET request to get the allowed content types', () => {
|
||||||
|
const expectedResponse = ['image/png', 'image/jpg'];
|
||||||
|
$httpBackend.when('GET', `/api/claimDms/allowedContentTypes`).respond(expectedResponse);
|
||||||
|
$httpBackend.expect('GET', `/api/claimDms/allowedContentTypes`);
|
||||||
|
controller.getAllowedContentTypes();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.allowedContentTypes).toBeDefined();
|
||||||
|
expect(controller.allowedContentTypes).toEqual('image/png, image/jpg');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,7 @@
|
||||||
|
vn-ticket-request {
|
||||||
|
vn-textfield {
|
||||||
|
margin: 0!important;
|
||||||
|
max-width: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
<vn-watcher
|
||||||
|
vn-id="watcher"
|
||||||
|
data="$ctrl.dms">
|
||||||
|
</vn-watcher>
|
||||||
|
<form name="form" ng-submit="$ctrl.onSubmit()" margin-medium enctype="multipart/form-data">
|
||||||
|
<div compact>
|
||||||
|
<vn-card pad-large>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield vn-one vn-focus
|
||||||
|
label="Reference"
|
||||||
|
field="$ctrl.dms.reference">
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-autocomplete vn-one required="true"
|
||||||
|
label="Company"
|
||||||
|
field="$ctrl.dms.companyId"
|
||||||
|
url="/api/Companies"
|
||||||
|
show-field="code"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete vn-one required="true"
|
||||||
|
label="Warehouse"
|
||||||
|
field="$ctrl.dms.warehouseId"
|
||||||
|
url="/api/Warehouses"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-autocomplete vn-one required="true"
|
||||||
|
label="Type"
|
||||||
|
field="$ctrl.dms.dmsTypeId"
|
||||||
|
url="/api/DmsTypes"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textarea vn-one required="true"
|
||||||
|
label="Description"
|
||||||
|
field="$ctrl.dms.description">
|
||||||
|
</vn-textarea>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-input-file vn-one
|
||||||
|
label="File"
|
||||||
|
model="$ctrl.dms.files"
|
||||||
|
on-change="$ctrl.onFileChange(files)"
|
||||||
|
accept="{{$ctrl.allowedContentTypes}}"
|
||||||
|
multiple="true">
|
||||||
|
<t-right-icons>
|
||||||
|
<vn-icon vn-none
|
||||||
|
color-secondary
|
||||||
|
title="{{$ctrl.contentTypesInfo}}"
|
||||||
|
icon="info">
|
||||||
|
</vn-icon>
|
||||||
|
</t-right-icons>
|
||||||
|
</vn-input-file>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-vertical>
|
||||||
|
<vn-check disabled="true"
|
||||||
|
label="Generate identifier for original file"
|
||||||
|
field="$ctrl.dms.hasFile">
|
||||||
|
</vn-check>
|
||||||
|
</vn-vertical>
|
||||||
|
</vn-card>
|
||||||
|
<vn-button-bar>
|
||||||
|
<vn-submit label="Save"></vn-submit>
|
||||||
|
<vn-button ui-sref="claim.card.dms.index" label="Cancel"></vn-button>
|
||||||
|
</vn-button-bar>
|
||||||
|
</div>
|
||||||
|
</form>
|
|
@ -0,0 +1,104 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
constructor($scope, $http, $state, $translate, vnApp) {
|
||||||
|
this.$ = $scope;
|
||||||
|
this.$http = $http;
|
||||||
|
this.$state = $state;
|
||||||
|
this.$stateParams = $state.params;
|
||||||
|
this.$translate = $translate;
|
||||||
|
this.vnApp = vnApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
get claim() {
|
||||||
|
return this._claim;
|
||||||
|
}
|
||||||
|
|
||||||
|
set claim(value) {
|
||||||
|
this._claim = value;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
this.setDefaultParams();
|
||||||
|
this.getAllowedContentTypes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getAllowedContentTypes() {
|
||||||
|
this.$http.get('/api/claimDms/allowedContentTypes').then(res => {
|
||||||
|
const contentTypes = res.data.join(', ');
|
||||||
|
this.allowedContentTypes = contentTypes;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get contentTypesInfo() {
|
||||||
|
return this.$translate.instant('ContentTypesInfo', {
|
||||||
|
allowedContentTypes: this.allowedContentTypes
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setDefaultParams() {
|
||||||
|
const path = `/api/Dms/${this.$stateParams.dmsId}`;
|
||||||
|
this.$http.get(path).then(res => {
|
||||||
|
const dms = res.data && res.data;
|
||||||
|
this.dms = {
|
||||||
|
reference: dms.reference,
|
||||||
|
warehouseId: dms.warehouseFk,
|
||||||
|
companyId: dms.companyFk,
|
||||||
|
dmsTypeId: dms.dmsTypeFk,
|
||||||
|
description: dms.description,
|
||||||
|
hasFile: dms.hasFile,
|
||||||
|
hasFileAttached: false,
|
||||||
|
files: []
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
const query = `/api/dms/${this.$stateParams.dmsId}/updateFile`;
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
url: query,
|
||||||
|
params: this.dms,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': undefined
|
||||||
|
},
|
||||||
|
transformRequest: files => {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
for (let i = 0; i < files.length; i++)
|
||||||
|
formData.append(files[i].name, files[i]);
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
},
|
||||||
|
data: this.dms.files
|
||||||
|
};
|
||||||
|
this.$http(options).then(res => {
|
||||||
|
if (res) {
|
||||||
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||||
|
this.$.watcher.updateOriginalData();
|
||||||
|
this.$state.go('claim.card.dms.index');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onFileChange(files) {
|
||||||
|
let hasFileAttached = false;
|
||||||
|
if (files.length > 0)
|
||||||
|
hasFileAttached = true;
|
||||||
|
|
||||||
|
this.$.$applyAsync(() => {
|
||||||
|
this.dms.hasFileAttached = hasFileAttached;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.$inject = ['$scope', '$http', '$state', '$translate', 'vnApp'];
|
||||||
|
|
||||||
|
ngModule.component('vnClaimDmsEdit', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: Controller,
|
||||||
|
bindings: {
|
||||||
|
claim: '<'
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,84 @@
|
||||||
|
import './index';
|
||||||
|
|
||||||
|
describe('Claim', () => {
|
||||||
|
describe('Component vnClaimDmsEdit', () => {
|
||||||
|
let controller;
|
||||||
|
let $scope;
|
||||||
|
let $httpBackend;
|
||||||
|
let $state;
|
||||||
|
|
||||||
|
beforeEach(ngModule('claim'));
|
||||||
|
|
||||||
|
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => {
|
||||||
|
$scope = $rootScope.$new();
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
$state = {params: {dmsId: 1}};
|
||||||
|
controller = $componentController('vnClaimDmsEdit', {$scope, $state});
|
||||||
|
controller._claim = {id: 1, ticketFk: 16};
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('claim() setter', () => {
|
||||||
|
it('should set the claim data and then call setDefaultParams() and getAllowedContentTypes()', () => {
|
||||||
|
spyOn(controller, 'setDefaultParams');
|
||||||
|
spyOn(controller, 'getAllowedContentTypes');
|
||||||
|
controller._claim = undefined;
|
||||||
|
controller.claim = {
|
||||||
|
id: 15,
|
||||||
|
ticketFk: 16
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(controller.setDefaultParams).toHaveBeenCalledWith();
|
||||||
|
expect(controller.claim).toBeDefined();
|
||||||
|
expect(controller.getAllowedContentTypes).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setDefaultParams()', () => {
|
||||||
|
it('should perform a GET query and define the dms property on controller', () => {
|
||||||
|
const dmsId = 1;
|
||||||
|
const expectedResponse = {
|
||||||
|
reference: 101,
|
||||||
|
warehouseFk: 1,
|
||||||
|
companyFk: 442,
|
||||||
|
dmsTypeFk: 20,
|
||||||
|
description: 'Test',
|
||||||
|
hasFile: false,
|
||||||
|
hasFileAttached: false
|
||||||
|
};
|
||||||
|
|
||||||
|
$httpBackend.when('GET', `/api/Dms/${dmsId}`).respond(expectedResponse);
|
||||||
|
$httpBackend.expect('GET', `/api/Dms/${dmsId}`).respond(expectedResponse);
|
||||||
|
controller.setDefaultParams();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.dms).toBeDefined();
|
||||||
|
expect(controller.dms.reference).toEqual(101);
|
||||||
|
expect(controller.dms.dmsTypeId).toEqual(20);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onFileChange()', () => {
|
||||||
|
it('should set dms hasFileAttached property to true if has any files', () => {
|
||||||
|
const files = [{id: 1, name: 'MyFile'}];
|
||||||
|
controller.dms = {hasFileAttached: false};
|
||||||
|
controller.onFileChange(files);
|
||||||
|
$scope.$apply();
|
||||||
|
|
||||||
|
expect(controller.dms.hasFileAttached).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getAllowedContentTypes()', () => {
|
||||||
|
it('should make an HTTP GET request to get the allowed content types', () => {
|
||||||
|
const expectedResponse = ['image/png', 'image/jpg'];
|
||||||
|
$httpBackend.when('GET', `/api/claimDms/allowedContentTypes`).respond(expectedResponse);
|
||||||
|
$httpBackend.expect('GET', `/api/claimDms/allowedContentTypes`);
|
||||||
|
controller.getAllowedContentTypes();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.allowedContentTypes).toBeDefined();
|
||||||
|
expect(controller.allowedContentTypes).toEqual('image/png, image/jpg');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,7 @@
|
||||||
|
vn-ticket-request {
|
||||||
|
vn-textfield {
|
||||||
|
margin: 0!important;
|
||||||
|
max-width: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
<vn-crud-model
|
||||||
|
vn-id="model"
|
||||||
|
url="/api/ClaimDms"
|
||||||
|
link="{claimFk: $ctrl.$stateParams.id}"
|
||||||
|
filter="::$ctrl.filter"
|
||||||
|
limit="20"
|
||||||
|
data="$ctrl.claimDms">
|
||||||
|
</vn-crud-model>
|
||||||
|
<vn-vertical>
|
||||||
|
<vn-card pad-large>
|
||||||
|
<vn-vertical>
|
||||||
|
<vn-table model="model">
|
||||||
|
<vn-thead>
|
||||||
|
<vn-tr>
|
||||||
|
<vn-th field="dmsFk" default-order="DESC" shrink>Id</vn-th>
|
||||||
|
<vn-th shrink>Type</vn-th>
|
||||||
|
<vn-th shrink number>Order</vn-th>
|
||||||
|
<vn-th shrink>Reference</vn-th>
|
||||||
|
<vn-th>Description</vn-th>
|
||||||
|
<vn-th shrink>Original</vn-th>
|
||||||
|
<vn-th>File</vn-th>
|
||||||
|
<vn-th shrink>Employee</vn-th>
|
||||||
|
<vn-th>Created</vn-th>
|
||||||
|
<vn-th number></vn-th>
|
||||||
|
</vn-tr>
|
||||||
|
</vn-thead>
|
||||||
|
<vn-tbody>
|
||||||
|
<vn-tr ng-repeat="document in $ctrl.claimDms">
|
||||||
|
<vn-td number shrink>{{::document.dmsFk}}</vn-td>
|
||||||
|
<vn-td shrink>
|
||||||
|
<span title="{{::document.dms.dmsType.name}}">
|
||||||
|
{{::document.dms.dmsType.name}}
|
||||||
|
</span>
|
||||||
|
</vn-td>
|
||||||
|
<vn-td shrink number>
|
||||||
|
<span title="{{::document.dms.hardCopyNumber}}">
|
||||||
|
{{::document.dms.hardCopyNumber}}
|
||||||
|
</span>
|
||||||
|
</vn-td>
|
||||||
|
<vn-td shrink>
|
||||||
|
<span title="{{::document.dms.reference}}">
|
||||||
|
{{::document.dms.reference}}
|
||||||
|
</span>
|
||||||
|
</vn-td>
|
||||||
|
<vn-td>
|
||||||
|
<span title="{{::document.dms.description}}">
|
||||||
|
{{::document.dms.description}}
|
||||||
|
</span>
|
||||||
|
</vn-td>
|
||||||
|
<vn-td shrink>
|
||||||
|
<vn-check disabled="true"
|
||||||
|
field="document.dms.hasFile">
|
||||||
|
</vn-check>
|
||||||
|
</vn-td>
|
||||||
|
<vn-td>
|
||||||
|
<a target="_blank"
|
||||||
|
title="{{'Download file' | translate}}"
|
||||||
|
href="api/dms/{{::document.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}">
|
||||||
|
{{::document.dms.file}}
|
||||||
|
</a>
|
||||||
|
</vn-td>
|
||||||
|
<vn-td shrink>
|
||||||
|
<span class="link"
|
||||||
|
ng-click="$ctrl.showWorkerDescriptor($event, document.dms.workerFk)">
|
||||||
|
{{::document.dms.worker.user.nickname | dashIfEmpty}}
|
||||||
|
</span></vn-td>
|
||||||
|
<vn-td>
|
||||||
|
{{::document.dms.created | dateTime:'dd/MM/yyyy HH:mm'}}
|
||||||
|
</vn-td>
|
||||||
|
<vn-td number>
|
||||||
|
<a target="_blank"
|
||||||
|
href="api/dms/{{::document.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}">
|
||||||
|
<vn-icon-button
|
||||||
|
icon="cloud_download"
|
||||||
|
title="{{'Download file' | translate}}">
|
||||||
|
</vn-icon-button>
|
||||||
|
</a>
|
||||||
|
<vn-icon-button ui-sref="claim.card.dms.edit({dmsId: {{::document.dmsFk}}})"
|
||||||
|
icon="edit"
|
||||||
|
title="{{'Edit file' | translate}}">
|
||||||
|
</vn-icon-button>
|
||||||
|
<vn-icon-button
|
||||||
|
icon="delete"
|
||||||
|
ng-click="$ctrl.showDeleteConfirm($index)"
|
||||||
|
title="{{'Remove file' | translate}}"
|
||||||
|
tabindex="-1">
|
||||||
|
</vn-icon-button>
|
||||||
|
</vn-td>
|
||||||
|
</vn-tr>
|
||||||
|
</vn-tbody>
|
||||||
|
</vn-table>
|
||||||
|
</vn-vertical>
|
||||||
|
<vn-pagination model="model"></vn-pagination>
|
||||||
|
</vn-card>
|
||||||
|
</vn-vertical>
|
||||||
|
<vn-worker-descriptor-popover
|
||||||
|
vn-id="workerDescriptor">
|
||||||
|
</vn-worker-descriptor-popover>
|
||||||
|
<a ui-sref="claim.card.dms.create"
|
||||||
|
vn-tooltip="Upload file"
|
||||||
|
vn-bind="+"
|
||||||
|
fixed-bottom-right>
|
||||||
|
<vn-float-button icon="add"></vn-float-button>
|
||||||
|
</a>
|
||||||
|
<vn-confirm
|
||||||
|
vn-id="confirm"
|
||||||
|
message="This file will be deleted"
|
||||||
|
question="Are you sure you want to continue?"
|
||||||
|
on-response="$ctrl.deleteDms(response)">
|
||||||
|
</vn-confirm>
|
|
@ -0,0 +1,79 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
constructor($stateParams, $scope, $http, $translate, vnToken, vnApp) {
|
||||||
|
this.$stateParams = $stateParams;
|
||||||
|
this.$ = $scope;
|
||||||
|
this.$http = $http;
|
||||||
|
this.$translate = $translate;
|
||||||
|
this.accessToken = vnToken.token;
|
||||||
|
this.vnApp = vnApp;
|
||||||
|
this.filter = {
|
||||||
|
include: {
|
||||||
|
relation: 'dms',
|
||||||
|
scope: {
|
||||||
|
fields: [
|
||||||
|
'dmsTypeFk',
|
||||||
|
'workerFk',
|
||||||
|
'hardCopyNumber',
|
||||||
|
'reference',
|
||||||
|
'description',
|
||||||
|
'hasFile',
|
||||||
|
'file',
|
||||||
|
'created',
|
||||||
|
],
|
||||||
|
include: [{
|
||||||
|
relation: 'dmsType',
|
||||||
|
scope: {
|
||||||
|
fields: ['name']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relation: 'worker',
|
||||||
|
scope: {
|
||||||
|
fields: ['userFk'],
|
||||||
|
include: {
|
||||||
|
relation: 'user',
|
||||||
|
scope: {
|
||||||
|
fields: ['nickname']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
showWorkerDescriptor(event, workerFk) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
this.$.workerDescriptor.parent = event.target;
|
||||||
|
this.$.workerDescriptor.workerFk = workerFk;
|
||||||
|
this.$.workerDescriptor.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
showDeleteConfirm(index) {
|
||||||
|
this.dmsIndex = index;
|
||||||
|
this.$.confirm.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteDms(response) {
|
||||||
|
if (response === 'ACCEPT') {
|
||||||
|
const dmsFk = this.claimDms[this.dmsIndex].dmsFk;
|
||||||
|
const query = `/api/claimDms/${dmsFk}/removeFile`;
|
||||||
|
this.$http.post(query).then(() => {
|
||||||
|
this.$.model.remove(this.dmsIndex);
|
||||||
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.$inject = ['$stateParams', '$scope', '$http', '$translate', 'vnToken', 'vnApp'];
|
||||||
|
|
||||||
|
ngModule.component('vnClaimDmsIndex', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: Controller,
|
||||||
|
});
|
|
@ -0,0 +1,40 @@
|
||||||
|
import './index';
|
||||||
|
import crudModel from 'core/mocks/crud-model';
|
||||||
|
|
||||||
|
describe('Claim', () => {
|
||||||
|
describe('Component vnClaimDmsIndex', () => {
|
||||||
|
let $componentController;
|
||||||
|
let $scope;
|
||||||
|
let $httpBackend;
|
||||||
|
let controller;
|
||||||
|
|
||||||
|
beforeEach(ngModule('claim'));
|
||||||
|
|
||||||
|
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_) => {
|
||||||
|
$componentController = _$componentController_;
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
$scope = $rootScope.$new();
|
||||||
|
controller = $componentController('vnClaimDmsIndex', {$: $scope});
|
||||||
|
controller.$.model = crudModel;
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('deleteDms()', () => {
|
||||||
|
it('should make an HTTP Post query', () => {
|
||||||
|
const dmsId = 1;
|
||||||
|
const dmsIndex = 0;
|
||||||
|
spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
spyOn(controller.$.model, 'remove');
|
||||||
|
controller.claimDms = [{dmsFk: 1}];
|
||||||
|
controller.dmsIndex = dmsIndex;
|
||||||
|
|
||||||
|
$httpBackend.when('POST', `/api/claimDms/${dmsId}/removeFile`).respond({});
|
||||||
|
$httpBackend.expect('POST', `/api/claimDms/${dmsId}/removeFile`);
|
||||||
|
controller.deleteDms('ACCEPT');
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.$.model.remove).toHaveBeenCalledWith(dmsIndex);
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,6 @@
|
||||||
|
vn-client-risk-index {
|
||||||
|
.totalBox {
|
||||||
|
display: table;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
FileDescription: Ticket id {{ticketId}} from client {{clientName}} id {{clientId}}
|
||||||
|
ContentTypesInfo: Allowed file types {{allowedContentTypes}}
|
|
@ -0,0 +1,8 @@
|
||||||
|
Upload file: Subir fichero
|
||||||
|
Edit file: Editar fichero
|
||||||
|
Upload: Subir
|
||||||
|
File: Fichero
|
||||||
|
FileDescription: Reclamación id {{claimId}} del cliente "{{clientName}}" id {{clientId}}
|
||||||
|
Generate identifier for original file: Generar identificador para archivo original
|
||||||
|
ContentTypesInfo: "Tipos de archivo permitidos: {{allowedContentTypes}}"
|
||||||
|
Are you sure you want to continue?: ¿Seguro que quieres continuar?
|
|
@ -9,3 +9,6 @@ import './descriptor';
|
||||||
import './development';
|
import './development';
|
||||||
import './search-panel';
|
import './search-panel';
|
||||||
import './summary';
|
import './summary';
|
||||||
|
import './dms/index';
|
||||||
|
import './dms/create';
|
||||||
|
import './dms/edit';
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
{"state": "claim.card.basicData", "icon": "settings"},
|
{"state": "claim.card.basicData", "icon": "settings"},
|
||||||
{"state": "claim.card.detail", "icon": "icon-details"},
|
{"state": "claim.card.detail", "icon": "icon-details"},
|
||||||
{"state": "claim.card.development", "icon": "icon-traceability"},
|
{"state": "claim.card.development", "icon": "icon-traceability"},
|
||||||
{"state": "claim.card.action", "icon": "icon-actions"}
|
{"state": "claim.card.action", "icon": "icon-actions"},
|
||||||
|
{"state": "claim.card.dms.index", "icon": "image"}
|
||||||
],
|
],
|
||||||
"keybindings": [
|
"keybindings": [
|
||||||
{"key": "r", "state": "claim.index"}
|
{"key": "r", "state": "claim.index"}
|
||||||
|
@ -74,6 +75,35 @@
|
||||||
"claim": "$ctrl.claim"
|
"claim": "$ctrl.claim"
|
||||||
},
|
},
|
||||||
"acl": ["salesAssistant"]
|
"acl": ["salesAssistant"]
|
||||||
|
}, {
|
||||||
|
"url": "/dms",
|
||||||
|
"state": "claim.card.dms",
|
||||||
|
"abstract": true,
|
||||||
|
"component": "ui-view"
|
||||||
|
}, {
|
||||||
|
"url" : "/index",
|
||||||
|
"state": "claim.card.dms.index",
|
||||||
|
"component": "vn-claim-dms-index",
|
||||||
|
"description": "Pictures",
|
||||||
|
"params": {
|
||||||
|
"claim": "$ctrl.claim"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"url" : "/create",
|
||||||
|
"state": "claim.card.dms.create",
|
||||||
|
"component": "vn-claim-dms-create",
|
||||||
|
"description": "Upload file",
|
||||||
|
"params": {
|
||||||
|
"claim": "$ctrl.claim"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"url": "/:dmsId/edit",
|
||||||
|
"state": "claim.card.dms.edit",
|
||||||
|
"component": "vn-claim-dms-edit",
|
||||||
|
"description": "Edit file",
|
||||||
|
"params": {
|
||||||
|
"claim": "$ctrl.claim"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -1,53 +0,0 @@
|
||||||
|
|
||||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
|
||||||
|
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethod('filter', {
|
|
||||||
description: 'Find all instances of the model matched by filter from the data source.',
|
|
||||||
accessType: 'READ',
|
|
||||||
accepts: [
|
|
||||||
{
|
|
||||||
arg: 'filter',
|
|
||||||
type: 'Object',
|
|
||||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
|
||||||
http: {source: 'query'}
|
|
||||||
}
|
|
||||||
|
|
||||||
],
|
|
||||||
returns: {
|
|
||||||
type: ['Object'],
|
|
||||||
root: true
|
|
||||||
},
|
|
||||||
http: {
|
|
||||||
path: `/filter`,
|
|
||||||
verb: 'GET'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.filter = async filter => {
|
|
||||||
let conn = Self.dataSource.connector;
|
|
||||||
|
|
||||||
let stmts = [];
|
|
||||||
let stmt;
|
|
||||||
|
|
||||||
filter.order = [
|
|
||||||
'c.defaultAddressFk DESC',
|
|
||||||
'a.isActive DESC',
|
|
||||||
'a.nickname ASC'
|
|
||||||
];
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(
|
|
||||||
`SELECT a.*
|
|
||||||
FROM vn.address a
|
|
||||||
LEFT JOIN vn.client c ON c.defaultAddressFk = a.id`
|
|
||||||
);
|
|
||||||
|
|
||||||
stmt.merge(conn.makeSuffix(filter));
|
|
||||||
let itemsIndex = stmts.push(stmt) - 1;
|
|
||||||
|
|
||||||
let sql = ParameterizedSQL.join(stmts, ';');
|
|
||||||
let result = await conn.executeStmt(sql);
|
|
||||||
return itemsIndex === 0 ? result : result[itemsIndex];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('allowedContentTypes', {
|
||||||
|
description: 'Returns a list of allowed contentTypes',
|
||||||
|
accessType: 'READ',
|
||||||
|
returns: {
|
||||||
|
type: ['Object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/allowedContentTypes`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.allowedContentTypes = async() => {
|
||||||
|
const storageConnector = Self.app.dataSources.storage.connector;
|
||||||
|
const allowedContentTypes = storageConnector.allowedContentTypes;
|
||||||
|
const modelAllowedContentTypes = Self.definition.settings.allowedContentTypes;
|
||||||
|
|
||||||
|
return modelAllowedContentTypes || allowedContentTypes;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -1,34 +1,39 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethod('threeLastActive', {
|
Self.remoteMethod('lastActiveTickets', {
|
||||||
description: 'Returns the last three tickets of a client that have the alertLevel at 0 and the shiped day is gt today',
|
description: 'Returns the last three tickets of a client that have the alertLevel at 0 and the shiped day is gt today',
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'filter',
|
arg: 'id',
|
||||||
type: 'object',
|
type: 'Number',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'client id, ticketFk'
|
description: 'Client id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
}, {
|
||||||
|
arg: 'ticketId',
|
||||||
|
type: 'Number',
|
||||||
|
required: true
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
type: [this.modelName],
|
type: ['Object'],
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
path: `/threeLastActive`,
|
path: `/:id/lastActiveTickets`,
|
||||||
verb: 'GET'
|
verb: 'GET'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.threeLastActive = async params => {
|
Self.lastActiveTickets = async(id, ticketId) => {
|
||||||
let query = `
|
const query = `
|
||||||
SELECT t.id, t.shipped, a.name AS agencyName, w.name AS warehouseName
|
SELECT t.id, t.shipped, a.name AS agencyName, w.name AS warehouseName
|
||||||
FROM vn.ticket t
|
FROM vn.ticket t
|
||||||
JOIN vn.ticketState ts ON t.id = ts.ticketFk
|
JOIN vn.ticketState ts ON t.id = ts.ticketFk
|
||||||
JOIN vn.agencyMode a ON t.agencyModeFk = a.id
|
JOIN vn.agencyMode a ON t.agencyModeFk = a.id
|
||||||
JOIN vn.warehouse w ON t.warehouseFk = w.id
|
JOIN vn.warehouse w ON t.warehouseFk = w.id
|
||||||
WHERE t.shipped > CURDATE() AND t.clientFk = ? AND ts.alertLevel = 0 AND t.id <> ?
|
WHERE t.shipped >= CURDATE() AND t.clientFk = ? AND ts.alertLevel = 0 AND t.id <> ?
|
||||||
ORDER BY t.shipped
|
ORDER BY t.shipped
|
||||||
LIMIT 3`;
|
LIMIT 3`;
|
||||||
let tickets = await Self.rawSql(query, [params.clientFk, params.ticketFk]);
|
|
||||||
return tickets;
|
return Self.rawSql(query, [id, ticketId]);
|
||||||
};
|
};
|
||||||
};
|
};
|
|
@ -0,0 +1,12 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
|
describe('client lastActiveTickets()', () => {
|
||||||
|
it('should return the last three active tickets', async() => {
|
||||||
|
const clientId = 109;
|
||||||
|
const ticketId = 19;
|
||||||
|
|
||||||
|
let result = await app.models.Client.lastActiveTickets(clientId, ticketId);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(3);
|
||||||
|
});
|
||||||
|
});
|
|
@ -5,7 +5,6 @@ let isMultiple = require('vn-loopback/util/hook').isMultiple;
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
// Methods
|
// Methods
|
||||||
require('../methods/address/createDefaultAddress')(Self);
|
require('../methods/address/createDefaultAddress')(Self);
|
||||||
require('../methods/address/filter')(Self);
|
|
||||||
|
|
||||||
Self.validateAsync('isEqualizated', cannotHaveET, {
|
Self.validateAsync('isEqualizated', cannotHaveET, {
|
||||||
message: 'Cannot check Equalization Tax in this NIF/CIF'
|
message: 'Cannot check Equalization Tax in this NIF/CIF'
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
require('../methods/client-dms/removeFile')(Self);
|
require('../methods/client-dms/removeFile')(Self);
|
||||||
|
require('../methods/client-dms/allowedContentTypes')(Self);
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,7 @@ module.exports = Self => {
|
||||||
require('../methods/client/confirmTransaction')(Self);
|
require('../methods/client/confirmTransaction')(Self);
|
||||||
require('../methods/client/canBeInvoiced')(Self);
|
require('../methods/client/canBeInvoiced')(Self);
|
||||||
require('../methods/client/uploadFile')(Self);
|
require('../methods/client/uploadFile')(Self);
|
||||||
|
require('../methods/client/lastActiveTickets')(Self);
|
||||||
|
|
||||||
// Validations
|
// Validations
|
||||||
|
|
||||||
|
|
|
@ -61,17 +61,11 @@
|
||||||
fields="['code', 'townFk']"
|
fields="['code', 'townFk']"
|
||||||
field="$ctrl.address.postalCode"
|
field="$ctrl.address.postalCode"
|
||||||
where="{townFk: town.selection.id}"
|
where="{townFk: town.selection.id}"
|
||||||
selection="$ctrl.postcodeSelection"
|
|
||||||
search-function="{code: $search}"
|
search-function="{code: $search}"
|
||||||
fetch-function="{townFk: town.selection.id}"
|
|
||||||
order="code, townFk"
|
order="code, townFk"
|
||||||
show-field="code"
|
show-field="code"
|
||||||
value-field="code"
|
value-field="code"
|
||||||
label="Postcode">
|
label="Postcode">
|
||||||
<tpl-item>
|
|
||||||
{{code}}, {{town.name}} - {{town.province.name}}
|
|
||||||
({{town.province.country.country}})
|
|
||||||
</tpl-item>
|
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-icon-button vn-auto margin-medium-v
|
<vn-icon-button vn-auto margin-medium-v
|
||||||
icon="add_circle"
|
icon="add_circle"
|
||||||
|
|
|
@ -20,23 +20,6 @@ export default class Controller {
|
||||||
this.$state.go('client.card.address.index');
|
this.$state.go('client.card.address.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
get postcodeSelection() {
|
|
||||||
return this._postcodeSelection;
|
|
||||||
}
|
|
||||||
|
|
||||||
set postcodeSelection(selection) {
|
|
||||||
const hasValue = this._postcodeSelection;
|
|
||||||
this._postcodeSelection = selection;
|
|
||||||
|
|
||||||
if (!selection || !hasValue) return;
|
|
||||||
|
|
||||||
const town = selection.town;
|
|
||||||
const province = town.province;
|
|
||||||
|
|
||||||
this.address.city = town.name;
|
|
||||||
this.address.provinceFk = province.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
onResponse(response) {
|
onResponse(response) {
|
||||||
this.address.postalCode = response.code;
|
this.address.postalCode = response.code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,31 +55,5 @@ describe('Client', () => {
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('client.card.address.index');
|
expect(controller.$state.go).toHaveBeenCalledWith('client.card.address.index');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('postcodeSelection() setter', () => {
|
|
||||||
it(`should set the town, province and contry properties`, () => {
|
|
||||||
controller.address = {};
|
|
||||||
controller._postcodeSelection = {townFk: 2};
|
|
||||||
controller.postcodeSelection = {
|
|
||||||
townFk: 1,
|
|
||||||
code: 46001,
|
|
||||||
town: {
|
|
||||||
id: 1,
|
|
||||||
name: 'New York',
|
|
||||||
province: {
|
|
||||||
id: 1,
|
|
||||||
name: 'New york',
|
|
||||||
country: {
|
|
||||||
id: 2,
|
|
||||||
name: 'USA'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.address.city).toEqual('New York');
|
|
||||||
expect(controller.address.provinceFk).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,26 +1,28 @@
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="/client/api/Addresses/filter"
|
url="/api/Clients/{{$ctrl.$stateParams.id}}/addresses"
|
||||||
|
filter="$ctrl.filter"
|
||||||
limit="10"
|
limit="10"
|
||||||
link="{clientFk: $ctrl.$stateParams.id}"
|
|
||||||
data="$ctrl.addresses"
|
data="$ctrl.addresses"
|
||||||
auto-load="true">
|
auto-load="true">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<div compact>
|
<div compact>
|
||||||
<vn-card pad-large>
|
<vn-card pad-large>
|
||||||
<vn-horizontal
|
<div
|
||||||
ng-repeat="address in $ctrl.addresses"
|
ng-repeat="address in $ctrl.addresses"
|
||||||
class="pad-medium-top"
|
class="address">
|
||||||
style="align-items: center;">
|
<a
|
||||||
<vn-one
|
ui-sref="client.card.address.edit({addressId: {{::address.id}}})"
|
||||||
border-radius
|
|
||||||
class="pad-small border-solid"
|
class="pad-small border-solid"
|
||||||
ng-class="{
|
ng-class="{
|
||||||
'item-hightlight': $ctrl.isDefaultAddress(address),
|
'item-hightlight': $ctrl.isDefaultAddress(address),
|
||||||
'item-disabled': !address.isActive && !$ctrl.isDefaultAddress(address)
|
'item-disabled': !address.isActive && !$ctrl.isDefaultAddress(address)
|
||||||
}">
|
}"
|
||||||
<vn-horizontal style="align-items: center;">
|
translate-attr="{title: 'Edit address'}"
|
||||||
<vn-none pad-medium-h>
|
border-radius>
|
||||||
|
<vn-none
|
||||||
|
pad-small-right
|
||||||
|
ng-click="$ctrl.onStarClick($event)">
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
icon="star"
|
icon="star"
|
||||||
ng-if="$ctrl.isDefaultAddress(address)">
|
ng-if="$ctrl.isDefaultAddress(address)">
|
||||||
|
@ -37,36 +39,34 @@
|
||||||
ng-click="$ctrl.setDefault(address)">
|
ng-click="$ctrl.setDefault(address)">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
</vn-none>
|
</vn-none>
|
||||||
<vn-one border-solid-right>
|
<vn-one
|
||||||
<vn-horizontal>
|
style="overflow: hidden; min-width: 14em;">
|
||||||
<vn-one>
|
<div class="ellipsize"><b>{{::address.nickname}}</b></div>
|
||||||
<div><b>{{::address.nickname}}</b></div>
|
<div class="ellipsize" name="street">{{::address.street}}</div>
|
||||||
<div name="street">{{::address.street}}</div>
|
<div class="ellipsize">{{::address.city}}, {{::address.province.name}}</div>
|
||||||
<div>{{::address.city}}, {{::address.province}}</div>
|
<div class="ellipsize">
|
||||||
<div>{{::address.phone}}, {{::address.mobile}}</div>
|
{{::address.phone}}<span ng-if="::address.mobile">, </span>
|
||||||
</vn-one>
|
{{::address.mobile}}
|
||||||
<vn-one>
|
</div>
|
||||||
<vn-check
|
<vn-check
|
||||||
vn-one label="Is equalizated"
|
vn-one label="Is equalizated"
|
||||||
field="address.isEqualizated"
|
field="address.isEqualizated"
|
||||||
disabled="true">
|
disabled="true">
|
||||||
</vn-check>
|
</vn-check>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
</vn-horizontal>
|
<vn-vertical
|
||||||
</vn-one>
|
vn-one
|
||||||
<vn-vertical vn-one pad-medium-h>
|
ng-if="address.observations.length"
|
||||||
|
border-solid-left
|
||||||
|
pad-medium-h
|
||||||
|
style="height: 6em; overflow: auto;">
|
||||||
<vn-one ng-repeat="observation in address.observations track by $index" ng-class="{'pad-small-top': $index}">
|
<vn-one ng-repeat="observation in address.observations track by $index" ng-class="{'pad-small-top': $index}">
|
||||||
<b margin-medium-right>{{::observation.observationType.description}}:</b>
|
<b>{{::observation.observationType.description}}:</b>
|
||||||
<span>{{::observation.description}}</span>
|
<span>{{::observation.description}}</span>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
<a pad-medium-h vn-tooltip="Edit address"
|
|
||||||
vn-auto ui-sref="client.card.address.edit({addressId: {{::address.id}}})">
|
|
||||||
<vn-icon-button icon="edit"></vn-icon-button>
|
|
||||||
</a>
|
</a>
|
||||||
</vn-horizontal>
|
</div>
|
||||||
</vn-one>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
</vn-card>
|
||||||
<vn-float-button
|
<vn-float-button
|
||||||
vn-bind="+"
|
vn-bind="+"
|
||||||
|
|
|
@ -1,10 +1,47 @@
|
||||||
import ngModule from '../../module';
|
import ngModule from '../../module';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
class Controller {
|
class Controller {
|
||||||
constructor($http, $scope, $stateParams) {
|
constructor($http, $scope, $stateParams) {
|
||||||
this.$http = $http;
|
this.$http = $http;
|
||||||
this.$scope = $scope;
|
this.$scope = $scope;
|
||||||
this.$stateParams = $stateParams;
|
this.$stateParams = $stateParams;
|
||||||
|
this.filter = {
|
||||||
|
fields: [
|
||||||
|
'id',
|
||||||
|
'isDefaultAddress',
|
||||||
|
'isActive',
|
||||||
|
'nickname',
|
||||||
|
'street',
|
||||||
|
'city',
|
||||||
|
'provinceFk',
|
||||||
|
'phone',
|
||||||
|
'mobile',
|
||||||
|
'isEqualizated'
|
||||||
|
],
|
||||||
|
order: [
|
||||||
|
'isDefaultAddress DESC',
|
||||||
|
'isActive DESC',
|
||||||
|
'nickname ASC'],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'observations',
|
||||||
|
scope: {
|
||||||
|
include: 'observationType'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
relation: 'province',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onStarClick(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
setDefault(address) {
|
setDefault(address) {
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
@import "variables";
|
||||||
|
@import "./effects";
|
||||||
|
|
||||||
|
vn-client-address-index {
|
||||||
|
.address {
|
||||||
|
padding-bottom: $pad-medium;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
& > a {
|
||||||
|
@extend %clickable;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
color: inherit;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
value-field="id"
|
value-field="id"
|
||||||
where="{role: 'employee'}"
|
where="{role: 'employee'}"
|
||||||
label="Salesperson">
|
label="Salesperson">
|
||||||
<tpl-item>{{firstName}} {{name}}</tpl-item>
|
<tpl-item>{{firstName}} {{lastName}}</tpl-item>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
|
|
|
@ -46,7 +46,16 @@
|
||||||
label="File"
|
label="File"
|
||||||
model="$ctrl.dms.files"
|
model="$ctrl.dms.files"
|
||||||
on-change="$ctrl.onFileChange(files)"
|
on-change="$ctrl.onFileChange(files)"
|
||||||
accept=".pdf, .png, .jpg, .jpeg, application/zip, application/rar, application/x-7z-compressed">
|
accept="{{$ctrl.allowedContentTypes}}"
|
||||||
|
required="true"
|
||||||
|
multiple="true">
|
||||||
|
<t-right-icons>
|
||||||
|
<vn-icon vn-none
|
||||||
|
color-secondary
|
||||||
|
title="{{$ctrl.contentTypesInfo}}"
|
||||||
|
icon="info">
|
||||||
|
</vn-icon>
|
||||||
|
</t-right-icons>
|
||||||
</vn-input-file>
|
</vn-input-file>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-vertical>
|
<vn-vertical>
|
||||||
|
|
|
@ -22,8 +22,23 @@ class Controller {
|
||||||
set client(value) {
|
set client(value) {
|
||||||
this._client = value;
|
this._client = value;
|
||||||
|
|
||||||
if (value)
|
if (value) {
|
||||||
this.setDefaultParams();
|
this.setDefaultParams();
|
||||||
|
this.getAllowedContentTypes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getAllowedContentTypes() {
|
||||||
|
this.$http.get('/api/clientDms/allowedContentTypes').then(res => {
|
||||||
|
const contentTypes = res.data.join(', ');
|
||||||
|
this.allowedContentTypes = contentTypes;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get contentTypesInfo() {
|
||||||
|
return this.$translate.instant('ContentTypesInfo', {
|
||||||
|
allowedContentTypes: this.allowedContentTypes
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setDefaultParams() {
|
setDefaultParams() {
|
||||||
|
|
|
@ -18,8 +18,9 @@ describe('Client', () => {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('client() setter', () => {
|
describe('client() setter', () => {
|
||||||
it('should set the client data and then call setDefaultParams()', () => {
|
it('should set the client data and then call setDefaultParams() and getAllowedContentTypes()', () => {
|
||||||
spyOn(controller, 'setDefaultParams');
|
spyOn(controller, 'setDefaultParams');
|
||||||
|
spyOn(controller, 'getAllowedContentTypes');
|
||||||
controller.client = {
|
controller.client = {
|
||||||
id: 15,
|
id: 15,
|
||||||
name: 'Bruce wayne'
|
name: 'Bruce wayne'
|
||||||
|
@ -27,6 +28,7 @@ describe('Client', () => {
|
||||||
|
|
||||||
expect(controller.client).toBeDefined();
|
expect(controller.client).toBeDefined();
|
||||||
expect(controller.setDefaultParams).toHaveBeenCalledWith();
|
expect(controller.setDefaultParams).toHaveBeenCalledWith();
|
||||||
|
expect(controller.getAllowedContentTypes).toHaveBeenCalledWith();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -56,5 +58,18 @@ describe('Client', () => {
|
||||||
expect(controller.dms.hasFileAttached).toBeTruthy();
|
expect(controller.dms.hasFileAttached).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getAllowedContentTypes()', () => {
|
||||||
|
it('should make an HTTP GET request to get the allowed content types', () => {
|
||||||
|
const expectedResponse = ['image/png', 'image/jpg'];
|
||||||
|
$httpBackend.when('GET', `/api/clientDms/allowedContentTypes`).respond(expectedResponse);
|
||||||
|
$httpBackend.expect('GET', `/api/clientDms/allowedContentTypes`);
|
||||||
|
controller.getAllowedContentTypes();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.allowedContentTypes).toBeDefined();
|
||||||
|
expect(controller.allowedContentTypes).toEqual('image/png, image/jpg');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
ClientFileDescription: "{{dmsTypeName}} from client {{clientName}} id {{clientId}}"
|
|
|
@ -1,5 +0,0 @@
|
||||||
Upload file: Subir fichero
|
|
||||||
Upload: Subir
|
|
||||||
File: Fichero
|
|
||||||
ClientFileDescription: "{{dmsTypeName}} del cliente {{clientName}} id {{clientId}}"
|
|
||||||
Generate identifier for original file: Generar identificador para archivo original
|
|
|
@ -18,8 +18,23 @@ class Controller {
|
||||||
set client(value) {
|
set client(value) {
|
||||||
this._client = value;
|
this._client = value;
|
||||||
|
|
||||||
if (value)
|
if (value) {
|
||||||
this.setDefaultParams();
|
this.setDefaultParams();
|
||||||
|
this.getAllowedContentTypes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getAllowedContentTypes() {
|
||||||
|
this.$http.get('/api/clientDms/allowedContentTypes').then(res => {
|
||||||
|
const contentTypes = res.data.join(', ');
|
||||||
|
this.allowedContentTypes = contentTypes;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get contentTypesInfo() {
|
||||||
|
return this.$translate.instant('ContentTypesInfo', {
|
||||||
|
allowedContentTypes: this.allowedContentTypes
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setDefaultParams() {
|
setDefaultParams() {
|
||||||
|
|
|
@ -1,43 +1,52 @@
|
||||||
import './index';
|
import './index';
|
||||||
|
|
||||||
describe('Client', () => {
|
describe('Client', () => {
|
||||||
describe('Component vnClientDmsCreate', () => {
|
describe('Component vnClientDmsEdit', () => {
|
||||||
let controller;
|
let controller;
|
||||||
let $scope;
|
let $scope;
|
||||||
let $httpBackend;
|
let $httpBackend;
|
||||||
let $httpParamSerializer;
|
let $state;
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
beforeEach(ngModule('client'));
|
||||||
|
|
||||||
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
|
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => {
|
||||||
$scope = $rootScope.$new();
|
$scope = $rootScope.$new();
|
||||||
$httpBackend = _$httpBackend_;
|
$httpBackend = _$httpBackend_;
|
||||||
$httpParamSerializer = _$httpParamSerializer_;
|
$state = {params: {dmsId: 1}};
|
||||||
controller = $componentController('vnClientDmsCreate', {$scope});
|
controller = $componentController('vnClientDmsEdit', {$scope, $state});
|
||||||
controller._client = {id: 101, name: 'Bruce wayne'};
|
controller._client = {id: 1};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('client() setter', () => {
|
describe('client() setter', () => {
|
||||||
it('should set the client data and then call setDefaultParams()', () => {
|
it('should set the client data and then call setDefaultParams() and getAllowedContentTypes()', () => {
|
||||||
spyOn(controller, 'setDefaultParams');
|
spyOn(controller, 'setDefaultParams');
|
||||||
|
spyOn(controller, 'getAllowedContentTypes');
|
||||||
|
controller._client = undefined;
|
||||||
controller.client = {
|
controller.client = {
|
||||||
id: 15,
|
id: 15
|
||||||
name: 'Bruce wayne'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(controller.client).toBeDefined();
|
|
||||||
expect(controller.setDefaultParams).toHaveBeenCalledWith();
|
expect(controller.setDefaultParams).toHaveBeenCalledWith();
|
||||||
|
expect(controller.client).toBeDefined();
|
||||||
|
expect(controller.getAllowedContentTypes).toHaveBeenCalledWith();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setDefaultParams()', () => {
|
describe('setDefaultParams()', () => {
|
||||||
it('should perform a GET query and define the dms property on controller', () => {
|
it('should perform a GET query and define the dms property on controller', () => {
|
||||||
const params = {filter: {
|
const dmsId = 1;
|
||||||
where: {code: 'paymentsLaw'}
|
const expectedResponse = {
|
||||||
}};
|
reference: 101,
|
||||||
let serializedParams = $httpParamSerializer(params);
|
warehouseFk: 1,
|
||||||
$httpBackend.when('GET', `/api/DmsTypes/findOne?${serializedParams}`).respond({id: 12, code: 'paymentsLaw'});
|
companyFk: 442,
|
||||||
$httpBackend.expect('GET', `/api/DmsTypes/findOne?${serializedParams}`);
|
dmsTypeFk: 12,
|
||||||
|
description: 'Test',
|
||||||
|
hasFile: false,
|
||||||
|
hasFileAttached: false
|
||||||
|
};
|
||||||
|
|
||||||
|
$httpBackend.when('GET', `/api/Dms/${dmsId}`).respond(expectedResponse);
|
||||||
|
$httpBackend.expect('GET', `/api/Dms/${dmsId}`).respond(expectedResponse);
|
||||||
controller.setDefaultParams();
|
controller.setDefaultParams();
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
@ -50,11 +59,25 @@ describe('Client', () => {
|
||||||
describe('onFileChange()', () => {
|
describe('onFileChange()', () => {
|
||||||
it('should set dms hasFileAttached property to true if has any files', () => {
|
it('should set dms hasFileAttached property to true if has any files', () => {
|
||||||
const files = [{id: 1, name: 'MyFile'}];
|
const files = [{id: 1, name: 'MyFile'}];
|
||||||
|
controller.dms = {hasFileAttached: false};
|
||||||
controller.onFileChange(files);
|
controller.onFileChange(files);
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
|
|
||||||
expect(controller.dms.hasFileAttached).toBeTruthy();
|
expect(controller.dms.hasFileAttached).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getAllowedContentTypes()', () => {
|
||||||
|
it('should make an HTTP GET request to get the allowed content types', () => {
|
||||||
|
const expectedResponse = ['image/png', 'image/jpg'];
|
||||||
|
$httpBackend.when('GET', `/api/clientDms/allowedContentTypes`).respond(expectedResponse);
|
||||||
|
$httpBackend.expect('GET', `/api/clientDms/allowedContentTypes`);
|
||||||
|
controller.getAllowedContentTypes();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.allowedContentTypes).toBeDefined();
|
||||||
|
expect(controller.allowedContentTypes).toEqual('image/png, image/jpg');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
Edit file: Editar fichero
|
|
||||||
File: Fichero
|
|
||||||
Generate identifier for original file: Generar identificador para archivo original
|
|
|
@ -13,14 +13,14 @@
|
||||||
<vn-thead>
|
<vn-thead>
|
||||||
<vn-tr>
|
<vn-tr>
|
||||||
<vn-th field="dmsFk" default-order="DESC" shrink>Id</vn-th>
|
<vn-th field="dmsFk" default-order="DESC" shrink>Id</vn-th>
|
||||||
<vn-th field="dmsTypeFk" shrink>Type</vn-th>
|
<vn-th shrink>Type</vn-th>
|
||||||
<vn-th field="hardCopyNumber" shrink number>Order</vn-th>
|
<vn-th shrink number>Order</vn-th>
|
||||||
<vn-th field="reference" shrink>Reference</vn-th>
|
<vn-th shrink>Reference</vn-th>
|
||||||
<vn-th>Description</vn-th>
|
<vn-th>Description</vn-th>
|
||||||
<vn-th field="hasFile" shrink>Original</vn-th>
|
<vn-th shrink>Original</vn-th>
|
||||||
<vn-th>File</vn-th>
|
<vn-th>File</vn-th>
|
||||||
<vn-th shrink>Employee</vn-th>
|
<vn-th shrink>Employee</vn-th>
|
||||||
<vn-th field="created">Created</vn-th>
|
<vn-th>Created</vn-th>
|
||||||
<vn-th number></vn-th>
|
<vn-th number></vn-th>
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-thead>
|
</vn-thead>
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td>
|
<vn-td>
|
||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
vn-tooltip="Download file"
|
title="{{'Download file' | translate}}"
|
||||||
href="api/dms/{{::document.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}">{{::document.dms.file}}
|
href="api/dms/{{::document.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}">{{::document.dms.file}}
|
||||||
</a>
|
</a>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
|
@ -68,22 +68,20 @@
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td number>
|
<vn-td number>
|
||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
vn-tooltip="Download file"
|
|
||||||
href="api/dms/{{::document.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}">
|
href="api/dms/{{::document.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}">
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
icon="cloud_download"
|
icon="cloud_download"
|
||||||
title="{{'Download PDF' | translate}}">
|
title="{{'Download file' | translate}}">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
</a>
|
</a>
|
||||||
<vn-icon-button ui-sref="client.card.dms.edit({dmsId: {{::document.dmsFk}}})"
|
<vn-icon-button ui-sref="client.card.dms.edit({dmsId: {{::document.dmsFk}}})"
|
||||||
vn-tooltip="Edit file"
|
|
||||||
icon="edit"
|
icon="edit"
|
||||||
title="{{'Edit file' | translate}}">
|
title="{{'Edit file' | translate}}">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
vn-tooltip="Remove file"
|
|
||||||
icon="delete"
|
icon="delete"
|
||||||
ng-click="$ctrl.showDeleteConfirm($index)"
|
ng-click="$ctrl.showDeleteConfirm($index)"
|
||||||
|
title="{{'Remove file' | translate}}"
|
||||||
tabindex="-1">
|
tabindex="-1">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
|
|
|
@ -62,7 +62,7 @@ class Controller {
|
||||||
deleteDms(response) {
|
deleteDms(response) {
|
||||||
if (response === 'ACCEPT') {
|
if (response === 'ACCEPT') {
|
||||||
const dmsFk = this.clientDms[this.dmsIndex].dmsFk;
|
const dmsFk = this.clientDms[this.dmsIndex].dmsFk;
|
||||||
const query = `/api/ClientDms/${dmsFk}/removeFile`;
|
const query = `/api/clientDms/${dmsFk}/removeFile`;
|
||||||
this.$http.post(query).then(() => {
|
this.$http.post(query).then(() => {
|
||||||
this.$.model.remove(this.dmsIndex);
|
this.$.model.remove(this.dmsIndex);
|
||||||
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
import './index';
|
||||||
|
import crudModel from 'core/mocks/crud-model';
|
||||||
|
|
||||||
|
describe('Client', () => {
|
||||||
|
describe('Component vnClientDmsIndex', () => {
|
||||||
|
let $componentController;
|
||||||
|
let $scope;
|
||||||
|
let $httpBackend;
|
||||||
|
let controller;
|
||||||
|
|
||||||
|
beforeEach(ngModule('client'));
|
||||||
|
|
||||||
|
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_) => {
|
||||||
|
$componentController = _$componentController_;
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
$scope = $rootScope.$new();
|
||||||
|
controller = $componentController('vnClientDmsIndex', {$: $scope});
|
||||||
|
controller.$.model = crudModel;
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('deleteDms()', () => {
|
||||||
|
it('should make an HTTP Post query', () => {
|
||||||
|
const dmsId = 1;
|
||||||
|
const dmsIndex = 0;
|
||||||
|
spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
spyOn(controller.$.model, 'remove');
|
||||||
|
controller.clientDms = [{dmsFk: 1}];
|
||||||
|
controller.dmsIndex = dmsIndex;
|
||||||
|
|
||||||
|
$httpBackend.when('POST', `/api/clientDms/${dmsId}/removeFile`).respond({});
|
||||||
|
$httpBackend.expect('POST', `/api/clientDms/${dmsId}/removeFile`);
|
||||||
|
controller.deleteDms('ACCEPT');
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.$.model.remove).toHaveBeenCalledWith(dmsIndex);
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,2 @@
|
||||||
|
ClientFileDescription: "{{dmsTypeName}} from client {{clientName}} id {{clientId}}"
|
||||||
|
ContentTypesInfo: Allowed file types {{allowedContentTypes}}
|
|
@ -0,0 +1,14 @@
|
||||||
|
Upload file: Subir fichero
|
||||||
|
Edit file: Editar fichero
|
||||||
|
Upload: Subir
|
||||||
|
File: Fichero
|
||||||
|
ClientFileDescription: "{{dmsTypeName}} del cliente {{clientName}} id {{clientId}}"
|
||||||
|
ContentTypesInfo: "Tipos de archivo permitidos: {{allowedContentTypes}}"
|
||||||
|
Generate identifier for original file: Generar identificador para archivo original
|
||||||
|
File management: Gestión documental
|
||||||
|
Hard copy: Copia
|
||||||
|
This file will be deleted: Este fichero va a ser borrado
|
||||||
|
Are you sure?: Estas seguro?
|
||||||
|
File deleted: Fichero eliminado
|
||||||
|
Remove file: Eliminar fichero
|
||||||
|
Download file: Descargar fichero
|
|
@ -58,16 +58,12 @@
|
||||||
url="/api/Postcodes/location"
|
url="/api/Postcodes/location"
|
||||||
fields="['code', 'townFk']"
|
fields="['code', 'townFk']"
|
||||||
field="$ctrl.client.postcode"
|
field="$ctrl.client.postcode"
|
||||||
selection="$ctrl.postcodeSelection"
|
|
||||||
search-function="{code: $search}"
|
search-function="{code: $search}"
|
||||||
where="{townFk: town.selection.id}"
|
where="{townFk: town.selection.id}"
|
||||||
|
order="code, townFk"
|
||||||
show-field="code"
|
show-field="code"
|
||||||
value-field="code"
|
value-field="code"
|
||||||
label="Postcode">
|
label="Postcode">
|
||||||
<tpl-item>
|
|
||||||
{{code}}, {{town.name}} - {{town.province.name}}
|
|
||||||
({{town.province.country.country}})
|
|
||||||
</tpl-item>
|
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal pad-small-v>
|
<vn-horizontal pad-small-v>
|
||||||
|
|
|
@ -56,24 +56,8 @@ export default class Controller {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get postcodeSelection() {
|
|
||||||
return this._postcodeSelection;
|
|
||||||
}
|
|
||||||
|
|
||||||
set postcodeSelection(selection) {
|
|
||||||
const hasValue = this._postcodeSelection;
|
|
||||||
this._postcodeSelection = selection;
|
|
||||||
|
|
||||||
if (!selection || !hasValue) return;
|
|
||||||
|
|
||||||
const town = selection.town;
|
|
||||||
const province = town.province;
|
|
||||||
|
|
||||||
this.address.city = town.name;
|
|
||||||
this.address.provinceFk = province.id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.$inject = ['$scope', '$http', 'vnApp', '$translate'];
|
Controller.$inject = ['$scope', '$http', 'vnApp', '$translate'];
|
||||||
|
|
||||||
ngModule.component('vnClientFiscalData', {
|
ngModule.component('vnClientFiscalData', {
|
||||||
|
|
|
@ -21,9 +21,9 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.delete = async id => {
|
Self.delete = async id => {
|
||||||
const tx = await Self.beginTransaction({});
|
const transaction = await Self.beginTransaction({});
|
||||||
try {
|
try {
|
||||||
let options = {transaction: tx};
|
let options = {transaction: transaction};
|
||||||
|
|
||||||
let invoiceOut = await Self.findById(id);
|
let invoiceOut = await Self.findById(id);
|
||||||
let tickets = await Self.app.models.Ticket.find({where: {refFk: invoiceOut.ref}});
|
let tickets = await Self.app.models.Ticket.find({where: {refFk: invoiceOut.ref}});
|
||||||
|
@ -35,10 +35,10 @@ module.exports = Self => {
|
||||||
|
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
await invoiceOut.destroy(options);
|
await invoiceOut.destroy(options);
|
||||||
await tx.commit();
|
await transaction.commit();
|
||||||
return tickets;
|
return tickets;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
await transaction.rollback();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,11 +38,6 @@ module.exports = Self => {
|
||||||
type: 'Integer',
|
type: 'Integer',
|
||||||
description: 'Type id',
|
description: 'Type id',
|
||||||
http: {source: 'query'}
|
http: {source: 'query'}
|
||||||
}, {
|
|
||||||
arg: 'hasVisible',
|
|
||||||
type: 'Boolean',
|
|
||||||
description: 'Whether the the item has visible or not',
|
|
||||||
http: {source: 'query'}
|
|
||||||
}, {
|
}, {
|
||||||
arg: 'isActive',
|
arg: 'isActive',
|
||||||
type: 'Boolean',
|
type: 'Boolean',
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
panel="vn-item-search-panel"
|
panel="vn-item-search-panel"
|
||||||
on-search="$ctrl.onSearch($params)"
|
on-search="$ctrl.onSearch($params)"
|
||||||
info="Search items by id, name or barcode"
|
info="Search items by id, name or barcode"
|
||||||
|
suggested-filter="{isActive: true}"
|
||||||
vn-focus>
|
vn-focus>
|
||||||
</vn-searchbar>
|
</vn-searchbar>
|
||||||
<vn-icon-menu
|
<vn-icon-menu
|
||||||
|
|
|
@ -38,9 +38,6 @@ class Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
onSearch(params) {
|
onSearch(params) {
|
||||||
if (params && params.hasVisible === undefined && params.isActive === undefined)
|
|
||||||
Object.assign(params, {hasVisible: true, isActive: true});
|
|
||||||
|
|
||||||
if (params)
|
if (params)
|
||||||
this.$.model.applyFilter(null, params);
|
this.$.model.applyFilter(null, params);
|
||||||
else
|
else
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('getItemTypeAvailable', {
|
||||||
|
description: 'Gets the item types available for an rder and item category ',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'order id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'itemCategoryId',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: 'number',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/:id/getItemTypeAvailable`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.getItemTypeAvailable = async(orderId, itemCategoryId) => {
|
||||||
|
let stmts = [];
|
||||||
|
let stmt;
|
||||||
|
|
||||||
|
let order = await app.models.Order.findById(orderId);
|
||||||
|
stmt = new ParameterizedSQL('call vn.available_calc(?, ?, ?)', [
|
||||||
|
order.landed,
|
||||||
|
order.addressFk,
|
||||||
|
order.agencyModeFk
|
||||||
|
]);
|
||||||
|
stmts.push(stmt);
|
||||||
|
stmt = new ParameterizedSQL(`SELECT it.id, it.name
|
||||||
|
FROM tmp.availableCalc ac
|
||||||
|
JOIN cache.available a ON a.calc_id = ac.calcFk
|
||||||
|
JOIN item i ON i.id = a.item_id
|
||||||
|
JOIN itemType it ON it.id = i.typeFk
|
||||||
|
WHERE it.categoryFk = ?
|
||||||
|
GROUP BY it.id`, [
|
||||||
|
itemCategoryId
|
||||||
|
]);
|
||||||
|
let categoriesIndex = stmts.push(stmt) - 1;
|
||||||
|
|
||||||
|
let sql = ParameterizedSQL.join(stmts, ';');
|
||||||
|
let result = await Self.rawStmt(sql);
|
||||||
|
|
||||||
|
return result[categoriesIndex];
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,19 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
|
describe('order getItemTypeAvailable()', () => {
|
||||||
|
it('should call the getItemTypeAvailable method with a valid order and item category', async() => {
|
||||||
|
let orderId = 11;
|
||||||
|
let itemCategoryId = 1;
|
||||||
|
let result = await app.models.Order.getItemTypeAvailable(orderId, itemCategoryId);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the getItemTypeAvailable method with the same order and different item category', async() => {
|
||||||
|
let orderId = 11;
|
||||||
|
let itemCategoryId = 4;//
|
||||||
|
let result = await app.models.Order.getItemTypeAvailable(orderId, itemCategoryId);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(0);
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,3 +1,5 @@
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
require('../methods/order/new')(Self);
|
require('../methods/order/new')(Self);
|
||||||
require('../methods/order/getTotalVolume')(Self);
|
require('../methods/order/getTotalVolume')(Self);
|
||||||
|
@ -13,4 +15,12 @@ module.exports = Self => {
|
||||||
require('../methods/order/updateBasicData')(Self);
|
require('../methods/order/updateBasicData')(Self);
|
||||||
require('../methods/order/confirm')(Self);
|
require('../methods/order/confirm')(Self);
|
||||||
require('../methods/order/filter')(Self);
|
require('../methods/order/filter')(Self);
|
||||||
|
require('../methods/order/getItemTypeAvailable')(Self);
|
||||||
|
|
||||||
|
Self.beforeRemote('deleteById', async function(ctx) {
|
||||||
|
const targetOrder = await Self.findById(ctx.args.id);
|
||||||
|
|
||||||
|
if (targetOrder.isConfirmed === 1)
|
||||||
|
throw new UserError(`You can't delete a confirmed order`);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue