Merge branch 'dev' into test
gitea/salix/test This commit looks good
Details
gitea/salix/test This commit looks good
Details
This commit is contained in:
commit
462abce981
|
@ -31,3 +31,4 @@ rules:
|
|||
curly: [error, multi-or-nest]
|
||||
indent: [error, 4]
|
||||
arrow-parens: [error, as-needed]
|
||||
jasmine/no-focused-tests: 0
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('download', {
|
||||
description: 'Download a document',
|
||||
accessType: 'READ',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'id',
|
||||
type: 'String',
|
||||
description: 'The document id',
|
||||
http: {source: 'path'}
|
||||
}
|
||||
],
|
||||
returns: [
|
||||
{
|
||||
arg: 'body',
|
||||
type: 'file',
|
||||
root: true
|
||||
}, {
|
||||
arg: 'Content-Type',
|
||||
type: 'String',
|
||||
http: {target: 'header'}
|
||||
}, {
|
||||
arg: 'Content-Disposition',
|
||||
type: 'String',
|
||||
http: {target: 'header'}
|
||||
}
|
||||
],
|
||||
http: {
|
||||
path: `/:id/download`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.download = async function(ctx, id) {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const env = process.env.NODE_ENV;
|
||||
const document = await Self.findById(id, {
|
||||
include: {
|
||||
relation: 'dmsType',
|
||||
scope: {
|
||||
fields: ['path', 'readRoleFk'],
|
||||
include: {
|
||||
relation: 'readRole'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const readRole = document.dmsType().readRole().name;
|
||||
const hasRequiredRole = await Self.app.models.Account.hasRole(userId, readRole);
|
||||
|
||||
if (!hasRequiredRole)
|
||||
throw new UserError(`You don't have enough privileges`);
|
||||
|
||||
if (env && env != 'development') {
|
||||
const path = `/${document.companyFk}/${document.dmsType().path}/${document.file}`;
|
||||
file = {
|
||||
path: `/var/lib/salix/dms/${path}`,
|
||||
contentType: 'application/octet-stream',
|
||||
name: document.file
|
||||
};
|
||||
} else {
|
||||
file = {
|
||||
path: `${process.cwd()}/README.md`,
|
||||
contentType: 'text/plain',
|
||||
name: `README.md`
|
||||
};
|
||||
}
|
||||
|
||||
await fs.access(file.path);
|
||||
let stream = fs.createReadStream(file.path);
|
||||
return [stream, file.contentType, `filename="${file.name}"`];
|
||||
};
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
/**
|
||||
* Pendiente de fixtures dms, dmsType, ticketDms
|
||||
* CAU: 10728
|
||||
*/
|
||||
xdescribe('dms download()', () => {
|
||||
let dmsId = 1;
|
||||
it('should return a response for an employee with text content-type', async() => {
|
||||
let workerFk = 107;
|
||||
let ctx = {req: {accessToken: {userId: workerFk}}};
|
||||
const result = await app.models.Dms.download(ctx, dmsId);
|
||||
|
||||
expect(result[1]).toEqual('text/plain');
|
||||
});
|
||||
|
||||
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.Dms.download(ctx, dmsId).catch(e => {
|
||||
error = e;
|
||||
}).finally(() => {
|
||||
expect(error.message).toEqual(`You don't have enough privileges`);
|
||||
});
|
||||
|
||||
expect(error).toBeDefined();
|
||||
});
|
||||
});
|
|
@ -37,6 +37,12 @@
|
|||
},
|
||||
"EmailUser": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Dms": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"DmsType": {
|
||||
"dataSource": "vn"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = Self => {
|
||||
require('../methods/dms/download')(Self);
|
||||
};
|
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"name": "Dms",
|
||||
"description": "Documental Managment system",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "dms"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "Number",
|
||||
"id": true,
|
||||
"description": "Identifier"
|
||||
},
|
||||
"file": {
|
||||
"type": "string"
|
||||
},
|
||||
"reference": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"created": {
|
||||
"type": "Date"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"dmsType": {
|
||||
"type": "belongsTo",
|
||||
"model": "DmsType",
|
||||
"foreignKey": "dmsTypeFk"
|
||||
},
|
||||
"worker": {
|
||||
"type": "belongsTo",
|
||||
"model": "Worker",
|
||||
"foreignKey": "workerFk"
|
||||
},
|
||||
"warehouse": {
|
||||
"type": "belongsTo",
|
||||
"model": "Warehouse",
|
||||
"foreignKey": "warehouseFk"
|
||||
},
|
||||
"company": {
|
||||
"type": "belongsTo",
|
||||
"model": "Company",
|
||||
"foreignKey": "companyFk"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"name": "DmsType",
|
||||
"description": "Documental Managment system types",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "dmsType"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "Number",
|
||||
"id": true,
|
||||
"description": "Identifier"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"readRole": {
|
||||
"type": "belongsTo",
|
||||
"model": "Role",
|
||||
"foreignKey": "readRoleFk"
|
||||
},
|
||||
"writeRole": {
|
||||
"type": "belongsTo",
|
||||
"model": "Role",
|
||||
"foreignKey": "writeRoleFk"
|
||||
}
|
||||
},
|
||||
"acls": [{
|
||||
"accessType": "READ",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (162, 'InvoiceOut', 'delete', 'WRITE', 'ALLOW', 'ROLE', 'invoicing');
|
||||
INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (163, 'InvoiceOut', 'book', 'WRITE', 'ALLOW', 'ROLE', 'invoicing');
|
||||
INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (164, 'InvoiceOut', 'regenerate', 'WRITE', 'ALLOW', 'ROLE', 'invoicing');
|
||||
INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (165, 'TicketDms', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
|
||||
INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES (166, 'Dms', 'download', 'READ', 'ALLOW', 'ROLE', 'employee');
|
|
@ -0,0 +1,20 @@
|
|||
USE `vn`;
|
||||
CREATE
|
||||
OR REPLACE ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`dms` AS
|
||||
SELECT
|
||||
`g`.`id` AS `id`,
|
||||
`g`.`gesttip_id` AS `dmsTypeFk`,
|
||||
`g`.`file` AS `file`,
|
||||
`g`.`trabajador_id` AS `workerFk`,
|
||||
`g`.`warehouse_id` AS `warehouseFk`,
|
||||
`g`.`emp_id` AS `companyFk`,
|
||||
`g`.`orden` AS `priority`,
|
||||
`g`.`file` AS `hasFile`,
|
||||
`g`.`sref` AS `reference`,
|
||||
`g`.`brief` AS `description`,
|
||||
`g`.`odbc_date` AS `created`
|
||||
FROM
|
||||
`vn2008`.`gestdoc` `g`
|
|
@ -0,0 +1,71 @@
|
|||
DROP procedure IF EXISTS `nst`.`nodeAdd`;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `nst`.`nodeAdd`(IN `vScheme` VARCHAR(45), IN `vTable` VARCHAR(45), IN `vParentFk` INT, IN `vChild` VARCHAR(100))
|
||||
BEGIN
|
||||
DECLARE vSql TEXT;
|
||||
DECLARE vTableClone VARCHAR(45);
|
||||
|
||||
SET vTableClone = CONCAT(vTable, 'Clone');
|
||||
|
||||
CALL util.exec(CONCAT('DROP TEMPORARY TABLE IF EXISTS tmp.', vTableClone));
|
||||
CALL util.exec(CONCAT(
|
||||
'CREATE TEMPORARY TABLE tmp.', vTableClone,
|
||||
' ENGINE = MEMORY',
|
||||
' SELECT * FROM ', vScheme, '.', vTable
|
||||
));
|
||||
|
||||
CALL util.exec(CONCAT(
|
||||
'SELECT COUNT(c.id) INTO @childs',
|
||||
' FROM ', vScheme, '.', vTable, ' p',
|
||||
' LEFT JOIN tmp.', vTableClone, ' c ON c.lft',
|
||||
' BETWEEN p.lft AND p.rgt AND c.id != ', vParentFk,
|
||||
' WHERE p.id = ', vParentFk
|
||||
));
|
||||
|
||||
IF @childs = 0 THEN
|
||||
CALL util.exec(CONCAT(
|
||||
'SELECT lft INTO @vLeft',
|
||||
' FROM ', vScheme, '.', vTable,
|
||||
' WHERE id = ', vParentFk
|
||||
));
|
||||
ELSE
|
||||
CALL util.exec(CONCAT(
|
||||
'SELECT c.rgt INTO @vLeft',
|
||||
' FROM ', vScheme, '.', vTable, ' p',
|
||||
' JOIN tmp.', vTableClone, ' c ON c.lft BETWEEN p.lft AND p.rgt',
|
||||
' WHERE p.id = ', vParentFk,
|
||||
' ORDER BY c.lft',
|
||||
' DESC LIMIT 1'
|
||||
));
|
||||
END IF;
|
||||
|
||||
CALL util.exec(CONCAT(
|
||||
'UPDATE ', vScheme, '.', vTable, ' SET rgt = rgt + 2',
|
||||
' WHERE rgt > @vLeft',
|
||||
' ORDER BY rgt DESC'
|
||||
));
|
||||
CALL util.exec(CONCAT(
|
||||
'UPDATE ', vScheme, '.', vTable, ' SET lft = lft + 2',
|
||||
' WHERE lft > @vLeft',
|
||||
' ORDER BY lft DESC'
|
||||
));
|
||||
|
||||
SET vChild = REPLACE(vChild, "'", "\\'");
|
||||
|
||||
CALL util.exec(CONCAT(
|
||||
'INSERT INTO ', vScheme, '.', vTable, ' (name, lft, rgt)',
|
||||
' VALUES ("', vChild, '", @vLeft + 1, @vLeft + 2)'
|
||||
));
|
||||
|
||||
CALL util.exec(CONCAT(
|
||||
'SELECT id, name, lft, rgt, depth, sons',
|
||||
' FROM ', vScheme, '.', vTable,
|
||||
' WHERE id = LAST_INSERT_ID()'
|
||||
));
|
||||
|
||||
CALL util.exec(CONCAT('DROP TEMPORARY TABLE tmp.', vTableClone));
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
DROP procedure IF EXISTS `nst`.`nodeDelete`;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `nst`.`nodeDelete`(IN `vScheme` VARCHAR(45), IN `vTable` VARCHAR(45), IN `vNodeId` INT)
|
||||
BEGIN
|
||||
DECLARE vMyRight INT;
|
||||
DECLARE vMyLeft INT;
|
||||
DECLARE vMyWidth INT;
|
||||
|
||||
CALL util.exec(CONCAT(
|
||||
'SELECT t.rgt, t.lft, t.rgt - t.lft + 1',
|
||||
' INTO @vMyRight, @vMyLeft, @vMyWidth',
|
||||
' FROM ', vScheme, '.', vTable, ' t',
|
||||
' WHERE t.id = ', vNodeId
|
||||
));
|
||||
|
||||
CALL util.exec(CONCAT(
|
||||
'DELETE FROM ', vScheme, '.', vTable,
|
||||
' WHERE lft BETWEEN @vMyLeft AND @vMyRight'
|
||||
));
|
||||
|
||||
CALL util.exec(CONCAT(
|
||||
'UPDATE ', vScheme, '.', vTable, ' SET rgt = rgt - @vMyWidth'
|
||||
' WHERE rgt > @vMyRight ORDER BY rgt'
|
||||
));
|
||||
|
||||
CALL util.exec(CONCAT(
|
||||
'UPDATE ', vScheme, '.', vTable, ' SET lft = lft - @vMyWidth'
|
||||
' WHERE lft > @vMyRight ORDER BY lft'
|
||||
));
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
DROP procedure IF EXISTS `nst`.`nodeRecalc`;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `nst`.`nodeRecalc`(IN `vScheme` VARCHAR(45), IN `vTable` VARCHAR(45))
|
||||
BEGIN
|
||||
CALL util.exec(CONCAT (
|
||||
'UPDATE ', vScheme, '.', vTable, ' d',
|
||||
' JOIN (SELECT',
|
||||
' node.id,',
|
||||
' COUNT(parent.id) - 1 as depth,',
|
||||
' cast((node.rgt - node.lft - 1) / 2 as DECIMAL) as sons',
|
||||
' FROM ',
|
||||
' ', vScheme, '.', vTable, ' AS node,',
|
||||
' ', vScheme, '.', vTable, ' AS parent',
|
||||
' WHERE node.lft BETWEEN parent.lft AND parent.rgt',
|
||||
' GROUP BY node.id',
|
||||
' ORDER BY node.lft) n ON n.id = d.id ',
|
||||
' SET d.`depth` = n.depth, d.sons = n.sons'
|
||||
));
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
DROP VIEW IF EXISTS `vn`.`dmsTicket` ;
|
||||
USE `vn`;
|
||||
CREATE
|
||||
OR REPLACE ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`ticketDms` AS
|
||||
SELECT
|
||||
`g`.`Id_Ticket` AS `ticketFk`,
|
||||
`g`.`gestdoc_id` AS `dmsFk`
|
||||
FROM
|
||||
`vn2008`.`tickets_gestdoc` `g`;
|
|
@ -0,0 +1,7 @@
|
|||
ALTER TABLE `vn2008`.`gesttip`
|
||||
ADD COLUMN `writeRoleFk` INT(10) UNSIGNED NULL AFTER `path`,
|
||||
ADD COLUMN `readRoleFk` INT(10) UNSIGNED NULL AFTER `writeRoleFk`,
|
||||
ADD CONSTRAINT `readRoleFk` FOREIGN KEY (`readRoleFk`) REFERENCES `account`.`role` (`id`),
|
||||
ADD CONSTRAINT `writeRoleFk` FOREIGN KEY (`writeRoleFk`) REFERENCES `account`.`role` (`id`);
|
||||
|
||||
UPDATE `vn2008`.`gesttip` SET `readRoleFk`='1' WHERE `id`='14';
|
|
@ -0,0 +1,13 @@
|
|||
CREATE
|
||||
OR REPLACE ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`dmsType` AS
|
||||
SELECT
|
||||
`g`.`id` AS `id`,
|
||||
`g`.`tipo` AS `name`,
|
||||
`g`.`path` AS `path`,
|
||||
`g`.`readRoleFk` AS `readRoleFk`,
|
||||
`g`.`writeRoleFk` AS `writeRoleFk`
|
||||
FROM
|
||||
`vn2008`.`gesttip` `g`;
|
|
@ -388,11 +388,11 @@ INSERT INTO `vn`.`company`(`id`, `code`, `supplierAccountFk`, `workerManagerFk`,
|
|||
|
||||
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `pdf`)
|
||||
VALUES
|
||||
( 1, 'T', 500 , DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 101, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1),
|
||||
( 2, 'T', 350.50 , DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 102, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1),
|
||||
( 3, 'T', 90.30 , CURDATE(), 103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1),
|
||||
( 4, 'T', 290.30 , DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1),
|
||||
( 5, 'A', 190.30 , DATE_ADD(CURDATE(), INTERVAL +2 MONTH), 103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1);
|
||||
( 1, 'T', 156.09, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 101, CURDATE(), 442, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), CURDATE(), 1, 1),
|
||||
( 2, 'T', 208.35, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 102, CURDATE(), 442, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), CURDATE(), 1, 1),
|
||||
( 3, 'T', 20.02, CURDATE(), 103, CURDATE(), 442, CURDATE(), null, 1, 1),
|
||||
( 4, 'T', 20.02, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 103, CURDATE(), 442, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), null, 1, 1),
|
||||
( 5, 'A', 20.22, DATE_ADD(CURDATE(), INTERVAL +2 MONTH), 103, CURDATE(), 442, DATE_ADD(CURDATE(), INTERVAL +2 MONTH), null, 1, 1);
|
||||
|
||||
UPDATE `vn`.`invoiceOut` SET ref = 'T1111111' WHERE id = 1;
|
||||
UPDATE `vn`.`invoiceOut` SET ref = 'T2222222' WHERE id = 2;
|
||||
|
@ -413,6 +413,19 @@ INSERT INTO `vn`.`invoiceOutTax` (`invoiceOutFk`, `taxableBase`, `vat`, `pgcFk`)
|
|||
(5, 100, 10, 4722000010),
|
||||
(5, 200, 21, 4722000021);
|
||||
|
||||
INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion`)
|
||||
VALUES
|
||||
('CEE', 1, 10),
|
||||
('EQU', 0, 1),
|
||||
('NATIONAL', 0, 1),
|
||||
('WORLD', 2, 15);
|
||||
|
||||
INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaFk`, `isCEE`)
|
||||
VALUES
|
||||
('A', 'Global nacional', 1, 'NATIONAL', 0),
|
||||
('T', 'Española rapida', 1, 'NATIONAL', 0),
|
||||
('V', 'Intracomunitaria global', 0, 'CEE', 1);
|
||||
|
||||
INSERT INTO `vn`.`ticket`(`id`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `created`)
|
||||
VALUES
|
||||
(1 , 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY) , DATE_ADD(CURDATE(), INTERVAL -15 DAY) , 101, 'address 21', 121, 'T1111111', 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY) ),
|
||||
|
@ -423,8 +436,8 @@ INSERT INTO `vn`.`ticket`(`id`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped
|
|||
(6 , 3, 3, 4, DATE_ADD(CURDATE(), INTERVAL -2 DAY) , DATE_ADD(CURDATE(), INTERVAL -2 DAY) , 103, 'address 23', 123, 'T4444444', 0, DATE_ADD(CURDATE(), INTERVAL -2 DAY) ),
|
||||
(7 , 4, 4, 4, DATE_ADD(CURDATE(), INTERVAL -1 DAY) , DATE_ADD(CURDATE(), INTERVAL -1 DAY) , 104, 'address 24', 124, 'T4444444', 0, DATE_ADD(CURDATE(), INTERVAL -1 DAY) ),
|
||||
(8 , 1, 1, 4, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 104, 'address 24', 124, NULL, 0, DATE_ADD(CURDATE(), INTERVAL +1 MONTH) ),
|
||||
(9 , 5, 5, 4, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 105, 'address 25', 125, NULL, 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH) ),
|
||||
(10, 6, 5, 5, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), DATE_ADD(CURDATE(), INTERVAL -3 MONTH), 105, 'address 25', 125, NULL, 0, DATE_ADD(CURDATE(), INTERVAL -3 MONTH) ),
|
||||
(9 , 5, 5, 4, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 105, 'address 25', 125, 'A1111111', 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH) ),
|
||||
(10, 6, 5, 5, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), DATE_ADD(CURDATE(), INTERVAL -3 MONTH), 105, 'address 25', 125, 'A1111111', 0, DATE_ADD(CURDATE(), INTERVAL -3 MONTH) ),
|
||||
(11, 7, 1, 1, CURDATE() , CURDATE() , 101, 'address 21', 121, NULL, 0, CURDATE() ),
|
||||
(12, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 101, 'address 21', 121, NULL, 0, DATE_ADD(CURDATE(), INTERVAL +1 MONTH) ),
|
||||
(13, 2, 2, 2, DATE_ADD(CURDATE(), INTERVAL +2 MONTH), DATE_ADD(CURDATE(), INTERVAL +2 MONTH), 101, 'address 21', 121, NULL, 0, DATE_ADD(CURDATE(), INTERVAL +2 MONTH) ),
|
||||
|
@ -614,22 +627,22 @@ INSERT INTO `vn`.`ticketPackaging`(`id`, `ticketFk`, `packagingFk`, `quantity`,
|
|||
INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `price`, `discount`, `reserved`, `isPicked`, `created`)
|
||||
VALUES
|
||||
(1, 1, 1, 'Ranged weapon longbow 2m', 5, 9.10, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
(2, 2, 1, 'Melee weapon combat first 15cm', 10, 1.07, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
(2, 2, 1, 'Melee weapon combat fist 15cm', 10, 1.07, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
(3, 1, 1, 'Ranged weapon longbow 2m', 2, 9.10, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
(4, 4, 1, 'Melee weapon heavy shield 1x0.5m', 20, 3.06, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
(5, 1, 2, 'Ranged weapon longbow 2m', 10, 9.10, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -10 DAY)),
|
||||
(6, 1, 3, 'Ranged weapon longbow 2m', 15, 6.50, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -5 DAY)),
|
||||
(7, 2, 11, 'Melee weapon combat first 15cm', 15, 1.46, 0, 0, 0, CURDATE()),
|
||||
(7, 2, 11, 'Melee weapon combat fist 15cm', 15, 1.46, 0, 0, 0, CURDATE()),
|
||||
(8, 4, 11, 'Melee weapon heavy shield 1x0.5m', 10, 3.04, 0, 0, 0, CURDATE()),
|
||||
(9, 1, 16, 'Ranged weapon longbow 2m', 5, 9.10, 0, 0, 0, CURDATE()),
|
||||
(10, 2, 16, 'Melee weapon combat first 15cm', 10, 1.07, 0, 0, 0, CURDATE()),
|
||||
(10, 2, 16, 'Melee weapon combat fist 15cm', 10, 1.07, 0, 0, 0, CURDATE()),
|
||||
(11, 1, 16, 'Ranged weapon longbow 2m', 2, 9.10, 0, 0, 0, CURDATE()),
|
||||
(12, 4, 16, 'Melee weapon heavy shield 1x0.5m', 20, 3.06, 0, 0, 0, CURDATE()),
|
||||
(13, 2, 8, 'Melee weapon combat first 15cm', 15, 1.30, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(13, 2, 8, 'Melee weapon combat fist 15cm', 15, 1.30, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(14, 1, 8, 'Ranged weapon longbow 2m', 10, 2.30, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(15, 1, 19, 'Ranged weapon longbow 2m', 10, 1.50, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL +1 DAY)),
|
||||
(16, 2, 20, 'Melee weapon combat first 15cm', 15, 1.30, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL +1 DAY)),
|
||||
(17, 2, 22, 'Melee weapon combat first 15cm', 30, 2.30, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL +1 DAY)),
|
||||
(16, 2, 20, 'Melee weapon combat fist 15cm', 15, 1.30, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL +1 DAY)),
|
||||
(17, 2, 22, 'Melee weapon combat fist 15cm', 30, 2.30, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL +1 DAY)),
|
||||
(18, 4, 22, 'Melee weapon heavy shield 1x0.5m', 20, 3.00, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL +1 DAY)),
|
||||
(19, 1, 4, 'Ranged weapon longbow 2m', 1, 9.10, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -4 DAY)),
|
||||
(20, 1, 5, 'Ranged weapon longbow 2m', 1, 9.10, 0, 0, 0, DATE_ADD(CURDATE(), INTERVAL -3 DAY)),
|
||||
|
@ -816,7 +829,7 @@ INSERT INTO `vn`.`itemTag`(`id`,`itemFk`,`tagFk`,`value`,`priority`)
|
|||
(6 , 1, 67, 'precission', 6),
|
||||
(7 , 1, 23, '1', 7),
|
||||
(8 , 2, 56, 'Melee weapon', 1),
|
||||
(9 , 2, 58, 'combat first', 2),
|
||||
(9 , 2, 58, 'combat fist', 2),
|
||||
(10, 2, 27, '15cm', 3),
|
||||
(11, 2, 36, 'Stark Industries', 4),
|
||||
(12, 2, 1, 'Silver', 5),
|
||||
|
@ -1213,13 +1226,15 @@ INSERT INTO `vn`.`ticketRequest`(`id`, `description`, `requesterFk`, `atenderFk`
|
|||
(1, 'Ranged weapon longbow 2m', 18, 35, 5, 1, 9.10, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
(2, 'Melee weapon combat first 15cm', 18, 35, 10, 2, 1.07, 0, NULL, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
(3, 'Melee weapon heavy shield 1x0.5m', 18, 35, 20, 4, 3.06, 0, NULL, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
(4, 'Melee weapon combat first 15cm', 18, 35, 15, 2, 1.30, NULL, NULL, 11, CURDATE());
|
||||
(4, 'Melee weapon combat first 15cm', 18, 35, 15, NULL, 1.30, NULL, NULL, 11, CURDATE());
|
||||
|
||||
INSERT INTO `vn`.`ticketService`(`id`, `description`, `quantity`, `price`, `taxClassFk`, `ticketFk`)
|
||||
VALUES
|
||||
(1, 'delivery charge', 1, 2.00, 1, 1),
|
||||
(2, 'training course', 1, 10.00, 1, 2),
|
||||
(3, 'delivery charge', 1, 5.50, 1, 11);
|
||||
(1, 'Documentos', 1, 2.00, 1, 1),
|
||||
(2, 'Porte Agencia', 1, 10.00, 1, 2),
|
||||
(3, 'Documentos', 1, 5.50, 1, 11),
|
||||
(4, 'Documentos', 1, 2.00, 1, 9),
|
||||
(5, 'Documentos', 1, 2.00, 1, 8);
|
||||
|
||||
|
||||
INSERT INTO `vn`.`zone` (`id`, `name`, `hour`, `warehouseFk`, `agencyModeFk`, `travelingDays`, `price`, `bonus`)
|
||||
|
@ -1260,7 +1275,7 @@ INSERT INTO `pbx`.`sip`(`user_id`, `extension`, `secret`, `caller_id`)
|
|||
(9, 1201, '123456', 'developer');
|
||||
|
||||
INSERT INTO `postgresql`.`person`(`person_id`, `name`, `nickname`, `nif`, `firstname`, `id_trabajador`)
|
||||
SELECT w.id, w.name, u.nickname,CONCAT(RPAD(CONCAT(w.id,9),8,w.id),'A'),w.firstName,w.id
|
||||
SELECT w.id, w.lastName, u.nickname,CONCAT(RPAD(CONCAT(w.id,9),8,w.id),'A'),w.firstName,w.id
|
||||
FROM `vn`.`worker` `w`
|
||||
JOIN `account`.`user` `u` ON `u`.`id` = `w`.`userFk`;
|
||||
|
||||
|
@ -1273,7 +1288,7 @@ INSERT INTO `postgresql`.`profile`(`profile_id`, `person_id`, `profile_type_id`)
|
|||
FROM `postgresql`.`person` `p`;
|
||||
|
||||
INSERT INTO `postgresql`.`business`(`business_id`, `client_id`, `provider_id`, `date_start`, `date_end`, `workerBusiness`, `reasonEndFk`)
|
||||
SELECT p.profile_id, p.profile_id, 1000, DATE_ADD(CURDATE(), INTERVAL -15 DAY), DATE_ADD(CURDATE(), INTERVAL +6 MONTH), CONCAT('E-46-',RPAD(CONCAT(p.profile_id,9),8,p.profile_id)), NULL
|
||||
SELECT p.profile_id, p.profile_id, 1000, CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR)), '-12-31'), CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL +1 YEAR)), '-01-01'), CONCAT('E-46-',RPAD(CONCAT(p.profile_id,9),8,p.profile_id)), NULL
|
||||
FROM `postgresql`.`profile` `p`;
|
||||
|
||||
INSERT INTO `postgresql`.`business_labour`(`business_id`, `notes`, `department_id`, `professional_category_id`, `incentivo`, `calendar_labour_type_id`, `porhoras`, `labour_agreement_id`, `workcenter_id`)
|
||||
|
|
|
@ -19,3 +19,4 @@ services:
|
|||
volumes:
|
||||
- /containers/salix:/etc/salix
|
||||
- /mnt/storage/pdfs:/var/lib/salix/pdfs
|
||||
- /mnt/storage/dms:/var/lib/salix/dms
|
|
@ -1,6 +1,3 @@
|
|||
// eslint max-len: ["error", 500]
|
||||
// eslint key-spacing: ["error", 500]
|
||||
|
||||
export default {
|
||||
vnTextfield: 'vn-textfield > div > div > div > input',
|
||||
vnInputNumber: 'vn-input-number > div > div > div > input',
|
||||
|
|
|
@ -2,30 +2,30 @@ import components from './components_selectors.js';
|
|||
|
||||
export default {
|
||||
globalItems: {
|
||||
applicationsMenuButton: `#apps`,
|
||||
applicationsMenuVisible: `vn-main-menu [vn-id="apps-menu"] ul`,
|
||||
clientsButton: `vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="client.index"]`,
|
||||
itemsButton: `vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="item.index"]`,
|
||||
ticketsButton: `vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="ticket.index"]`,
|
||||
claimsButton: `vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="claim.index"]`,
|
||||
applicationsMenuButton: '#apps',
|
||||
applicationsMenuVisible: 'vn-main-menu [vn-id="apps-menu"] ul',
|
||||
clientsButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="client.index"]',
|
||||
itemsButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="item.index"]',
|
||||
ticketsButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="ticket.index"]',
|
||||
claimsButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="claim.index"]',
|
||||
returnToModuleIndexButton: `a[translate-attr="{title: 'Return to module index'}"]`,
|
||||
userMenuButton: `vn-topbar #user`,
|
||||
userLocalWarehouse: `vn-topbar vn-popover vn-autocomplete[field="$ctrl.localWarehouseFk"]`,
|
||||
userLocalBank: `vn-topbar vn-popover vn-autocomplete[field="$ctrl.localBankFk"]`,
|
||||
userLocalCompany: `vn-topbar vn-popover vn-autocomplete[field="$ctrl.localCompanyFk"]`,
|
||||
userWarehouse: `vn-topbar vn-popover vn-autocomplete[field="$ctrl.warehouseFk"]`,
|
||||
userCompany: `vn-topbar vn-popover vn-autocomplete[field="$ctrl.companyFk"]`,
|
||||
userMenuButton: 'vn-topbar #user',
|
||||
userLocalWarehouse: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.localWarehouseFk"]',
|
||||
userLocalBank: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.localBankFk"]',
|
||||
userLocalCompany: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.localCompanyFk"]',
|
||||
userWarehouse: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.warehouseFk"]',
|
||||
userCompany: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.companyFk"]',
|
||||
userConfigFirstAutocompleteClear: '#localWarehouse > div > div > div > vn-icon.clear',
|
||||
userConfigSecondAutocompleteClear: '#localBank > div > div > div > vn-icon.clear',
|
||||
userConfigThirdAutocompleteClear: '#localCompany > div > div > div > vn-icon.clear',
|
||||
acceptVnConfirm: `vn-confirm button[response=ACCEPT]`
|
||||
acceptVnConfirm: 'vn-confirm button[response=ACCEPT]'
|
||||
},
|
||||
clientsIndex: {
|
||||
searchClientInput: `${components.vnTextfield}`,
|
||||
searchButton: `vn-searchbar vn-icon[icon="search"]`,
|
||||
searchResult: `vn-client-index .vn-list-item`,
|
||||
searchButton: 'vn-searchbar vn-icon[icon="search"]',
|
||||
searchResult: 'vn-client-index .vn-list-item',
|
||||
createClientButton: `${components.vnFloatButton}`,
|
||||
othersButton: `vn-left-menu li[name="Others"] > a`
|
||||
othersButton: 'vn-left-menu li[name="Others"] > a'
|
||||
},
|
||||
createClientView: {
|
||||
name: `${components.vnTextfield}[name="name"]`,
|
||||
|
@ -37,53 +37,53 @@ export default {
|
|||
email: `${components.vnTextfield}[name="email"]`,
|
||||
salesPersonAutocomplete: `vn-autocomplete[field="$ctrl.client.salesPersonFk"]`,
|
||||
createButton: `${components.vnSubmit}`,
|
||||
cancelButton: `vn-button[href="#!/client/index"]`
|
||||
cancelButton: 'vn-button[href="#!/client/index"]'
|
||||
},
|
||||
clientDescriptor: {
|
||||
moreMenu: `vn-client-descriptor vn-icon-menu > div > vn-icon`,
|
||||
moreMenu: 'vn-client-descriptor vn-icon-menu > div > vn-icon',
|
||||
simpleTicketButton: 'vn-client-descriptor vn-popover > div > div.content > div > div.list > ul > li'
|
||||
},
|
||||
clientBasicData: {
|
||||
basicDataButton: `vn-left-menu a[ui-sref="client.card.basicData"]`,
|
||||
basicDataButton: 'vn-left-menu a[ui-sref="client.card.basicData"]',
|
||||
nameInput: `${components.vnTextfield}[name="name"]`,
|
||||
contactInput: `${components.vnTextfield}[name="contact"]`,
|
||||
phoneInput: `${components.vnTextfield}[name="phone"]`,
|
||||
mobileInput: `${components.vnTextfield}[name="mobile"]`,
|
||||
faxInput: `${components.vnTextfield}[name="fax"]`,
|
||||
emailInput: `${components.vnTextfield}[name="email"]`,
|
||||
salesPersonAutocomplete: `vn-autocomplete[field="$ctrl.client.salesPersonFk"]`,
|
||||
channelAutocomplete: `vn-autocomplete[field="$ctrl.client.contactChannelFk"]`,
|
||||
salesPersonAutocomplete: 'vn-autocomplete[field="$ctrl.client.salesPersonFk"]',
|
||||
channelAutocomplete: 'vn-autocomplete[field="$ctrl.client.contactChannelFk"]',
|
||||
saveButton: `${components.vnSubmit}`
|
||||
},
|
||||
clientFiscalData: {
|
||||
fiscalDataButton: `vn-left-menu a[ui-sref="client.card.fiscalData"]`,
|
||||
fiscalDataButton: 'vn-left-menu a[ui-sref="client.card.fiscalData"]',
|
||||
socialNameInput: `${components.vnTextfield}[name="socialName"]`,
|
||||
fiscalIdInput: `${components.vnTextfield}[name="fi"]`,
|
||||
equalizationTaxCheckbox: `vn-check[label='Is equalizated'] md-checkbox`,
|
||||
acceptPropagationButton: `vn-client-fiscal-data > vn-confirm button[response=ACCEPT]`,
|
||||
equalizationTaxCheckbox: 'vn-check[label="Is equalizated"] md-checkbox',
|
||||
acceptPropagationButton: 'vn-client-fiscal-data > vn-confirm button[response=ACCEPT]',
|
||||
addressInput: `${components.vnTextfield}[name="street"]`,
|
||||
cityInput: `${components.vnTextfield}[name="city"]`,
|
||||
postcodeInput: `${components.vnTextfield}[name="postcode"]`,
|
||||
provinceAutocomplete: `vn-autocomplete[field="$ctrl.client.provinceFk"]`,
|
||||
countryAutocomplete: `vn-autocomplete[field="$ctrl.client.countryFk"]`,
|
||||
activeCheckbox: `vn-check[label="Active"] md-checkbox`,
|
||||
frozenCheckbox: `vn-check[label="Frozen"] md-checkbox`,
|
||||
invoiceByAddressCheckbox: `vn-check[label='Invoice by address'] md-checkbox`,
|
||||
verifiedDataCheckbox: `vn-check[label="Verified data"] md-checkbox`,
|
||||
hasToInvoiceCheckbox: `vn-check[label='Has to invoice'] md-checkbox`,
|
||||
invoiceByMailCheckbox: `vn-check[label='Invoice by mail'] md-checkbox`,
|
||||
viesCheckbox: `vn-check[label='Vies'] md-checkbox`,
|
||||
provinceAutocomplete: 'vn-autocomplete[field="$ctrl.client.provinceFk"]',
|
||||
countryAutocomplete: 'vn-autocomplete[field="$ctrl.client.countryFk"]',
|
||||
activeCheckbox: 'vn-check[label="Active"] md-checkbox',
|
||||
frozenCheckbox: 'vn-check[label="Frozen"] md-checkbox',
|
||||
invoiceByAddressCheckbox: 'vn-check[label="Invoice by address"] md-checkbox',
|
||||
verifiedDataCheckbox: 'vn-check[label="Verified data"] md-checkbox',
|
||||
hasToInvoiceCheckbox: 'vn-check[label="Has to invoice"] md-checkbox',
|
||||
invoiceByMailCheckbox: 'vn-check[label="Invoice by mail"] md-checkbox',
|
||||
viesCheckbox: 'vn-check[label="Vies"] md-checkbox',
|
||||
saveButton: `${components.vnSubmit}`
|
||||
},
|
||||
clientPayMethod: {
|
||||
payMethodAutocomplete: `vn-autocomplete[field="$ctrl.client.payMethodFk"]`,
|
||||
clientBillingData: {
|
||||
payMethodAutocomplete: 'vn-autocomplete[field="$ctrl.client.payMethodFk"]',
|
||||
IBANInput: `${components.vnTextfield}[name="iban"]`,
|
||||
dueDayInput: `${components.vnInputNumber}[name="dueDay"]`,
|
||||
receivedCoreLCRCheckbox: `vn-check[label='Received LCR'] md-checkbox`,
|
||||
receivedCoreVNLCheckbox: `vn-check[label='Received core VNL'] md-checkbox`,
|
||||
receivedB2BVNLCheckbox: `vn-check[label='Received B2B VNL'] md-checkbox`,
|
||||
receivedCoreLCRCheckbox: 'vn-check[label="Received LCR"] md-checkbox',
|
||||
receivedCoreVNLCheckbox: 'vn-check[label="Received core VNL"] md-checkbox',
|
||||
receivedB2BVNLCheckbox: 'vn-check[label="Received B2B VNL"] md-checkbox',
|
||||
swiftBicAutocomplete: 'vn-client-billing-data vn-autocomplete[field="$ctrl.client.bankEntityFk"]',
|
||||
clearswiftBicButton: `vn-client-billing-data vn-autocomplete[field="$ctrl.client.bankEntityFk"] > div > div > div > vn-icon > i`,
|
||||
clearswiftBicButton: 'vn-client-billing-data vn-autocomplete[field="$ctrl.client.bankEntityFk"] > div > div > div > vn-icon > i',
|
||||
newBankEntityButton: 'vn-client-billing-data vn-icon-button[vn-tooltip="New bank entity"] > button',
|
||||
newBankEntityName: 'vn-client-billing-data > vn-dialog vn-textfield[label="Name"] input',
|
||||
newBankEntityBIC: 'vn-client-billing-data > vn-dialog vn-textfield[label="Swift / BIC"] input',
|
||||
|
@ -92,41 +92,41 @@ export default {
|
|||
saveButton: `${components.vnSubmit}`
|
||||
},
|
||||
clientAddresses: {
|
||||
addressesButton: `vn-left-menu a[ui-sref="client.card.address.index"]`,
|
||||
addressesButton: 'vn-left-menu a[ui-sref="client.card.address.index"]',
|
||||
createAddress: `vn-client-address-index ${components.vnFloatButton}`,
|
||||
defaultCheckboxInput: `vn-check[label='Default'] md-checkbox`,
|
||||
defaultCheckboxInput: 'vn-check[label="Default"] md-checkbox',
|
||||
consigneeInput: `${components.vnTextfield}[name="nickname"]`,
|
||||
streetAddressInput: `${components.vnTextfield}[name="street"]`,
|
||||
postcodeInput: `${components.vnTextfield}[name="postalCode"]`,
|
||||
cityInput: `${components.vnTextfield}[name="city"]`,
|
||||
provinceAutocomplete: `vn-autocomplete[field="$ctrl.address.provinceFk"]`,
|
||||
agencyAutocomplete: `vn-autocomplete[field="$ctrl.address.agencyModeFk"]`,
|
||||
provinceAutocomplete: 'vn-autocomplete[field="$ctrl.address.provinceFk"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[field="$ctrl.address.agencyModeFk"]',
|
||||
phoneInput: `${components.vnTextfield}[name="phone"]`,
|
||||
mobileInput: `${components.vnTextfield}[name="mobile"]`,
|
||||
defaultAddress: 'vn-client-address-index vn-horizontal:nth-child(1) div[name="street"]',
|
||||
secondMakeDefaultStar: 'vn-client-address-index vn-card vn-horizontal:nth-child(2) vn-icon-button[icon="star_border"]',
|
||||
firstEditButton: `vn-client-address-index vn-icon-button[icon='edit']`,
|
||||
secondEditButton: `vn-client-address-index vn-horizontal:nth-child(2) vn-icon-button[icon='edit']`,
|
||||
activeCheckbox: `vn-check[label='Enabled'] 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"]`,
|
||||
firstObservationDescriptionInput: `vn-client-address-edit [name=observations] :nth-child(1) [model="observation.description"] input`,
|
||||
secondObservationTypeAutocomplete: `vn-client-address-edit [name=observations] :nth-child(2) [field="observation.observationTypeFk"]`,
|
||||
secondObservationDescriptionInput: `vn-client-address-edit [name=observations] :nth-child(2) [model="observation.description"] input`,
|
||||
addObservationButton: `vn-client-address-edit vn-icon-button[icon="add_circle"]`,
|
||||
firstEditButton: 'vn-client-address-index vn-icon-button[icon="edit"]',
|
||||
secondEditButton: 'vn-client-address-index vn-horizontal:nth-child(2) vn-icon-button[icon="edit"]',
|
||||
activeCheckbox: 'vn-check[label="Enabled"] 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"]',
|
||||
firstObservationDescriptionInput: 'vn-client-address-edit [name=observations] :nth-child(1) [model="observation.description"] input',
|
||||
secondObservationTypeAutocomplete: 'vn-client-address-edit [name=observations] :nth-child(2) [field="observation.observationTypeFk"]',
|
||||
secondObservationDescriptionInput: 'vn-client-address-edit [name=observations] :nth-child(2) [model="observation.description"] input',
|
||||
addObservationButton: 'vn-client-address-edit vn-icon-button[icon="add_circle"]',
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
cancelCreateAddressButton: `button[ui-sref="client.card.address.index"]`,
|
||||
cancelCreateAddressButton: 'button[ui-sref="client.card.address.index"]',
|
||||
cancelEditAddressButton: 'vn-client-address-edit > form > vn-button-bar > vn-button > button'
|
||||
},
|
||||
clientWebAccess: {
|
||||
webAccessButton: `vn-left-menu a[ui-sref="client.card.webAccess"]`,
|
||||
enableWebAccessCheckbox: `vn-check[label='Enable web access'] md-checkbox`,
|
||||
webAccessButton: 'vn-left-menu a[ui-sref="client.card.webAccess"]',
|
||||
enableWebAccessCheckbox: 'vn-check[label="Enable web access"] md-checkbox',
|
||||
userNameInput: `${components.vnTextfield}[name="name"]`,
|
||||
saveButton: `${components.vnSubmit}`
|
||||
},
|
||||
clientNotes: {
|
||||
addNoteFloatButton: `${components.vnFloatButton}`,
|
||||
noteInput: `vn-textarea[label="Note"]`,
|
||||
noteInput: 'vn-textarea[label="Note"]',
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
firstNoteText: 'vn-client-note .text'
|
||||
},
|
||||
|
@ -140,7 +140,7 @@ export default {
|
|||
addGreugeFloatButton: `${components.vnFloatButton}`,
|
||||
amountInput: `${components.vnInputNumber}[name="amount"]`,
|
||||
descriptionInput: `${components.vnTextfield}[name="description"]`,
|
||||
typeAutocomplete: `vn-autocomplete[field="$ctrl.greuge.greugeTypeFk"]`,
|
||||
typeAutocomplete: 'vn-autocomplete[field="$ctrl.greuge.greugeTypeFk"]',
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
firstGreugeText: 'vn-client-greuge-index vn-card > div vn-table vn-tbody > vn-tr'
|
||||
},
|
||||
|
@ -151,20 +151,20 @@ export default {
|
|||
firstInvoiceText: 'vn-client-invoice vn-card > div vn-table vn-tbody > vn-tr'
|
||||
},
|
||||
clientLog: {
|
||||
logButton: `vn-left-menu a[ui-sref="client.card.log"]`,
|
||||
logButton: 'vn-left-menu a[ui-sref="client.card.log"]',
|
||||
lastModificationDate: 'vn-client-log > vn-log vn-table vn-tbody > vn-tr > vn-td:nth-child(1)',
|
||||
lastModificationPreviousValue: 'vn-client-log vn-table vn-td.before',
|
||||
lastModificationCurrentValue: 'vn-client-log vn-table vn-td.after'
|
||||
|
||||
},
|
||||
clientRisk: {
|
||||
riskButton: `vn-left-menu a[ui-sref="client.card.risk.index"]`,
|
||||
companyAutocomplete: 'vn-client-risk-index vn-autocomplete[field="$ctrl.companyFk"]',
|
||||
clientBalance: {
|
||||
balanceButton: 'vn-left-menu a[ui-sref="client.card.balance.index"]',
|
||||
companyAutocomplete: 'vn-client-balance-index vn-autocomplete[field="$ctrl.companyFk"]',
|
||||
newPaymentButton: `${components.vnFloatButton}`,
|
||||
newPaymentBankInut: `vn-client-risk-create vn-textfield[field="$ctrl.receipt.bankFk"] input`,
|
||||
newPaymentAmountInput: `vn-client-risk-create vn-input-number[field="$ctrl.receipt.amountPaid"] input`,
|
||||
saveButton: `vn-client-risk-create vn-button[label="Save"]`,
|
||||
firstRiskLineBalance: 'vn-client-risk-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(8)'
|
||||
newPaymentBankInut: 'vn-client-balance-create vn-textfield[field="$ctrl.receipt.bankFk"] input',
|
||||
newPaymentAmountInput: 'vn-client-balance-create vn-input-number[field="$ctrl.receipt.amountPaid"] input',
|
||||
saveButton: 'vn-client-balance-create vn-button[label="Save"]',
|
||||
firstBalanceLine: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(8)'
|
||||
|
||||
},
|
||||
webPayment: {
|
||||
|
@ -172,15 +172,15 @@ export default {
|
|||
firstPaymentConfirmed: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon[icon="check"][aria-hidden="false"]'
|
||||
},
|
||||
itemsIndex: {
|
||||
searchIcon: `vn-item-index vn-searchbar vn-icon[icon="search"]`,
|
||||
goBackToModuleIndexButton: `vn-item-descriptor a[href="#!/item/index"]`,
|
||||
searchIcon: 'vn-item-index vn-searchbar vn-icon[icon="search"]',
|
||||
goBackToModuleIndexButton: 'vn-item-descriptor a[href="#!/item/index"]',
|
||||
createItemButton: `${components.vnFloatButton}`,
|
||||
searchResult: `vn-item-index a.vn-tr`,
|
||||
searchResultPreviewButton: `vn-item-index .buttons > [icon="desktop_windows"]`,
|
||||
searchResultCloneButton: `vn-item-index .buttons > [icon="icon-clone"]`,
|
||||
acceptClonationAlertButton: `vn-item-index [vn-id="clone"] [response="ACCEPT"]`,
|
||||
searchItemInput: `vn-searchbar vn-textfield input`,
|
||||
searchButton: `vn-searchbar vn-icon[icon="search"]`,
|
||||
searchResult: 'vn-item-index a.vn-tr',
|
||||
searchResultPreviewButton: 'vn-item-index .buttons > [icon="desktop_windows"]',
|
||||
searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]',
|
||||
acceptClonationAlertButton: 'vn-item-index [vn-id="clone"] [response="ACCEPT"]',
|
||||
searchItemInput: 'vn-searchbar vn-textfield input',
|
||||
searchButton: 'vn-searchbar vn-icon[icon="search"]',
|
||||
closeItemSummaryPreview: 'vn-item-index [vn-id="preview"] button.close',
|
||||
fieldsToShowButton: 'vn-item-index vn-table > div.ng-scope > div > vn-icon-button[icon="menu"]',
|
||||
fieldsToShowForm: 'vn-item-index > div > vn-card > div > vn-table > div.ng-scope > div > vn-dialog > div > form',
|
||||
|
@ -201,90 +201,90 @@ export default {
|
|||
},
|
||||
itemCreateView: {
|
||||
temporalName: `${components.vnTextfield}[name="provisionalName"]`,
|
||||
typeAutocomplete: `vn-autocomplete[field="$ctrl.item.typeFk"]`,
|
||||
intrastatAutocomplete: `vn-autocomplete[field="$ctrl.item.intrastatFk"]`,
|
||||
originAutocomplete: `vn-autocomplete[field="$ctrl.item.originFk"]`,
|
||||
typeAutocomplete: 'vn-autocomplete[field="$ctrl.item.typeFk"]',
|
||||
intrastatAutocomplete: 'vn-autocomplete[field="$ctrl.item.intrastatFk"]',
|
||||
originAutocomplete: 'vn-autocomplete[field="$ctrl.item.originFk"]',
|
||||
createButton: `${components.vnSubmit}`,
|
||||
cancelButton: `button[ui-sref="item.index"]`
|
||||
cancelButton: 'button[ui-sref="item.index"]'
|
||||
},
|
||||
itemDescriptor: {
|
||||
moreMenu: `vn-item-descriptor vn-icon-menu > div > vn-icon`,
|
||||
moreMenuRegularizeButton: `vn-item-descriptor vn-icon-menu > div > vn-drop-down > vn-popover ul > li:nth-child(1)`,
|
||||
regularizeQuantityInput: `vn-item-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-textfield > div > div > div.infix > input`,
|
||||
moreMenu: 'vn-item-descriptor vn-icon-menu > div > vn-icon',
|
||||
moreMenuRegularizeButton: 'vn-item-descriptor vn-drop-down > vn-popover ul > li[name="Regularize stock"]',
|
||||
regularizeQuantityInput: 'vn-item-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-textfield > div > div > div.infix > input',
|
||||
regularizeWarehouseAutocomplete: 'vn-item-descriptor vn-dialog vn-autocomplete[field="$ctrl.warehouseFk"]',
|
||||
editButton: 'vn-item-card vn-item-descriptor vn-float-button[icon="edit"]',
|
||||
regularizeSaveButton: `vn-item-descriptor > vn-dialog > div > form > div.buttons > tpl-buttons > button`,
|
||||
regularizeSaveButton: 'vn-item-descriptor > vn-dialog > div > form > div.buttons > tpl-buttons > button',
|
||||
inactiveIcon: 'vn-item-descriptor vn-icon[icon="icon-unavailable"]',
|
||||
navigateBackToIndex: 'vn-item-descriptor vn-icon[icon="chevron_left"]'
|
||||
},
|
||||
itemBasicData: {
|
||||
basicDataButton: `vn-left-menu a[ui-sref="item.card.data"]`,
|
||||
basicDataButton: 'vn-left-menu a[ui-sref="item.card.basicData"]',
|
||||
goToItemIndexButton: 'vn-item-descriptor [ui-sref="item.index"]',
|
||||
typeAutocomplete: `vn-autocomplete[field="$ctrl.item.typeFk"]`,
|
||||
intrastatAutocomplete: `vn-autocomplete[field="$ctrl.item.intrastatFk"]`,
|
||||
nameInput: `vn-textfield[label="Name"] input`,
|
||||
relevancyInput: `vn-input-number[label="Relevancy"] input`,
|
||||
originAutocomplete: `vn-autocomplete[field="$ctrl.item.originFk"]`,
|
||||
expenceAutocomplete: `vn-autocomplete[field="$ctrl.item.expenceFk"]`,
|
||||
longNameInput: `vn-textfield[field="$ctrl.item.longName"] input`,
|
||||
isActiveCheckbox: `vn-check[label='Active'] md-checkbox`,
|
||||
typeAutocomplete: 'vn-autocomplete[field="$ctrl.item.typeFk"]',
|
||||
intrastatAutocomplete: 'vn-autocomplete[field="$ctrl.item.intrastatFk"]',
|
||||
nameInput: 'vn-textfield[label="Name"] input',
|
||||
relevancyInput: 'vn-input-number[label="Relevancy"] input',
|
||||
originAutocomplete: 'vn-autocomplete[field="$ctrl.item.originFk"]',
|
||||
expenceAutocomplete: 'vn-autocomplete[field="$ctrl.item.expenceFk"]',
|
||||
longNameInput: 'vn-textfield[field="$ctrl.item.longName"] input',
|
||||
isActiveCheckbox: 'vn-check[label="Active"] md-checkbox',
|
||||
submitBasicDataButton: `${components.vnSubmit}`
|
||||
},
|
||||
itemTags: {
|
||||
goToItemIndexButton: 'vn-item-descriptor [ui-sref="item.index"]',
|
||||
tagsButton: `vn-left-menu a[ui-sref="item.card.tags"]`,
|
||||
fourthTagAutocomplete: `vn-item-tags vn-horizontal:nth-child(4) > vn-autocomplete[field="itemTag.tagFk"]`,
|
||||
fourthValueInput: `vn-item-tags vn-horizontal:nth-child(4) > vn-textfield[label="Value"] input`,
|
||||
fourthRelevancyInput: `vn-item-tags vn-horizontal:nth-child(4) > vn-textfield[label="Relevancy"] input`,
|
||||
fourthRemoveTagButton: `vn-item-tags vn-horizontal:nth-child(4) vn-icon-button[icon="delete"]`,
|
||||
fifthTagAutocomplete: `vn-item-tags vn-horizontal:nth-child(5) > vn-autocomplete[field="itemTag.tagFk"]`,
|
||||
fifthValueInput: `vn-item-tags vn-horizontal:nth-child(5) > vn-textfield[label="Value"] input`,
|
||||
fifthRelevancyInput: `vn-item-tags vn-horizontal:nth-child(5) > vn-textfield[label="Relevancy"] input`,
|
||||
sixthTagAutocomplete: `vn-item-tags vn-horizontal:nth-child(6) > vn-autocomplete[field="itemTag.tagFk"]`,
|
||||
sixthValueInput: `vn-item-tags vn-horizontal:nth-child(6) > vn-textfield[label="Value"] input`,
|
||||
sixthRelevancyInput: `vn-item-tags vn-horizontal:nth-child(6) > vn-textfield[label="Relevancy"] input`,
|
||||
seventhTagAutocomplete: `vn-item-tags vn-horizontal:nth-child(7) > vn-autocomplete[field="itemTag.tagFk"]`,
|
||||
seventhValueInput: `vn-item-tags vn-horizontal:nth-child(7) > vn-textfield[label="Value"] input`,
|
||||
seventhRelevancyInput: `vn-item-tags vn-horizontal:nth-child(7) > vn-textfield[label="Relevancy"] input`,
|
||||
addItemTagButton: `vn-item-tags vn-icon-button[icon="add_circle"]`,
|
||||
tagsButton: 'vn-left-menu a[ui-sref="item.card.tags"]',
|
||||
fourthTagAutocomplete: 'vn-item-tags vn-horizontal:nth-child(4) > vn-autocomplete[field="itemTag.tagFk"]',
|
||||
fourthValueInput: 'vn-item-tags vn-horizontal:nth-child(4) > vn-textfield[label="Value"] input',
|
||||
fourthRelevancyInput: 'vn-item-tags vn-horizontal:nth-child(4) > vn-textfield[label="Relevancy"] input',
|
||||
fourthRemoveTagButton: 'vn-item-tags vn-horizontal:nth-child(4) vn-icon-button[icon="delete"]',
|
||||
fifthTagAutocomplete: 'vn-item-tags vn-horizontal:nth-child(5) > vn-autocomplete[field="itemTag.tagFk"]',
|
||||
fifthValueInput: 'vn-item-tags vn-horizontal:nth-child(5) > vn-textfield[label="Value"] input',
|
||||
fifthRelevancyInput: 'vn-item-tags vn-horizontal:nth-child(5) > vn-textfield[label="Relevancy"] input',
|
||||
sixthTagAutocomplete: 'vn-item-tags vn-horizontal:nth-child(6) > vn-autocomplete[field="itemTag.tagFk"]',
|
||||
sixthValueInput: 'vn-item-tags vn-horizontal:nth-child(6) > vn-textfield[label="Value"] input',
|
||||
sixthRelevancyInput: 'vn-item-tags vn-horizontal:nth-child(6) > vn-textfield[label="Relevancy"] input',
|
||||
seventhTagAutocomplete: 'vn-item-tags vn-horizontal:nth-child(7) > vn-autocomplete[field="itemTag.tagFk"]',
|
||||
seventhValueInput: 'vn-item-tags vn-horizontal:nth-child(7) > vn-textfield[label="Value"] input',
|
||||
seventhRelevancyInput: 'vn-item-tags vn-horizontal:nth-child(7) > vn-textfield[label="Relevancy"] input',
|
||||
addItemTagButton: 'vn-item-tags vn-icon-button[icon="add_circle"]',
|
||||
submitItemTagsButton: `vn-item-tags ${components.vnSubmit}`
|
||||
},
|
||||
itemTax: {
|
||||
firstClassAutocomplete: `vn-item-tax vn-horizontal:nth-child(1) > vn-autocomplete[field="tax.taxClassFk"]`,
|
||||
secondClassAutocomplete: `vn-item-tax vn-horizontal:nth-child(2) > vn-autocomplete[field="tax.taxClassFk"]`,
|
||||
thirdClassAutocomplete: `vn-item-tax vn-horizontal:nth-child(3) > vn-autocomplete[field="tax.taxClassFk"]`,
|
||||
firstClassAutocomplete: 'vn-item-tax vn-horizontal:nth-child(1) > vn-autocomplete[field="tax.taxClassFk"]',
|
||||
secondClassAutocomplete: 'vn-item-tax vn-horizontal:nth-child(2) > vn-autocomplete[field="tax.taxClassFk"]',
|
||||
thirdClassAutocomplete: 'vn-item-tax vn-horizontal:nth-child(3) > vn-autocomplete[field="tax.taxClassFk"]',
|
||||
submitTaxButton: `vn-item-tax ${components.vnSubmit}`
|
||||
},
|
||||
itemBarcodes: {
|
||||
addBarcodeButton: `vn-item-barcode vn-icon[icon="add_circle"]`,
|
||||
addBarcodeButton: 'vn-item-barcode vn-icon[icon="add_circle"]',
|
||||
thirdCodeInput: `vn-item-barcode vn-horizontal:nth-child(3) > ${components.vnTextfield}`,
|
||||
submitBarcodesButton: `vn-item-barcode ${components.vnSubmit}`,
|
||||
firstCodeRemoveButton: `vn-item-barcode vn-horizontal vn-none vn-icon[icon="delete"]`
|
||||
firstCodeRemoveButton: 'vn-item-barcode vn-horizontal vn-none vn-icon[icon="delete"]'
|
||||
},
|
||||
itemNiches: {
|
||||
addNicheButton: `vn-item-niche vn-icon[icon="add_circle"]`,
|
||||
firstWarehouseAutocomplete: `vn-item-niche vn-autocomplete[field="niche.warehouseFk"]`,
|
||||
firstCodeInput: `vn-item-niche vn-horizontal:nth-child(1) > vn-textfield[label="Code"] input`,
|
||||
secondWarehouseAutocomplete: `vn-item-niche vn-horizontal:nth-child(2) > vn-autocomplete[field="niche.warehouseFk"]`,
|
||||
secondCodeInput: `vn-item-niche vn-horizontal:nth-child(2) > vn-textfield[label="Code"] input`,
|
||||
secondNicheRemoveButton: `vn-item-niche vn-horizontal:nth-child(2) > vn-none > vn-icon-button[icon="delete"]`,
|
||||
thirdWarehouseAutocomplete: `vn-item-niche vn-horizontal:nth-child(3) > vn-autocomplete[field="niche.warehouseFk"]`,
|
||||
thirdCodeInput: `vn-item-niche vn-horizontal:nth-child(3) > vn-textfield[label="Code"] input`,
|
||||
addNicheButton: 'vn-item-niche vn-icon[icon="add_circle"]',
|
||||
firstWarehouseAutocomplete: 'vn-item-niche vn-autocomplete[field="niche.warehouseFk"]',
|
||||
firstCodeInput: 'vn-item-niche vn-horizontal:nth-child(1) > vn-textfield[label="Code"] input',
|
||||
secondWarehouseAutocomplete: 'vn-item-niche vn-horizontal:nth-child(2) > vn-autocomplete[field="niche.warehouseFk"]',
|
||||
secondCodeInput: 'vn-item-niche vn-horizontal:nth-child(2) > vn-textfield[label="Code"] input',
|
||||
secondNicheRemoveButton: 'vn-item-niche vn-horizontal:nth-child(2) > vn-none > vn-icon-button[icon="delete"]',
|
||||
thirdWarehouseAutocomplete: 'vn-item-niche vn-horizontal:nth-child(3) > vn-autocomplete[field="niche.warehouseFk"]',
|
||||
thirdCodeInput: 'vn-item-niche vn-horizontal:nth-child(3) > vn-textfield[label="Code"] input',
|
||||
submitNichesButton: `vn-item-niche ${components.vnSubmit}`
|
||||
},
|
||||
itemBotanical: {
|
||||
botanicalInput: `vn-item-botanical vn-horizontal:nth-child(1) > ${components.vnTextfield}`,
|
||||
genusAutocomplete: `vn-item-botanical vn-autocomplete[field="$ctrl.botanical.genusFk"]`,
|
||||
speciesAutocomplete: `vn-item-botanical vn-autocomplete[field="$ctrl.botanical.specieFk"]`,
|
||||
genusAutocomplete: 'vn-item-botanical vn-autocomplete[field="$ctrl.botanical.genusFk"]',
|
||||
speciesAutocomplete: 'vn-item-botanical vn-autocomplete[field="$ctrl.botanical.specieFk"]',
|
||||
submitBotanicalButton: `vn-item-botanical ${components.vnSubmit}`
|
||||
},
|
||||
itemSummary: {
|
||||
basicData: `vn-item-summary [name="basicData"]`,
|
||||
vat: `vn-item-summary [name="tax"]`,
|
||||
tags: `vn-item-summary [name="tags"]`,
|
||||
niche: `vn-item-summary [name="niche"]`,
|
||||
botanical: `vn-item-summary [name="botanical"]`,
|
||||
barcode: `vn-item-summary [name="barcode"]`
|
||||
basicData: 'vn-item-summary [name="basicData"]',
|
||||
vat: 'vn-item-summary [name="tax"]',
|
||||
tags: 'vn-item-summary [name="tags"]',
|
||||
niche: 'vn-item-summary [name="niche"]',
|
||||
botanical: 'vn-item-summary [name="botanical"]',
|
||||
barcode: 'vn-item-summary [name="barcode"]'
|
||||
},
|
||||
itemDiary: {
|
||||
thirdTicketId: 'vn-item-diary vn-tbody > vn-tr:nth-child(3) > vn-td:nth-child(2) > span',
|
||||
|
@ -301,20 +301,20 @@ export default {
|
|||
firstSaleItemId: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
|
||||
popoverDiaryButton: 'vn-ticket-summary vn-item-descriptor-popover vn-item-descriptor vn-icon[icon="icon-transaction"]',
|
||||
firstSaleQuantity: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3)',
|
||||
firstSaleDiscount: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6)'
|
||||
firstSaleDiscount: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6)',
|
||||
invoiceOutRef: 'vn-ticket-summary > vn-card > div > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(6) > section > span'
|
||||
},
|
||||
ticketsIndex: {
|
||||
newTicketButton: 'vn-ticket-index > a',
|
||||
searchResult: `vn-ticket-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr`,
|
||||
searchResultDate: `vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(4)`,
|
||||
searchResultAddress: `vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(6)`,
|
||||
searchResult: 'vn-ticket-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
|
||||
searchResultDate: 'vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(5)',
|
||||
searchTicketInput: `vn-ticket-index ${components.vnTextfield}`,
|
||||
searchButton: `vn-ticket-index vn-searchbar vn-icon[icon="search"]`,
|
||||
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`,
|
||||
sixthWeeklyTicketTurn: `vn-ticket-weekly > form > div > vn-card > div > vn-table > div > vn-tbody > vn-tr:nth-child(6) > vn-td:nth-child(3) > vn-autocomplete > div > div > input`,
|
||||
weeklyTicket: `vn-ticket-weekly vn-table > div > vn-tbody > vn-tr`,
|
||||
sixthWeeklyTicketDeleteIcon: `vn-ticket-weekly > form vn-tbody > vn-tr:nth-child(6) > vn-td:nth-child(6) > vn-icon-button[icon="delete"]`
|
||||
searchButton: 'vn-ticket-index vn-searchbar vn-icon[icon="search"]',
|
||||
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)',
|
||||
sixthWeeklyTicketTurn: 'vn-ticket-weekly > form > div > vn-card > div > vn-table > div > vn-tbody > vn-tr:nth-child(6) > vn-td:nth-child(3) > vn-autocomplete > div > div > input',
|
||||
weeklyTicket: 'vn-ticket-weekly vn-table > div > vn-tbody > vn-tr',
|
||||
sixthWeeklyTicketDeleteIcon: 'vn-ticket-weekly > form vn-tbody > vn-tr:nth-child(6) > vn-td:nth-child(6) > vn-icon-button[icon="delete"]'
|
||||
},
|
||||
createTicketView: {
|
||||
clientAutocomplete: 'vn-ticket-create vn-autocomplete[field="$ctrl.clientFk"]',
|
||||
|
@ -325,57 +325,59 @@ export default {
|
|||
createButton: `${components.vnSubmit}`
|
||||
},
|
||||
ticketDescriptor: {
|
||||
moreMenu: `vn-ticket-descriptor vn-icon-menu > div > vn-icon`,
|
||||
moreMenuAddStowaway: `vn-ticket-descriptor vn-icon-menu > div > vn-drop-down > vn-popover ul > li:nth-child(1)`,
|
||||
moreMenuDeleteStowawayButton: 'vn-ticket-descriptor vn-icon-menu > div > vn-drop-down > vn-popover ul > li:nth-child(5)',
|
||||
moreMenuAddToTurn: `vn-ticket-descriptor vn-icon-menu > div > vn-drop-down > vn-popover ul > li:nth-child(2)`,
|
||||
moreMenuDeleteTicket: `vn-ticket-descriptor vn-icon-menu > div > vn-drop-down > vn-popover ul > li:nth-child(3)`,
|
||||
moreMenu: 'vn-ticket-descriptor vn-icon-menu > div > vn-icon',
|
||||
moreMenuAddStowaway: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Add stowaway"]',
|
||||
moreMenuDeleteStowawayButton: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Remove stowaway"]',
|
||||
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"]',
|
||||
moreMenuMakeInvoice: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Make invoice"]',
|
||||
addStowawayDialogSecondTicket: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog vn-table vn-tr:nth-child(2)',
|
||||
shipSelectButton: 'vn-ticket-descriptor > div > div.body > div.quicklinks > vn-button-menu[icon="icon-stowaway"]',
|
||||
shipButton: 'vn-ticket-descriptor > div > div.body > div.quicklinks vn-icon[icon="icon-stowaway"]',
|
||||
shipMenuSecondTicket: 'vn-ticket-descriptor div.quicklinks vn-drop-down li:nth-child(2)',
|
||||
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)`,
|
||||
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)',
|
||||
closeStowawayDialog: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog > div > button[class="close"]',
|
||||
acceptDeleteButton: 'vn-ticket-descriptor 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"]'
|
||||
},
|
||||
ticketNotes: {
|
||||
firstNoteRemoveButton: `vn-icon[icon="delete"]`,
|
||||
addNoteButton: `vn-icon[icon="add_circle"]`,
|
||||
firstNoteTypeAutocomplete: `vn-autocomplete[field="observation.observationTypeFk"]`,
|
||||
firstDescriptionInput: `vn-textfield[label="Description"] input`,
|
||||
firstNoteRemoveButton: 'vn-icon[icon="delete"]',
|
||||
addNoteButton: 'vn-icon[icon="add_circle"]',
|
||||
firstNoteTypeAutocomplete: 'vn-autocomplete[field="observation.observationTypeFk"]',
|
||||
firstDescriptionInput: 'vn-textfield[label="Description"] input',
|
||||
submitNotesButton: `${components.vnSubmit}`
|
||||
},
|
||||
ticketExpedition: {
|
||||
expeditionButton: `vn-left-menu a[ui-sref="ticket.card.expedition"]`,
|
||||
secondExpeditionRemoveButton: `vn-ticket-expedition vn-table div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(1) > vn-icon-button[icon="delete"]`,
|
||||
acceptDeleteRowButton: `vn-ticket-expedition > vn-confirm[vn-id="delete-expedition"] button[response=ACCEPT]`,
|
||||
expeditionRow: `vn-ticket-expedition vn-table vn-tbody > vn-tr`
|
||||
expeditionButton: 'vn-left-menu a[ui-sref="ticket.card.expedition"]',
|
||||
secondExpeditionRemoveButton: 'vn-ticket-expedition vn-table div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(1) > vn-icon-button[icon="delete"]',
|
||||
acceptDeleteRowButton: 'vn-ticket-expedition > vn-confirm[vn-id="delete-expedition"] button[response=ACCEPT]',
|
||||
expeditionRow: 'vn-ticket-expedition vn-table vn-tbody > vn-tr'
|
||||
},
|
||||
ticketPackages: {
|
||||
packagesButton: `vn-left-menu a[ui-sref="ticket.card.package.index"]`,
|
||||
firstPackageAutocomplete: `vn-autocomplete[label="Package"]`,
|
||||
firstQuantityInput: `vn-input-number[label="Quantity"] input`,
|
||||
firstRemovePackageButton: `vn-icon-button[vn-tooltip="Remove package"]`,
|
||||
addPackageButton: `vn-icon-button[vn-tooltip="Add package"]`,
|
||||
clearPackageAutocompleteButton: `vn-autocomplete[label="Package"] > div > div > div > vn-icon > i`,
|
||||
packagesButton: 'vn-left-menu a[ui-sref="ticket.card.package"]',
|
||||
firstPackageAutocomplete: 'vn-autocomplete[label="Package"]',
|
||||
firstQuantityInput: 'vn-input-number[label="Quantity"] input',
|
||||
firstRemovePackageButton: 'vn-icon-button[vn-tooltip="Remove package"]',
|
||||
addPackageButton: 'vn-icon-button[vn-tooltip="Add package"]',
|
||||
clearPackageAutocompleteButton: 'vn-autocomplete[label="Package"] > div > div > div > vn-icon > i',
|
||||
savePackagesButton: `${components.vnSubmit}`
|
||||
},
|
||||
ticketSales: {
|
||||
saleButton: `vn-left-menu a[ui-sref="ticket.card.sale"]`,
|
||||
saleLine: `vn-table div > vn-tbody > vn-tr`,
|
||||
saleButton: 'vn-left-menu a[ui-sref="ticket.card.sale"]',
|
||||
saleLine: 'vn-table div > vn-tbody > vn-tr',
|
||||
saleDescriptorPopover: 'vn-ticket-sale vn-item-descriptor-popover > vn-popover',
|
||||
saleDescriptorPopoverSummaryButton: 'vn-item-descriptor-popover a[href="#!/item/1/summary"]',
|
||||
descriptorItemDiaryButton: `vn-item-descriptor .quicklinks.ng-scope > vn-horizontal > a > vn-icon > i`,
|
||||
descriptorItemDiaryButton: 'vn-item-descriptor .quicklinks.ng-scope > vn-horizontal > a > vn-icon > i',
|
||||
newItemButton: 'vn-float-button[icon="add"]',
|
||||
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)',
|
||||
firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img',
|
||||
firstSaleZoomedImage: 'body > div > div > img',
|
||||
firstSaleQuantity: `vn-textfield[model="sale.quantity"]:nth-child(1) input`,
|
||||
firstSaleQuantityCell: `vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable`,
|
||||
firstSaleQuantityClearInput: `vn-textfield[model="sale.quantity"] div.suffix > i`,
|
||||
firstSaleQuantity: 'vn-textfield[model="sale.quantity"]:nth-child(1) input',
|
||||
firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable',
|
||||
firstSaleQuantityClearInput: 'vn-textfield[model="sale.quantity"] div.suffix > i',
|
||||
firstSaleID: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(4) > span',
|
||||
firstSalePrice: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) > vn-td:nth-child(7) > span',
|
||||
firstSalePriceInput: 'vn-ticket-sale:nth-child(1) vn-popover.edit.dialog-summary.ng-isolate-scope.vn-popover.shown vn-textfield input',
|
||||
|
@ -383,52 +385,45 @@ export default {
|
|||
firstSaleDiscountInput: 'vn-ticket-sale:nth-child(1) vn-ticket-sale-edit-discount vn-textfield input',
|
||||
firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(9)',
|
||||
firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td:nth-child(2) > vn-icon:nth-child(3)',
|
||||
firstSaleColour: `vn-ticket-sale vn-tr:nth-child(1) vn-td:nth-child(6) section:nth-child(1)`,
|
||||
firstSaleLength: `vn-ticket-sale vn-tr:nth-child(1) vn-td:nth-child(6) section:nth-child(3)`,
|
||||
firstSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(1) vn-check[field="sale.checked"] md-checkbox`,
|
||||
firstSaleColour: 'vn-ticket-sale vn-tr:nth-child(1) vn-td:nth-child(6) section:nth-child(1)',
|
||||
firstSaleLength: 'vn-ticket-sale vn-tr:nth-child(1) vn-td:nth-child(6) section:nth-child(3)',
|
||||
firstSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(1) vn-check[field="sale.checked"] md-checkbox',
|
||||
secondSaleClaimIcon: 'vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(2) > a > vn-icon',
|
||||
secondSaleColour: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(6) section:nth-child(5)`,
|
||||
secondSalePrice: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(7) > span`,
|
||||
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)`,
|
||||
secondSaleText: `vn-table div > vn-tbody > vn-tr:nth-child(2)`,
|
||||
secondSaleColour: 'vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(6) section:nth-child(5)',
|
||||
secondSalePrice: 'vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(7) > span',
|
||||
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)',
|
||||
secondSaleText: 'vn-table div > vn-tbody > vn-tr:nth-child(2)',
|
||||
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`,
|
||||
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`,
|
||||
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',
|
||||
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"]',
|
||||
transferSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="call_split"]',
|
||||
moveToTicketInput: 'vn-ticket-sale vn-popover.transfer vn-textfield[model="$ctrl.moveToTicketFk"] input',
|
||||
moveToTicketInputClearButton: 'vn-popover.shown i[title="Clear"]',
|
||||
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"]',
|
||||
acceptDeleteLineButton: `vn-ticket-sale > vn-confirm[vn-id="delete-lines"] button[response=ACCEPT]`,
|
||||
acceptDeleteTicketButton: `vn-ticket-sale > vn-confirm[vn-id="deleteConfirmation"] button[response=ACCEPT]`,
|
||||
stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="State"] button',
|
||||
stateMenuOptions: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(1)',
|
||||
moreMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="More"] button',
|
||||
moreMenuReseveOption: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(2)',
|
||||
moreMenuUnmarkResevedOption: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(3)',
|
||||
moreMenuUpdateDiscount: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(4)',
|
||||
moreMenuUpdateDiscountInput: 'vn-ticket-sale vn-dialog.shown vn-ticket-sale-edit-discount input',
|
||||
moreMenuCreateClaim: 'vn-ticket-sale vn-drop-down > vn-popover ul > li:nth-child(1)'
|
||||
acceptDeleteLineButton: 'vn-ticket-sale > vn-confirm[vn-id="delete-lines"] button[response=ACCEPT]',
|
||||
acceptDeleteTicketButton: 'vn-ticket-sale > vn-confirm[vn-id="deleteConfirmation"] button[response=ACCEPT]',
|
||||
stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="State"]'
|
||||
},
|
||||
ticketTracking: {
|
||||
trackingButton: `vn-left-menu a[ui-sref="ticket.card.tracking.index"]`,
|
||||
trackingButton: 'vn-left-menu a[ui-sref="ticket.card.tracking.index"]',
|
||||
createStateButton: `${components.vnFloatButton}`,
|
||||
stateAutocomplete: 'vn-ticket-tracking-edit vn-autocomplete[field="$ctrl.stateFk"]',
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
cancelButton: `vn-ticket-tracking-edit vn-button[ui-sref="ticket.card.tracking.index"]`
|
||||
cancelButton: 'vn-ticket-tracking-edit vn-button[ui-sref="ticket.card.tracking.index"]'
|
||||
},
|
||||
ticketBasicData: {
|
||||
basicDataButton: `vn-left-menu a[ui-sref="ticket.card.data.stepOne"]`,
|
||||
clientAutocomplete: `vn-autocomplete[field="$ctrl.clientFk"]`,
|
||||
addressAutocomplete: `vn-autocomplete[field="$ctrl.ticket.addressFk"]`,
|
||||
agencyAutocomplete: `vn-autocomplete[field="$ctrl.ticket.agencyModeFk"]`,
|
||||
nextStepButton: `vn-step-control > section > section.buttons > section:nth-child(2) > vn-button`,
|
||||
finalizeButton: `vn-step-control > section > section.buttons > section:nth-child(2) > vn-submit`,
|
||||
stepTwoTotalPriceDif: `vn-ticket-data-step-two > form > vn-card > div > vn-horizontal > table > tfoot > tr > td:nth-child(4)`,
|
||||
chargesReasonAutocomplete: `vn-autocomplete[field="$ctrl.ticket.option"]`,
|
||||
basicDataButton: 'vn-left-menu a[ui-sref="ticket.card.basicData.stepOne"]',
|
||||
clientAutocomplete: 'vn-autocomplete[field="$ctrl.clientFk"]',
|
||||
addressAutocomplete: 'vn-autocomplete[field="$ctrl.ticket.addressFk"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[field="$ctrl.ticket.agencyModeFk"]',
|
||||
nextStepButton: 'vn-step-control > section > section.buttons > section:nth-child(2) > vn-button',
|
||||
finalizeButton: 'vn-step-control > section > section.buttons > section:nth-child(2) > vn-submit',
|
||||
stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > form > vn-card > div > vn-horizontal > table > tfoot > tr > td:nth-child(4)',
|
||||
chargesReasonAutocomplete: 'vn-autocomplete[field="$ctrl.ticket.option"]',
|
||||
},
|
||||
ticketComponents: {
|
||||
base: 'vn-ticket-components tfoot > tr:nth-child(1) > td',
|
||||
|
@ -436,19 +431,19 @@ export default {
|
|||
total: 'vn-ticket-components tfoot > tr:nth-child(3) > td'
|
||||
},
|
||||
ticketRequests: {
|
||||
addRequestButton: `vn-ticket-request-index > a > vn-float-button > button`,
|
||||
addRequestButton: 'vn-ticket-request-index > a > vn-float-button > button',
|
||||
request: 'vn-ticket-request-index > form > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr',
|
||||
descriptionInput: `vn-ticket-request-create > form > div > vn-card > div > vn-horizontal:nth-child(1) > vn-textfield > div > div > div.infix > input`,
|
||||
atenderAutocomplete: `vn-ticket-request-create vn-autocomplete[field="$ctrl.ticketRequest.atenderFk"]`,
|
||||
quantityInput: `vn-ticket-request-create > form > div > vn-card > div > vn-horizontal:nth-child(2) > vn-input-number:nth-child(1) > div > div > div.infix > input`,
|
||||
priceInput: `vn-ticket-request-create > form > div > vn-card > div > vn-horizontal:nth-child(2) > vn-input-number:nth-child(2) > div > div > div.infix > input`,
|
||||
firstRemoveRequestButton: `vn-ticket-request-index vn-icon[icon="delete"]:nth-child(1)`,
|
||||
saveButton: `vn-ticket-request-create > form > div > vn-button-bar > vn-submit[label="Create"] input`,
|
||||
descriptionInput: 'vn-ticket-request-create > form > div > vn-card > div > vn-horizontal:nth-child(1) > vn-textfield > div > div > div.infix > input',
|
||||
atenderAutocomplete: 'vn-ticket-request-create vn-autocomplete[field="$ctrl.ticketRequest.atenderFk"]',
|
||||
quantityInput: 'vn-ticket-request-create > form > div > vn-card > div > vn-horizontal:nth-child(2) > vn-input-number:nth-child(1) > div > div > div.infix > input',
|
||||
priceInput: 'vn-ticket-request-create > form > div > vn-card > div > vn-horizontal:nth-child(2) > vn-input-number:nth-child(2) > div > div > div.infix > input',
|
||||
firstRemoveRequestButton: 'vn-ticket-request-index vn-icon[icon="delete"]:nth-child(1)',
|
||||
saveButton: 'vn-ticket-request-create > form > div > vn-button-bar > vn-submit[label="Create"] input',
|
||||
firstDescription: 'vn-ticket-request-index > form > vn-card > div > vn-horizontal > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(2)',
|
||||
|
||||
},
|
||||
ticketLog: {
|
||||
logButton: `vn-left-menu a[ui-sref="ticket.card.log"]`,
|
||||
logButton: 'vn-left-menu a[ui-sref="ticket.card.log"]',
|
||||
changedBy: 'vn-ticket-log > vn-log > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(2) > span',
|
||||
actionTaken: 'vn-ticket-log > vn-log > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > div > div:nth-child(3) > span.value.ng-scope.ng-binding',
|
||||
id: 'vn-ticket-log > vn-log > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr > vn-td.before > vn-one:nth-child(1) > div > span.value.ng-scope.ng-binding'
|
||||
|
@ -464,25 +459,25 @@ export default {
|
|||
saveServiceButton: `${components.vnSubmit}`
|
||||
},
|
||||
createStateView: {
|
||||
stateAutocomplete: `vn-autocomplete[field="$ctrl.stateFk"]`,
|
||||
workerAutocomplete: `vn-autocomplete[field="$ctrl.workerFk"]`,
|
||||
clearStateInputButton: `vn-autocomplete[field="$ctrl.stateFk"] > div > div > div > vn-icon > i`,
|
||||
stateAutocomplete: 'vn-autocomplete[field="$ctrl.stateFk"]',
|
||||
workerAutocomplete: 'vn-autocomplete[field="$ctrl.workerFk"]',
|
||||
clearStateInputButton: 'vn-autocomplete[field="$ctrl.stateFk"] > div > div > div > vn-icon > i',
|
||||
saveStateButton: `${components.vnSubmit}`
|
||||
},
|
||||
claimsIndex: {
|
||||
searchClaimInput: `vn-claim-index ${components.vnTextfield}`,
|
||||
searchResult: `vn-claim-index vn-card > div > vn-table > div > vn-tbody > a`,
|
||||
searchButton: `vn-claim-index vn-searchbar vn-icon[icon="search"]`
|
||||
searchResult: 'vn-claim-index vn-card > div > vn-table > div > vn-tbody > a',
|
||||
searchButton: 'vn-claim-index vn-searchbar vn-icon[icon="search"]'
|
||||
},
|
||||
claimBasicData: {
|
||||
claimStateAutocomplete: 'vn-claim-basic-data vn-autocomplete[field="$ctrl.claim.claimStateFk"]',
|
||||
isPaidWithManaCheckbox: 'vn-check[field="$ctrl.claim.isChargedToMana"] md-checkbox',
|
||||
responsabilityInputRange: `vn-input-range`,
|
||||
observationInput: `vn-textarea[label="Observation"] textarea`,
|
||||
responsabilityInputRange: 'vn-input-range',
|
||||
observationInput: 'vn-textarea[label="Observation"] textarea',
|
||||
saveButton: `${components.vnSubmit}`
|
||||
},
|
||||
claimDetail: {
|
||||
addItemButton: `vn-claim-detail a vn-float-button`,
|
||||
addItemButton: 'vn-claim-detail a vn-float-button',
|
||||
firstClaimableSaleFromTicket: 'vn-claim-detail > vn-dialog vn-tbody > vn-tr',
|
||||
claimDetailLine: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr',
|
||||
secondItemQuantityInput: 'vn-claim-detail vn-tr:nth-child(2) vn-input-number[model="saleClaimed.quantity"] input',
|
||||
|
@ -516,29 +511,29 @@ export default {
|
|||
|
||||
},
|
||||
ordersIndex: {
|
||||
searchResult: `vn-order-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr`,
|
||||
searchResultDate: `vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(4)`,
|
||||
searchResultAddress: `vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(6)`,
|
||||
searchResult: 'vn-order-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
|
||||
searchResultDate: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(4)',
|
||||
searchResultAddress: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(6)',
|
||||
searchOrderInput: `vn-order-index ${components.vnTextfield}`,
|
||||
searchButton: `vn-order-index vn-searchbar vn-icon[icon="search"]`,
|
||||
searchButton: 'vn-order-index vn-searchbar vn-icon[icon="search"]',
|
||||
createOrderButton: `${components.vnFloatButton}`,
|
||||
},
|
||||
createOrderView: {
|
||||
clientAutocomplete: `vn-autocomplete[label="Client"]`,
|
||||
addressAutocomplete: `vn-autocomplete[label="Address"]`,
|
||||
agencyAutocomplete: `vn-autocomplete[label="Agency"]`,
|
||||
landedDatePicker: `vn-date-picker[label="Landed"]`,
|
||||
clientAutocomplete: 'vn-autocomplete[label="Client"]',
|
||||
addressAutocomplete: 'vn-autocomplete[label="Address"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[label="Agency"]',
|
||||
landedDatePicker: 'vn-date-picker[label="Landed"]',
|
||||
createButton: `${components.vnSubmit}`,
|
||||
cancelButton: `vn-button[href="#!/client/index"]`
|
||||
cancelButton: 'vn-button[href="#!/client/index"]'
|
||||
},
|
||||
orderCatalog: {
|
||||
orderByAutocomplete: `vn-autocomplete[label="Order by"]`,
|
||||
orderByAutocomplete: 'vn-autocomplete[label="Order by"]',
|
||||
},
|
||||
orderBasicData: {
|
||||
clientAutocomplete: `vn-autocomplete[label="Client"]`,
|
||||
addressAutocomplete: `vn-autocomplete[label="Address"]`,
|
||||
agencyAutocomplete: `vn-autocomplete[label="Agency"]`,
|
||||
observationInput: `vn-textarea[label="Observation"] textarea`,
|
||||
clientAutocomplete: 'vn-autocomplete[label="Client"]',
|
||||
addressAutocomplete: 'vn-autocomplete[label="Address"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[label="Agency"]',
|
||||
observationInput: 'vn-textarea[label="Observation"] textarea',
|
||||
saveButton: `${components.vnSubmit}`
|
||||
},
|
||||
orderLine: {
|
||||
|
|
|
@ -41,7 +41,7 @@ describe('Client create path', () => {
|
|||
.write(selectors.createClientView.taxNumber, '74451390E')
|
||||
.write(selectors.createClientView.userName, 'CaptainMarvel')
|
||||
.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es')
|
||||
.autocompleteSearch(selectors.createClientView.salesPersonAutocomplete, 'Accessory')
|
||||
.autocompleteSearch(selectors.createClientView.salesPersonAutocomplete, 'replenisher')
|
||||
.waitToClick(selectors.createClientView.createButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ describe('Client Edit basicData path', () => {
|
|||
.write(selectors.clientBasicData.mobileInput, '987654321')
|
||||
.clearInput(selectors.clientBasicData.emailInput)
|
||||
.write(selectors.clientBasicData.emailInput, 'Storm@verdnatura.es')
|
||||
.autocompleteSearch(selectors.clientBasicData.salesPersonAutocomplete, 'AccessoryNick')
|
||||
.autocompleteSearch(selectors.clientBasicData.salesPersonAutocomplete, 'replenisherNick')
|
||||
.autocompleteSearch(selectors.clientBasicData.channelAutocomplete, 'Metropolis newspaper')
|
||||
.waitToClick(selectors.clientBasicData.saveButton)
|
||||
.waitForLastSnackbar();
|
||||
|
@ -162,7 +162,7 @@ describe('Client Edit basicData path', () => {
|
|||
const result = await nightmare
|
||||
.waitToGetProperty(`${selectors.clientBasicData.salesPersonAutocomplete} input`, 'value');
|
||||
|
||||
expect(result).toEqual('accessoryNick');
|
||||
expect(result).toEqual('replenisherNick');
|
||||
});
|
||||
|
||||
it('should now confirm the channel have been selected', async() => {
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import createNightmare from '../../helpers/nightmare';
|
||||
|
||||
describe('Client Edit billing data path', () => {
|
||||
const nightmare = createNightmare();
|
||||
|
||||
beforeAll(() => {
|
||||
nightmare
|
||||
.loginAndModule('administrative', 'client')
|
||||
.accessToSearchResult('Bruce Banner')
|
||||
.accessToSection('client.card.billingData');
|
||||
});
|
||||
|
||||
it(`should attempt to edit the billing data without an IBAN but fail`, async() => {
|
||||
const snackbarMessage = await nightmare
|
||||
.autocompleteSearch(selectors.clientBillingData.payMethodAutocomplete, 'PayMethod with IBAN')
|
||||
.autocompleteSearch(selectors.clientBillingData.swiftBicAutocomplete, 'BBKKESMMMMM')
|
||||
.clearInput(selectors.clientBillingData.dueDayInput)
|
||||
.write(selectors.clientBillingData.dueDayInput, '60')
|
||||
.waitForTextInInput(selectors.clientBillingData.dueDayInput, '60')
|
||||
.waitToClick(selectors.clientBillingData.receivedCoreLCRCheckbox)
|
||||
.waitToClick(selectors.clientBillingData.receivedCoreVNLCheckbox)
|
||||
.waitToClick(selectors.clientBillingData.receivedB2BVNLCheckbox)
|
||||
.waitToClick(selectors.clientBillingData.saveButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(snackbarMessage).toEqual('That payment method requires an IBAN');
|
||||
});
|
||||
|
||||
it(`should add the IBAN but fail as it requires a BIC code`, async() => {
|
||||
const snackbarMessage = await nightmare
|
||||
.waitToClick(selectors.clientBillingData.clearswiftBicButton)
|
||||
.clearInput(selectors.clientBillingData.IBANInput)
|
||||
.write(selectors.clientBillingData.IBANInput, 'FR9121000418450200051332')
|
||||
.waitForTextInInput(selectors.clientBillingData.IBANInput, 'FR9121000418450200051332')
|
||||
.wait(1000)
|
||||
.waitToClick(selectors.clientBillingData.saveButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(snackbarMessage).toEqual('That payment method requires a BIC');
|
||||
});
|
||||
|
||||
it(`should create a new BIC code`, async() => {
|
||||
const newcode = await nightmare
|
||||
.waitToClick(selectors.clientBillingData.newBankEntityButton)
|
||||
.write(selectors.clientBillingData.newBankEntityName, 'Gotham City Bank')
|
||||
.write(selectors.clientBillingData.newBankEntityCode, 9999)
|
||||
.write(selectors.clientBillingData.newBankEntityBIC, 'GTHMCT')
|
||||
.waitToClick(selectors.clientBillingData.acceptBankEntityButton)
|
||||
.waitToGetProperty(`${selectors.clientBillingData.swiftBicAutocomplete} input`, 'value');
|
||||
|
||||
expect(newcode).toEqual('GTHMCT Gotham City Bank');
|
||||
});
|
||||
|
||||
it(`should confirm the IBAN pay method is sucessfully saved`, async() => {
|
||||
const payMethod = await nightmare
|
||||
.waitToGetProperty(`${selectors.clientBillingData.payMethodAutocomplete} input`, 'value');
|
||||
|
||||
expect(payMethod).toEqual('PayMethod with IBAN');
|
||||
});
|
||||
|
||||
it(`should clear the BIC code field, update the IBAN to see how he BIC code autocompletes`, async() => {
|
||||
const AutomaticCode = await nightmare
|
||||
.clearInput(selectors.clientBillingData.IBANInput)
|
||||
.waitToClick(selectors.clientBillingData.clearswiftBicButton)
|
||||
.write(selectors.clientBillingData.IBANInput, 'ES9121000418450200051332')
|
||||
.waitToGetProperty(`${selectors.clientBillingData.swiftBicAutocomplete} input`, 'value');
|
||||
|
||||
expect(AutomaticCode).toEqual('CAIXESBB Caixa Bank');
|
||||
});
|
||||
|
||||
it(`should save the form with all its new data`, async() => {
|
||||
const snackbarMessages = await nightmare
|
||||
.waitToClick(selectors.clientBillingData.saveButton)
|
||||
.waitForSnackbar();
|
||||
|
||||
expect(snackbarMessages).toEqual(jasmine.arrayContaining(['Data saved!']));
|
||||
});
|
||||
|
||||
it('should confirm the due day have been edited', async() => {
|
||||
const dueDate = await nightmare
|
||||
.waitToGetProperty(selectors.clientBillingData.dueDayInput, 'value');
|
||||
|
||||
expect(dueDate).toEqual('60');
|
||||
});
|
||||
|
||||
it('should confirm the IBAN was saved', async() => {
|
||||
const IBAN = await nightmare
|
||||
.waitToGetProperty(selectors.clientBillingData.IBANInput, 'value');
|
||||
|
||||
expect(IBAN).toEqual('ES9121000418450200051332');
|
||||
});
|
||||
|
||||
it('should confirm the swift / BIC code was saved', async() => {
|
||||
const code = await nightmare
|
||||
.waitToGetProperty(`${selectors.clientBillingData.swiftBicAutocomplete} input`, 'value');
|
||||
|
||||
expect(code).toEqual('CAIXESBB Caixa Bank');
|
||||
});
|
||||
|
||||
it('should confirm Received LCR checkbox is checked', async() => {
|
||||
const result = await nightmare
|
||||
.checkboxState(selectors.clientBillingData.receivedCoreLCRCheckbox);
|
||||
|
||||
expect(result).toBe('checked');
|
||||
});
|
||||
|
||||
it('should confirm Received core VNL checkbox is unchecked', async() => {
|
||||
const result = await nightmare
|
||||
.checkboxState(selectors.clientBillingData.receivedCoreVNLCheckbox);
|
||||
|
||||
expect(result).toBe('unchecked');
|
||||
});
|
||||
|
||||
it('should confirm Received B2B VNL checkbox is unchecked', async() => {
|
||||
const result = await nightmare
|
||||
.checkboxState(selectors.clientBillingData.receivedB2BVNLCheckbox);
|
||||
|
||||
expect(result).toBe('unchecked');
|
||||
});
|
||||
});
|
|
@ -1,121 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import createNightmare from '../../helpers/nightmare';
|
||||
|
||||
describe('Client Edit pay method path', () => {
|
||||
const nightmare = createNightmare();
|
||||
|
||||
beforeAll(() => {
|
||||
nightmare
|
||||
.loginAndModule('administrative', 'client')
|
||||
.accessToSearchResult('Bruce Banner')
|
||||
.accessToSection('client.card.billingData');
|
||||
});
|
||||
|
||||
it(`should attempt to edit the Pay method without an IBAN but fail`, async() => {
|
||||
const snackbarMessage = await nightmare
|
||||
.autocompleteSearch(selectors.clientPayMethod.payMethodAutocomplete, 'PayMethod with IBAN')
|
||||
.autocompleteSearch(selectors.clientPayMethod.swiftBicAutocomplete, 'BBKKESMMMMM')
|
||||
.clearInput(selectors.clientPayMethod.dueDayInput)
|
||||
.write(selectors.clientPayMethod.dueDayInput, '60')
|
||||
.waitForTextInInput(selectors.clientPayMethod.dueDayInput, '60')
|
||||
.waitToClick(selectors.clientPayMethod.receivedCoreLCRCheckbox)
|
||||
.waitToClick(selectors.clientPayMethod.receivedCoreVNLCheckbox)
|
||||
.waitToClick(selectors.clientPayMethod.receivedB2BVNLCheckbox)
|
||||
.waitToClick(selectors.clientPayMethod.saveButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(snackbarMessage).toEqual('That payment method requires an IBAN');
|
||||
});
|
||||
|
||||
it(`should add the IBAN but fail as it requires a BIC code`, async() => {
|
||||
const snackbarMessage = await nightmare
|
||||
.waitToClick(selectors.clientPayMethod.clearswiftBicButton)
|
||||
.clearInput(selectors.clientPayMethod.IBANInput)
|
||||
.write(selectors.clientPayMethod.IBANInput, 'FR9121000418450200051332')
|
||||
.waitForTextInInput(selectors.clientPayMethod.IBANInput, 'FR9121000418450200051332')
|
||||
.wait(1000)
|
||||
.waitToClick(selectors.clientPayMethod.saveButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(snackbarMessage).toEqual('That payment method requires a BIC');
|
||||
});
|
||||
|
||||
it(`should create a new BIC code`, async() => {
|
||||
const newcode = await nightmare
|
||||
.waitToClick(selectors.clientPayMethod.newBankEntityButton)
|
||||
.write(selectors.clientPayMethod.newBankEntityName, 'Gotham City Bank')
|
||||
.write(selectors.clientPayMethod.newBankEntityCode, 9999)
|
||||
.write(selectors.clientPayMethod.newBankEntityBIC, 'GTHMCT')
|
||||
.waitToClick(selectors.clientPayMethod.acceptBankEntityButton)
|
||||
.waitToGetProperty(`${selectors.clientPayMethod.swiftBicAutocomplete} input`, 'value');
|
||||
|
||||
expect(newcode).toEqual('GTHMCT Gotham City Bank');
|
||||
});
|
||||
|
||||
it(`should confirm the IBAN pay method is sucessfully saved`, async() => {
|
||||
const payMethod = await nightmare
|
||||
.waitToGetProperty(`${selectors.clientPayMethod.payMethodAutocomplete} input`, 'value');
|
||||
|
||||
expect(payMethod).toEqual('PayMethod with IBAN');
|
||||
});
|
||||
|
||||
it(`should clear the BIC code field, update the IBAN to see how he BIC code autocompletes`, async() => {
|
||||
const AutomaticCode = await nightmare
|
||||
.clearInput(selectors.clientPayMethod.IBANInput)
|
||||
.waitToClick(selectors.clientPayMethod.clearswiftBicButton)
|
||||
.write(selectors.clientPayMethod.IBANInput, 'ES9121000418450200051332')
|
||||
.waitToGetProperty(`${selectors.clientPayMethod.swiftBicAutocomplete} input`, 'value');
|
||||
|
||||
expect(AutomaticCode).toEqual('CAIXESBB Caixa Bank');
|
||||
});
|
||||
|
||||
it(`should save the form with all its new data`, async() => {
|
||||
const snackbarMessages = await nightmare
|
||||
.waitToClick(selectors.clientPayMethod.saveButton)
|
||||
.waitForSnackbar();
|
||||
|
||||
expect(snackbarMessages).toEqual(jasmine.arrayContaining(['Data saved!']));
|
||||
});
|
||||
|
||||
it('should confirm the due day have been edited', async() => {
|
||||
const dueDate = await nightmare
|
||||
.waitToGetProperty(selectors.clientPayMethod.dueDayInput, 'value');
|
||||
|
||||
expect(dueDate).toEqual('60');
|
||||
});
|
||||
|
||||
it('should confirm the IBAN was saved', async() => {
|
||||
const IBAN = await nightmare
|
||||
.waitToGetProperty(selectors.clientPayMethod.IBANInput, 'value');
|
||||
|
||||
expect(IBAN).toEqual('ES9121000418450200051332');
|
||||
});
|
||||
|
||||
it('should confirm the swift / BIC code was saved', async() => {
|
||||
const code = await nightmare
|
||||
.waitToGetProperty(`${selectors.clientPayMethod.swiftBicAutocomplete} input`, 'value');
|
||||
|
||||
expect(code).toEqual('CAIXESBB Caixa Bank');
|
||||
});
|
||||
|
||||
it('should confirm Received LCR checkbox is checked', async() => {
|
||||
const result = await nightmare
|
||||
.checkboxState(selectors.clientPayMethod.receivedCoreLCRCheckbox);
|
||||
|
||||
expect(result).toBe('checked');
|
||||
});
|
||||
|
||||
it('should confirm Received core VNL checkbox is unchecked', async() => {
|
||||
const result = await nightmare
|
||||
.checkboxState(selectors.clientPayMethod.receivedCoreVNLCheckbox);
|
||||
|
||||
expect(result).toBe('unchecked');
|
||||
});
|
||||
|
||||
it('should confirm Received B2B VNL checkbox is unchecked', async() => {
|
||||
const result = await nightmare
|
||||
.checkboxState(selectors.clientPayMethod.receivedB2BVNLCheckbox);
|
||||
|
||||
expect(result).toBe('unchecked');
|
||||
});
|
||||
});
|
|
@ -1,7 +1,7 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import createNightmare from '../../helpers/nightmare';
|
||||
|
||||
describe('Client risk path', () => {
|
||||
describe('Client balance path', () => {
|
||||
const nightmare = createNightmare();
|
||||
|
||||
beforeAll(() => {
|
||||
|
@ -19,10 +19,10 @@ describe('Client risk path', () => {
|
|||
expect(result).toEqual('Data saved!');
|
||||
});
|
||||
|
||||
it('should access to the risk section to check the data shown matches the local settings', async() => {
|
||||
it('should access to the balance section to check the data shown matches the local settings', async() => {
|
||||
let result = await nightmare
|
||||
.accessToSection('client.card.risk.index')
|
||||
.waitToGetProperty(`${selectors.clientRisk.companyAutocomplete} input`, 'value');
|
||||
.accessToSection('client.card.balance.index')
|
||||
.waitToGetProperty(`${selectors.clientBalance.companyAutocomplete} input`, 'value');
|
||||
|
||||
expect(result).toEqual('CCs');
|
||||
});
|
||||
|
@ -38,19 +38,19 @@ describe('Client risk path', () => {
|
|||
|
||||
it('should click the new payment button', async() => {
|
||||
let url = await nightmare
|
||||
.reloadSection('client.card.risk.index')
|
||||
.waitToClick(selectors.clientRisk.newPaymentButton)
|
||||
.waitForURL('/risk')
|
||||
.reloadSection('client.card.balance.index')
|
||||
.waitToClick(selectors.clientBalance.newPaymentButton)
|
||||
.waitForURL('/balance')
|
||||
.parsedUrl();
|
||||
|
||||
expect(url.hash).toContain('/risk');
|
||||
expect(url.hash).toContain('/balance');
|
||||
});
|
||||
|
||||
it('should create a new payment that clears the debt', async() => {
|
||||
let result = await nightmare
|
||||
.clearInput(selectors.clientRisk.newPaymentBankInut)
|
||||
.write(selectors.clientRisk.newPaymentBankInut, '2')
|
||||
.waitToClick(selectors.clientRisk.saveButton)
|
||||
.clearInput(selectors.clientBalance.newPaymentBankInut)
|
||||
.write(selectors.clientBalance.newPaymentBankInut, '2')
|
||||
.waitToClick(selectors.clientBalance.saveButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result).toContain('Data saved!');
|
||||
|
@ -58,30 +58,30 @@ describe('Client risk path', () => {
|
|||
|
||||
it('should check balance is now 0 and the company is now VNL becouse the user local settings were removed', async() => {
|
||||
let company = await nightmare
|
||||
.waitToGetProperty(`${selectors.clientRisk.companyAutocomplete} input`, 'value');
|
||||
.waitToGetProperty(`${selectors.clientBalance.companyAutocomplete} input`, 'value');
|
||||
|
||||
let firstRiskLineBalance = await nightmare
|
||||
.waitToGetProperty(selectors.clientRisk.firstRiskLineBalance, 'innerText');
|
||||
let firstBalanceLine = await nightmare
|
||||
.waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText');
|
||||
|
||||
|
||||
expect(company).toEqual('VNL');
|
||||
expect(firstRiskLineBalance).toContain('0.00');
|
||||
expect(firstBalanceLine).toContain('0.00');
|
||||
});
|
||||
|
||||
it('should now click the new payment button', async() => {
|
||||
let url = await nightmare
|
||||
.waitToClick(selectors.clientRisk.newPaymentButton)
|
||||
.waitForURL('/risk')
|
||||
.waitToClick(selectors.clientBalance.newPaymentButton)
|
||||
.waitForURL('/balance')
|
||||
.parsedUrl();
|
||||
|
||||
expect(url.hash).toContain('/risk');
|
||||
expect(url.hash).toContain('/balance');
|
||||
});
|
||||
|
||||
it('should create a new payment that sets the balance to positive value', async() => {
|
||||
let result = await nightmare
|
||||
.clearInput(selectors.clientRisk.newPaymentAmountInput)
|
||||
.write(selectors.clientRisk.newPaymentAmountInput, '100')
|
||||
.waitToClick(selectors.clientRisk.saveButton)
|
||||
.clearInput(selectors.clientBalance.newPaymentAmountInput)
|
||||
.write(selectors.clientBalance.newPaymentAmountInput, '100')
|
||||
.waitToClick(selectors.clientBalance.saveButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result).toContain('Data saved!');
|
||||
|
@ -89,26 +89,26 @@ describe('Client risk path', () => {
|
|||
|
||||
it('should check balance is now 100', async() => {
|
||||
let result = await nightmare
|
||||
.waitToGetProperty(selectors.clientRisk.firstRiskLineBalance, 'innerText');
|
||||
.waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText');
|
||||
|
||||
expect(result).toContain('100.00');
|
||||
});
|
||||
|
||||
it('should again click the new payment button', async() => {
|
||||
let url = await nightmare
|
||||
.waitToClick(selectors.clientRisk.newPaymentButton)
|
||||
.waitForURL('/risk')
|
||||
.waitToClick(selectors.clientBalance.newPaymentButton)
|
||||
.waitForURL('/balance')
|
||||
.parsedUrl();
|
||||
|
||||
expect(url.hash).toContain('/risk');
|
||||
expect(url.hash).toContain('/balance');
|
||||
});
|
||||
|
||||
it('should create a new payment that sets the balance back to the original negative value', async() => {
|
||||
let result = await nightmare
|
||||
.clearInput(selectors.clientRisk.newPaymentAmountInput)
|
||||
.write(selectors.clientRisk.newPaymentAmountInput, '-150')
|
||||
.clearInput(selectors.clientBalance.newPaymentAmountInput)
|
||||
.write(selectors.clientBalance.newPaymentAmountInput, '-150')
|
||||
.wait(1999)
|
||||
.waitToClick(selectors.clientRisk.saveButton)
|
||||
.waitToClick(selectors.clientBalance.saveButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result).toContain('Data saved!');
|
||||
|
@ -116,7 +116,7 @@ describe('Client risk path', () => {
|
|||
|
||||
it('should check balance is now -50', async() => {
|
||||
let result = await nightmare
|
||||
.waitToGetProperty(selectors.clientRisk.firstRiskLineBalance, 'innerText');
|
||||
.waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText');
|
||||
|
||||
expect(result).toContain('€50.00');
|
||||
});
|
||||
|
@ -143,20 +143,20 @@ describe('Client risk path', () => {
|
|||
expect(resultCount).toEqual(1);
|
||||
});
|
||||
|
||||
it(`should click on the search result to access to the client's risk`, async() => {
|
||||
it(`should click on the search result to access to the client's balance`, async() => {
|
||||
let url = await nightmare
|
||||
.waitForTextInElement(selectors.clientsIndex.searchResult, 'Petter Parker')
|
||||
.waitToClick(selectors.clientsIndex.searchResult)
|
||||
.waitToClick(selectors.clientRisk.riskButton)
|
||||
.waitForURL('/risk')
|
||||
.waitToClick(selectors.clientBalance.balanceButton)
|
||||
.waitForURL('/balance')
|
||||
.parsedUrl();
|
||||
|
||||
expect(url.hash).toContain('/risk');
|
||||
expect(url.hash).toContain('/balance');
|
||||
});
|
||||
|
||||
it('should not be able to click the new payment button as it isnt present', async() => {
|
||||
let result = await nightmare
|
||||
.exists(selectors.clientRisk.newPaymentButton);
|
||||
.exists(selectors.clientBalance.newPaymentButton);
|
||||
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
|
|
@ -84,7 +84,7 @@ describe('Item summary path', () => {
|
|||
const result = await nightmare
|
||||
.clearInput('vn-item-index vn-searchbar input')
|
||||
.waitToClick(selectors.itemsIndex.searchButton)
|
||||
.write(selectors.itemsIndex.searchItemInput, 'Melee weapon combat first 15cm')
|
||||
.write(selectors.itemsIndex.searchItemInput, 'Melee weapon combat fist 15cm')
|
||||
.waitToClick(selectors.itemsIndex.searchButton)
|
||||
.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1)
|
||||
.countElement(selectors.itemsIndex.searchResult);
|
||||
|
@ -94,7 +94,7 @@ describe('Item summary path', () => {
|
|||
|
||||
it(`should now click on the search result summary button to open the item summary popup`, async() => {
|
||||
const isVisibleBefore = await nightmare
|
||||
.waitForTextInElement(selectors.itemsIndex.searchResult, 'Melee weapon combat first 15cm')
|
||||
.waitForTextInElement(selectors.itemsIndex.searchResult, 'Melee weapon combat fist 15cm')
|
||||
.isVisible(selectors.itemSummary.basicData);
|
||||
|
||||
const isVisibleAfter = await nightmare
|
||||
|
@ -108,10 +108,10 @@ describe('Item summary path', () => {
|
|||
|
||||
it(`should now check the item summary preview shows fields from basic data`, async() => {
|
||||
const result = await nightmare
|
||||
.waitForTextInElement(selectors.itemSummary.basicData, 'Melee weapon combat first 15cm')
|
||||
.waitForTextInElement(selectors.itemSummary.basicData, 'Melee weapon combat fist 15cm')
|
||||
.waitToGetProperty(selectors.itemSummary.basicData, 'innerText');
|
||||
|
||||
expect(result).toContain('Melee weapon combat first 15cm');
|
||||
expect(result).toContain('Melee weapon combat fist 15cm');
|
||||
});
|
||||
|
||||
it(`should now check the item summary preview shows fields from tags`, async() => {
|
||||
|
@ -172,10 +172,10 @@ describe('Item summary path', () => {
|
|||
|
||||
it(`should check the item summary shows fields from basic data section`, async() => {
|
||||
const result = await nightmare
|
||||
.waitForTextInElement(selectors.itemSummary.basicData, 'Melee weapon combat first 15cm')
|
||||
.waitForTextInElement(selectors.itemSummary.basicData, 'Melee weapon combat fist 15cm')
|
||||
.waitToGetProperty(selectors.itemSummary.basicData, 'innerText');
|
||||
|
||||
expect(result).toContain('Melee weapon combat first 15cm');
|
||||
expect(result).toContain('Melee weapon combat fist 15cm');
|
||||
});
|
||||
|
||||
it(`should check the item summary shows fields from tags section`, async() => {
|
||||
|
|
|
@ -7,8 +7,8 @@ describe('Item Edit basic data path', () => {
|
|||
beforeAll(() => {
|
||||
nightmare
|
||||
.loginAndModule('buyer', 'item')
|
||||
.accessToSearchResult('Melee weapon combat first 15cm')
|
||||
.accessToSection('item.card.data');
|
||||
.accessToSearchResult('Melee weapon combat fist 15cm')
|
||||
.accessToSection('item.card.basicData');
|
||||
});
|
||||
|
||||
it(`should check the descritor edit button is visible for buyer`, async() => {
|
||||
|
@ -39,7 +39,7 @@ describe('Item Edit basic data path', () => {
|
|||
|
||||
it(`should confirm the item name was edited`, async() => {
|
||||
const result = await nightmare
|
||||
.reloadSection('item.card.data')
|
||||
.reloadSection('item.card.basicData')
|
||||
.waitToGetProperty(selectors.itemBasicData.nameInput, 'value');
|
||||
|
||||
expect(result).toEqual('Rose of Purity');
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import createNightmare from '../../helpers/nightmare';
|
||||
|
||||
// #1186 repearar e2e ticket.sale, item.regularize.
|
||||
xdescribe('Item regularize path', () => {
|
||||
describe('Item regularize path', () => {
|
||||
const nightmare = createNightmare();
|
||||
beforeAll(() => {
|
||||
nightmare
|
||||
|
@ -177,7 +176,7 @@ xdescribe('Item regularize path', () => {
|
|||
|
||||
it('should search for the ticket with id 23 once again', async() => {
|
||||
const result = await nightmare
|
||||
.write(selectors.ticketsIndex.searchTicketInput, 'id:24')
|
||||
.write(selectors.ticketsIndex.searchTicketInput, 23)
|
||||
.waitToClick(selectors.ticketsIndex.searchButton)
|
||||
.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1)
|
||||
.countElement(selectors.ticketsIndex.searchResult);
|
||||
|
@ -187,7 +186,7 @@ xdescribe('Item regularize path', () => {
|
|||
|
||||
it(`should now click on the search result to access to the ticket summary`, async() => {
|
||||
const url = await nightmare
|
||||
.waitForTextInElement(selectors.ticketsIndex.searchResult, '24')
|
||||
.waitForTextInElement(selectors.ticketsIndex.searchResult, '23')
|
||||
.waitToClick(selectors.ticketsIndex.searchResult)
|
||||
.waitForURL('/summary')
|
||||
.parsedUrl();
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Item descriptor path', () => {
|
|||
nightmare
|
||||
.loginAndModule('buyer', 'item')
|
||||
.accessToSearchResult(1)
|
||||
.accessToSection('item.card.data');
|
||||
.accessToSection('item.card.basicData');
|
||||
});
|
||||
|
||||
it('should check the descriptor inactive icon is dark as the item is active', async() => {
|
||||
|
@ -30,7 +30,7 @@ describe('Item descriptor path', () => {
|
|||
|
||||
it('should reload the section and check the inactive icon is bright', async() => {
|
||||
let brightIcon = await nightmare
|
||||
.reloadSection('item.card.data')
|
||||
.reloadSection('item.card.basicData')
|
||||
.waitForClassPresent(selectors.itemDescriptor.inactiveIcon, 'bright')
|
||||
.isVisible(selectors.itemDescriptor.inactiveIcon);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ describe('Ticket Create packages path', () => {
|
|||
return nightmare
|
||||
.loginAndModule('employee', 'ticket')
|
||||
.accessToSearchResult('id:1')
|
||||
.accessToSection('ticket.card.package.index');
|
||||
.accessToSection('ticket.card.package');
|
||||
});
|
||||
|
||||
it(`should attempt create a new package but receive an error if package is blank`, async() => {
|
||||
|
@ -53,7 +53,7 @@ describe('Ticket Create packages path', () => {
|
|||
|
||||
it(`should confirm the first select is the expected one`, async() => {
|
||||
const result = await nightmare
|
||||
.reloadSection('ticket.card.package.index')
|
||||
.reloadSection('ticket.card.package')
|
||||
.waitForTextInInput(`${selectors.ticketPackages.firstPackageAutocomplete} input`, 'Container medical box 1m')
|
||||
.waitToGetProperty(`${selectors.ticketPackages.firstPackageAutocomplete} input`, 'value');
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ describe('Ticket Create new tracking state path', () => {
|
|||
|
||||
it(`should create a new state with all it's data`, async() => {
|
||||
let result = await nightmare
|
||||
.autocompleteSearch(selectors.createStateView.workerAutocomplete, 'accessory')
|
||||
.autocompleteSearch(selectors.createStateView.workerAutocomplete, 'replenisher')
|
||||
.waitToClick(selectors.createStateView.saveStateButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ describe('Ticket Edit basic data path', () => {
|
|||
return nightmare
|
||||
.loginAndModule('employee', 'ticket')
|
||||
.accessToSearchResult('id:11')
|
||||
.accessToSection('ticket.card.data.stepOne');
|
||||
.accessToSection('ticket.card.basicData.stepOne');
|
||||
});
|
||||
|
||||
it(`should edit the client and address of the ticket then click next`, async() => {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import createNightmare from '../../helpers/nightmare';
|
||||
|
||||
// #1186 repearar e2e ticket.sale, item.regularize.
|
||||
// #1387 e2e Ticket Edit sale path
|
||||
xdescribe('Ticket Edit sale path', () => {
|
||||
const nightmare = createNightmare();
|
||||
|
||||
|
|
|
@ -148,4 +148,43 @@ describe('Ticket descriptor path', () => {
|
|||
expect(exists).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Make invoice', () => {
|
||||
it('should login as adminBoss role then search for a ticket', async() => {
|
||||
const invoiceableTicketId = 11;
|
||||
|
||||
const url = await nightmare
|
||||
.loginAndModule('adminBoss', 'ticket')
|
||||
.accessToSearchResult(invoiceableTicketId)
|
||||
.waitForURL('/summary')
|
||||
.parsedUrl();
|
||||
|
||||
expect(url.hash).toContain(`ticket/${invoiceableTicketId}/summary`);
|
||||
});
|
||||
|
||||
it(`should make sure the ticket doesn't have an invoiceOutFk yet`, async() => {
|
||||
const result = await nightmare
|
||||
.waitToGetProperty(selectors.ticketSummary.invoiceOutRef, 'innerText');
|
||||
|
||||
expect(result).toEqual('-');
|
||||
});
|
||||
|
||||
it('should invoice the ticket using the descriptor more menu', async() => {
|
||||
const result = await nightmare
|
||||
.waitToClick(selectors.ticketDescriptor.moreMenu)
|
||||
.waitToClick(selectors.ticketDescriptor.moreMenuMakeInvoice)
|
||||
.waitToClick(selectors.ticketDescriptor.acceptInvoiceOutButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result).toEqual('Ticket invoiced');
|
||||
});
|
||||
|
||||
it(`should make sure the ticket summary have an invoiceOutFk`, async() => {
|
||||
const result = await nightmare
|
||||
.waitForTextInElement(selectors.ticketSummary.invoiceOutRef, 'T4444445')
|
||||
.waitToGetProperty(selectors.ticketSummary.invoiceOutRef, 'innerText');
|
||||
|
||||
expect(result).toEqual('T4444445');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Ticket services path', () => {
|
|||
beforeAll(() => {
|
||||
nightmare
|
||||
.loginAndModule('employee', 'ticket')
|
||||
.accessToSearchResult('1')
|
||||
.accessToSearchResult(8)
|
||||
.accessToSection('ticket.card.service');
|
||||
});
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import Component from '../../lib/component';
|
|||
import './style.scss';
|
||||
|
||||
/**
|
||||
* Calendar.
|
||||
* Flat calendar.
|
||||
*
|
||||
*/
|
||||
export default class Calendar extends Component {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// #937 front test datePicker awaiting loopback connector refactor to store dates correctly.
|
||||
xdescribe('Component vnDatePicker', () => {
|
||||
describe('Component vnDatePicker', () => {
|
||||
let controller;
|
||||
let $attrs;
|
||||
let $element;
|
||||
|
|
|
@ -277,6 +277,7 @@ export default class DropDown extends Component {
|
|||
if (data) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let option = data[i];
|
||||
option.orgShowField = option[this.showField];
|
||||
|
||||
if (this.translateFields) {
|
||||
option = Object.assign({}, option);
|
||||
|
@ -285,6 +286,8 @@ export default class DropDown extends Component {
|
|||
}
|
||||
|
||||
let li = this.document.createElement('li');
|
||||
|
||||
li.setAttribute('name', option.orgShowField);
|
||||
fragment.appendChild(li);
|
||||
|
||||
if (this.multiple) {
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
<vn-check field="$ctrl.checkAll"></vn-check>
|
||||
<vn-check field="$ctrl.checked"
|
||||
intermediate="$ctrl.isIntermediate"
|
||||
vn-tooltip="Check all"
|
||||
tooltip-position="up">
|
||||
</vn-check>
|
|
@ -10,23 +10,104 @@ import Input from '../../lib/input';
|
|||
export default class MultiCheck extends Input {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this._checkAll = false;
|
||||
this._checked = false;
|
||||
this.checkField = 'checked';
|
||||
this.isIntermediate = false;
|
||||
}
|
||||
|
||||
get checkAll() {
|
||||
return this._checkAll;
|
||||
/**
|
||||
* Gets array model instance
|
||||
*
|
||||
* @return {ArrayModel} - Array model instance
|
||||
*/
|
||||
get model() {
|
||||
return this._model;
|
||||
}
|
||||
|
||||
set checkAll(value) {
|
||||
this._checkAll = value;
|
||||
this.switchChecks();
|
||||
/**
|
||||
* Sets the array model instance
|
||||
* Changes intermediate property for
|
||||
* the check component
|
||||
*
|
||||
* @param {ArrayModel} value - Array model instance
|
||||
*/
|
||||
set model(value) {
|
||||
this._model = value;
|
||||
|
||||
if (value) {
|
||||
value.on('rowChange', () => {
|
||||
this.isIntermediate = !this.areAllUnchecked() && !this.areAllChecked();
|
||||
|
||||
if (this.areAllChecked())
|
||||
this._checked = true;
|
||||
else if (!this.areAllChecked())
|
||||
this._checked = false;
|
||||
});
|
||||
|
||||
value.on('dataChange', () => {
|
||||
if (this.checked) this.toggle();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
switchChecks() {
|
||||
if (!this.data) return;
|
||||
this.data.forEach(el => {
|
||||
el[this.checkField] = this._checkAll;
|
||||
/**
|
||||
* Gets current check state
|
||||
*/
|
||||
get checked() {
|
||||
return this._checked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets current check state
|
||||
*
|
||||
* @param {Boolean} value - Checkbox state [undefined, true, false]
|
||||
*/
|
||||
set checked(value) {
|
||||
this._checked = value;
|
||||
this.checkAll = value;
|
||||
|
||||
this.toggle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bolean result for
|
||||
* checked instances
|
||||
*
|
||||
* @return {Boolean} - True if all instances are checked
|
||||
*/
|
||||
areAllChecked() {
|
||||
if (!this.model || !this.model.data) return;
|
||||
|
||||
const data = this.model.data;
|
||||
return data.every(item => {
|
||||
return item[this.checkField] === true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bolean result for
|
||||
* checked instances
|
||||
*
|
||||
* @return {Boolean} - False if all instances are checked
|
||||
*/
|
||||
areAllUnchecked() {
|
||||
if (!this.model || !this.model.data) return;
|
||||
|
||||
const data = this.model.data;
|
||||
return data.every(item => {
|
||||
return item[this.checkField] === false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles checked property on
|
||||
* all instances
|
||||
*/
|
||||
toggle() {
|
||||
const data = this.model.data;
|
||||
if (!data) return;
|
||||
data.forEach(el => {
|
||||
el[this.checkField] = this.checkAll;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +116,7 @@ ngModule.component('vnMultiCheck', {
|
|||
template: require('./multi-check.html'),
|
||||
controller: MultiCheck,
|
||||
bindings: {
|
||||
data: '=',
|
||||
model: '<',
|
||||
checkField: '<?',
|
||||
checkAll: '=?',
|
||||
disabled: '<?'
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import './multi-check.js';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
|
||||
describe('Component vnMultiCheck', () => {
|
||||
let controller;
|
||||
|
@ -9,33 +10,94 @@ describe('Component vnMultiCheck', () => {
|
|||
beforeEach(angular.mock.inject($componentController => {
|
||||
$element = angular.element(`<div class="shown"></div>`);
|
||||
controller = $componentController('vnMultiCheck', {$element: $element});
|
||||
controller._model = crudModel;
|
||||
controller._model.data = [
|
||||
{id: 1, name: 'My item 1'},
|
||||
{id: 2, name: 'My item 2'},
|
||||
{id: 3, name: 'My item 3'}
|
||||
];
|
||||
}));
|
||||
|
||||
describe('checkAll() setter', () => {
|
||||
it(`should set controller _checkAll property with the argument received then call switchChecks()`, () => {
|
||||
let argument = 'I am the model';
|
||||
spyOn(controller, 'switchChecks');
|
||||
controller.checkAll = argument;
|
||||
describe('checked() setter', () => {
|
||||
it(`should set controller _checked property with the argument received then call toggle()`, () => {
|
||||
spyOn(controller, 'toggle');
|
||||
controller.checked = crudModel;
|
||||
|
||||
expect(controller._checkAll).toEqual(argument);
|
||||
expect(controller.switchChecks).toHaveBeenCalledWith();
|
||||
expect(controller._checked).toEqual(crudModel);
|
||||
expect(controller.toggle).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('switchChecks()', () => {
|
||||
describe('toggle()', () => {
|
||||
it(`should set checked property inside each existing element`, () => {
|
||||
controller.data = [
|
||||
{name: 'name'},
|
||||
{name: null}
|
||||
];
|
||||
const data = controller.model.data;
|
||||
|
||||
expect(controller.data[0].checked).not.toBeDefined();
|
||||
expect(controller.data[1].checked).not.toBeDefined();
|
||||
controller._checkAll = 1;
|
||||
controller.switchChecks();
|
||||
expect(data[0].checked).not.toBeDefined();
|
||||
expect(data[1].checked).not.toBeDefined();
|
||||
expect(data[2].checked).not.toBeDefined();
|
||||
|
||||
expect(controller.data[0].checked).toBeTruthy();
|
||||
expect(controller.data[1].checked).toBeTruthy();
|
||||
controller._checked = true;
|
||||
controller.checkAll = true;
|
||||
controller.toggle();
|
||||
|
||||
expect(data[0].checked).toBeTruthy();
|
||||
expect(data[1].checked).toBeTruthy();
|
||||
expect(data[2].checked).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should unset checked property inside each existing element`, () => {
|
||||
const data = controller.model.data;
|
||||
data[0].checked = true;
|
||||
data[1].checked = true;
|
||||
data[2].checked = true;
|
||||
|
||||
controller._checked = false;
|
||||
controller.checkAll = false;
|
||||
controller.toggle();
|
||||
|
||||
expect(data[0].checked).toBeFalsy();
|
||||
expect(data[1].checked).toBeFalsy();
|
||||
expect(data[2].checked).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('areAllChecked()', () => {
|
||||
it(`should set return true if all elements are checked`, () => {
|
||||
const data = controller.model.data;
|
||||
data[0].checked = true;
|
||||
data[1].checked = true;
|
||||
data[2].checked = true;
|
||||
|
||||
expect(controller.areAllChecked()).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should set return false if not all elements are checked`, () => {
|
||||
const data = controller.model.data;
|
||||
data[0].checked = true;
|
||||
data[1].checked = false;
|
||||
data[2].checked = true;
|
||||
|
||||
expect(controller.areAllChecked()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('areAllUnchecked()', () => {
|
||||
it(`should set return true if all elements are unchecked`, () => {
|
||||
const data = controller.model.data;
|
||||
data[0].checked = false;
|
||||
data[1].checked = false;
|
||||
data[2].checked = false;
|
||||
|
||||
expect(controller.areAllUnchecked()).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should set return false if not all elements are unchecked`, () => {
|
||||
const data = controller.model.data;
|
||||
data[0].checked = false;
|
||||
data[1].checked = true;
|
||||
data[2].checked = false;
|
||||
|
||||
expect(controller.areAllUnchecked()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,14 +5,13 @@
|
|||
'collapsed': !item.active,
|
||||
'included': item.selected == 1,
|
||||
'excluded': item.selected == 0
|
||||
}">
|
||||
}" vn-draggable="{{::$ctrl.draggable}}" vn-droppable="{{::$ctrl.droppable}}" on-drop="$ctrl.onDrop(item, dragged, dropped)">
|
||||
<vn-horizontal>
|
||||
<vn-auto class="actions">
|
||||
<vn-icon icon="keyboard_arrow_down" title="{{'Toggle' | translate}}"
|
||||
ng-click="$ctrl.toggle(item, $event)">
|
||||
</vn-icon>
|
||||
</vn-auto>
|
||||
<vn-one class="description">
|
||||
<vn-check vn-auto vn-acl="{{$ctrl.aclRole}}"
|
||||
ng-if="$ctrl.selectable"
|
||||
field="item.selected"
|
||||
|
@ -20,12 +19,11 @@
|
|||
on-change="$ctrl.select(item, value)"
|
||||
triple-state="true">
|
||||
</vn-check>
|
||||
{{::item.name}}
|
||||
</vn-one>
|
||||
<vn-one class="description">{{::item.name}}</vn-one>
|
||||
<vn-auto>
|
||||
<vn-icon-button icon="{{icon.icon}}"
|
||||
ng-repeat="icon in $ctrl.icons"
|
||||
ng-click="$ctrl.onClick(icon, item, $ctrl.parent, $parent.$index)"
|
||||
ng-click="$ctrl.onIconClick(icon, item, $ctrl.parent, $parent.$index)"
|
||||
vn-acl="{{$ctrl.aclRole}}" vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
</vn-auto>
|
||||
|
@ -34,7 +32,10 @@
|
|||
selectable="$ctrl.selectable"
|
||||
disabled="$ctrl.disabled"
|
||||
editable="$ctrl.editable"
|
||||
icons="$ctrl.icons"
|
||||
draggable="::$ctrl.draggable"
|
||||
droppable="::$ctrl.droppable"
|
||||
icons="::$ctrl.icons"
|
||||
parent-scope="::$ctrl.parentScope"
|
||||
acl-role="$ctrl.aclRole">
|
||||
</vn-treeview-child>
|
||||
</li>
|
||||
|
|
|
@ -15,9 +15,8 @@ class Controller extends Component {
|
|||
this.treeview.onSelection(item, value);
|
||||
}
|
||||
|
||||
onClick(icon, item, parent, index) {
|
||||
let parentScope = this.$scope.$parent.$parent;
|
||||
let parentController = parentScope.$ctrl;
|
||||
onIconClick(icon, item, parent, index) {
|
||||
let parentController = this.parentScope.$ctrl;
|
||||
icon.callback.call(parentController, item, parent, index);
|
||||
}
|
||||
|
||||
|
@ -25,6 +24,10 @@ class Controller extends Component {
|
|||
this.treeview.onCreate(parent);
|
||||
}
|
||||
|
||||
onDrop(item, dragged, dropped) {
|
||||
this.treeview.onDrop(item, dragged, dropped);
|
||||
}
|
||||
|
||||
get isInsertable() {
|
||||
return Array.isArray(this.parent) || this.parent.childs;
|
||||
}
|
||||
|
@ -40,7 +43,10 @@ ngModule.component('vnTreeviewChild', {
|
|||
disabled: '<?',
|
||||
selectable: '<?',
|
||||
editable: '<?',
|
||||
draggable: '<?',
|
||||
droppable: '<?',
|
||||
aclRole: '<?',
|
||||
parentScope: '<'
|
||||
},
|
||||
require: {
|
||||
treeview: '^vnTreeview'
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
<vn-treeview-child
|
||||
<vn-treeview-child acl-role="$ctrl.aclRole"
|
||||
items="$ctrl.data"
|
||||
parent="$ctrl.data"
|
||||
selectable="$ctrl.selectable"
|
||||
editable="$ctrl.editable"
|
||||
disabled="$ctrl.disabled"
|
||||
icons="$ctrl.icons"
|
||||
acl-role="$ctrl.aclRole">
|
||||
parent-scope="$ctrl.$scope.$parent"
|
||||
draggable="$ctrl.draggable"
|
||||
droppable="$ctrl.droppable"
|
||||
vn-droppable="{{$ctrl.droppable}}">
|
||||
</vn-treeview-child>
|
||||
|
|
|
@ -3,13 +3,14 @@ import Component from '../../lib/component';
|
|||
import './style.scss';
|
||||
|
||||
/**
|
||||
* A simple tooltip.
|
||||
* Treeview
|
||||
*
|
||||
* @property {String} position The relative position to the parent
|
||||
*/
|
||||
export default class Treeview extends Component {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.$scope = $scope;
|
||||
this.data = [];
|
||||
}
|
||||
|
||||
|
@ -69,6 +70,10 @@ export default class Treeview extends Component {
|
|||
|
||||
item.active = !item.active;
|
||||
}
|
||||
|
||||
onDrop(item, dragged, dropped) {
|
||||
this.emit('drop', {item, dragged, dropped});
|
||||
}
|
||||
}
|
||||
|
||||
Treeview.$inject = ['$element', '$scope'];
|
||||
|
@ -82,6 +87,8 @@ ngModule.component('vnTreeview', {
|
|||
disabled: '<?',
|
||||
selectable: '<?',
|
||||
editable: '<?',
|
||||
draggable: '<?',
|
||||
droppable: '<?',
|
||||
aclRole: '@?'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
@import "variables";
|
||||
|
||||
vn-treeview {
|
||||
vn-treeview-child {
|
||||
display: block
|
||||
}
|
||||
|
||||
ul {
|
||||
line-height: 24px;
|
||||
padding: 0;
|
||||
|
@ -9,17 +13,21 @@ vn-treeview {
|
|||
|
||||
li {
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
|
||||
.actions {
|
||||
min-width: 24px;
|
||||
}
|
||||
|
||||
.description {
|
||||
pointer-events: none;
|
||||
padding-left: 5px
|
||||
}
|
||||
}
|
||||
|
||||
li vn-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
li ul {
|
||||
padding-left: 1.8em;
|
||||
}
|
||||
|
@ -46,19 +54,22 @@ vn-treeview {
|
|||
& > vn-horizontal > .description {
|
||||
color: $color-notice;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& > vn-check .md-icon {
|
||||
& > vn-horizontal > vn-check .md-icon {
|
||||
background-color: $color-notice
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
li.excluded {
|
||||
& > vn-horizontal > .description {
|
||||
color: $color-alert;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& > vn-horizontal > vn-check .md-icon {
|
||||
background-color: $color-alert;
|
||||
border-color: transparent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
/**
|
||||
* Enables a draggable element and his drag events
|
||||
*
|
||||
* @return {Object} The directive
|
||||
*/
|
||||
export function directive() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function($scope, $element, $attrs) {
|
||||
const element = $element[0];
|
||||
const isDraggable = $attrs.vnDraggable === 'true';
|
||||
|
||||
if (!isDraggable) return;
|
||||
|
||||
// Set draggable style properties
|
||||
element.style.cursor = 'move';
|
||||
|
||||
|
||||
// Enable as draggable element
|
||||
element.setAttribute('draggable', true);
|
||||
|
||||
/**
|
||||
* Fires when a drag event starts
|
||||
*/
|
||||
element.addEventListener('dragstart', event => {
|
||||
element.style.opacity = 0.5;
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
/**
|
||||
* Fires when a drag event ends
|
||||
*/
|
||||
element.addEventListener('dragend', event => {
|
||||
element.style.opacity = 1;
|
||||
event.stopPropagation();
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ngModule.directive('vnDraggable', directive);
|
|
@ -0,0 +1,93 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
|
||||
export function directive($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function($scope, $element, $attrs) {
|
||||
const element = $element[0];
|
||||
const onDropEvent = $parse($attrs.onDrop);
|
||||
const isDroppable = $attrs.vnDroppable === 'true';
|
||||
|
||||
if (!isDroppable) return;
|
||||
|
||||
/**
|
||||
* Captures current dragging element
|
||||
*/
|
||||
element.addEventListener('dragstart', () => {
|
||||
this.dragged = element;
|
||||
});
|
||||
|
||||
/**
|
||||
* Enter droppable area event
|
||||
*/
|
||||
element.addEventListener('dragenter', event => {
|
||||
element.style.backgroundColor = 'yellow';
|
||||
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault();
|
||||
}, false);
|
||||
|
||||
|
||||
/**
|
||||
* Exit droppable area event
|
||||
*/
|
||||
element.addEventListener('dragleave', event => {
|
||||
element.style.backgroundColor = 'transparent';
|
||||
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
/**
|
||||
* Prevent dragover for allowing
|
||||
* dispatch drop event
|
||||
*/
|
||||
element.addEventListener('dragover', event => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
/**
|
||||
* Fires when a drop events
|
||||
*/
|
||||
element.addEventListener('drop', event => {
|
||||
const draggedParent = this.dragged.parentNode;
|
||||
const targetChild = element.querySelector('ul');
|
||||
|
||||
|
||||
element.style.transition = 'background 2s';
|
||||
element.style.backgroundColor = 'transparent';
|
||||
|
||||
if (this.dragged === element)
|
||||
return event.preventDefault();
|
||||
|
||||
|
||||
if (targetChild) {
|
||||
const targetNodes = targetChild.querySelectorAll('li');
|
||||
const before = targetNodes[targetNodes.length - 1];
|
||||
|
||||
targetChild.insertBefore(this.dragged, before);
|
||||
} else
|
||||
draggedParent.removeChild(this.dragged);
|
||||
|
||||
onDropEvent($scope, {
|
||||
dragged: {
|
||||
element: this.dragged,
|
||||
scope: angular.element(this.dragged).scope()
|
||||
},
|
||||
dropped: {
|
||||
element: element,
|
||||
scope: angular.element(element).scope()
|
||||
}
|
||||
});
|
||||
|
||||
event.stopImmediatePropagation();
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
directive.$inject = ['$parse'];
|
||||
|
||||
ngModule.directive('vnDroppable', directive);
|
|
@ -11,3 +11,5 @@ import './bind';
|
|||
import './repeat-last';
|
||||
import './title';
|
||||
import './uvc';
|
||||
import './draggable';
|
||||
import './droppable';
|
||||
|
|
|
@ -42,3 +42,4 @@ Loading: Cargando
|
|||
Fields to show: Campos a mostrar
|
||||
Create new one: Crear nuevo
|
||||
Toggle: Desplegar/Plegar
|
||||
Check all: Seleccionar todo
|
|
@ -24,7 +24,14 @@ module.exports = {
|
|||
}
|
||||
};
|
||||
},
|
||||
on: () => {
|
||||
return {
|
||||
then: callback => {
|
||||
callback({data: {id: 1234}});
|
||||
}
|
||||
};
|
||||
},
|
||||
refresh: () => {},
|
||||
addFilter: () => {},
|
||||
applyFilter: () => {}
|
||||
applyFilter: () => {},
|
||||
};
|
||||
|
|
|
@ -24,5 +24,5 @@ window.ngModule = function(moduleName) {
|
|||
let testsContext = require.context('./', true, /\.spec\.js$/);
|
||||
testsContext.keys().forEach(testsContext);
|
||||
|
||||
let modulesContext = require.context('../modules/', true, /^\.\/[a-z0-9]+\/front\/.+\.spec\.js$/);
|
||||
let modulesContext = require.context('../modules/', true, /^\.\/[a-zA-Z0-9-]+\/front\/.+\.spec\.js$/);
|
||||
modulesContext.keys().forEach(modulesContext);
|
||||
|
|
|
@ -41,5 +41,7 @@
|
|||
"City cannot be empty": "City cannot be empty",
|
||||
"EXTENSION_INVALID_FORMAT": "Invalid extension",
|
||||
"The secret can't be blank": "The secret can't be blank",
|
||||
"Invalid TIN": "Invalid Tax number"
|
||||
"Invalid TIN": "Invalid Tax number",
|
||||
"This ticket can't be invoiced": "This ticket can't be invoiced",
|
||||
"The value should be a number": "The value should be a number"
|
||||
}
|
|
@ -79,6 +79,7 @@
|
|||
"We weren't able to send this SMS": "No hemos podido enviar el SMS",
|
||||
"This client can't be invoiced": "Este cliente no puede ser facturado",
|
||||
"This ticket can't be invoiced": "Este ticket no puede ser facturado",
|
||||
"That item is not available on that day": "That item is not available on that day",
|
||||
"That item doesn't exists": "That item doesn't exists"
|
||||
"That item is not available on that day": "El item no esta disponible para esa fecha",
|
||||
"That item doesn't exists": "That item doesn't exists",
|
||||
"You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado"
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import './index.js';
|
||||
|
||||
xdescribe('Agency', () => {
|
||||
describe('Component vnZoneCard', () => {
|
||||
describe('Agency Component vnZoneCard', () => {
|
||||
let $scope;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
@ -33,5 +32,4 @@ xdescribe('Agency', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import './index';
|
||||
import watcher from 'core/mocks/watcher';
|
||||
|
||||
xdescribe('Agency', () => {
|
||||
describe('Component vnZoneCreate', () => {
|
||||
describe('Agency Component vnZoneCreate', () => {
|
||||
let $scope;
|
||||
let $state;
|
||||
let controller;
|
||||
|
@ -33,8 +32,8 @@ xdescribe('Agency', () => {
|
|||
|
||||
controller.onSubmit();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('zone.card.basicData', {id: 1234});
|
||||
});
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('zone.card.location', Object({id: 1234}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import './index.js';
|
||||
|
||||
xdescribe('Agency', () => {
|
||||
describe('Component vnZoneIndex', () => {
|
||||
describe('Agency Component vnZoneIndex', () => {
|
||||
let $componentController;
|
||||
let controller;
|
||||
|
||||
|
@ -29,7 +28,7 @@ xdescribe('Agency', () => {
|
|||
expect(result).toEqual({warehouseFk: 'Silla'});
|
||||
});
|
||||
|
||||
it('should return a formated object with the warehouseFk in case of warehouseFk', () => {
|
||||
it('should return a formated object with the warehouseFk in case of agencyModeFk', () => {
|
||||
let param = 'agencyModeFk';
|
||||
let value = 'My Delivery';
|
||||
let result = controller.exprBuilder(param, value);
|
||||
|
@ -38,4 +37,3 @@ xdescribe('Agency', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
on-search="$ctrl.onSearch()"
|
||||
vn-focus>
|
||||
</vn-searchbar>
|
||||
<vn-treeview vn-id="treeview" model="model" selectable="true" acl-role="deliveryBoss"
|
||||
on-selection="$ctrl.onSelection(item, value)">
|
||||
<vn-treeview vn-id="treeview" model="model" acl-role="deliveryBoss"
|
||||
on-selection="$ctrl.onSelection(item, value)"
|
||||
selectable="true">
|
||||
</vn-treeview>
|
||||
</vn-card>
|
||||
<vn-side-menu side="right">
|
||||
|
|
|
@ -99,7 +99,7 @@ module.exports = Self => {
|
|||
let stmt;
|
||||
|
||||
stmt = new ParameterizedSQL(
|
||||
`SELECT cl.id, c.name, u.nickName, cs.description, cl.created
|
||||
`SELECT cl.id, c.name, cl.clientFk, cl.workerFk, u.nickName, cs.description, cl.created
|
||||
FROM claim cl
|
||||
LEFT JOIN client c ON c.id = cl.clientFk
|
||||
LEFT JOIN worker w ON w.id = cl.workerFk
|
||||
|
|
|
@ -161,11 +161,13 @@ describe('claim', () => {
|
|||
|
||||
describe('onUpdateGreugeResponse()', () => {
|
||||
it('should do nothing', () => {
|
||||
spyOn(controller.$http, 'post');
|
||||
spyOn(controller.card, 'reload');
|
||||
spyOn(controller.vnApp, 'showSuccess');
|
||||
|
||||
controller.onUpdateGreugeResponse('CANCEL');
|
||||
|
||||
expect(controller.$http.post).not.toHaveBeenCalledWith();
|
||||
expect(controller.card.reload).not.toHaveBeenCalledWith();
|
||||
expect(controller.vnApp.showSuccess).not.toHaveBeenCalledWith('Greuge inserted!');
|
||||
});
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
value="{{$ctrl.claim.claimState.description}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Created"
|
||||
value="{{$ctrl.claim.created | dateTime: 'dd/MM/yyyy'}}">
|
||||
value="{{$ctrl.claim.created | dateTime: 'dd/MM/yyyy HH:mm'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Salesperson"
|
||||
value="{{$ctrl.claim.client.salesPerson.user.nickname}}">
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
ui-sref="claim.card.summary({id: claim.id})">
|
||||
<vn-td number>{{::claim.id}}</vn-td>
|
||||
<vn-td expand>
|
||||
<span class="link" ng-click="$ctrl.showClientDescriptor($event, claim.client.id)">
|
||||
<span class="link" ng-click="$ctrl.showClientDescriptor($event, claim.clientFk)">
|
||||
{{::claim.name}}
|
||||
</span>
|
||||
</vn-td>
|
||||
|
@ -43,7 +43,7 @@
|
|||
<vn-td expand>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, claim.worker.user.id)">
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, claim.workerFk)">
|
||||
{{::claim.nickName}}
|
||||
</span>
|
||||
</vn-td>
|
||||
|
@ -68,7 +68,7 @@
|
|||
<vn-client-descriptor-popover vn-id="clientDescriptor"></vn-client-descriptor-popover>
|
||||
<vn-worker-descriptor-popover
|
||||
vn-id="workerDescriptor"
|
||||
user-id="$ctrl.selectedWorker">
|
||||
worker-fk="$ctrl.selectedWorker">
|
||||
</vn-worker-descriptor-popover>
|
||||
<vn-dialog class="dialog-summary"
|
||||
vn-id="dialog-summary-claim">
|
||||
|
|
|
@ -25,10 +25,10 @@ export default class Controller {
|
|||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
showWorkerDescriptor(event, userId) {
|
||||
showWorkerDescriptor(event, workerFk) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
this.selectedWorker = userId;
|
||||
this.selectedWorker = workerFk;
|
||||
this.$.workerDescriptor.parent = event.target;
|
||||
this.$.workerDescriptor.show();
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
<vn-td expand>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, development.worker.user.id)">
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, development.workerFk)">
|
||||
{{::development.worker.user.nickname}}
|
||||
</span>
|
||||
</vn-td>
|
||||
|
@ -156,7 +156,7 @@
|
|||
</vn-item-descriptor-popover>
|
||||
<vn-worker-descriptor-popover
|
||||
vn-id="workerDescriptor"
|
||||
user-id="$ctrl.selectedWorker">
|
||||
worker-fk="$ctrl.selectedWorker">
|
||||
</vn-worker-descriptor-popover>
|
||||
<vn-ticket-descriptor-popover
|
||||
vn-id="ticketDescriptor">
|
||||
|
|
|
@ -32,8 +32,8 @@ class Controller {
|
|||
this.$.itemDescriptor.show();
|
||||
}
|
||||
|
||||
showWorkerDescriptor(event, userId) {
|
||||
this.selectedWorker = userId;
|
||||
showWorkerDescriptor(event, workerFk) {
|
||||
this.selectedWorker = workerFk;
|
||||
this.$.workerDescriptor.parent = event.target;
|
||||
this.$.workerDescriptor.show();
|
||||
}
|
||||
|
|
|
@ -16,14 +16,14 @@ module.exports = function(Self) {
|
|||
Self.listWorkers = function() {
|
||||
let query =
|
||||
`SELECT w.id,
|
||||
CONCAT(w.firstName, IFNULL(CONCAT(" ", w.name), "")) \`name\`
|
||||
CONCAT(w.firstName, IFNULL(CONCAT(" ", w.lastName), "")) \`name\`
|
||||
FROM worker w
|
||||
JOIN account.user u ON w.userFk = u.id
|
||||
JOIN account.roleRole rr ON rr.role = u.role
|
||||
JOIN account.role r ON r.id = rr.inheritsFrom
|
||||
WHERE u.active
|
||||
AND r.\`name\` = 'employee'
|
||||
ORDER BY w.name ASC`;
|
||||
ORDER BY w.lastName ASC`;
|
||||
|
||||
return Self.rawSql(query);
|
||||
};
|
||||
|
|
|
@ -7,6 +7,6 @@ describe('Client get', () => {
|
|||
|
||||
expect(result.id).toEqual(101);
|
||||
expect(result.name).toEqual('Bruce Wayne');
|
||||
expect(result.debt).toEqual(329.13);
|
||||
expect(result.debt).toEqual(-14.78);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,7 +4,7 @@ describe('client getDebt()', () => {
|
|||
it('should return the client debt', async() => {
|
||||
let result = await app.models.Client.getDebt(101);
|
||||
|
||||
expect(result.debt).toEqual(329.13);
|
||||
expect(result.debt).toEqual(-14.78);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ describe('client summary()', () => {
|
|||
it('should return a summary object containing debt', async() => {
|
||||
let result = await app.models.Client.summary(101);
|
||||
|
||||
expect(result.debt.debt).toEqual(329.13);
|
||||
expect(result.debt.debt).toEqual(-14.78);
|
||||
});
|
||||
|
||||
it('should return a summary object containing averageInvoiced', async() => {
|
||||
|
|
|
@ -34,6 +34,7 @@ module.exports = Self => {
|
|||
r.id,
|
||||
r.isConciliate,
|
||||
r.payed,
|
||||
r.workerFk,
|
||||
c.code company,
|
||||
r.created,
|
||||
r.invoiceFk ref,
|
||||
|
@ -41,7 +42,6 @@ module.exports = Self => {
|
|||
r.amountPaid credit,
|
||||
r.bankFk,
|
||||
u.nickname userNickname,
|
||||
u.id userId,
|
||||
r.clientFk,
|
||||
FALSE pdf,
|
||||
FALSE isInvoice
|
||||
|
|
|
@ -26,6 +26,12 @@
|
|||
},
|
||||
"isConciliate": {
|
||||
"type": "date"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"mysql": {
|
||||
"columnName": "invoiceFk"
|
||||
}
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
|
@ -48,11 +54,6 @@
|
|||
"type": "belongsTo",
|
||||
"model": "Bank",
|
||||
"foreignKey": "bankFk"
|
||||
},
|
||||
"invoice": {
|
||||
"type": "belongsTo",
|
||||
"model": "InvoiceOut",
|
||||
"foreignKey": "invoiceFk"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,11 +29,31 @@ class Controller {
|
|||
this.receipt.amountPaid = value;
|
||||
}
|
||||
|
||||
get amountPaid() {
|
||||
return this.receipt.amountPaid;
|
||||
}
|
||||
|
||||
set clientFk(value) {
|
||||
this.receipt.clientFk = value;
|
||||
}
|
||||
|
||||
get clientFk() {
|
||||
return this.receipt.clientFk;
|
||||
}
|
||||
|
||||
set companyFk(value) {
|
||||
this.receipt.companyFk = value;
|
||||
this.getAmountPaid();
|
||||
}
|
||||
|
||||
set description(value) {
|
||||
this.receipt.description = value;
|
||||
}
|
||||
|
||||
get description() {
|
||||
return this.receipt.description;
|
||||
}
|
||||
|
||||
getAmountPaid() {
|
||||
let filter = {
|
||||
where: {
|
||||
|
@ -68,7 +88,7 @@ class Controller {
|
|||
}
|
||||
Controller.$inject = ['$scope', '$state', '$http', 'vnApp', '$translate'];
|
||||
|
||||
ngModule.component('vnClientRiskCreate', {
|
||||
ngModule.component('vnClientBalanceCreate', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
|
@ -76,6 +96,8 @@ ngModule.component('vnClientRiskCreate', {
|
|||
bankFk: '<?',
|
||||
amountPaid: '<?',
|
||||
onResponse: '&?',
|
||||
companyFk: '<?'
|
||||
companyFk: '<?',
|
||||
description: '<?',
|
||||
clientFk: '<?'
|
||||
}
|
||||
});
|
|
@ -9,15 +9,14 @@
|
|||
vn-id="riskModel"
|
||||
url="/client/api/ClientRisks"
|
||||
filter="$ctrl.filter"
|
||||
data="$ctrl.riskTotal">
|
||||
data="$ctrl.clientRisks">
|
||||
</vn-crud-model>
|
||||
<vn-vertical>
|
||||
<vn-card pad-large>
|
||||
<vn-horizontal>
|
||||
<vn-one></vn-one>
|
||||
<vn-one>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<vn-autocomplete vn-one
|
||||
<vn-autocomplete
|
||||
vn-id="company"
|
||||
field="$ctrl.companyFk"
|
||||
on-change="$ctrl.setOrder(value)"
|
||||
|
@ -28,9 +27,9 @@
|
|||
</vn-autocomplete>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<div class="totalBox" ng-if="$ctrl.riskTotal.length">
|
||||
<div class="totalBox" ng-if="$ctrl.clientRisks.length">
|
||||
<h6 translate>Total by company</h6>
|
||||
<vn-auto ng-repeat="riskByCompany in $ctrl.riskTotal">
|
||||
<vn-auto ng-repeat="riskByCompany in $ctrl.clientRisks">
|
||||
<vn-label-value
|
||||
label="{{riskByCompany.company.code}}"
|
||||
value="{{riskByCompany.amount | currency: 'EUR':2}}">
|
||||
|
@ -62,7 +61,7 @@
|
|||
<vn-td>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, balance.userId)">
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, balance.workerFk)">
|
||||
{{::balance.userNickname}}
|
||||
</span>
|
||||
</vn-td>
|
||||
|
@ -89,7 +88,7 @@
|
|||
href="api/InvoiceOuts/{{::balance.id}}/download?access_token={{::$ctrl.accessToken}}">
|
||||
<vn-icon-button
|
||||
icon="cloud_download"
|
||||
title="Download PDF">
|
||||
title="{{'Download PDF' | translate}}">
|
||||
</vn-icon-button>
|
||||
</a>
|
||||
</vn-td>
|
||||
|
@ -111,12 +110,12 @@
|
|||
ng-click="$ctrl.openCreateDialog()">
|
||||
</vn-float-button>
|
||||
|
||||
<vn-client-risk-create vn-id="riskCreateDialog">
|
||||
</vn-client-risk-create>
|
||||
<vn-client-balance-create vn-id="balanceCreateDialog">
|
||||
</vn-client-balance-create>
|
||||
|
||||
<vn-worker-descriptor-popover
|
||||
vn-id="workerDescriptor"
|
||||
user-id="$ctrl.selectedWorker">
|
||||
worker-fk="$ctrl.selectedWorker">
|
||||
</vn-worker-descriptor-popover>
|
||||
|
||||
<vn-invoice-out-descriptor-popover
|
|
@ -46,7 +46,7 @@ class Controller {
|
|||
const params = {filter: this.filter};
|
||||
this.$http.get(`/client/api/ClientRisks`, {params}).then(response => {
|
||||
if (response.data) {
|
||||
this.riskTotal = response.data;
|
||||
this.clientRisks = response.data;
|
||||
|
||||
this.getBalances();
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ class Controller {
|
|||
|
||||
getCurrentBalance() {
|
||||
const selectedCompany = this.$.company.selection;
|
||||
const currentBalance = this.riskTotal.find(balance => {
|
||||
const currentBalance = this.clientRisks.find(balance => {
|
||||
return balance.companyFk === selectedCompany.id;
|
||||
});
|
||||
|
||||
|
@ -80,24 +80,20 @@ class Controller {
|
|||
|
||||
|
||||
openCreateDialog() {
|
||||
this.$.riskCreateDialog.companyFk = this.companyFk;
|
||||
this.$.riskCreateDialog.onResponse = () => {
|
||||
this.$.balanceCreateDialog.companyFk = this.companyFk;
|
||||
this.$.balanceCreateDialog.onResponse = () => {
|
||||
this.refresh();
|
||||
};
|
||||
this.$.riskCreateDialog.show();
|
||||
this.$.balanceCreateDialog.show();
|
||||
}
|
||||
|
||||
onDownload() {
|
||||
alert('Not implemented yet');
|
||||
}
|
||||
|
||||
showWorkerDescriptor(event, userId) {
|
||||
showWorkerDescriptor(event, workerFk) {
|
||||
if (event.defaultPrevented) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
this.selectedWorker = userId;
|
||||
this.selectedWorker = workerFk;
|
||||
this.$.workerDescriptor.parent = event.target;
|
||||
this.$.workerDescriptor.show();
|
||||
}
|
||||
|
@ -117,7 +113,7 @@ class Controller {
|
|||
|
||||
Controller.$inject = ['$stateParams', '$translate', '$scope', 'vnToken', '$http'];
|
||||
|
||||
ngModule.component('vnClientRiskIndex', {
|
||||
ngModule.component('vnClientBalanceIndex', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
});
|
|
@ -1,7 +1,7 @@
|
|||
import './index';
|
||||
|
||||
describe('Client', () => {
|
||||
describe('Component vnClientRiskIndex', () => {
|
||||
describe('Component vnClientBalanceIndex', () => {
|
||||
let $componentController;
|
||||
let $scope;
|
||||
let $httpBackend;
|
||||
|
@ -15,7 +15,7 @@ describe('Client', () => {
|
|||
$httpBackend = _$httpBackend_;
|
||||
$httpParamSerializer = _$httpParamSerializer_;
|
||||
$scope = $rootScope.$new();
|
||||
controller = $componentController('vnClientRiskIndex', {$scope});
|
||||
controller = $componentController('vnClientBalanceIndex', {$scope});
|
||||
}));
|
||||
|
||||
describe('balances() setter', () => {
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
@import "./variables";
|
||||
|
||||
vn-client-balance-index {
|
||||
.totalBox {
|
||||
border: $border-thin-light;
|
||||
text-align: left;
|
||||
float: right
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="Pay method"
|
||||
label="Billing data"
|
||||
vn-acl="salesAssistant"
|
||||
field="$ctrl.client.payMethodFk"
|
||||
url="/client/api/PayMethods"
|
||||
|
|
|
@ -19,8 +19,8 @@ import './credit/index';
|
|||
import './credit/create';
|
||||
import './greuge/index';
|
||||
import './greuge/create';
|
||||
import './risk/index';
|
||||
import './risk/create';
|
||||
import './balance/index';
|
||||
import './balance/create';
|
||||
import './mandate';
|
||||
import './summary';
|
||||
import './recovery/index';
|
||||
|
|
|
@ -34,7 +34,7 @@ Search client by id or name: Buscar clientes por identificador o nombre
|
|||
Clients: Clientes
|
||||
New client: Nuevo cliente
|
||||
Fiscal data: Datos fiscales
|
||||
Pay method: Forma de pago
|
||||
Billing data: Forma de pago
|
||||
Addresses: Consignatarios
|
||||
New address: Nuevo consignatario
|
||||
Edit address: Editar consignatario
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
{"state": "client.card.note.index", "icon": "insert_drive_file"},
|
||||
{"state": "client.card.credit.index", "icon": "credit_card"},
|
||||
{"state": "client.card.greuge.index", "icon": "work"},
|
||||
{"state": "client.card.risk.index", "icon": "icon-invoices"},
|
||||
{"state": "client.card.balance.index", "icon": "icon-invoices"},
|
||||
{"state": "client.card.recovery.index", "icon": "icon-recovery"},
|
||||
{"state": "client.card.log", "icon": "history"},
|
||||
{
|
||||
|
@ -82,7 +82,7 @@
|
|||
"url": "/billing-data",
|
||||
"state": "client.card.billingData",
|
||||
"component": "vn-client-billing-data",
|
||||
"description": "Pay method",
|
||||
"description": "Billing data",
|
||||
"params": {
|
||||
"client": "$ctrl.client"
|
||||
}
|
||||
|
@ -188,22 +188,22 @@
|
|||
"component": "vn-client-mandate",
|
||||
"description": "Mandates"
|
||||
}, {
|
||||
"url": "/risk",
|
||||
"url": "/balance",
|
||||
"abstract": true,
|
||||
"state": "client.card.risk",
|
||||
"state": "client.card.balance",
|
||||
"component": "ui-view"
|
||||
}, {
|
||||
"url": "/index",
|
||||
"state": "client.card.risk.index",
|
||||
"component": "vn-client-risk-index",
|
||||
"state": "client.card.balance.index",
|
||||
"component": "vn-client-balance-index",
|
||||
"description": "Balance",
|
||||
"params": {
|
||||
"client": "$ctrl.client"
|
||||
}
|
||||
}, {
|
||||
"url": "/create?payed&companyFk&bankFk&payedAmount",
|
||||
"state": "client.card.risk.create",
|
||||
"component": "vn-client-risk-create",
|
||||
"state": "client.card.balance.create",
|
||||
"component": "vn-client-balance-create",
|
||||
"description": "New payment",
|
||||
"params": {
|
||||
"client": "$ctrl.client"
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('book', {
|
||||
description: 'Book a invoiceOut',
|
||||
accessType: 'WRITE',
|
||||
accepts: {
|
||||
arg: 'ref',
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'The invoiceOut ref',
|
||||
http: {source: 'path'}
|
||||
},
|
||||
returns: {
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: '/:ref/book',
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.book = async ref => {
|
||||
return Self.rawSql(`CALL vn.invoiceOutAgain(?)`, [ref]);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('delete', {
|
||||
description: 'Delete a invoiceOut',
|
||||
accessType: 'WRITE',
|
||||
accepts: {
|
||||
arg: 'id',
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'The invoiceOut id',
|
||||
http: {source: 'path'}
|
||||
},
|
||||
returns: {
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: '/:id/delete',
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.delete = async id => {
|
||||
const transaction = await Self.beginTransaction({});
|
||||
try {
|
||||
let invoiceOut = await Self.findById(id);
|
||||
let tickets = await Self.app.models.Ticket.find({where: {refFk: invoiceOut.ref}});
|
||||
|
||||
const promises = [];
|
||||
tickets.forEach(ticket => {
|
||||
promises.push(ticket.updateAttribute('refFk', null, {transaction}));
|
||||
});
|
||||
|
||||
return Promise.all(promises).then(async() => {
|
||||
await invoiceOut.destroy({transaction});
|
||||
await transaction.commit();
|
||||
|
||||
return tickets;
|
||||
});
|
||||
} catch (e) {
|
||||
await transaction.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -0,0 +1,128 @@
|
|||
|
||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
const buildFilter = require('vn-loopback/util/filter').buildFilter;
|
||||
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('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'}
|
||||
},
|
||||
{
|
||||
arg: 'search',
|
||||
type: 'String',
|
||||
description: 'Searchs the invoiceOut by id',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'clientFk',
|
||||
type: 'Integer',
|
||||
description: 'The client id',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'hasPdf',
|
||||
type: 'Boolean',
|
||||
description: 'Whether the the invoiceOut has PDF or not',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'amount',
|
||||
type: 'Number',
|
||||
description: 'The amount filter',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'min',
|
||||
type: 'Number',
|
||||
description: 'The minimun amount flter',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'max',
|
||||
type: 'Number',
|
||||
description: 'The maximun amount flter',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'issued',
|
||||
type: 'Date',
|
||||
description: 'The issued date filter',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'created',
|
||||
type: 'Date',
|
||||
description: 'The created date filter',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'dued',
|
||||
type: 'Date',
|
||||
description: 'The due date filter',
|
||||
http: {source: 'query'}
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: ['Object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/filter`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.filter = async(ctx, filter) => {
|
||||
let conn = Self.dataSource.connector;
|
||||
|
||||
let where = buildFilter(ctx.args, (param, value) => {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return {ref: {like: `%${value}%`}};
|
||||
case 'min':
|
||||
return {amount: {gte: value}};
|
||||
case 'max':
|
||||
return {amount: {lte: value}};
|
||||
case 'hasPdf':
|
||||
return {'i.pdf': value};
|
||||
case 'created':
|
||||
return {'i.created': value};
|
||||
case 'amount':
|
||||
case 'clientFk':
|
||||
case 'companyFk':
|
||||
case 'issued':
|
||||
case 'dued':
|
||||
return {[param]: value};
|
||||
}
|
||||
});
|
||||
|
||||
filter = mergeFilters(ctx.args.filter, {where});
|
||||
|
||||
let stmts = [];
|
||||
let stmt;
|
||||
|
||||
stmt = new ParameterizedSQL(
|
||||
`SELECT
|
||||
i.id,
|
||||
i.ref,
|
||||
i.issued,
|
||||
i.amount,
|
||||
i.created,
|
||||
i.dued,
|
||||
i.clientFk,
|
||||
i.pdf AS hasPdf,
|
||||
c.socialName AS clientSocialName,
|
||||
co.code AS companyCode
|
||||
FROM invoiceOut i
|
||||
LEFT JOIN client c ON c.id = i.clientFk
|
||||
LEFT JOIN company co ON co.id = i.companyFk`
|
||||
);
|
||||
|
||||
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,49 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('regenerate', {
|
||||
description: 'Sends an invoice to a regeneration queue',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'The invoiceOut id',
|
||||
http: {source: 'path'}
|
||||
}],
|
||||
returns: {
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: '/:id/regenerate',
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.regenerate = async(ctx, id) => {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const models = Self.app.models;
|
||||
const invoiceReportFk = 30; // FIXME - Should be deprecated
|
||||
const worker = await models.Worker.findOne({where: {userFk: userId}});
|
||||
const transaction = await Self.beginTransaction({});
|
||||
|
||||
try {
|
||||
// Remove all invoice references from tickets
|
||||
const invoiceOut = await models.InvoiceOut.findById(id, {transaction});
|
||||
await invoiceOut.updateAttributes({
|
||||
hasPdf: false
|
||||
});
|
||||
|
||||
// Send to print queue
|
||||
await Self.rawSql(`
|
||||
INSERT INTO vn.printServerQueue (reportFk, param1, workerFk)
|
||||
VALUES (?, ?, ?)`, [invoiceReportFk, id, worker.id], {transaction});
|
||||
|
||||
await transaction.commit();
|
||||
|
||||
return invoiceOut;
|
||||
} catch (e) {
|
||||
await transaction.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('invoiceOut book()', () => {
|
||||
const invoiceOutId = 5;
|
||||
let invoiceOutRef;
|
||||
let OriginalInvoiceOut;
|
||||
let updatedInvoiceOut;
|
||||
afterAll(async done => {
|
||||
updatedInvoiceOut.updateAttributes({booked: OriginalInvoiceOut.booked, hasPdf: OriginalInvoiceOut.hasPdf});
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should check that invoice out booked is untainted', async() => {
|
||||
const invoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
||||
|
||||
expect(invoiceOut.booked).toBeNull();
|
||||
expect(invoiceOut.hasPdf).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should confirm the book property have been updated`, async() => {
|
||||
OriginalInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
||||
invoiceOutRef = OriginalInvoiceOut.ref;
|
||||
|
||||
await app.models.InvoiceOut.book(invoiceOutRef);
|
||||
|
||||
updatedInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
||||
|
||||
expect(updatedInvoiceOut.booked).toEqual(jasmine.any(Object));
|
||||
expect(updatedInvoiceOut.hasPdf).toBeFalsy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('invoiceOut delete()', () => {
|
||||
const invoiceOutId = 2;
|
||||
let OriginalInvoiceOut;
|
||||
let OriginalTickets;
|
||||
afterAll(async done => {
|
||||
const newInvoiceOut = await app.models.InvoiceOut.create(OriginalInvoiceOut);
|
||||
await newInvoiceOut.updateAttribute('ref', OriginalInvoiceOut.ref);
|
||||
|
||||
const promises = [];
|
||||
OriginalTickets.forEach(ticket => {
|
||||
promises.push(ticket.updateAttribute('refFk', newInvoiceOut.ref));
|
||||
});
|
||||
Promise.all(promises);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should check that there is two tickets from the invoice id 2', async() => {
|
||||
const invoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
||||
const tickets = await app.models.Ticket.find({where: {refFk: invoiceOut.ref}});
|
||||
|
||||
expect(tickets.length).toEqual(2);
|
||||
expect(tickets[0].id).toEqual(2);
|
||||
});
|
||||
|
||||
it(`should check the two tickets from the invoice id 2 that are not invoiced`, async() => {
|
||||
OriginalInvoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
||||
await app.models.InvoiceOut.delete(invoiceOutId);
|
||||
OriginalTickets = await app.models.Ticket.find({where: {id: {inq: [2, 3]}}});
|
||||
const invoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
||||
|
||||
expect(OriginalTickets[0].refFk).toBeNull();
|
||||
expect(OriginalTickets[1].refFk).toBeNull();
|
||||
expect(invoiceOut).toBeNull();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,39 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('invoiceOut regenerate()', () => {
|
||||
const invoiceReportFk = 30; // FIXME - Should be deprecated
|
||||
const invoiceOutId = 1;
|
||||
|
||||
afterAll(async done => {
|
||||
const invoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
||||
await invoiceOut.updateAttributes({hasPdf: true});
|
||||
await app.models.InvoiceOut.rawSql(`
|
||||
DELETE FROM vn.printServerQueue
|
||||
WHERE reportFk = ?`, [invoiceReportFk]);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should check that the invoice has a PDF and is not in print generation queue', async() => {
|
||||
const invoiceOut = await app.models.InvoiceOut.findById(invoiceOutId);
|
||||
const [queue] = await app.models.InvoiceOut.rawSql(`
|
||||
SELECT COUNT(*) AS total
|
||||
FROM vn.printServerQueue
|
||||
WHERE reportFk = ?`, [invoiceReportFk]);
|
||||
|
||||
expect(invoiceOut.hasPdf).toBeTruthy();
|
||||
expect(queue.total).toEqual(0);
|
||||
});
|
||||
|
||||
it(`should mark the invoice as doesn't have PDF and add it to a print queue`, async() => {
|
||||
const ctx = {req: {accessToken: {userId: 5}}};
|
||||
const invoiceOut = await app.models.InvoiceOut.regenerate(ctx, invoiceOutId);
|
||||
const [queue] = await app.models.InvoiceOut.rawSql(`
|
||||
SELECT COUNT(*) AS total
|
||||
FROM vn.printServerQueue
|
||||
WHERE reportFk = ?`, [invoiceReportFk]);
|
||||
|
||||
expect(invoiceOut.hasPdf).toBeFalsy();
|
||||
expect(queue.total).toEqual(1);
|
||||
});
|
||||
});
|
|
@ -81,14 +81,11 @@ module.exports = Self => {
|
|||
let ticketTotalsIndex = stmts.push('SELECT * FROM tmp.ticketTotal') - 1;
|
||||
|
||||
stmt = new ParameterizedSQL(`
|
||||
SELECT tc.description as type, SUM(ROUND(s.quantity * s.price * (100 - s.discount) / 100,2)) AS base
|
||||
FROM vn.sale s
|
||||
JOIN vn.ticket t ON t.id = s.ticketFk
|
||||
LEFT JOIN vn.itemTaxCountry itc ON itc.itemFk = s.itemFk
|
||||
JOIN vn.country c ON c.id = itc.countryFK AND c.id = ?
|
||||
LEFT JOIN vn.taxClass tc ON tc.id = itc.taxClassFk
|
||||
WHERE t.refFk = ?
|
||||
GROUP BY type`, [summary.invoiceOut.supplier().countryFk, summary.invoiceOut.ref]);
|
||||
SELECT iot.* , pgc.*, IF(pe.equFk IS NULL, taxableBase, 0) AS Base, pgc.rate / 100 as vatPercent
|
||||
FROM vn.invoiceOutTax iot
|
||||
JOIN vn.pgc ON pgc.code = iot.pgcFk
|
||||
LEFT JOIN vn.pgcEqu pe ON pe.equFk = pgc.code
|
||||
WHERE invoiceOutFk = ?`, [summary.invoiceOut.id]);
|
||||
let invoiceOutTaxesIndex = stmts.push(stmt) - 1;
|
||||
|
||||
stmts.push(
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
module.exports = Self => {
|
||||
require('../methods/invoiceOut/filter')(Self);
|
||||
require('../methods/invoiceOut/summary')(Self);
|
||||
require('../methods/invoiceOut/download')(Self);
|
||||
require('../methods/invoiceOut/regenerate')(Self);
|
||||
require('../methods/invoiceOut/delete')(Self);
|
||||
require('../methods/invoiceOut/book')(Self);
|
||||
};
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
"type": "date"
|
||||
},
|
||||
"hasPdf": {
|
||||
"type": "Number",
|
||||
"type": "Boolean",
|
||||
"mysql": {
|
||||
"columnName": "pdf"
|
||||
}
|
||||
|
|
|
@ -6,6 +6,16 @@
|
|||
<a translate-attr="{title: 'Preview'}" ui-sref="invoiceOut.card.summary({id: $ctrl.invoiceOut.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<vn-icon-menu
|
||||
vn-id="more-button"
|
||||
icon="more_vert"
|
||||
show-filter="false"
|
||||
value-field="callback"
|
||||
translate-fields="['name']"
|
||||
data="$ctrl.moreOptions"
|
||||
on-change="$ctrl.onMoreChange(value)"
|
||||
on-open="$ctrl.onMoreOpen()">
|
||||
</vn-icon-menu>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div class="attributes">
|
||||
|
@ -40,14 +50,16 @@
|
|||
icon="{{::$ctrl.quicklinks.btnTwo.icon}}">
|
||||
</vn-icon>
|
||||
</a>
|
||||
<a ng-if="$ctrl.quicklinks.btnThree"
|
||||
vn-tooltip="{{::$ctrl.quicklinks.btnThree.tooltip}}"
|
||||
ui-sref="{{::$ctrl.quicklinks.btnThree.state}}" target="_blank">
|
||||
<vn-icon
|
||||
class="mdl-button mdl-js-button mdl-button--colored"
|
||||
icon="{{::$ctrl.quicklinks.btnThree.icon}}">
|
||||
</vn-icon>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<vn-confirm
|
||||
vn-id="deleteConfirmation"
|
||||
on-response="$ctrl.deleteInvoiceOut(response)"
|
||||
question="Are you sure you want to delete this invoice?">
|
||||
</vn-confirm>
|
||||
<vn-confirm
|
||||
vn-id="bookConfirmation"
|
||||
on-response="$ctrl.bookInvoiceOut(response)"
|
||||
question="Are you sure you want to book this invoice?">
|
||||
</vn-confirm>
|
|
@ -1,6 +1,34 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class Controller {
|
||||
constructor($scope, vnToken, vnApp, $state, $translate, $http, aclService) {
|
||||
this.$scope = $scope;
|
||||
this.accessToken = vnToken.token;
|
||||
this.vnApp = vnApp;
|
||||
this.$state = $state;
|
||||
this.$translate = $translate;
|
||||
this.$http = $http;
|
||||
this.aclService = aclService;
|
||||
this.moreOptions = [
|
||||
{callback: this.showInvoiceOutPdf, name: 'Show invoice PDF'},
|
||||
{callback: this.showDeleteInvoiceOutDialog, name: 'Delete Invoice', acl: 'invoicing'},
|
||||
{callback: this.showBookInvoiceOutDialog, name: 'Book invoice', acl: 'invoicing'}
|
||||
];
|
||||
}
|
||||
|
||||
onMoreOpen() {
|
||||
let options = this.moreOptions.filter(option => {
|
||||
const hasAclProperty = Object.hasOwnProperty.call(option, 'acl');
|
||||
|
||||
return !hasAclProperty || (hasAclProperty && this.aclService.hasAny([option.acl]));
|
||||
});
|
||||
this.$scope.moreButton.data = options;
|
||||
}
|
||||
|
||||
onMoreChange(callback) {
|
||||
callback.call(this);
|
||||
}
|
||||
|
||||
set invoiceOut(value) {
|
||||
this._invoiceOut = value;
|
||||
|
||||
|
@ -24,6 +52,39 @@ class Controller {
|
|||
return this._invoiceOut;
|
||||
}
|
||||
|
||||
showInvoiceOutPdf() {
|
||||
let url = `api/InvoiceOuts/${this.invoiceOut.id}/download?access_token=${this.accessToken}`;
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
|
||||
showDeleteInvoiceOutDialog() {
|
||||
this.$scope.deleteConfirmation.show();
|
||||
}
|
||||
|
||||
showBookInvoiceOutDialog() {
|
||||
this.$scope.bookConfirmation.show();
|
||||
}
|
||||
|
||||
deleteInvoiceOut(response) {
|
||||
if (response === 'ACCEPT') {
|
||||
const query = `/invoiceOut/api/InvoiceOuts/${this.invoiceOut.id}/delete`;
|
||||
this.$http.post(query).then(() => {
|
||||
this.vnApp.showSuccess(this.$translate.instant('InvoiceOut deleted'));
|
||||
this.$state.go('invoiceOut.index');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bookInvoiceOut(response) {
|
||||
if (response === 'ACCEPT') {
|
||||
const query = `/invoiceOut/api/InvoiceOuts/${this.invoiceOut.ref}/book`;
|
||||
this.$http.post(query).then(() => {
|
||||
this.vnApp.showSuccess(this.$translate.instant('InvoiceOut booked'));
|
||||
this.$state.reload();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
set quicklinks(value = {}) {
|
||||
this._quicklinks = Object.assign(value, this._quicklinks);
|
||||
}
|
||||
|
@ -33,7 +94,7 @@ class Controller {
|
|||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$http', '$state'];
|
||||
Controller.$inject = ['$scope', 'vnToken', 'vnApp', '$state', '$translate', '$http', 'aclService'];
|
||||
|
||||
ngModule.component('vnInvoiceOutDescriptor', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -2,3 +2,10 @@ Volume exceded: Volumen excedido
|
|||
Volume: Volumen
|
||||
Client card: Ficha del cliente
|
||||
Invoice ticket list: Listado de tickets de la factura
|
||||
Show invoice PDF: Ver factura en PDF
|
||||
Delete Invoice: Borrar factura
|
||||
InvoiceOut deleted: Factura eliminada
|
||||
Are you sure you want to delete this invoice?: Estas seguro de eliminar esta factura?
|
||||
Book invoice: Asentar factura
|
||||
InvoiceOut booked: Factura asentada
|
||||
Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura?
|
|
@ -1,20 +1,16 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/api/InvoiceOuts"
|
||||
filter="::$ctrl.filter"
|
||||
url="/api/InvoiceOuts/filter"
|
||||
limit="20"
|
||||
data="invoicesOut"
|
||||
order="issued DESC"
|
||||
auto-load="false">
|
||||
data="invoiceOuts"
|
||||
order="issued DESC">
|
||||
</vn-crud-model>
|
||||
<div class="content-block">
|
||||
<div class="vn-list">
|
||||
<vn-card pad-medium-h>
|
||||
<vn-searchbar
|
||||
panel="vn-invoice-search-panel"
|
||||
model="model"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)"
|
||||
auto-load="true"
|
||||
on-search="$ctrl.onSearch($params)"
|
||||
info="Search invoices by reference"
|
||||
vn-focus>
|
||||
</vn-searchbar>
|
||||
|
@ -36,7 +32,7 @@
|
|||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<a ng-repeat="invoiceOut in invoicesOut"
|
||||
<a ng-repeat="invoiceOut in invoiceOuts"
|
||||
class="clickable vn-tr searchResult"
|
||||
ui-sref="invoiceOut.card.summary({id: {{::invoiceOut.id}}})">
|
||||
<vn-td>{{::invoiceOut.ref | dashIfEmpty}}</vn-td>
|
||||
|
@ -46,11 +42,11 @@
|
|||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showClientDescriptor($event, invoiceOut.clientFk)">
|
||||
{{::invoiceOut.client.name | dashIfEmpty}}
|
||||
{{::invoiceOut.clientSocialName | dashIfEmpty}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>{{::invoiceOut.created | dateTime:'dd/MM/yyyy' | dashIfEmpty}}</vn-td>
|
||||
<vn-td>{{::invoiceOut.company.code | dashIfEmpty}}</vn-td>
|
||||
<vn-td>{{::invoiceOut.companyCode | dashIfEmpty}}</vn-td>
|
||||
<vn-td>{{::invoiceOut.dued | dateTime:'dd/MM/yyyy' | dashIfEmpty}}</vn-td>
|
||||
<vn-td>
|
||||
<vn-icon-button
|
||||
|
|
|
@ -5,42 +5,6 @@ export default class Controller {
|
|||
this.accessToken = vnToken.token;
|
||||
this.$ = $scope;
|
||||
this.selectedInvoiceOut = null;
|
||||
|
||||
this.filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'company',
|
||||
scope: {
|
||||
fields: ['code']
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return {ref: {like: `%${value}%`}};
|
||||
case 'min':
|
||||
return {amount: {gte: value}};
|
||||
case 'max':
|
||||
return {amount: {lte: value}};
|
||||
case 'hasPdf':
|
||||
case 'amount':
|
||||
case 'clientFk':
|
||||
case 'companyFk':
|
||||
case 'issued':
|
||||
case 'created':
|
||||
case 'dued':
|
||||
return {[param]: value};
|
||||
}
|
||||
}
|
||||
|
||||
showClientDescriptor(event, clientFk) {
|
||||
|
@ -68,6 +32,13 @@ export default class Controller {
|
|||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
onSearch(params) {
|
||||
if (params)
|
||||
this.$.model.applyFilter(null, params);
|
||||
else
|
||||
this.$.model.clear();
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', 'vnToken'];
|
||||
|
|
|
@ -14,25 +14,31 @@
|
|||
<vn-label-value label="Booked"
|
||||
value="{{$ctrl.summary.invoiceOut.booked | dateTime: 'dd/MM/yyyy'}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<vn-label-value label="Company"
|
||||
value="{{$ctrl.summary.invoiceOut.company.code | dashIfEmpty}}">
|
||||
</vn-label-value>
|
||||
<vn-icon-button
|
||||
ng-show="$ctrl.summary.invoiceOut.hasPdf"
|
||||
ng-click="$ctrl.openPdf(invoiceOut.id, $event)"
|
||||
icon="cloud_download"
|
||||
title="Download PDF"
|
||||
vn-tooltip="Download PDF">
|
||||
</vn-icon-button>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<vn-label-value ng-repeat="tax in $ctrl.summary.invoiceOut.taxesBreakdown"
|
||||
label="{{tax.type}}"
|
||||
value="{{tax.base | currency: 'EUR': 2}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-two>
|
||||
<h4 translate>Desglose impositivo</h4>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th>Type</vn-th>
|
||||
<vn-th>Taxable base</vn-th>
|
||||
<vn-th>Rate</vn-th>
|
||||
<vn-th>Fee</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="tax in $ctrl.summary.invoiceOut.taxesBreakdown">
|
||||
<vn-td>{{tax.name}}</vn-td>
|
||||
<vn-td>{{tax.taxableBase | currency: 'EUR': 2}}</vn-td>
|
||||
<vn-td>{{tax.rate}}%</vn-td>
|
||||
<vn-td>{{tax.vat | currency: 'EUR': 2}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-two>
|
||||
<vn-auto>
|
||||
<h4 translate>Ticket</h4>
|
||||
<vn-table model="model">
|
||||
|
@ -40,6 +46,7 @@
|
|||
<vn-tr>
|
||||
<vn-th number>Ticket id</vn-th>
|
||||
<vn-th>Alias</vn-th>
|
||||
<vn-th>Shipped</vn-th>
|
||||
<vn-th number>Amount</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
|
@ -59,6 +66,7 @@
|
|||
{{ticket.nickname}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>{{ticket.shipped | dateTime: 'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td number>{{ticket.total | currency: 'EUR': 2}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
|
|
|
@ -18,13 +18,6 @@ class Controller {
|
|||
return this._invoiceOut;
|
||||
}
|
||||
|
||||
openPdf(id, event) {
|
||||
let url = `api/InvoiceOuts/${id}/download?access_token=${this.accessToken}`;
|
||||
window.open(url, '_blank');
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
getSummary() {
|
||||
this.$http.get(`/api/InvoiceOuts/${this.invoiceOut.id}/summary`).then(response => {
|
||||
this.summary = response.data;
|
||||
|
@ -36,7 +29,6 @@ class Controller {
|
|||
this.$.clientDescriptor.parent = event.target;
|
||||
this.$.clientDescriptor.show();
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
showTicketDescriptor(event, ticketFk) {
|
||||
|
@ -44,14 +36,12 @@ class Controller {
|
|||
this.$.ticketDescriptor.parent = event.target;
|
||||
this.$.ticketDescriptor.show();
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
preview(event, invoiceOut) {
|
||||
this.selectedInvoiceOut = invoiceOut;
|
||||
this.$.invoiceOutSummaryDialog.show();
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +1,26 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Route', () => {
|
||||
describe('InvoiceOut', () => {
|
||||
describe('Component summary', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('route'));
|
||||
beforeEach(ngModule('invoiceOut'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnRouteSummary');
|
||||
controller.route = {id: 1};
|
||||
controller = $componentController('vnInvoiceOutSummary');
|
||||
controller.invoiceOut = {id: 1};
|
||||
}));
|
||||
|
||||
describe('getSummary()', () => {
|
||||
it('should perform a query to set summary', () => {
|
||||
$httpBackend.when('GET', `/api/Routes/1/summary`).respond(200, 24);
|
||||
$httpBackend.expect('GET', `/api/Routes/1/summary`);
|
||||
$httpBackend.when('GET', `/api/InvoiceOuts/1/summary`).respond(200, 'the data you are looking for');
|
||||
$httpBackend.expect('GET', `/api/InvoiceOuts/1/summary`);
|
||||
controller.getSummary();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.summary).toEqual(24);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sumPackages()', () => {
|
||||
it('should calculate the packages total', () => {
|
||||
controller.summary = {
|
||||
tickets: [
|
||||
{packages: 3},
|
||||
{packages: 1}
|
||||
]
|
||||
};
|
||||
controller.sumPackages();
|
||||
|
||||
expect(controller.packagesTotal).toEqual(4);
|
||||
expect(controller.summary).toEqual('the data you are looking for');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue