4794-mdb_block #1170

Merged
vicent merged 17 commits from 4794-mdb_block into dev 2022-12-22 09:19:16 +00:00
120 changed files with 33591 additions and 36564 deletions
Showing only changes of commit 1d7145d74b - Show all commits

View File

@ -43,6 +43,9 @@ module.exports = Self => {
if (!recipient) if (!recipient)
throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${userId}`); throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${userId}`);
if (process.env.NODE_ENV == 'test')
message = `[Test:Environment to user ${userId}] ` + message;
await models.Chat.create({ await models.Chat.create({
senderFk: sender.id, senderFk: sender.id,
recipient: `@${recipient.name}`, recipient: `@${recipient.name}`,

View File

@ -19,11 +19,11 @@ describe('getStarredModules()', () => {
}); });
it(`should return the starred modules for a given user`, async() => { it(`should return the starred modules for a given user`, async() => {
const newStarred = await app.models.StarredModule.create({workerFk: 9, moduleFk: 'Clients', position: 1}); const newStarred = await app.models.StarredModule.create({workerFk: 9, moduleFk: 'customer', position: 1});
const starredModules = await app.models.StarredModule.getStarredModules(ctx); const starredModules = await app.models.StarredModule.getStarredModules(ctx);
expect(starredModules.length).toEqual(1); expect(starredModules.length).toEqual(1);
expect(starredModules[0].moduleFk).toEqual('Clients'); expect(starredModules[0].moduleFk).toEqual('customer');
// restores // restores
await app.models.StarredModule.destroyById(newStarred.id); await app.models.StarredModule.destroyById(newStarred.id);

View File

@ -26,29 +26,29 @@ describe('setPosition()', () => {
const filter = { const filter = {
where: { where: {
workerFk: ctx.req.accessToken.userId, workerFk: ctx.req.accessToken.userId,
moduleFk: 'Orders' moduleFk: 'order'
} }
}; };
try { try {
const options = {transaction: tx}; const options = {transaction: tx};
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders', options); await app.models.StarredModule.toggleStarredModule(ctx, 'order', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Clients', options); await app.models.StarredModule.toggleStarredModule(ctx, 'customer', options);
let orders = await app.models.StarredModule.findOne(filter, options); let orders = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Clients'; filter.where.moduleFk = 'customer';
let clients = await app.models.StarredModule.findOne(filter, options); let clients = await app.models.StarredModule.findOne(filter, options);
expect(orders.position).toEqual(1); expect(orders.position).toEqual(1);
expect(clients.position).toEqual(2); expect(clients.position).toEqual(2);
await app.models.StarredModule.setPosition(ctx, 'Clients', 'left', options); await app.models.StarredModule.setPosition(ctx, 'customer', 'left', options);
filter.where.moduleFk = 'Clients'; filter.where.moduleFk = 'customer';
clients = await app.models.StarredModule.findOne(filter, options); clients = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Orders'; filter.where.moduleFk = 'order';
orders = await app.models.StarredModule.findOne(filter, options); orders = await app.models.StarredModule.findOne(filter, options);
expect(clients.position).toEqual(1); expect(clients.position).toEqual(1);
@ -67,29 +67,29 @@ describe('setPosition()', () => {
const filter = { const filter = {
where: { where: {
workerFk: ctx.req.accessToken.userId, workerFk: ctx.req.accessToken.userId,
moduleFk: 'Orders' moduleFk: 'order'
} }
}; };
try { try {
const options = {transaction: tx}; const options = {transaction: tx};
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders', options); await app.models.StarredModule.toggleStarredModule(ctx, 'order', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Clients', options); await app.models.StarredModule.toggleStarredModule(ctx, 'customer', options);
let orders = await app.models.StarredModule.findOne(filter, options); let orders = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Clients'; filter.where.moduleFk = 'customer';
let clients = await app.models.StarredModule.findOne(filter, options); let clients = await app.models.StarredModule.findOne(filter, options);
expect(orders.position).toEqual(1); expect(orders.position).toEqual(1);
expect(clients.position).toEqual(2); expect(clients.position).toEqual(2);
await app.models.StarredModule.setPosition(ctx, 'Orders', 'right', options); await app.models.StarredModule.setPosition(ctx, 'order', 'right', options);
filter.where.moduleFk = 'Orders'; filter.where.moduleFk = 'order';
orders = await app.models.StarredModule.findOne(filter, options); orders = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Clients'; filter.where.moduleFk = 'customer';
clients = await app.models.StarredModule.findOne(filter, options); clients = await app.models.StarredModule.findOne(filter, options);
expect(orders.position).toEqual(2); expect(orders.position).toEqual(2);
@ -108,35 +108,35 @@ describe('setPosition()', () => {
const filter = { const filter = {
where: { where: {
workerFk: ctx.req.accessToken.userId, workerFk: ctx.req.accessToken.userId,
moduleFk: 'Items' moduleFk: 'item'
} }
}; };
try { try {
const options = {transaction: tx}; const options = {transaction: tx};
await app.models.StarredModule.toggleStarredModule(ctx, 'Clients', options); await app.models.StarredModule.toggleStarredModule(ctx, 'customer', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders', options); await app.models.StarredModule.toggleStarredModule(ctx, 'order', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Clients', options); await app.models.StarredModule.toggleStarredModule(ctx, 'customer', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders', options); await app.models.StarredModule.toggleStarredModule(ctx, 'order', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Items', options); await app.models.StarredModule.toggleStarredModule(ctx, 'item', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Claims', options); await app.models.StarredModule.toggleStarredModule(ctx, 'claim', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Clients', options); await app.models.StarredModule.toggleStarredModule(ctx, 'customer', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders', options); await app.models.StarredModule.toggleStarredModule(ctx, 'order', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Zones', options); await app.models.StarredModule.toggleStarredModule(ctx, 'zone', options);
const items = await app.models.StarredModule.findOne(filter, options); const items = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Claims'; filter.where.moduleFk = 'claim';
const claims = await app.models.StarredModule.findOne(filter, options); const claims = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Clients'; filter.where.moduleFk = 'customer';
let clients = await app.models.StarredModule.findOne(filter, options); let clients = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Orders'; filter.where.moduleFk = 'order';
let orders = await app.models.StarredModule.findOne(filter, options); let orders = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Zones'; filter.where.moduleFk = 'zone';
const zones = await app.models.StarredModule.findOne(filter, options); const zones = await app.models.StarredModule.findOne(filter, options);
expect(items.position).toEqual(1); expect(items.position).toEqual(1);
@ -145,12 +145,12 @@ describe('setPosition()', () => {
expect(orders.position).toEqual(4); expect(orders.position).toEqual(4);
expect(zones.position).toEqual(5); expect(zones.position).toEqual(5);
await app.models.StarredModule.setPosition(ctx, 'Clients', 'right', options); await app.models.StarredModule.setPosition(ctx, 'customer', 'right', options);
filter.where.moduleFk = 'Orders'; filter.where.moduleFk = 'order';
orders = await app.models.StarredModule.findOne(filter, options); orders = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Clients'; filter.where.moduleFk = 'customer';
clients = await app.models.StarredModule.findOne(filter, options); clients = await app.models.StarredModule.findOne(filter, options);
expect(orders.position).toEqual(3); expect(orders.position).toEqual(3);
@ -169,31 +169,31 @@ describe('setPosition()', () => {
const filter = { const filter = {
where: { where: {
workerFk: ctx.req.accessToken.userId, workerFk: ctx.req.accessToken.userId,
moduleFk: 'Items' moduleFk: 'item'
} }
}; };
try { try {
const options = {transaction: tx}; const options = {transaction: tx};
await app.models.StarredModule.toggleStarredModule(ctx, 'Items', options); await app.models.StarredModule.toggleStarredModule(ctx, 'item', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Clients', options); await app.models.StarredModule.toggleStarredModule(ctx, 'customer', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Claims', options); await app.models.StarredModule.toggleStarredModule(ctx, 'claim', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders', options); await app.models.StarredModule.toggleStarredModule(ctx, 'order', options);
await app.models.StarredModule.toggleStarredModule(ctx, 'Zones', options); await app.models.StarredModule.toggleStarredModule(ctx, 'zone', options);
const items = await app.models.StarredModule.findOne(filter, options); const items = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Clients'; filter.where.moduleFk = 'customer';
let clients = await app.models.StarredModule.findOne(filter, options); let clients = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Claims'; filter.where.moduleFk = 'claim';
const claims = await app.models.StarredModule.findOne(filter, options); const claims = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Orders'; filter.where.moduleFk = 'order';
let orders = await app.models.StarredModule.findOne(filter, options); let orders = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Zones'; filter.where.moduleFk = 'zone';
const zones = await app.models.StarredModule.findOne(filter, options); const zones = await app.models.StarredModule.findOne(filter, options);
expect(items.position).toEqual(1); expect(items.position).toEqual(1);
@ -202,13 +202,13 @@ describe('setPosition()', () => {
expect(orders.position).toEqual(4); expect(orders.position).toEqual(4);
expect(zones.position).toEqual(5); expect(zones.position).toEqual(5);
await app.models.StarredModule.toggleStarredModule(ctx, 'Claims', options); await app.models.StarredModule.toggleStarredModule(ctx, 'claim', options);
await app.models.StarredModule.setPosition(ctx, 'Clients', 'right', options); await app.models.StarredModule.setPosition(ctx, 'customer', 'right', options);
filter.where.moduleFk = 'Clients'; filter.where.moduleFk = 'customer';
clients = await app.models.StarredModule.findOne(filter, options); clients = await app.models.StarredModule.findOne(filter, options);
filter.where.moduleFk = 'Orders'; filter.where.moduleFk = 'order';
orders = await app.models.StarredModule.findOne(filter, options); orders = await app.models.StarredModule.findOne(filter, options);
expect(orders.position).toEqual(2); expect(orders.position).toEqual(2);

View File

@ -21,15 +21,15 @@ describe('toggleStarredModule()', () => {
}); });
it('should create a new starred module and then remove it by calling the method again with same args', async() => { it('should create a new starred module and then remove it by calling the method again with same args', async() => {
const starredModule = await app.models.StarredModule.toggleStarredModule(ctx, 'Orders'); const starredModule = await app.models.StarredModule.toggleStarredModule(ctx, 'order');
let starredModules = await app.models.StarredModule.getStarredModules(ctx); let starredModules = await app.models.StarredModule.getStarredModules(ctx);
expect(starredModules.length).toEqual(1); expect(starredModules.length).toEqual(1);
expect(starredModule.moduleFk).toEqual('Orders'); expect(starredModule.moduleFk).toEqual('order');
expect(starredModule.workerFk).toEqual(activeCtx.accessToken.userId); expect(starredModule.workerFk).toEqual(activeCtx.accessToken.userId);
expect(starredModule.position).toEqual(starredModules.length); expect(starredModule.position).toEqual(starredModules.length);
await app.models.StarredModule.toggleStarredModule(ctx, 'Orders'); await app.models.StarredModule.toggleStarredModule(ctx, 'order');
starredModules = await app.models.StarredModule.getStarredModules(ctx); starredModules = await app.models.StarredModule.getStarredModules(ctx);
expect(starredModules.length).toEqual(0); expect(starredModules.length).toEqual(0);

View File

@ -12,14 +12,9 @@ BEGIN
* @param vAuthorFk The notification author or %NULL if there is no author * @param vAuthorFk The notification author or %NULL if there is no author
* @return The notification id * @return The notification id
*/ */
DECLARE vNotificationFk INT;
SELECT id INTO vNotificationFk
FROM `notification`
WHERE `name` = vNotificationName;
INSERT INTO notificationQueue INSERT INTO notificationQueue
SET notificationFk = vNotificationFk, SET notificationFk = vNotificationName,
params = vParams, params = vParams,
authorFk = vAuthorFk; authorFk = vAuthorFk;

View File

@ -0,0 +1 @@
ALTER TABLE `vn`.`entry` DROP COLUMN `ref`;

View File

@ -0,0 +1,12 @@
CREATE TABLE `vn`.`invoiceInConfig` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`retentionRate` int(3) NOT NULL,
`retentionName` varchar(25) NOT NULL,
`sageWithholdingFk` smallint(6) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `invoiceInConfig_sageWithholdingFk` FOREIGN KEY (`sageWithholdingFk`) REFERENCES `sage`.`TiposRetencion`(`CodigoRetencion`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
INSERT INTO `vn`.`invoiceInConfig` (`id`, `retentionRate`, `retentionName`, `sageWithholdingFk`)
VALUES
(1, -2, 'Retención 2%', 2);

View File

@ -0,0 +1,46 @@
DROP TRIGGER IF EXISTS `vn`.`supplier_beforeUpdate`;
USE `vn`;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` TRIGGER `vn`.`supplier_beforeUpdate`
BEFORE UPDATE ON `supplier`
FOR EACH ROW
BEGIN
DECLARE vHasChange BOOL;
DECLARE vPayMethodChanged BOOL;
DECLARE vPayMethodHasVerified BOOL;
DECLARE vParams JSON;
DECLARE vOldPayMethodName VARCHAR(20);
DECLARE vNewPayMethodName VARCHAR(20);
SELECT hasVerified INTO vPayMethodHasVerified
FROM payMethod
WHERE id = NEW.payMethodFk;
SET vPayMethodChanged = NOT(NEW.payMethodFk <=> OLD.payMethodFk);
IF vPayMethodChanged THEN
SELECT name INTO vOldPayMethodName
FROM payMethod
WHERE id = OLD.payMethodFk;
SELECT name INTO vNewPayMethodName
FROM payMethod
WHERE id = NEW.payMethodFk;
SET vParams = JSON_OBJECT(
'name', NEW.name,
'oldPayMethod', vOldPayMethodName,
'newPayMethod', vNewPayMethodName
);
SELECT util.notification_send('supplier-pay-method-update', vParams, NULL) INTO @id;
END IF;
SET vHasChange = NOT(NEW.payDemFk <=> OLD.payDemFk AND NEW.payDay <=> OLD.payDay) OR vPayMethodChanged;
IF vHasChange AND vPayMethodHasVerified THEN
SET NEW.isPayMethodChecked = FALSE;
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,73 @@
DROP PROCEDURE IF EXISTS `vn`.`ticket_canbePostponed`;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_canbePostponed`(vOriginDated DATE, vFutureDated DATE, vWarehouseFk INT)
BEGIN
/**
* Devuelve un listado de tickets susceptibles de fusionarse con otros tickets en el futuro
*
* @param vOriginDated Fecha en cuestión
* @param vFutureDated Fecha en el futuro a sondear
* @param vWarehouseFk Identificador de vn.warehouse
*/
DROP TEMPORARY TABLE IF EXISTS tmp.filter;
CREATE TEMPORARY TABLE tmp.filter
(INDEX (id))
SELECT sv.ticketFk id,
sub2.id futureId,
GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt,
CAST(sum(litros) AS DECIMAL(10,0)) liters,
CAST(count(*) AS DECIMAL(10,0)) `lines`,
st.name state,
sub2.iptd futureIpt,
sub2.state futureState,
t.clientFk,
t.warehouseFk,
ts.alertLevel,
t.shipped,
sub2.shipped futureShipped,
t.workerFk,
st.code stateCode,
sub2.code futureStateCode
FROM vn.saleVolume sv
JOIN vn.sale s ON s.id = sv.saleFk
JOIN vn.item i ON i.id = s.itemFk
JOIN vn.ticket t ON t.id = sv.ticketFk
JOIN vn.address a ON a.id = t.addressFk
JOIN vn.province p ON p.id = a.provinceFk
JOIN vn.country c ON c.id = p.countryFk
JOIN vn.ticketState ts ON ts.ticketFk = t.id
JOIN vn.state st ON st.id = ts.stateFk
JOIN vn.alertLevel al ON al.id = ts.alertLevel
LEFT JOIN vn.ticketParking tp ON tp.ticketFk = t.id
LEFT JOIN (
SELECT *
FROM (
SELECT
t.addressFk,
t.id,
t.shipped,
st.name state,
st.code code,
GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) iptd
FROM vn.ticket t
JOIN vn.ticketState ts ON ts.ticketFk = t.id
JOIN vn.state st ON st.id = ts.stateFk
JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk
WHERE t.shipped BETWEEN vFutureDated
AND util.dayend(vFutureDated)
AND t.warehouseFk = vWarehouseFk
GROUP BY t.id
) sub
GROUP BY sub.addressFk
) sub2 ON sub2.addressFk = t.addressFk AND t.id != sub2.id
WHERE t.shipped BETWEEN vOriginDated AND util.dayend(vOriginDated)
AND t.warehouseFk = vWarehouseFk
AND al.code = 'FREE'
AND tp.ticketFk IS NULL
GROUP BY sv.ticketFk
HAVING futureId;
END$$
DELIMITER ;

View File

@ -0,0 +1,60 @@
UPDATE salix.module t
SET t.code = 'supplier'
WHERE t.code LIKE 'Suppliers' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'travel'
WHERE t.code LIKE 'Travels' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'ticket'
WHERE t.code LIKE 'Tickets' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'zone'
WHERE t.code LIKE 'Zones' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'monitor'
WHERE t.code LIKE 'Monitors' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'entry'
WHERE t.code LIKE 'Entries' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'invoiceIn'
WHERE t.code LIKE 'Invoices in' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'customer'
WHERE t.code LIKE 'Clients' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'route'
WHERE t.code LIKE 'Routes' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'item'
WHERE t.code LIKE 'Items' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'claim'
WHERE t.code LIKE 'Claims' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'user'
WHERE t.code LIKE 'Users' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'invoiceOut'
WHERE t.code LIKE 'Invoices out' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'order'
WHERE t.code LIKE 'Orders' ESCAPE '#';
UPDATE salix.module t
SET t.code = 'worker'
WHERE t.code LIKE 'Workers' ESCAPE '#';

View File

@ -0,0 +1,16 @@
UPDATE `vn`.starredModule SET moduleFk = 'customer' WHERE moduleFk = 'Clients';
UPDATE `vn`.starredModule SET moduleFk = 'ticket' WHERE moduleFk = 'Tickets';
UPDATE `vn`.starredModule SET moduleFk = 'route' WHERE moduleFk = 'Routes';
UPDATE `vn`.starredModule SET moduleFk = 'zone' WHERE moduleFk = 'Zones';
UPDATE `vn`.starredModule SET moduleFk = 'order' WHERE moduleFk = 'Orders';
UPDATE `vn`.starredModule SET moduleFk = 'claim' WHERE moduleFk = 'Claims';
UPDATE `vn`.starredModule SET moduleFk = 'item' WHERE moduleFk = 'Items';
UPDATE `vn`.starredModule SET moduleFk = 'worker' WHERE moduleFk = 'Workers';
UPDATE `vn`.starredModule SET moduleFk = 'entry' WHERE moduleFk = 'Entries';
UPDATE `vn`.starredModule SET moduleFk = 'invoiceOut' WHERE moduleFk = 'Invoices out';
UPDATE `vn`.starredModule SET moduleFk = 'invoiceIn' WHERE moduleFk = 'Invoices in';
UPDATE `vn`.starredModule SET moduleFk = 'monitor' WHERE moduleFk = 'Monitors';
UPDATE `vn`.starredModule SET moduleFk = 'user' WHERE moduleFk = 'Users';
UPDATE `vn`.starredModule SET moduleFk = 'supplier' WHERE moduleFk = 'Suppliers';
UPDATE `vn`.starredModule SET moduleFk = 'travel' WHERE moduleFk = 'Travels';
UPDATE `vn`.starredModule SET moduleFk = 'shelving' WHERE moduleFk = 'Shelvings';

File diff suppressed because one or more lines are too long

View File

@ -60,7 +60,7 @@ INSERT INTO `vn`.`educationLevel` (`id`, `name`)
INSERT INTO `vn`.`worker`(`id`,`code`, `firstName`, `lastName`, `userFk`, `bossFk`) INSERT INTO `vn`.`worker`(`id`,`code`, `firstName`, `lastName`, `userFk`, `bossFk`)
SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id, 9 SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id, 9
FROM `vn`.`user`; FROM `account`.`user`;
UPDATE `vn`.`worker` SET bossFk = NULL WHERE id = 20; UPDATE `vn`.`worker` SET bossFk = NULL WHERE id = 20;
UPDATE `vn`.`worker` SET bossFk = 20 WHERE id = 1 OR id = 9; UPDATE `vn`.`worker` SET bossFk = 20 WHERE id = 1 OR id = 9;
@ -105,20 +105,8 @@ INSERT INTO `account`.`mailForward`(`account`, `forwardTo`)
VALUES VALUES
(1, 'employee@domain.local'); (1, 'employee@domain.local');
INSERT INTO `vn`.`printer` (`id`, `name`, `path`, `isLabeler`)
VALUES
(1, 'printer1', 'path1', 0),
(2, 'printer2', 'path2', 1);
INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossFk`, `phone`, `sectorFk`, `labelerFk`)
VALUES
(1106, 'LGN', 'David Charles', 'Haller', 1106, 19, 432978106, NULL, NULL),
(1107, 'ANT', 'Hank' , 'Pym' , 1107, 19, 432978107, NULL, 1),
(1108, 'DCX', 'Charles' , 'Xavier', 1108, 19, 432978108, 1, NULL),
(1109, 'HLK', 'Bruce' , 'Banner', 1109, 19, 432978109, 1, 2),
(1110, 'JJJ', 'Jessica' , 'Jones' , 1110, 19, 432978110, 2, 1);
INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`) INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
VALUES VALUES
(1, 'EUR', 'Euro', 1), (1, 'EUR', 'Euro', 1),
@ -159,6 +147,19 @@ INSERT INTO `vn`.`sector`(`id`, `description`, `warehouseFk`, `isPreviousPrepare
(1, 'First sector', 1, 1, 'FIRST'), (1, 'First sector', 1, 1, 'FIRST'),
(2, 'Second sector', 2, 0, 'SECOND'); (2, 'Second sector', 2, 0, 'SECOND');
INSERT INTO `vn`.`printer` (`id`, `name`, `path`, `isLabeler`, `sectorFk`)
VALUES
(1, 'printer1', 'path1', 0, 1),
(2, 'printer2', 'path2', 1, 1);
INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossFk`, `phone`, `sectorFk`, `labelerFk`)
VALUES
(1106, 'LGN', 'David Charles', 'Haller', 1106, 19, 432978106, NULL, NULL),
(1107, 'ANT', 'Hank' , 'Pym' , 1107, 19, 432978107, NULL, NULL),
(1108, 'DCX', 'Charles' , 'Xavier', 1108, 19, 432978108, 1, NULL),
(1109, 'HLK', 'Bruce' , 'Banner', 1109, 19, 432978109, 1, NULL),
(1110, 'JJJ', 'Jessica' , 'Jones' , 1110, 19, 432978110, 2, NULL);
INSERT INTO `vn`.`parking` (`id`, `column`, `row`, `sectorFk`, `code`, `pickingOrder`) INSERT INTO `vn`.`parking` (`id`, `column`, `row`, `sectorFk`, `code`, `pickingOrder`)
VALUES VALUES
('1', 700, '01', 1, '700-01', 70001), ('1', 700, '01', 1, '700-01', 70001),
@ -216,18 +217,18 @@ INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`)
(3, 'PICKUP', 'Recogida'), (3, 'PICKUP', 'Recogida'),
(4, 'OTHER', 'Otros'); (4, 'OTHER', 'Otros');
INSERT INTO `vn`.`agency`(`id`, `name`, `warehouseFk`, `bankFk__`, `warehouseAliasFk`) INSERT INTO `vn`.`agency`(`id`, `name`, `warehouseFk`, `warehouseAliasFk`)
VALUES VALUES
(1, 'inhouse pickup' , 1, 1, 1), (1, 'inhouse pickup' , 1, 1),
(2, 'Super-Man delivery' , 1, 1, 1), (2, 'Super-Man delivery' , 1, 1),
(3, 'Teleportation device' , 1, 1, 1), (3, 'Teleportation device' , 1, 1),
(4, 'Entanglement' , 1, 1, 1), (4, 'Entanglement' , 1, 1),
(5, 'Quantum break device' , 1, 1, 1), (5, 'Quantum break device' , 1, 1),
(6, 'Walking' , 1, 1, 1), (6, 'Walking' , 1, 1),
(7, 'Gotham247' , 1, 1, 1), (7, 'Gotham247' , 1, 1),
(8, 'Gotham247Expensive' , 1, 1, 1), (8, 'Gotham247Expensive' , 1, 1),
(9, 'Refund' , 1, 1, 1), (9, 'Refund' , 1, 1),
(10, 'Other agency' , 1, 1, 1); (10, 'Other agency' , 1, 1);
UPDATE `vn`.`agencyMode` SET `id` = 1 WHERE `name` = 'inhouse pickup'; UPDATE `vn`.`agencyMode` SET `id` = 1 WHERE `name` = 'inhouse pickup';
UPDATE `vn`.`agencyMode` SET `id` = 2 WHERE `name` = 'Super-Man delivery'; UPDATE `vn`.`agencyMode` SET `id` = 2 WHERE `name` = 'Super-Man delivery';
@ -921,21 +922,21 @@ INSERT INTO `vn`.`expeditionStateType`(`id`, `description`, `code`)
(3, 'Perdida', 'LOST'); (3, 'Perdida', 'LOST');
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `freightItemFk`, `created`, `itemFk__`, `counter`, `workerFk`, `externalId`, `packagingFk`, `stateTypeFk`, `hostFk`) INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `freightItemFk`, `created`, `counter`, `workerFk`, `externalId`, `packagingFk`, `stateTypeFk`, `hostFk`)
VALUES VALUES
(1, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 15, 1, 18, 'UR9000006041', 94, 1, 'pc1'), (1, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, 'UR9000006041', 94, 1, 'pc1'),
(2, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 16, 2, 18, 'UR9000006041', 94, 1, NULL), (2, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 18, 'UR9000006041', 94, 1, NULL),
(3, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), NULL, 3, 18, 'UR9000006041', 94, 2, NULL), (3, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 3, 18, 'UR9000006041', 94, 2, NULL),
(4, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), NULL, 4, 18, 'UR9000006041', 94, 2, NULL), (4, 1, 1, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 4, 18, 'UR9000006041', 94, 2, NULL),
(5, 1, 2, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), NULL, 1, 18, NULL, 94, 3, NULL), (5, 1, 2, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, NULL, 94, 3, NULL),
(6, 7, 3, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), NULL, 1, 18, NULL, 94, 3, NULL), (6, 7, 3, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), 1, 18, NULL, 94, 3, NULL),
(7, 2, 4, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), NULL, 1, 18, NULL, 94, NULL,NULL), (7, 2, 4, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), 1, 18, NULL, 94, NULL,NULL),
(8, 3, 5, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), NULL, 1, 18, NULL, 94, 1, NULL), (8, 3, 5, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), 1, 18, NULL, 94, 1, NULL),
(9, 3, 6, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), NULL, 1, 18, NULL, 94, 2, NULL), (9, 3, 6, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, NULL, 94, 2, NULL),
(10, 7, 7, 71, NOW(), NULL, 1, 18, NULL, 94, 3, NULL), (10, 7, 7, 71, NOW(), 1, 18, NULL, 94, 3, NULL),
(11, 7, 8, 71, NOW(), NULL, 1, 18, NULL, 94, 3, NULL), (11, 7, 8, 71, NOW(), 1, 18, NULL, 94, 3, NULL),
(12, 7, 9, 71, NOW(), NULL, 1, 18, NULL, 94, 3, NULL), (12, 7, 9, 71, NOW(), 1, 18, NULL, 94, 3, NULL),
(13, 1, 10,71, NOW(), NULL, 1, 18, NULL, 94, 3, NULL); (13, 1, 10,71, NOW(), 1, 18, NULL, 94, 3, NULL);
INSERT INTO `vn`.`expeditionState`(`id`, `created`, `expeditionFk`, `typeFk`, `userFk`) INSERT INTO `vn`.`expeditionState`(`id`, `created`, `expeditionFk`, `typeFk`, `userFk`)
@ -1132,11 +1133,11 @@ INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
(32, 36, -92.324), (32, 36, -92.324),
(32, 39, 0.994); (32, 39, 0.994);
INSERT INTO `vn`.`itemShelving` (`itemFk`, `shelvingFk`, `shelve`, `visible`, `grouping`, `packing`, `userFk`) INSERT INTO `vn`.`itemShelving` (`itemFk`, `shelvingFk`, `visible`, `grouping`, `packing`, `userFk`)
VALUES VALUES
(2, 'GVC', 'A', 1, 1, 1, 1106), (2, 'GVC', 1, 1, 1, 1106),
(4, 'HEJ', 'A', 1, 1, 1, 1106), (4, 'HEJ', 1, 1, 1, 1106),
(1, 'UXN', 'A', 2, 12, 12, 1106); (1, 'UXN', 2, 12, 12, 1106);
INSERT INTO `vn`.`itemShelvingSale` (`itemShelvingFk`, `saleFk`, `quantity`, `created`, `userFk`) INSERT INTO `vn`.`itemShelvingSale` (`itemShelvingFk`, `saleFk`, `quantity`, `created`, `userFk`)
VALUES VALUES
@ -1377,16 +1378,16 @@ INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseO
(7, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 4, 1, 50.00, 500, 'seventh travel', 2, 1), (7, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 4, 1, 50.00, 500, 'seventh travel', 2, 1),
(8, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 1, 1, 50.00, 500, 'eight travel', 1, 2); (8, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 1, 1, 50.00, 500, 'eight travel', 1, 2);
INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed`, `companyFk`, `ref`,`isExcludedFromAvailable`, `isRaid`, `notes`, `evaNotes`) INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed`, `companyFk`, `invoiceNumber`, `reference`, `isExcludedFromAvailable`, `isRaid`, `notes`, `evaNotes`)
VALUES VALUES
(1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 1, 442, 'Movement 1', 0, 0, '', ''), (1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 1, 442, 'IN2001', 'Movement 1', 0, 0, '', ''),
(2, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 0, 442, 'Movement 2', 0, 0, 'this is the note two', 'observation two'), (2, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 0, 442, 'IN2002', 'Movement 2', 0, 0, 'this is the note two', 'observation two'),
(3, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 3, 0, 442, 'Movement 3', 0, 0, 'this is the note three', 'observation three'), (3, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 3, 0, 442, 'IN2003', 'Movement 3', 0, 0, 'this is the note three', 'observation three'),
(4, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 0, 69, 'Movement 4', 0, 0, 'this is the note four', 'observation four'), (4, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2, 0, 69, 'IN2004', 'Movement 4', 0, 0, 'this is the note four', 'observation four'),
(5, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 0, 442, 'Movement 5', 0, 0, 'this is the note five', 'observation five'), (5, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 0, 442, 'IN2005', 'Movement 5', 0, 0, 'this is the note five', 'observation five'),
(6, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 6, 0, 442, 'Movement 6', 0, 0, 'this is the note six', 'observation six'), (6, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 6, 0, 442, 'IN2006', 'Movement 6', 0, 0, 'this is the note six', 'observation six'),
(7, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'Movement 7', 0, 0, 'this is the note seven', 'observation seven'), (7, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'IN2007', 'Movement 7', 0, 0, 'this is the note seven', 'observation seven'),
(8, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'Movement 8', 1, 1, '', ''); (8, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'IN2008', 'Movement 8', 1, 1, '', '');
INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `itemFk`, `itemTypeFk`, `saleTotal`, `saleWaste`, `rate`) INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `itemFk`, `itemTypeFk`, `saleTotal`, `saleWaste`, `rate`)
VALUES VALUES
@ -1406,23 +1407,23 @@ INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `itemFk`, `itemTypeF
('HankPym', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Miscellaneous Accessories', 6, 1, '186', '0', '0.0'), ('HankPym', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Miscellaneous Accessories', 6, 1, '186', '0', '0.0'),
('HankPym', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Adhesives', 7, 1, '277', '0', '0.0'); ('HankPym', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 'Adhesives', 7, 1, '277', '0', '0.0');
INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`,`producer`,`printedStickers`,`isChecked`,`isIgnored`,`weight`, `created`) INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`, `printedStickers`,`isChecked`,`isIgnored`,`weight`, `created`)
VALUES VALUES
(1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH)), (1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH)),
(2, 2, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)), (2, 2, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)),
(3, 3, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 0, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 1, util.VN_CURDATE()), (3, 3, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 0, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE()),
(4, 2, 2, 5, 450, 3, 1, 1.000, 1.000, 0.000, 10, 10, 0, NULL, 0.00, 7.30, 7.00, NULL, 0, 1, 0, 2.5, util.VN_CURDATE()), (4, 2, 2, 5, 450, 3, 1, 1.000, 1.000, 0.000, 10, 10, 0, NULL, 0.00, 7.30, 7.00, 0, 1, 0, 2.5, util.VN_CURDATE()),
(5, 3, 3, 55, 500, 5, 1, 1.000, 1.000, 0.000, 1, 1, 0, NULL, 0.00, 78.3, 75.6, NULL, 0, 1, 0, 2.5, util.VN_CURDATE()), (5, 3, 3, 55, 500, 5, 1, 1.000, 1.000, 0.000, 1, 1, 0, NULL, 0.00, 78.3, 75.6, 0, 1, 0, 2.5, util.VN_CURDATE()),
(6, 4, 8, 50, 1000, 4, 1, 1.000, 1.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 2.5, util.VN_CURDATE()), (6, 4, 8, 50, 1000, 4, 1, 1.000, 1.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 2.5, util.VN_CURDATE()),
(7, 4, 9, 20, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 30.50, 29.00, NULL, 0, 1, 0, 2.5, util.VN_CURDATE()), (7, 4, 9, 20, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 30.50, 29.00, 0, 1, 0, 2.5, util.VN_CURDATE()),
(8, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 2.5, util.VN_CURDATE()), (8, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0, 1, 0, 2.5, util.VN_CURDATE()),
(9, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 4, util.VN_CURDATE()), (9, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
(10, 5, 1, 50, 10, 4, 1, 2.500, 2.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 4, util.VN_CURDATE()), (10, 5, 1, 50, 10, 4, 1, 2.500, 2.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 4, util.VN_CURDATE()),
(11, 5, 4, 1.25, 10, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 4, util.VN_CURDATE()), (11, 5, 4, 1.25, 10, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
(12, 6, 4, 1.25, 0, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 4, util.VN_CURDATE()), (12, 6, 4, 1.25, 0, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
(13, 7, 1, 50, 0, 3, 1, 2.000, 2.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 4, util.VN_CURDATE()), (13, 7, 1, 50, 0, 3, 1, 2.000, 2.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0, 1, 0, 4, util.VN_CURDATE()),
(14, 7, 2, 5, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 7.30, 7.00, NULL, 0, 1, 0, 4, util.VN_CURDATE()), (14, 7, 2, 5, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 7.30, 7.00, 0, 1, 0, 4, util.VN_CURDATE()),
(15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 4, util.VN_CURDATE()); (15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE());
INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_id`, `agency_id`, `address_id`, `company_id`, `note`, `source_app`, `confirmed`,`total`, `date_make`, `first_row_stamp`, `confirm_date`) INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_id`, `agency_id`, `address_id`, `company_id`, `note`, `source_app`, `confirmed`,`total`, `date_make`, `first_row_stamp`, `confirm_date`)
VALUES VALUES
@ -1951,30 +1952,34 @@ INSERT INTO `vn`.`workerBusinessType` (`id`, `name`, `isFullTime`, `isPermanent`
(100, 'INDEFINIDO A TIEMPO COMPLETO', 1, 1, 1), (100, 'INDEFINIDO A TIEMPO COMPLETO', 1, 1, 1),
(109, 'CONVERSION DE TEMPORAL EN INDEFINIDO T.COMPLETO', 1, 1, 1); (109, 'CONVERSION DE TEMPORAL EN INDEFINIDO T.COMPLETO', 1, 1, 1);
INSERT INTO `vn`.`businessCategory` (`id`, `description`, `rate`)
VALUES
(1, 'basic employee', 1);
UPDATE `vn`.`business` b UPDATE `vn`.`business` b
SET `rate` = 7, SET `rate` = 7,
`workerBusinessCategoryFk` = 12, `workerBusinessCategoryFk` = 1,
`workerBusinessTypeFk` = 100, `workerBusinessTypeFk` = 100,
`amount` = 900.50 `amount` = 900.50
WHERE b.id = 1; WHERE b.id = 1;
UPDATE `vn`.`business` b UPDATE `vn`.`business` b
SET `rate` = 7, SET `rate` = 7,
`workerBusinessCategoryFk` = 12, `workerBusinessCategoryFk` = 1,
`workerBusinessTypeFk` = 100, `workerBusinessTypeFk` = 100,
`amount` = 1263.03 `amount` = 1263.03
WHERE b.id = 1106; WHERE b.id = 1106;
UPDATE `vn`.`business` b UPDATE `vn`.`business` b
SET `rate` = 7, SET `rate` = 7,
`workerBusinessCategoryFk` = 12, `workerBusinessCategoryFk` = 1,
`workerBusinessTypeFk` = 100, `workerBusinessTypeFk` = 100,
`amount` = 2000 `amount` = 2000
WHERE b.id = 1107; WHERE b.id = 1107;
UPDATE `vn`.`business` b UPDATE `vn`.`business` b
SET `rate` = 7, SET `rate` = 7,
`workerBusinessCategoryFk` = 12, `workerBusinessCategoryFk` = 1,
`workerBusinessTypeFk` = 100, `workerBusinessTypeFk` = 100,
`amount` = 1500 `amount` = 1500
WHERE b.id = 1108; WHERE b.id = 1108;
@ -2684,7 +2689,8 @@ INSERT INTO `util`.`notificationConfig`
INSERT INTO `util`.`notification` (`id`, `name`, `description`) INSERT INTO `util`.`notification` (`id`, `name`, `description`)
VALUES VALUES
(1, 'print-email', 'notification fixture one'); (1, 'print-email', 'notification fixture one'),
(3, 'supplier-pay-method-update', 'A supplier pay method has been updated');
INSERT INTO `util`.`notificationAcl` (`notificationFk`, `roleFk`) INSERT INTO `util`.`notificationAcl` (`notificationFk`, `roleFk`)
VALUES VALUES
@ -2736,3 +2742,13 @@ INSERT INTO `vn`.`mdbApp` (`app`, `baselineBranchFk`, `userFk`, `locked`)
INSERT INTO `vn`.`ticketLog` (`id`, `originFk`, `userFk`, `action`, `changedModel`, `oldInstance`, `newInstance`, `changedModelId`) INSERT INTO `vn`.`ticketLog` (`id`, `originFk`, `userFk`, `action`, `changedModel`, `oldInstance`, `newInstance`, `changedModelId`)
VALUES VALUES
(1, 1, 9, 'insert', 'Ticket', '{}', '{"clientFk":1, "nickname": "Bat cave"}', 1); (1, 1, 9, 'insert', 'Ticket', '{}', '{"clientFk":1, "nickname": "Bat cave"}', 1);
INSERT INTO `salix`.`url` (`appName`, `environment`, `url`)
VALUES
('lilium', 'dev', 'http://localhost:8080/#/'),
('salix', 'dev', 'http://localhost:5000/#!/');
INSERT INTO `vn`.`payDemDetail` (`id`, `detail`)
VALUES
(1, 1);

File diff suppressed because it is too large Load Diff

View File

@ -41,6 +41,7 @@ dump_tables ${TABLES[@]}
TABLES=( TABLES=(
vn vn
agencyTermConfig
alertLevel alertLevel
bookingPlanner bookingPlanner
businessType businessType

View File

@ -6,7 +6,6 @@ SCHEMAS=(
cache cache
edi edi
hedera hedera
nst
pbx pbx
postgresql postgresql
sage sage
@ -104,4 +103,4 @@ mysqldump \
| sed 's/\bLOCALTIME\b/util.VN_NOW/ig' \ | sed 's/\bLOCALTIME\b/util.VN_NOW/ig' \
| sed 's/\bLOCALTIMESTAMP\b/util.VN_NOW/ig' \ | sed 's/\bLOCALTIMESTAMP\b/util.VN_NOW/ig' \
| sed 's/ AUTO_INCREMENT=[0-9]* //g' \ | sed 's/ AUTO_INCREMENT=[0-9]* //g' \
> dump/structure.sql > dump/structure.sql

View File

@ -735,18 +735,16 @@ export default {
}, },
ticketFuture: { ticketFuture: {
openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]', openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
originDated: 'vn-date-picker[label="Origin ETD"]', originDated: 'vn-date-picker[label="Origin date"]',
futureDated: 'vn-date-picker[label="Destination ETD"]', futureDated: 'vn-date-picker[label="Destination date"]',
shipped: 'vn-date-picker[label="Origin date"]',
tfShipped: 'vn-date-picker[label="Destination date"]',
linesMax: 'vn-textfield[label="Max Lines"]', linesMax: 'vn-textfield[label="Max Lines"]',
litersMax: 'vn-textfield[label="Max Liters"]', litersMax: 'vn-textfield[label="Max Liters"]',
ipt: 'vn-autocomplete[label="Origin IPT"]', ipt: 'vn-autocomplete[label="Origin IPT"]',
tfIpt: 'vn-autocomplete[label="Destination IPT"]', futureIpt: 'vn-autocomplete[label="Destination IPT"]',
tableIpt: 'vn-autocomplete[name="ipt"]', tableIpt: 'vn-autocomplete[name="ipt"]',
tableTfIpt: 'vn-autocomplete[name="tfIpt"]', tableFutureIpt: 'vn-autocomplete[name="futureIpt"]',
state: 'vn-autocomplete[label="Origin Grouped State"]', state: 'vn-autocomplete[label="Origin Grouped State"]',
tfState: 'vn-autocomplete[label="Destination Grouped State"]', futureState: 'vn-autocomplete[label="Destination Grouped State"]',
warehouseFk: 'vn-autocomplete[label="Warehouse"]', warehouseFk: 'vn-autocomplete[label="Warehouse"]',
problems: 'vn-check[label="With problems"]', problems: 'vn-check[label="With problems"]',
tableButtonSearch: 'vn-button[vn-tooltip="Search"]', tableButtonSearch: 'vn-button[vn-tooltip="Search"]',
@ -755,9 +753,9 @@ export default {
firstCheck: 'tbody > tr:nth-child(1) > td > vn-check', firstCheck: 'tbody > tr:nth-child(1) > td > vn-check',
multiCheck: 'vn-multi-check', multiCheck: 'vn-multi-check',
tableId: 'vn-textfield[name="id"]', tableId: 'vn-textfield[name="id"]',
tableTfId: 'vn-textfield[name="ticketFuture"]', tableFutureId: 'vn-textfield[name="futureId"]',
tableLiters: 'vn-textfield[name="litersMax"]', tableLiters: 'vn-textfield[name="liters"]',
tableLines: 'vn-textfield[name="linesMax"]', tableLines: 'vn-textfield[name="lines"]',
submit: 'vn-submit[label="Search"]', submit: 'vn-submit[label="Search"]',
table: 'tbody > tr:not(.empty-rows)' table: 'tbody > tr:not(.empty-rows)'
}, },

View File

@ -1,7 +1,8 @@
import selectors from '../../helpers/selectors'; import selectors from '../../helpers/selectors';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
describe('Login path', async() => { // https://redmine.verdnatura.es/issues/4995 fix login
xdescribe('RecoverPassword path', async() => {
let browser; let browser;
let page; let page;

View File

@ -16,9 +16,6 @@ describe('Ticket Future path', () => {
await browser.close(); await browser.close();
}); });
const now = new Date();
const tomorrow = new Date(now.getDate() + 1);
it('should show errors snackbar because of the required data', async() => { it('should show errors snackbar because of the required data', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton); await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.warehouseFk); await page.clearInput(selectors.ticketFuture.warehouseFk);
@ -27,20 +24,6 @@ describe('Ticket Future path', () => {
expect(message.text).toContain('warehouseFk is a required argument'); expect(message.text).toContain('warehouseFk is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.litersMax);
await page.waitToClick(selectors.ticketFuture.submit);
message = await page.waitForSnackbar();
expect(message.text).toContain('litersMax is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.linesMax);
await page.waitToClick(selectors.ticketFuture.submit);
message = await page.waitForSnackbar();
expect(message.text).toContain('linesMax is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton); await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.futureDated); await page.clearInput(selectors.ticketFuture.futureDated);
await page.waitToClick(selectors.ticketFuture.submit); await page.waitToClick(selectors.ticketFuture.submit);
@ -62,44 +45,13 @@ describe('Ticket Future path', () => {
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4); await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
}); });
it('should search with the origin shipped today', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.pickDate(selectors.ticketFuture.shipped, now);
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
it('should search with the origin shipped tomorrow', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.pickDate(selectors.ticketFuture.shipped, tomorrow);
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
});
it('should search with the destination shipped today', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
await page.pickDate(selectors.ticketFuture.tfShipped, now);
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
});
it('should search with the destination shipped tomorrow', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.pickDate(selectors.ticketFuture.tfShipped, tomorrow);
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
});
it('should search with the origin IPT', async() => { it('should search with the origin IPT', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton); await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
await page.clearInput(selectors.ticketFuture.tfShipped);
await page.clearInput(selectors.ticketFuture.ipt); await page.clearInput(selectors.ticketFuture.ipt);
await page.clearInput(selectors.ticketFuture.tfIpt); await page.clearInput(selectors.ticketFuture.futureIpt);
await page.clearInput(selectors.ticketFuture.state); await page.clearInput(selectors.ticketFuture.state);
await page.clearInput(selectors.ticketFuture.tfState); await page.clearInput(selectors.ticketFuture.futureState);
await page.autocompleteSearch(selectors.ticketFuture.ipt, 'Horizontal'); await page.autocompleteSearch(selectors.ticketFuture.ipt, 'Horizontal');
await page.waitToClick(selectors.ticketFuture.submit); await page.waitToClick(selectors.ticketFuture.submit);
@ -109,14 +61,12 @@ describe('Ticket Future path', () => {
it('should search with the destination IPT', async() => { it('should search with the destination IPT', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton); await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
await page.clearInput(selectors.ticketFuture.tfShipped);
await page.clearInput(selectors.ticketFuture.ipt); await page.clearInput(selectors.ticketFuture.ipt);
await page.clearInput(selectors.ticketFuture.tfIpt); await page.clearInput(selectors.ticketFuture.futureIpt);
await page.clearInput(selectors.ticketFuture.state); await page.clearInput(selectors.ticketFuture.state);
await page.clearInput(selectors.ticketFuture.tfState); await page.clearInput(selectors.ticketFuture.futureState);
await page.autocompleteSearch(selectors.ticketFuture.tfIpt, 'Horizontal'); await page.autocompleteSearch(selectors.ticketFuture.futureIpt, 'Horizontal');
await page.waitToClick(selectors.ticketFuture.submit); await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0); await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
}); });
@ -124,12 +74,10 @@ describe('Ticket Future path', () => {
it('should search with the origin grouped state', async() => { it('should search with the origin grouped state', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton); await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
await page.clearInput(selectors.ticketFuture.tfShipped);
await page.clearInput(selectors.ticketFuture.ipt); await page.clearInput(selectors.ticketFuture.ipt);
await page.clearInput(selectors.ticketFuture.tfIpt); await page.clearInput(selectors.ticketFuture.futureIpt);
await page.clearInput(selectors.ticketFuture.state); await page.clearInput(selectors.ticketFuture.state);
await page.clearInput(selectors.ticketFuture.tfState); await page.clearInput(selectors.ticketFuture.futureState);
await page.autocompleteSearch(selectors.ticketFuture.state, 'Free'); await page.autocompleteSearch(selectors.ticketFuture.state, 'Free');
await page.waitToClick(selectors.ticketFuture.submit); await page.waitToClick(selectors.ticketFuture.submit);
@ -139,24 +87,20 @@ describe('Ticket Future path', () => {
it('should search with the destination grouped state', async() => { it('should search with the destination grouped state', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton); await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
await page.clearInput(selectors.ticketFuture.tfShipped);
await page.clearInput(selectors.ticketFuture.ipt); await page.clearInput(selectors.ticketFuture.ipt);
await page.clearInput(selectors.ticketFuture.tfIpt); await page.clearInput(selectors.ticketFuture.futureIpt);
await page.clearInput(selectors.ticketFuture.state); await page.clearInput(selectors.ticketFuture.state);
await page.clearInput(selectors.ticketFuture.tfState); await page.clearInput(selectors.ticketFuture.futureState);
await page.autocompleteSearch(selectors.ticketFuture.tfState, 'Free'); await page.autocompleteSearch(selectors.ticketFuture.futureState, 'Free');
await page.waitToClick(selectors.ticketFuture.submit); await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 0); await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton); await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.shipped);
await page.clearInput(selectors.ticketFuture.tfShipped);
await page.clearInput(selectors.ticketFuture.ipt); await page.clearInput(selectors.ticketFuture.ipt);
await page.clearInput(selectors.ticketFuture.tfIpt); await page.clearInput(selectors.ticketFuture.futureIpt);
await page.clearInput(selectors.ticketFuture.state); await page.clearInput(selectors.ticketFuture.state);
await page.clearInput(selectors.ticketFuture.tfState); await page.clearInput(selectors.ticketFuture.futureState);
await page.waitToClick(selectors.ticketFuture.submit); await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.table, 4); await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
@ -176,7 +120,7 @@ describe('Ticket Future path', () => {
it('should search in smart-table with an ID Destination', async() => { it('should search in smart-table with an ID Destination', async() => {
await page.waitToClick(selectors.ticketFuture.tableButtonSearch); await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
await page.write(selectors.ticketFuture.tableTfId, '12'); await page.write(selectors.ticketFuture.tableFutureId, '12');
await page.keyboard.press('Enter'); await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketFuture.table, 5); await page.waitForNumberOfElements(selectors.ticketFuture.table, 5);
@ -199,7 +143,7 @@ describe('Ticket Future path', () => {
it('should search in smart-table with an IPT Destination', async() => { it('should search in smart-table with an IPT Destination', async() => {
await page.waitToClick(selectors.ticketFuture.tableButtonSearch); await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
await page.autocompleteSearch(selectors.ticketFuture.tableTfIpt, 'Vertical'); await page.autocompleteSearch(selectors.ticketFuture.tableFutureIpt, 'Vertical');
await page.waitForNumberOfElements(selectors.ticketFuture.table, 1); await page.waitForNumberOfElements(selectors.ticketFuture.table, 1);
await page.waitToClick(selectors.ticketFuture.tableButtonSearch); await page.waitToClick(selectors.ticketFuture.tableButtonSearch);

View File

@ -147,7 +147,7 @@ export default class SmartTable extends Component {
for (const column of this.columns) { for (const column of this.columns) {
if (viewConfig.configuration[column.field] == false) { if (viewConfig.configuration[column.field] == false) {
const baseSelector = `smart-table[view-config-id="${this.viewConfigId}"] table`; const baseSelector = `smart-table[view-config-id="${this.viewConfigId}"] table`;
selectors.push(`${baseSelector} thead > tr > th:nth-child(${column.index + 1})`); selectors.push(`${baseSelector} thead > tr:not([second-header]) > th:nth-child(${column.index + 1})`);
selectors.push(`${baseSelector} tbody > tr > td:nth-child(${column.index + 1})`); selectors.push(`${baseSelector} tbody > tr > td:nth-child(${column.index + 1})`);
} }
} }
@ -235,7 +235,7 @@ export default class SmartTable extends Component {
} }
registerColumns() { registerColumns() {
const header = this.element.querySelector('thead > tr'); const header = this.element.querySelector('thead > tr:not([second-header])');
if (!header) return; if (!header) return;
const columns = header.querySelectorAll('th'); const columns = header.querySelectorAll('th');
@ -254,7 +254,7 @@ export default class SmartTable extends Component {
} }
emptyDataRows() { emptyDataRows() {
const header = this.element.querySelector('thead > tr'); const header = this.element.querySelector('thead > tr:not([second-header])');
const columns = header.querySelectorAll('th'); const columns = header.querySelectorAll('th');
const tbody = this.element.querySelector('tbody'); const tbody = this.element.querySelector('tbody');
if (tbody) { if (tbody) {
@ -333,7 +333,7 @@ export default class SmartTable extends Component {
} }
displaySearch() { displaySearch() {
const header = this.element.querySelector('thead > tr'); const header = this.element.querySelector('thead > tr:not([second-header])');
if (!header) return; if (!header) return;
const tbody = this.element.querySelector('tbody'); const tbody = this.element.querySelector('tbody');

View File

@ -8,6 +8,16 @@ smart-table table {
& > thead { & > thead {
border-bottom: $border; border-bottom: $border;
& > tr[second-header] {
& > th
{
text-align: center;
border-bottom-style: groove;
font-weight: bold;
text-transform: uppercase;
}
}
& > * > th { & > * > th {
font-weight: normal; font-weight: normal;
} }
@ -60,6 +70,9 @@ smart-table table {
vertical-align: middle; vertical-align: middle;
} }
} }
&[separator]{
border-left-style: groove;
}
vn-icon.bright, i.bright { vn-icon.bright, i.bright {
color: #f7931e; color: #f7931e;
} }
@ -108,4 +121,4 @@ smart-table table {
font-size: 1.375rem; font-size: 1.375rem;
text-align: center; text-align: center;
} }
} }

View File

@ -29,6 +29,7 @@ export default class Modules {
const module = { const module = {
name: mod.name || mod.module, name: mod.name || mod.module,
code: mod.module,
icon: mod.icon || null, icon: mod.icon || null,
route, route,
keyBind keyBind

View File

@ -1,8 +1,9 @@
<vn-layout <vn-layout
ng-if="$ctrl.showLayout"> ng-if="$ctrl.showLayout">
</vn-layout> </vn-layout>
<vn-out-layout <ui-view
name="login"
ng-if="!$ctrl.showLayout"> ng-if="!$ctrl.showLayout">
</vn-out-layout> </ui-view>
<vn-snackbar vn-id="snackbar"></vn-snackbar> <vn-snackbar vn-id="snackbar"></vn-snackbar>
<vn-debug-info></vn-debug-info> <vn-debug-info></vn-debug-info>

View File

@ -21,7 +21,7 @@ export default class App extends Component {
get showLayout() { get showLayout() {
const state = this.$state.current.name || this.$location.$$path.substring(1).replace('/', '.'); const state = this.$state.current.name || this.$location.$$path.substring(1).replace('/', '.');
const outLayout = ['login', 'recoverPassword', 'resetPassword']; const outLayout = ['login', 'recoverPassword', 'resetPassword', 'reset-password'];
return state && !outLayout.some(ol => ol == state); return state && !outLayout.some(ol => ol == state);
} }

View File

@ -33,7 +33,9 @@ export default class Controller extends Component {
if (!res.data.length) return; if (!res.data.length) return;
for (let starredModule of res.data) { for (let starredModule of res.data) {
const module = this.modules.find(mod => mod.name === starredModule.moduleFk); let moduleName = starredModule.moduleFk;
if (moduleName === 'customer') moduleName = 'client';
const module = this.modules.find(mod => mod.code === moduleName);
if (module) { if (module) {
module.starred = true; module.starred = true;
module.position = starredModule.position; module.position = starredModule.position;
@ -47,8 +49,10 @@ export default class Controller extends Component {
if (event.defaultPrevented) return; if (event.defaultPrevented) return;
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
let moduleName = module.code;
if (moduleName === 'client') moduleName = 'customer';
const params = {moduleName: module.name}; const params = {moduleName};
const query = `starredModules/toggleStarredModule`; const query = `starredModules/toggleStarredModule`;
this.$http.post(query, params).then(res => { this.$http.post(query, params).then(res => {
if (res.data) { if (res.data) {
@ -84,13 +88,16 @@ export default class Controller extends Component {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
const params = {moduleName: module.name, direction: direction}; let moduleName = module.code;
if (moduleName === 'client') moduleName = 'customer';
const params = {moduleName: moduleName, direction: direction};
const query = `starredModules/setPosition`; const query = `starredModules/setPosition`;
this.$http.post(query, params).then(res => { this.$http.post(query, params).then(res => {
if (res.data) { if (res.data) {
module.position = res.data.movingModule.position; module.position = res.data.movingModule.position;
this.modules.forEach(mod => { this.modules.forEach(mod => {
if (mod.name == res.data.pushedModule.moduleFk) if (mod.code == res.data.pushedModule.moduleFk)
mod.position = res.data.pushedModule.position; mod.position = res.data.pushedModule.position;
}); });
this.vnApp.showSuccess(this.$t('Data saved!')); this.vnApp.showSuccess(this.$t('Data saved!'));

View File

@ -19,7 +19,7 @@ describe('Salix Component vnHome', () => {
describe('getStarredModules()', () => { describe('getStarredModules()', () => {
it('should not set any of the modules as starred if there are no starred modules for the user', () => { it('should not set any of the modules as starred if there are no starred modules for the user', () => {
const expectedResponse = []; const expectedResponse = [];
controller._modules = [{module: 'client', name: 'Clients'}]; controller._modules = [{code: 'client', name: 'Clients'}];
$httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond(expectedResponse); $httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond(expectedResponse);
$httpBackend.expectGET('starredModules/getStarredModules').respond(expectedResponse); $httpBackend.expectGET('starredModules/getStarredModules').respond(expectedResponse);
@ -31,8 +31,8 @@ describe('Salix Component vnHome', () => {
}); });
it('should set the example module as starred since its the starred module for the user', () => { it('should set the example module as starred since its the starred module for the user', () => {
const expectedResponse = [{id: 1, moduleFk: 'Clients', workerFk: 9}]; const expectedResponse = [{id: 1, moduleFk: 'customer', workerFk: 9}];
controller._modules = [{module: 'client', name: 'Clients'}]; controller._modules = [{code: 'client', name: 'Clients'}];
$httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond(expectedResponse); $httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond(expectedResponse);
$httpBackend.expectGET('starredModules/getStarredModules').respond(expectedResponse); $httpBackend.expectGET('starredModules/getStarredModules').respond(expectedResponse);
@ -48,7 +48,7 @@ describe('Salix Component vnHome', () => {
it(`should set the received module as starred if it wasn't starred`, () => { it(`should set the received module as starred if it wasn't starred`, () => {
const expectedResponse = [{id: 1, moduleFk: 'Clients', workerFk: 9}]; const expectedResponse = [{id: 1, moduleFk: 'Clients', workerFk: 9}];
const event = new Event('target'); const event = new Event('target');
controller._modules = [{module: 'client', name: 'Clients'}]; controller._modules = [{code: 'client', name: 'Clients'}];
$httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond(expectedResponse); $httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond(expectedResponse);
$httpBackend.expectPOST('starredModules/toggleStarredModule').respond(expectedResponse); $httpBackend.expectPOST('starredModules/toggleStarredModule').respond(expectedResponse);
@ -61,7 +61,7 @@ describe('Salix Component vnHome', () => {
it('should set the received module as regular if it was starred', () => { it('should set the received module as regular if it was starred', () => {
const event = new Event('target'); const event = new Event('target');
controller._modules = [{module: 'client', name: 'Clients', starred: true}]; controller._modules = [{code: 'client', name: 'Clients', starred: true}];
$httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond([]); $httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond([]);
$httpBackend.expectPOST('starredModules/toggleStarredModule').respond(undefined); $httpBackend.expectPOST('starredModules/toggleStarredModule').respond(undefined);
@ -76,18 +76,18 @@ describe('Salix Component vnHome', () => {
describe('moveModule()', () => { describe('moveModule()', () => {
it('should perform a query to setPosition and the apply the position to the moved and pushed modules', () => { it('should perform a query to setPosition and the apply the position to the moved and pushed modules', () => {
const starredModules = [ const starredModules = [
{id: 1, moduleFk: 'Clients', workerFk: 9}, {id: 1, moduleFk: 'customer', workerFk: 9},
{id: 2, moduleFk: 'Orders', workerFk: 9} {id: 2, moduleFk: 'order', workerFk: 9}
]; ];
const movedModules = { const movedModules = {
movingModule: {position: 2, moduleFk: 'Clients'}, movingModule: {position: 2, moduleFk: 'customer'},
pushedModule: {position: 1, moduleFk: 'Orders'} pushedModule: {position: 1, moduleFk: 'order'}
}; };
const event = new Event('target'); const event = new Event('target');
controller._modules = [ controller._modules = [
{module: 'client', name: 'Clients', position: 1}, {code: 'client', name: 'Clients', position: 1},
{module: 'orders', name: 'Orders', position: 2} {code: 'order', name: 'Orders', position: 2}
]; ];
$httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond(starredModules); $httpBackend.whenRoute('GET', 'starredModules/getStarredModules').respond(starredModules);

View File

@ -19,3 +19,4 @@ import './user-popover';
import './upload-photo'; import './upload-photo';
import './bank-entity'; import './bank-entity';
import './log'; import './log';
import './sendSms';

View File

@ -1,27 +1,32 @@
<vn-textfield <div class="box">
label="User" <img src="./logo.svg"/>
ng-model="$ctrl.user" <form name="form" ng-submit="$ctrl.submit()">
vn-id="userField" <vn-textfield
vn-focus> label="User"
</vn-textfield> ng-model="$ctrl.user"
<vn-textfield vn-id="userField"
label="Password" vn-focus>
ng-model="$ctrl.password" </vn-textfield>
type="password"> <vn-textfield
</vn-textfield> label="Password"
<vn-check ng-model="$ctrl.password"
label="Do not close session" type="password">
ng-model="$ctrl.remember" </vn-textfield>
name="remember"> <vn-check
</vn-check> label="Do not close session"
<div class="footer"> ng-model="$ctrl.remember"
<vn-submit label="Enter" ng-click="$ctrl.submit()"></vn-submit> name="remember">
<div class="spinner-wrapper"> </vn-check>
<vn-spinner enable="$ctrl.loading"></vn-spinner> <div class="footer">
</div> <vn-submit label="Enter" ng-click="$ctrl.submit()"></vn-submit>
<div class="vn-pt-lg"> <div class="spinner-wrapper">
<a ui-sref="recoverPassword" translate> <vn-spinner enable="$ctrl.loading"></vn-spinner>
I do not remember my password </div>
</a> <!--<div class="vn-pt-lg">
</div> <a ui-sref="recoverPassword" translate>
I do not remember my password
</a>
</div>-->
</div>
</form>
</div> </div>

View File

@ -25,7 +25,7 @@ vn-recover-password{
} }
} }
vn-out-layout{ vn-login{
position: absolute; position: absolute;
height: 100%; height: 100%;
width: 100%; width: 100%;

View File

@ -1,19 +1,26 @@
import ngModule from '../module'; import ngModule from '../../module';
import Component from 'core/lib/component';
import './style.scss'; import './style.scss';
import Dialog from '../../../core/components/dialog';
export default class sendSmsDialog extends Dialog {
constructor($element, $scope, $http, $translate, vnApp) {
super($element, $scope, $http, $translate, vnApp);
new CustomEvent('openSmsDialog', {
detail: {
this: this
}
});
}
class Controller extends Component {
open() { open() {
this.$.SMSDialog.show(); this.$.SMSDialog.show();
} }
charactersRemaining() { charactersRemaining() {
const element = this.$.message; const element = this.sms.message;
const value = element.input.value;
const maxLength = 160; const maxLength = 160;
const textAreaLength = new Blob([value]).size; return maxLength - element.length;
return maxLength - textAreaLength;
} }
onResponse() { onResponse() {
@ -25,23 +32,19 @@ class Controller extends Component {
if (this.charactersRemaining() < 0) if (this.charactersRemaining() < 0)
throw new Error(`The message it's too long`); throw new Error(`The message it's too long`);
this.$http.post(`Tickets/${this.sms.ticketId}/sendSms`, this.sms).then(res => { return this.onSend({$sms: this.sms});
this.vnApp.showMessage(this.$t('SMS sent!'));
if (res.data) this.emit('send', {response: res.data});
});
} catch (e) { } catch (e) {
this.vnApp.showError(this.$t(e.message)); this.vnApp.showError(this.$t(e.message));
return false; return false;
} }
return true;
} }
} }
ngModule.vnComponent('vnTicketSms', { ngModule.vnComponent('vnSmsDialog', {
template: require('./index.html'), template: require('./index.html'),
controller: Controller, controller: sendSmsDialog,
bindings: { bindings: {
sms: '<', sms: '<',
onSend: '&',
} }
}); });

View File

@ -9,7 +9,9 @@ function config($stateProvider, $urlRouterProvider) {
.state('login', { .state('login', {
url: '/login?continue', url: '/login?continue',
description: 'Login', description: 'Login',
template: '<vn-login></vn-login>' views: {
'login': {template: '<vn-login></vn-login>'},
}
}) })
.state('recoverPassword', { .state('recoverPassword', {
url: '/recover-password', url: '/recover-password',

View File

@ -66,9 +66,9 @@
"MESSAGE_INSURANCE_CHANGE": "I have changed the insurence credit of client [{{clientName}} ({{clientId}})]({{{url}}}) to *{{credit}} €*", "MESSAGE_INSURANCE_CHANGE": "I have changed the insurence credit of client [{{clientName}} ({{clientId}})]({{{url}}}) to *{{credit}} €*",
"Changed client paymethod": "I have changed the pay method for client [{{clientName}} ({{clientId}})]({{{url}}})", "Changed client paymethod": "I have changed the pay method for client [{{clientName}} ({{clientId}})]({{{url}}})",
"Sent units from ticket": "I sent *{{quantity}}* units of [{{concept}} ({{itemId}})]({{{itemUrl}}}) to *\"{{nickname}}\"* coming from ticket id [{{ticketId}}]({{{ticketUrl}}})", "Sent units from ticket": "I sent *{{quantity}}* units of [{{concept}} ({{itemId}})]({{{itemUrl}}}) to *\"{{nickname}}\"* coming from ticket id [{{ticketId}}]({{{ticketUrl}}})",
"Claim will be picked": "The product from the claim [({{claimId}})]({{{claimUrl}}}) from the client *{{clientName}}* will be picked", "Claim will be picked": "The product from the claim [{{claimId}}]({{{claimUrl}}}) from the client *{{clientName}}* will be picked",
"Claim state has changed to incomplete": "The state of the claim [({{claimId}})]({{{claimUrl}}}) from client *{{clientName}}* has changed to *incomplete*", "Claim state has changed to incomplete": "The state of the claim [{{claimId}}]({{{claimUrl}}}) from client *{{clientName}}* has changed to *incomplete*",
"Claim state has changed to canceled": "The state of the claim [({{claimId}})]({{{claimUrl}}}) from client *{{clientName}}* has changed to *canceled*", "Claim state has changed to canceled": "The state of the claim [{{claimId}}]({{{claimUrl}}}) from client *{{clientName}}* has changed to *canceled*",
"Customs agent is required for a non UEE member": "Customs agent is required for a non UEE member", "Customs agent is required for a non UEE member": "Customs agent is required for a non UEE member",
"Incoterms is required for a non UEE member": "Incoterms is required for a non UEE member", "Incoterms is required for a non UEE member": "Incoterms is required for a non UEE member",
"Client checked as validated despite of duplication": "Client checked as validated despite of duplication from client id {{clientId}}", "Client checked as validated despite of duplication": "Client checked as validated despite of duplication from client id {{clientId}}",
@ -136,11 +136,11 @@
"Password does not meet requirements": "Password does not meet requirements", "Password does not meet requirements": "Password does not meet requirements",
"You don't have privileges to change the zone": "You don't have privileges to change the zone or for these parameters there are more than one shipping options, talk to agencies", "You don't have privileges to change the zone": "You don't have privileges to change the zone or for these parameters there are more than one shipping options, talk to agencies",
"Not enough privileges to edit a client": "Not enough privileges to edit a client", "Not enough privileges to edit a client": "Not enough privileges to edit a client",
"Claim pickup order sent": "Claim pickup order sent [({{claimId}})]({{{claimUrl}}}) to client *{{clientName}}*", "Claim pickup order sent": "Claim pickup order sent [{{claimId}}]({{{claimUrl}}}) to client *{{clientName}}*",
"You don't have grant privilege": "You don't have grant privilege", "You don't have grant privilege": "You don't have grant privilege",
"You don't own the role and you can't assign it to another user": "You don't own the role and you can't assign it to another user", "You don't own the role and you can't assign it to another user": "You don't own the role and you can't assign it to another user",
"Email verify": "Email verify", "Email verify": "Email verify",
"Ticket merged": "Ticket [{{id}}]({{{fullPath}}}) ({{{originDated}}}) merged with [{{tfId}}]({{{fullPathFuture}}}) ({{{futureDated}}})", "Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) merged with [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})",
"Sale(s) blocked, please contact production": "Sale(s) blocked, please contact production", "Sale(s) blocked, please contact production": "Sale(s) blocked, please contact production",
"App locked": "App locked by user {{userId}}", "App locked": "App locked by user {{userId}}",
"Receipt's bank was not found": "Receipt's bank was not found", "Receipt's bank was not found": "Receipt's bank was not found",

View File

@ -134,9 +134,9 @@
"MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*", "MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*",
"Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})", "Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})",
"Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})", "Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})",
"Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*", "Claim will be picked": "Se recogerá el género de la reclamación [{{claimId}}]({{{claimUrl}}}) del cliente *{{clientName}}*",
"Claim state has changed to incomplete": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *incompleta*", "Claim state has changed to incomplete": "Se ha cambiado el estado de la reclamación [{{claimId}}]({{{claimUrl}}}) del cliente *{{clientName}}* a *incompleta*",
"Claim state has changed to canceled": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *anulado*", "Claim state has changed to canceled": "Se ha cambiado el estado de la reclamación [{{claimId}}]({{{claimUrl}}}) del cliente *{{clientName}}* a *anulado*",
"Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}", "Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}",
"ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto", "ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto",
"Distance must be lesser than 1000": "La distancia debe ser inferior a 1000", "Distance must be lesser than 1000": "La distancia debe ser inferior a 1000",
@ -238,10 +238,10 @@
"Modifiable password only via recovery or by an administrator": "Contraseña modificable solo a través de la recuperación o por un administrador", "Modifiable password only via recovery or by an administrator": "Contraseña modificable solo a través de la recuperación o por un administrador",
"Not enough privileges to edit a client": "No tienes suficientes privilegios para editar un cliente", "Not enough privileges to edit a client": "No tienes suficientes privilegios para editar un cliente",
"This route does not exists": "Esta ruta no existe", "This route does not exists": "Esta ruta no existe",
"Claim pickup order sent": "Reclamación Orden de recogida enviada [({{claimId}})]({{{claimUrl}}}) al cliente *{{clientName}}*", "Claim pickup order sent": "Reclamación Orden de recogida enviada [{{claimId}}]({{{claimUrl}}}) al cliente *{{clientName}}*",
"You don't have grant privilege": "No tienes privilegios para dar privilegios", "You don't have grant privilege": "No tienes privilegios para dar privilegios",
"You don't own the role and you can't assign it to another user": "No eres el propietario del rol y no puedes asignarlo a otro usuario", "You don't own the role and you can't assign it to another user": "No eres el propietario del rol y no puedes asignarlo a otro usuario",
"Ticket merged": "Ticket [{{id}}]({{{fullPath}}}) ({{{originDated}}}) fusionado con [{{tfId}}]({{{fullPathFuture}}}) ({{{futureDated}}})", "Ticket merged": "Ticket [{{originId}}]({{{originFullPath}}}) ({{{originDated}}}) fusionado con [{{destinationId}}]({{{destinationFullPath}}}) ({{{destinationDated}}})",
"Already has this status": "Ya tiene este estado", "Already has this status": "Ya tiene este estado",
"There aren't records for this week": "No existen registros para esta semana", "There aren't records for this week": "No existen registros para esta semana",
"Empty data source": "Origen de datos vacio", "Empty data source": "Origen de datos vacio",

View File

@ -15,7 +15,7 @@
"legacyUtcDateProcessing": false, "legacyUtcDateProcessing": false,
"timezone": "local", "timezone": "local",
"connectTimeout": 40000, "connectTimeout": 40000,
"acquireTimeout": 20000, "acquireTimeout": 60000,
"waitForConnections": true "waitForConnections": true
}, },
"osticket": { "osticket": {

View File

@ -113,10 +113,11 @@
</div> </div>
</slot-body> </slot-body>
</vn-descriptor-content> </vn-descriptor-content>
<vn-client-sms <vn-sms-dialog
vn-id="sms" vn-id="sms"
on-send="$ctrl.onSmsSend($sms)"
sms="$ctrl.newSMS"> sms="$ctrl.newSMS">
</vn-client-sms> </vn-sms-dialog>
<vn-worker-descriptor-popover <vn-worker-descriptor-popover
vn-id="workerDescriptor"> vn-id="workerDescriptor">
</vn-worker-descriptor-popover> </vn-worker-descriptor-popover>

View File

@ -39,6 +39,11 @@ class Controller extends Descriptor {
}; };
this.$.sms.open(); this.$.sms.open();
} }
onSmsSend(sms) {
return this.$http.post(`Clients/${this.id}/sendSms`, sms)
.then(() => this.vnApp.showSuccess(this.$t('SMS sent')));
}
} }
ngModule.vnComponent('vnClientDescriptor', { ngModule.vnComponent('vnClientDescriptor', {

View File

@ -35,7 +35,6 @@ import './sample/index';
import './sample/create'; import './sample/create';
import './web-payment'; import './web-payment';
import './log'; import './log';
import './sms';
import './postcode'; import './postcode';
import './postcode/province'; import './postcode/province';
import './postcode/city'; import './postcode/city';

View File

@ -1,49 +0,0 @@
import ngModule from '../module';
import Section from 'salix/components/section';
import './style.scss';
class Controller extends Section {
open() {
this.$.SMSDialog.show();
}
charactersRemaining() {
const element = this.$.message;
const value = element.input.value;
const maxLength = 160;
const textAreaLength = new Blob([value]).size;
return maxLength - textAreaLength;
}
onResponse() {
try {
if (!this.sms.destination)
throw new Error(`The destination can't be empty`);
if (!this.sms.message)
throw new Error(`The message can't be empty`);
if (this.charactersRemaining() < 0)
throw new Error(`The message it's too long`);
this.$http.post(`Clients/${this.$params.id}/sendSms`, this.sms).then(res => {
this.vnApp.showMessage(this.$t('SMS sent!'));
if (res.data) this.emit('send', {response: res.data});
});
} catch (e) {
this.vnApp.showError(this.$t(e.message));
return false;
}
return true;
}
}
Controller.$inject = ['$element', '$scope', '$http', '$translate', 'vnApp'];
ngModule.vnComponent('vnClientSms', {
template: require('./index.html'),
controller: Controller,
bindings: {
sms: '<',
}
});

View File

@ -1,74 +0,0 @@
import './index';
describe('Client', () => {
describe('Component vnClientSms', () => {
let controller;
let $httpBackend;
let $element;
beforeEach(ngModule('client'));
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
$httpBackend = _$httpBackend_;
let $scope = $rootScope.$new();
$element = angular.element('<vn-dialog></vn-dialog>');
controller = $componentController('vnClientSms', {$element, $scope});
controller.client = {id: 1101};
controller.$params = {id: 1101};
controller.$.message = {
input: {
value: 'My SMS'
}
};
}));
describe('onResponse()', () => {
it('should perform a POST query and show a success snackbar', () => {
let params = {destinationFk: 1101, destination: 111111111, message: 'My SMS'};
controller.sms = {destinationFk: 1101, destination: 111111111, message: 'My SMS'};
jest.spyOn(controller.vnApp, 'showMessage');
$httpBackend.expect('POST', `Clients/1101/sendSms`, params).respond(200, params);
controller.onResponse();
$httpBackend.flush();
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('SMS sent!');
});
it('should call onResponse without the destination and show an error snackbar', () => {
controller.sms = {destinationFk: 1101, message: 'My SMS'};
jest.spyOn(controller.vnApp, 'showError');
controller.onResponse('accept');
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The destination can't be empty`);
});
it('should call onResponse without the message and show an error snackbar', () => {
controller.sms = {destinationFk: 1101, destination: 222222222};
jest.spyOn(controller.vnApp, 'showError');
controller.onResponse('accept');
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The message can't be empty`);
});
});
describe('charactersRemaining()', () => {
it('should return the characters remaining in a element', () => {
controller.$.message = {
input: {
value: 'My message 0€'
}
};
let result = controller.charactersRemaining();
expect(result).toEqual(145);
});
});
});
});

View File

@ -154,8 +154,8 @@ module.exports = Self => {
e.id, e.id,
e.supplierFk, e.supplierFk,
e.dated, e.dated,
e.ref reference, e.reference,
e.ref invoiceNumber, e.invoiceNumber,
e.isBooked, e.isBooked,
e.isExcludedFromAvailable, e.isExcludedFromAvailable,
e.notes, e.notes,

View File

@ -19,16 +19,10 @@
"type": "date" "type": "date"
}, },
"reference": { "reference": {
"type": "string", "type": "string"
"mysql": {
"columnName": "ref"
}
}, },
"invoiceNumber": { "invoiceNumber": {
"type": "string", "type": "string"
"mysql": {
"columnName": "ref"
}
}, },
"isBooked": { "isBooked": {
"type": "boolean" "type": "boolean"

View File

@ -2,7 +2,7 @@
"InvoiceIn": { "InvoiceIn": {
"dataSource": "vn" "dataSource": "vn"
}, },
"InvoiceInTax": { "InvoiceInConfig": {
"dataSource": "vn" "dataSource": "vn"
}, },
"InvoiceInDueDay": { "InvoiceInDueDay": {
@ -13,5 +13,8 @@
}, },
"InvoiceInLog": { "InvoiceInLog": {
"dataSource": "vn" "dataSource": "vn"
},
"InvoiceInTax": {
"dataSource": "vn"
} }
} }

View File

@ -0,0 +1,35 @@
{
"name": "InvoiceInConfig",
"base": "VnModel",
"options": {
"mysql": {
"table": "invoiceInConfig"
}
},
"properties": {
"id": {
"id": true,
"type": "number",
"description": "Identifier"
},
"retentionRate": {
"type": "number"
},
"retentionName": {
"type": "string"
}
},
"relations": {
"sageWithholding": {
"type": "belongsTo",
"model": "SageWithholding",
"foreignKey": "sageWithholdingFk"
}
},
"acls": [{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
}]
}

View File

@ -1,3 +1,10 @@
<vn-crud-model
url="InvoiceInConfigs"
data="$ctrl.config"
filter="{fields: ['sageWithholdingFk']}"
id-value="1"
auto-load="true">
</vn-crud-model>
<vn-descriptor-content <vn-descriptor-content
module="invoiceIn" module="invoiceIn"
description="$ctrl.invoiceIn.supplierRef" description="$ctrl.invoiceIn.supplierRef"
@ -26,13 +33,13 @@
Clone Invoice Clone Invoice
</vn-item> </vn-item>
<vn-item <vn-item
ng-if="false" ng-if="$ctrl.isAgricultural()"
ng-click="$ctrl.showPdfInvoice()" ng-click="$ctrl.showPdfInvoice()"
translate> translate>
Show agricultural invoice as PDF Show agricultural invoice as PDF
</vn-item> </vn-item>
<vn-item <vn-item
ng-if="false" ng-if="$ctrl.isAgricultural()"
ng-click="sendPdfConfirmation.show({email: $ctrl.entity.supplierContact[0].email})" ng-click="sendPdfConfirmation.show({email: $ctrl.entity.supplierContact[0].email})"
translate> translate>
Send agricultural invoice as PDF Send agricultural invoice as PDF

View File

@ -110,6 +110,10 @@ class Controller extends Descriptor {
recipientId: this.entity.supplier.id recipientId: this.entity.supplier.id
}); });
} }
isAgricultural() {
return this.invoiceIn.supplier.sageWithholdingFk == this.config[0].sageWithholdingFk;
}
} }
ngModule.vnComponent('vnInvoiceInDescriptor', { ngModule.vnComponent('vnInvoiceInDescriptor', {

View File

@ -13,6 +13,7 @@ describe('InvoiceOut downloadZip()', () => {
}; };
it('should return part of link to dowloand the zip', async() => { it('should return part of link to dowloand the zip', async() => {
pending('https://redmine.verdnatura.es/issues/4875');
const tx = await models.InvoiceOut.beginTransaction({}); const tx = await models.InvoiceOut.beginTransaction({});
try { try {
@ -30,7 +31,6 @@ describe('InvoiceOut downloadZip()', () => {
}); });
it('should return an error if the size of the files is too large', async() => { it('should return an error if the size of the files is too large', async() => {
pending('https://redmine.verdnatura.es/issues/4875');
const tx = await models.InvoiceOut.beginTransaction({}); const tx = await models.InvoiceOut.beginTransaction({});
let error; let error;

View File

@ -16,7 +16,6 @@ describe('AgencyTerm createInvoiceIn()', () => {
]; ];
it('should make an invoiceIn', async() => { it('should make an invoiceIn', async() => {
pending('Include after #3638 export database');
const tx = await models.AgencyTerm.beginTransaction({}); const tx = await models.AgencyTerm.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};

View File

@ -89,12 +89,12 @@ module.exports = Self => {
ENGINE = MEMORY ENGINE = MEMORY
SELECT SELECT
e.id, e.id,
e.ref, e.invoiceNumber,
e.supplierFk, e.supplierFk,
t.shipped t.shipped
FROM vn.entry e FROM vn.entry e
JOIN vn.travel t ON t.id = e.travelFk JOIN vn.travel t ON t.id = e.travelFk
JOIN buy b ON b.id = b.entryFk JOIN buy b ON e.id = b.entryFk
JOIN item i ON i.id = b.itemFk JOIN item i ON i.id = b.itemFk
JOIN itemType it ON it.id = i.typeFk`); JOIN itemType it ON it.id = i.typeFk`);
stmt.merge(conn.makeWhere(filter.where)); stmt.merge(conn.makeWhere(filter.where));
@ -104,7 +104,7 @@ module.exports = Self => {
const entriesIndex = stmts.push('SELECT * FROM tmp.entry') - 1; const entriesIndex = stmts.push('SELECT * FROM tmp.entry') - 1;
stmt = new ParameterizedSQL( stmt = new ParameterizedSQL(
`SELECT `SELECT
b.id AS buyId, b.id AS buyId,
b.itemFk, b.itemFk,
b.entryFk, b.entryFk,

View File

@ -11,7 +11,7 @@ describe('supplier consumption() filter', () => {
}; };
const result = await app.models.Supplier.consumption(ctx, filter); const result = await app.models.Supplier.consumption(ctx, filter);
expect(result.length).toEqual(6); expect(result.length).toEqual(5);
}); });
it('should return a list of entries from the item id 1 and supplier 1', async() => { it('should return a list of entries from the item id 1 and supplier 1', async() => {

View File

@ -8,7 +8,6 @@ describe('loopback model Supplier', () => {
beforeAll(async() => { beforeAll(async() => {
supplierOne = await models.Supplier.findById(1); supplierOne = await models.Supplier.findById(1);
supplierTwo = await models.Supplier.findById(442); supplierTwo = await models.Supplier.findById(442);
const activeCtx = { const activeCtx = {
accessToken: {userId: 9}, accessToken: {userId: 9},
http: { http: {
@ -23,71 +22,106 @@ describe('loopback model Supplier', () => {
}); });
}); });
afterAll(async() => {
await supplierOne.updateAttribute('payMethodFk', supplierOne.payMethodFk);
await supplierTwo.updateAttribute('payMethodFk', supplierTwo.payMethodFk);
});
describe('payMethodFk', () => { describe('payMethodFk', () => {
it('should throw an error when attempting to set an invalid payMethod id in the supplier', async() => { it('should throw an error when attempting to set an invalid payMethod id in the supplier', async() => {
let error; const tx = await models.Supplier.beginTransaction({});
const expectedError = 'You can not select this payment method without a registered bankery account'; const options = {transaction: tx};
const supplier = await models.Supplier.findById(1);
await supplier.updateAttribute('payMethodFk', 8) try {
.catch(e => { let error;
error = e; const expectedError = 'You can not select this payment method without a registered bankery account';
expect(error.message).toContain(expectedError); await supplierOne.updateAttribute('payMethodFk', 8, options)
}); .catch(e => {
error = e;
expect(error).toBeDefined(); expect(error.message).toContain(expectedError);
});
expect(error).toBeDefined();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should not throw if the payMethod id is valid', async() => { it('should not throw if the payMethod id is valid', async() => {
let error; const tx = await models.Supplier.beginTransaction({});
const supplier = await models.Supplier.findById(442); const options = {transaction: tx};
await supplier.updateAttribute('payMethodFk', 4)
.catch(e => {
error = e;
});
expect(error).not.toBeDefined(); try {
let error;
await supplierTwo.updateAttribute('payMethodFk', 4, options)
.catch(e => {
error = e;
});
expect(error).not.toBeDefined();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should have checked isPayMethodChecked for payMethod hasVerfified is false', async() => { it('should have checked isPayMethodChecked for payMethod hasVerfified is false', async() => {
const supplier = await models.Supplier.findById(442); const tx = await models.Supplier.beginTransaction({});
await supplier.updateAttribute('isPayMethodChecked', true); const options = {transaction: tx};
await supplier.updateAttribute('payMethodFk', 5);
const result = await models.Supplier.findById(442); try {
await supplierTwo.updateAttribute('isPayMethodChecked', true, options);
await supplierTwo.updateAttribute('payMethodFk', 5, options);
expect(result.isPayMethodChecked).toEqual(true); const result = await models.Supplier.findById(442, null, options);
expect(result.isPayMethodChecked).toEqual(true);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should have unchecked isPayMethodChecked for payMethod hasVerfified is true', async() => { it('should have unchecked isPayMethodChecked for payMethod hasVerfified is true', async() => {
const supplier = await models.Supplier.findById(442); const tx = await models.Supplier.beginTransaction({});
await supplier.updateAttribute('isPayMethodChecked', true); const options = {transaction: tx};
await supplier.updateAttribute('payMethodFk', 2);
const result = await models.Supplier.findById(442); try {
await supplierTwo.updateAttribute('isPayMethodChecked', true, options);
await supplierTwo.updateAttribute('payMethodFk', 2, options);
expect(result.isPayMethodChecked).toEqual(false); const result = await models.Supplier.findById(442, null, options);
expect(result.isPayMethodChecked).toEqual(false);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should have unchecked isPayMethodChecked for payDay and peyDemFk', async() => { it('should have unchecked isPayMethodChecked for payDay and peyDemFk', async() => {
const supplier = await models.Supplier.findById(442); const tx = await models.Supplier.beginTransaction({});
const options = {transaction: tx};
await supplier.updateAttribute('isPayMethodChecked', true); try {
await supplier.updateAttribute('payDay', 5); await supplierTwo.updateAttribute('payMethodFk', 2, options);
const firstResult = await models.Supplier.findById(442); await supplierTwo.updateAttribute('isPayMethodChecked', true, options);
await supplierTwo.updateAttribute('payDay', 5, options);
const firstResult = await models.Supplier.findById(442, null, options);
await supplier.updateAttribute('isPayMethodChecked', true); await supplierTwo.updateAttribute('isPayMethodChecked', true, options);
await supplier.updateAttribute('payDemFk', 1); await supplierTwo.updateAttribute('payDemFk', 1, options);
const secondResult = await models.Supplier.findById(442); const secondResult = await models.Supplier.findById(442, null, options);
expect(firstResult.isPayMethodChecked).toEqual(false); expect(firstResult.isPayMethodChecked).toEqual(false);
expect(secondResult.isPayMethodChecked).toEqual(false); expect(secondResult.isPayMethodChecked).toEqual(false);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });
}); });

View File

@ -31,8 +31,8 @@
</vn-button> </vn-button>
</vn-tool-bar> </vn-tool-bar>
</section> </section>
<vn-table model="model" <vn-table model="model"
ng-repeat="entry in entries" ng-repeat="entry in entries"
ng-if="entry.buys"> ng-if="entry.buys">
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>
@ -40,8 +40,8 @@
<vn-td>{{::entry.id}}</vn-td> <vn-td>{{::entry.id}}</vn-td>
<vn-th field="data">Date</vn-th> <vn-th field="data">Date</vn-th>
<vn-td>{{::entry.shipped | date: 'dd/MM/yyyy'}}</vn-td> <vn-td>{{::entry.shipped | date: 'dd/MM/yyyy'}}</vn-td>
<vn-th field="ref">Reference</vn-th> <vn-th field="invoiceNumber">Reference</vn-th>
<vn-td vn-tooltip="{{::entry.ref}}">{{::entry.ref}}</vn-td> <vn-td vn-tooltip="{{::entry.invoiceNumber}}">{{::entry.invoiceNumber}}</vn-td>
</vn-tr> </vn-tr>
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
@ -83,8 +83,8 @@
</vn-table> </vn-table>
</vn-card> </vn-card>
</vn-data-viewer> </vn-data-viewer>
<vn-confirm <vn-confirm
vn-id="confirm" vn-id="confirm"
question="Please, confirm" question="Please, confirm"
message="The consumption report will be sent" message="The consumption report will be sent"
on-accept="$ctrl.sendEmail()"> on-accept="$ctrl.sendEmail()">

View File

@ -1,3 +1,2 @@
Total entry: Total entrada Total entry: Total entrada
This supplier doesn't have a contact with an email address: Este proveedor no tiene ningún contacto con una dirección de email This supplier doesn't have a contact with an email address: Este proveedor no tiene ningún contacto con una dirección de email

View File

@ -20,3 +20,4 @@ routeFk: route
companyFk: company companyFk: company
agencyModeFk: agency agencyModeFk: agency
ticketFk: ticket ticketFk: ticket
mergedTicket: merged ticket

View File

@ -20,3 +20,4 @@ routeFk: ruta
companyFk: empresa companyFk: empresa
agencyModeFk: agencia agencyModeFk: agencia
ticketFk: ticket ticketFk: ticket
mergedTicket: ticket fusionado

View File

@ -11,7 +11,12 @@ module.exports = Self => {
required: true, required: true,
description: 'The ticket id', description: 'The ticket id',
http: {source: 'path'} http: {source: 'path'}
}, }, {
arg: 'labelCount',
type: 'number',
required: false,
description: 'The number of labels'
}
], ],
returns: [ returns: [
{ {

View File

@ -0,0 +1,55 @@
const {Report} = require('vn-print');
module.exports = Self => {
Self.remoteMethodCtx('expeditionPalletLabel', {
description: 'Returns the expedition pallet label',
accessType: 'READ',
accepts: [
{
arg: 'id',
type: 'number',
required: true,
description: 'The pallet id',
http: {source: 'path'}
}, {
arg: 'userFk',
type: 'number',
required: true,
description: 'The user id'
}
],
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/expedition-pallet-label',
verb: 'GET'
}
});
Self.expeditionPalletLabel = async(ctx, id) => {
const args = Object.assign({}, ctx.args);
const params = {lang: ctx.req.getLocale()};
delete args.ctx;
for (const param in args)
params[param] = args[param];
const report = new Report('expedition-pallet-label', params);
const stream = await report.toPdfStream();
return [stream, 'application/pdf', `filename="doc-${id}.pdf"`];
};
};

View File

@ -20,18 +20,6 @@ module.exports = Self => {
description: 'The date to probe', description: 'The date to probe',
required: true required: true
}, },
{
arg: 'litersMax',
type: 'number',
description: 'Maximum volume of tickets to catapult',
required: true
},
{
arg: 'linesMax',
type: 'number',
description: 'Maximum number of lines of tickets to catapult',
required: true
},
{ {
arg: 'warehouseFk', arg: 'warehouseFk',
type: 'number', type: 'number',
@ -39,15 +27,15 @@ module.exports = Self => {
required: true required: true
}, },
{ {
arg: 'shipped', arg: 'litersMax',
type: 'date', type: 'number',
description: 'Origin shipped', description: 'Maximum volume of tickets to catapult',
required: false required: false
}, },
{ {
arg: 'tfShipped', arg: 'linesMax',
type: 'date', type: 'number',
description: 'Destination shipped', description: 'Maximum number of lines of tickets to catapult',
required: false required: false
}, },
{ {
@ -57,7 +45,7 @@ module.exports = Self => {
required: false required: false
}, },
{ {
arg: 'tfIpt', arg: 'futureIpt',
type: 'string', type: 'string',
description: 'Destination Item Packaging Type', description: 'Destination Item Packaging Type',
required: false required: false
@ -69,7 +57,7 @@ module.exports = Self => {
required: false required: false
}, },
{ {
arg: 'tfId', arg: 'futureId',
type: 'number', type: 'number',
description: 'Destination id', description: 'Destination id',
required: false required: false
@ -81,7 +69,7 @@ module.exports = Self => {
required: false required: false
}, },
{ {
arg: 'tfState', arg: 'futureState',
type: 'string', type: 'string',
description: 'Destination state', description: 'Destination state',
required: false required: false
@ -108,7 +96,7 @@ module.exports = Self => {
} }
}); });
Self.getTicketsFuture = async (ctx, options) => { Self.getTicketsFuture = async(ctx, options) => {
const args = ctx.args; const args = ctx.args;
const conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
const myOptions = {}; const myOptions = {};
@ -118,32 +106,32 @@ module.exports = Self => {
const where = buildFilter(ctx.args, (param, value) => { const where = buildFilter(ctx.args, (param, value) => {
switch (param) { switch (param) {
case 'id': case 'id':
return { 'f.id': value }; return {'f.id': value};
case 'tfId': case 'lines':
return { 'f.ticketFuture': value }; return {'f.lines': {lte: value}};
case 'shipped': case 'liters':
return { 'f.shipped': value }; return {'f.liters': {lte: value}};
case 'tfShipped': case 'futureId':
return { 'f.tfShipped': value }; return {'f.futureId': value};
case 'ipt': case 'ipt':
return { 'f.ipt': value }; return {'f.ipt': value};
case 'tfIpt': case 'futureIpt':
return { 'f.tfIpt': value }; return {'f.futureIpt': value};
case 'state': case 'state':
return { 'f.code': { like: `%${value}%` } }; return {'f.stateCode': {like: `%${value}%`}};
case 'tfState': case 'futureState':
return { 'f.tfCode': { like: `%${value}%` } }; return {'f.futureStateCode': {like: `%${value}%`}};
} }
}); });
let filter = mergeFilters(ctx.args.filter, { where }); let filter = mergeFilters(ctx.args.filter, {where});
const stmts = []; const stmts = [];
let stmt; let stmt;
stmt = new ParameterizedSQL( stmt = new ParameterizedSQL(
`CALL vn.ticket_canbePostponed(?,?,?,?,?)`, `CALL vn.ticket_canbePostponed(?,?,?)`,
[args.originDated, args.futureDated, args.litersMax, args.linesMax, args.warehouseFk]); [args.originDated, args.futureDated, args.warehouseFk]);
stmts.push(stmt); stmts.push(stmt);
@ -153,7 +141,7 @@ module.exports = Self => {
CREATE TEMPORARY TABLE tmp.sale_getProblems CREATE TEMPORARY TABLE tmp.sale_getProblems
(INDEX (ticketFk)) (INDEX (ticketFk))
ENGINE = MEMORY ENGINE = MEMORY
SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped, f.lines, f.liters
FROM tmp.filter f FROM tmp.filter f
LEFT JOIN alertLevel al ON al.id = f.alertLevel LEFT JOIN alertLevel al ON al.id = f.alertLevel
WHERE (al.code = 'FREE' OR f.alertLevel IS NULL)`); WHERE (al.code = 'FREE' OR f.alertLevel IS NULL)`);
@ -174,35 +162,34 @@ module.exports = Self => {
let range; let range;
let hasWhere; let hasWhere;
switch (args.problems) { switch (args.problems) {
case true: case true:
condition = `or`; condition = `or`;
hasProblem = true; hasProblem = true;
range = { neq: null }; range = {neq: null};
hasWhere = true; hasWhere = true;
break; break;
case false: case false:
condition = `and`; condition = `and`;
hasProblem = null; hasProblem = null;
range = null; range = null;
hasWhere = true; hasWhere = true;
break; break;
} }
const problems = { const problems = {
[condition]: [ [condition]: [
{ 'tp.isFreezed': hasProblem }, {'tp.isFreezed': hasProblem},
{ 'tp.risk': hasProblem }, {'tp.risk': hasProblem},
{ 'tp.hasTicketRequest': hasProblem }, {'tp.hasTicketRequest': hasProblem},
{ 'tp.itemShortage': range }, {'tp.itemShortage': range},
{ 'tp.hasComponentLack': hasProblem }, {'tp.hasComponentLack': hasProblem},
{ 'tp.isTooLittle': hasProblem } {'tp.isTooLittle': hasProblem}
] ]
}; };
if (hasWhere) { if (hasWhere)
filter = mergeFilters(filter, { where: problems }); filter = mergeFilters(filter, {where: problems});
}
stmt.merge(conn.makeWhere(filter.where)); stmt.merge(conn.makeWhere(filter.where));
stmt.merge(conn.makeOrderBy(filter.order)); stmt.merge(conn.makeOrderBy(filter.order));

View File

@ -40,19 +40,32 @@ module.exports = Self => {
try { try {
for (let ticket of tickets) { for (let ticket of tickets) {
const fullPath = `${origin}/#!/ticket/${ticket.id}/summary`; const originFullPath = `${origin}/#!/ticket/${ticket.originId}/summary`;
const fullPathFuture = `${origin}/#!/ticket/${ticket.ticketFuture}/summary`; const destinationFullPath = `${origin}/#!/ticket/${ticket.destinationId}/summary`;
const message = $t('Ticket merged', { const message = $t('Ticket merged', {
originDated: dateUtil.toString(new Date(ticket.originETD)), originDated: dateUtil.toString(new Date(ticket.originShipped)),
futureDated: dateUtil.toString(new Date(ticket.destETD)), destinationDated: dateUtil.toString(new Date(ticket.destinationShipped)),
id: ticket.id, originId: ticket.originId,
tfId: ticket.ticketFuture, destinationId: ticket.destinationId,
fullPath, originFullPath,
fullPathFuture destinationFullPath
}); });
if (!ticket.id || !ticket.ticketFuture) continue; if (!ticket.originId || !ticket.destinationId) continue;
await models.Sale.updateAll({ticketFk: ticket.id}, {ticketFk: ticket.ticketFuture}, myOptions);
await models.Ticket.setDeleted(ctx, ticket.id, myOptions); const ticketDestinationLogRecord = {
originFk: ticket.destinationId,
userFk: ctx.req.accessToken.userId,
action: 'update',
changedModel: 'Ticket',
changedModelId: ticket.destinationId,
changedModelValue: ticket.destinationId,
oldInstance: {},
newInstance: {mergedTicket: ticket.originId}
};
await models.TicketLog.create(ticketDestinationLogRecord, myOptions);
await models.Sale.updateAll({ticketFk: ticket.originId}, {ticketFk: ticket.destinationId}, myOptions);
await models.Ticket.setDeleted(ctx, ticket.originId, myOptions);
await models.Chat.sendCheckingPresence(ctx, ticket.workerFk, message); await models.Chat.sendCheckingPresence(ctx, ticket.workerFk, message);
} }
if (tx) if (tx)

View File

@ -1,25 +1,22 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
describe('TicketFuture getTicketsFuture()', () => { describe('ticket getTicketsFuture()', () => {
const today = new Date(); const today = new Date();
today.setHours(0, 0, 0, 0); today.setHours(0, 0, 0, 0);
const tomorrow = new Date(today.getDate() + 1);
it('should return the tickets passing the required data', async () => { it('should return the tickets passing the required data', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const args = { const args = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1, warehouseFk: 1,
}; };
const ctx = { req: { accessToken: { userId: 9 } }, args }; const ctx = {req: {accessToken: {userId: 9}}, args};
const result = await models.Ticket.getTicketsFuture(ctx, options); const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(4); expect(result.length).toEqual(4);
@ -30,22 +27,20 @@ describe('TicketFuture getTicketsFuture()', () => {
} }
}); });
it('should return the tickets matching the problems on true', async () => { it('should return the tickets matching the problems on true', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const args = { const args = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1, warehouseFk: 1,
problems: true problems: true
}; };
const ctx = { req: { accessToken: { userId: 9 } }, args }; const ctx = {req: {accessToken: {userId: 9}}, args};
const result = await models.Ticket.getTicketsFuture(ctx, options); const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(4); expect(result.length).toEqual(4);
@ -57,22 +52,20 @@ describe('TicketFuture getTicketsFuture()', () => {
} }
}); });
it('should return the tickets matching the problems on false', async () => { it('should return the tickets matching the problems on false', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const args = { const args = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1, warehouseFk: 1,
problems: false problems: false
}; };
const ctx = { req: { accessToken: { userId: 9 } }, args }; const ctx = {req: {accessToken: {userId: 9}}, args};
const result = await models.Ticket.getTicketsFuture(ctx, options); const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(0); expect(result.length).toEqual(0);
@ -84,22 +77,20 @@ describe('TicketFuture getTicketsFuture()', () => {
} }
}); });
it('should return the tickets matching the problems on null', async () => { it('should return the tickets matching the problems on null', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const args = { const args = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1, warehouseFk: 1,
problems: null problems: null
}; };
const ctx = { req: { accessToken: { userId: 9 } }, args }; const ctx = {req: {accessToken: {userId: 9}}, args};
const result = await models.Ticket.getTicketsFuture(ctx, options); const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(4); expect(result.length).toEqual(4);
@ -111,130 +102,20 @@ describe('TicketFuture getTicketsFuture()', () => {
} }
}); });
it('should return the tickets matching the correct origin shipped', async () => { it('should return the tickets matching the OK State in origin date', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const args = { const args = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1, warehouseFk: 1,
shipped: today state: 'OK'
}; };
const ctx = { req: { accessToken: { userId: 9 } }, args }; const ctx = {req: {accessToken: {userId: 9}}, args};
const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should return the tickets matching the an incorrect origin shipped', async () => {
const tx = await models.Ticket.beginTransaction({});
try {
const options = { transaction: tx };
const args = {
originDated: today,
futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1,
shipped: tomorrow
};
const ctx = { req: { accessToken: { userId: 9 } }, args };
const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should return the tickets matching the correct destination shipped', async () => {
const tx = await models.Ticket.beginTransaction({});
try {
const options = { transaction: tx };
const args = {
originDated: today,
futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1,
tfShipped: today
};
const ctx = { req: { accessToken: { userId: 9 } }, args };
const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should return the tickets matching the an incorrect destination shipped', async () => {
const tx = await models.Ticket.beginTransaction({});
try {
const options = { transaction: tx };
const args = {
originDated: today,
futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1,
tfShipped: tomorrow
};
const ctx = { req: { accessToken: { userId: 9 } }, args };
const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should return the tickets matching the OK State in origin date', async () => {
const tx = await models.Ticket.beginTransaction({});
try {
const options = { transaction: tx };
const args = {
originDated: today,
futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1,
state: "OK"
};
const ctx = { req: { accessToken: { userId: 9 } }, args };
const result = await models.Ticket.getTicketsFuture(ctx, options); const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(1); expect(result.length).toEqual(1);
@ -246,22 +127,20 @@ describe('TicketFuture getTicketsFuture()', () => {
} }
}); });
it('should return the tickets matching the OK State in destination date', async () => { it('should return the tickets matching the OK State in destination date', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const args = { const args = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1, warehouseFk: 1,
tfState: "OK" futureState: 'OK'
}; };
const ctx = { req: { accessToken: { userId: 9 } }, args }; const ctx = {req: {accessToken: {userId: 9}}, args};
const result = await models.Ticket.getTicketsFuture(ctx, options); const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(4); expect(result.length).toEqual(4);
@ -273,22 +152,20 @@ describe('TicketFuture getTicketsFuture()', () => {
} }
}); });
it('should return the tickets matching the correct IPT in origin date', async () => { it('should return the tickets matching the correct IPT in origin date', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const args = { const args = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1, warehouseFk: 1,
ipt: null ipt: null
}; };
const ctx = { req: { accessToken: { userId: 9 } }, args }; const ctx = {req: {accessToken: {userId: 9}}, args};
const result = await models.Ticket.getTicketsFuture(ctx, options); const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(4); expect(result.length).toEqual(4);
@ -300,22 +177,20 @@ describe('TicketFuture getTicketsFuture()', () => {
} }
}); });
it('should return the tickets matching the incorrect IPT in origin date', async () => { it('should return the tickets matching the incorrect IPT in origin date', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const args = { const args = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1, warehouseFk: 1,
ipt: 0 ipt: 0
}; };
const ctx = { req: { accessToken: { userId: 9 } }, args }; const ctx = {req: {accessToken: {userId: 9}}, args};
const result = await models.Ticket.getTicketsFuture(ctx, options); const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(0); expect(result.length).toEqual(0);
@ -327,22 +202,20 @@ describe('TicketFuture getTicketsFuture()', () => {
} }
}); });
it('should return the tickets matching the correct IPT in destination date', async () => { it('should return the tickets matching the correct IPT in destination date', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const args = { const args = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1, warehouseFk: 1,
tfIpt: null futureIpt: null
}; };
const ctx = { req: { accessToken: { userId: 9 } }, args }; const ctx = {req: {accessToken: {userId: 9}}, args};
const result = await models.Ticket.getTicketsFuture(ctx, options); const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(4); expect(result.length).toEqual(4);
@ -354,22 +227,20 @@ describe('TicketFuture getTicketsFuture()', () => {
} }
}); });
it('should return the tickets matching the incorrect IPT in destination date', async () => { it('should return the tickets matching the incorrect IPT in destination date', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const args = { const args = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1, warehouseFk: 1,
tfIpt: 0 futureIpt: 0
}; };
const ctx = { req: { accessToken: { userId: 9 } }, args }; const ctx = {req: {accessToken: {userId: 9}}, args};
const result = await models.Ticket.getTicketsFuture(ctx, options); const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(0); expect(result.length).toEqual(0);
@ -381,22 +252,20 @@ describe('TicketFuture getTicketsFuture()', () => {
} }
}); });
it('should return the tickets matching the ID in origin date', async () => { it('should return the tickets matching the ID in origin date', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const args = { const args = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1, warehouseFk: 1,
id: 13 id: 13
}; };
const ctx = { req: { accessToken: { userId: 9 } }, args }; const ctx = {req: {accessToken: {userId: 9}}, args};
const result = await models.Ticket.getTicketsFuture(ctx, options); const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(1); expect(result.length).toEqual(1);
@ -408,22 +277,20 @@ describe('TicketFuture getTicketsFuture()', () => {
} }
}); });
it('should return the tickets matching the ID in destination date', async () => { it('should return the tickets matching the ID in destination date', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const args = { const args = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
litersMax: 9999,
linesMax: 9999,
warehouseFk: 1, warehouseFk: 1,
tfId: 12 futureId: 12
}; };
const ctx = { req: { accessToken: { userId: 9 } }, args }; const ctx = {req: {accessToken: {userId: 9}}, args};
const result = await models.Ticket.getTicketsFuture(ctx, options); const result = await models.Ticket.getTicketsFuture(ctx, options);
expect(result.length).toEqual(4); expect(result.length).toEqual(4);
@ -434,5 +301,4 @@ describe('TicketFuture getTicketsFuture()', () => {
throw e; throw e;
} }
}); });
}); });

View File

@ -3,15 +3,15 @@ const LoopBackContext = require('loopback-context');
describe('ticket merge()', () => { describe('ticket merge()', () => {
const tickets = [{ const tickets = [{
id: 13, originId: 13,
ticketFuture: 12, destinationId: 12,
workerFk: 1, originShipped: new Date(),
originETD: new Date(), destinationShipped: new Date(),
destETD: new Date() workerFk: 1
}]; }];
const activeCtx = { const activeCtx = {
accessToken: { userId: 9 }, accessToken: {userId: 9},
}; };
beforeEach(() => { beforeEach(() => {
@ -22,26 +22,26 @@ describe('ticket merge()', () => {
const ctx = { const ctx = {
req: { req: {
accessToken: { userId: 9 }, accessToken: {userId: 9},
headers: { origin: 'http://localhost:5000' }, headers: {origin: 'http://localhost:5000'},
} }
}; };
ctx.req.__ = value => { ctx.req.__ = value => {
return value; return value;
}; };
it('should merge two tickets', async () => { it('should merge two tickets', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});
try { try {
const options = { transaction: tx }; const options = {transaction: tx};
const chatNotificationBeforeMerge = await models.Chat.find(); const chatNotificationBeforeMerge = await models.Chat.find();
await models.Ticket.merge(ctx, tickets, options); await models.Ticket.merge(ctx, tickets, options);
const createdTicketLog = await models.TicketLog.find({ where: { originFk: tickets[0].id } }, options); const createdTicketLog = await models.TicketLog.find({where: {originFk: tickets[0].originId}}, options);
const deletedTicket = await models.Ticket.findOne({ where: { id: tickets[0].id } }, options); const deletedTicket = await models.Ticket.findOne({where: {id: tickets[0].originId}}, options);
const salesTicketFuture = await models.Sale.find({ where: { ticketFk: tickets[0].ticketFuture } }, options); const salesTicketFuture = await models.Sale.find({where: {ticketFk: tickets[0].destinationId}}, options);
const chatNotificationAfterMerge = await models.Chat.find(); const chatNotificationAfterMerge = await models.Chat.find();
expect(createdTicketLog.length).toEqual(1); expect(createdTicketLog.length).toEqual(1);

View File

@ -94,8 +94,5 @@
}, },
"TicketConfig": { "TicketConfig": {
"dataSource": "vn" "dataSource": "vn"
},
"TicketFuture": {
"dataSource": "vn"
} }
} }

View File

@ -1,12 +0,0 @@
{
"name": "TicketFuture",
"base": "PersistedModel",
"acls": [
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "employee",
"permission": "ALLOW"
}
]
}

View File

@ -33,8 +33,9 @@ module.exports = function(Self) {
require('../methods/ticket/closeByTicket')(Self); require('../methods/ticket/closeByTicket')(Self);
require('../methods/ticket/closeByAgency')(Self); require('../methods/ticket/closeByAgency')(Self);
require('../methods/ticket/closeByRoute')(Self); require('../methods/ticket/closeByRoute')(Self);
require('../methods/ticket-future/getTicketsFuture')(Self); require('../methods/ticket/getTicketsFuture')(Self);
require('../methods/ticket/merge')(Self); require('../methods/ticket/merge')(Self);
require('../methods/ticket/isRoleAdvanced')(Self); require('../methods/ticket/isRoleAdvanced')(Self);
require('../methods/ticket/collectionLabel')(Self); require('../methods/ticket/collectionLabel')(Self);
require('../methods/ticket/expeditionPalletLabel')(Self);
}; };

View File

@ -280,10 +280,11 @@
</vn-dialog> </vn-dialog>
<!-- Send SMS popup --> <!-- Send SMS popup -->
<vn-ticket-sms <vn-sms-dialog
vn-id="sms" vn-id="sms"
on-send="$ctrl.onSmsSend($sms)"
sms="$ctrl.newSMS"> sms="$ctrl.newSMS">
</vn-ticket-sms> </vn-sms-dialog>
<!-- Make invoice confirmation dialog --> <!-- Make invoice confirmation dialog -->
<vn-confirm <vn-confirm

View File

@ -239,6 +239,7 @@ class Controller extends Section {
destinationFk: this.ticket.clientFk, destinationFk: this.ticket.clientFk,
destination: phone destination: phone
}, params); }, params);
this.$.sms.open(); this.$.sms.open();
} }
@ -256,7 +257,7 @@ class Controller extends Section {
this.$http.post(`NotificationQueues`, { this.$http.post(`NotificationQueues`, {
notificationFk: 'invoiceElectronic', notificationFk: 'invoiceElectronic',
authorFk: client.id, authorFk: client.id,
}).then(a => { }).then(() => {
this.vnApp.showSuccess(this.$t('Invoice sent')); this.vnApp.showSuccess(this.$t('Invoice sent'));
}); });
} }
@ -294,6 +295,11 @@ class Controller extends Section {
this.$state.go('ticket.card.sale', {id: refundTicket.id}); this.$state.go('ticket.card.sale', {id: refundTicket.id});
}); });
} }
onSmsSend(sms) {
return this.$http.post(`Tickets/${this.id}/sendSms`, sms)
.then(() => this.vnApp.showSuccess(this.$t('SMS sent')));
}
} }
Controller.$inject = ['$element', '$scope', 'vnReport', 'vnEmail']; Controller.$inject = ['$element', '$scope', 'vnReport', 'vnEmail'];

View File

@ -261,11 +261,8 @@ describe('Ticket Component vnTicketDescriptorMenu', () => {
describe('showSMSDialog()', () => { describe('showSMSDialog()', () => {
it('should set the destionationFk and destination properties and then call the sms open() method', () => { it('should set the destionationFk and destination properties and then call the sms open() method', () => {
controller.$.sms = {open: () => {}}; controller.$.sms = {open: () => {}};
jest.spyOn(controller.$.sms, 'open');
controller.showSMSDialog(); controller.showSMSDialog();
expect(controller.$.sms.open).toHaveBeenCalledWith();
expect(controller.newSMS).toEqual({ expect(controller.newSMS).toEqual({
destinationFk: ticket.clientFk, destinationFk: ticket.clientFk,
destination: ticket.address.mobile, destination: ticket.address.mobile,

View File

@ -4,43 +4,26 @@
<vn-date-picker <vn-date-picker
vn-one vn-one
label="Origin date" label="Origin date"
ng-model="filter.shipped" ng-model="filter.originDated"
on-change="$ctrl.from = value"> required="true">
</vn-date-picker> </vn-date-picker>
<vn-date-picker <vn-date-picker
vn-one vn-one
label="Destination date" label="Destination date"
ng-model="filter.tfShipped">
</vn-date-picker>
</vn-horizontal>
<vn-horizontal class="vn-px-lg">
<vn-date-picker
vn-one
label="Origin ETD"
ng-model="filter.originDated"
required="true"
info="ETD">
</vn-date-picker>
<vn-date-picker
vn-one
label="Destination ETD"
ng-model="filter.futureDated" ng-model="filter.futureDated"
required="true" required="true">
info="ETD">
</vn-date-picker> </vn-date-picker>
</vn-horizontal> </vn-horizontal>
<vn-horizontal class="vn-px-lg"> <vn-horizontal class="vn-px-lg">
<vn-textfield
vn-one
label="Max Lines"
ng-model="filter.linesMax"
required="true">
</vn-textfield>
<vn-textfield <vn-textfield
vn-one vn-one
label="Max Liters" label="Max Liters"
ng-model="filter.litersMax" ng-model="filter.litersMax">
required="true"> </vn-textfield>
<vn-textfield
vn-one
label="Max Lines"
ng-model="filter.linesMax">
</vn-textfield> </vn-textfield>
</vn-horizontal> </vn-horizontal>
<vn-horizontal class="vn-px-lg"> <vn-horizontal class="vn-px-lg">
@ -48,22 +31,22 @@
data="$ctrl.itemPackingTypes" data="$ctrl.itemPackingTypes"
label="Origin IPT" label="Origin IPT"
value-field="code" value-field="code"
show-field="name" show-field="description"
ng-model="filter.ipt" ng-model="filter.ipt"
info="IPT"> info="IPT">
<tpl-item> <tpl-item>
{{name}} {{description}}
</tpl-item> </tpl-item>
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete vn-one <vn-autocomplete vn-one
data="$ctrl.itemPackingTypes" data="$ctrl.itemPackingTypes"
label="Destination IPT" label="Destination IPT"
value-field="code" value-field="code"
show-field="name" show-field="description"
ng-model="filter.tfIpt" ng-model="filter.futureIpt"
info="IPT"> info="IPT">
<tpl-item> <tpl-item>
{{name}} {{description}}
</tpl-item> </tpl-item>
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>
@ -83,7 +66,7 @@
label="Destination Grouped State" label="Destination Grouped State"
value-field="code" value-field="code"
show-field="name" show-field="name"
ng-model="filter.tfState"> ng-model="filter.futureState">
<tpl-item> <tpl-item>
{{name}} {{name}}
</tpl-item> </tpl-item>

View File

@ -28,9 +28,8 @@ class Controller extends SearchPanel {
this.$http.get('ItemPackingTypes').then(res => { this.$http.get('ItemPackingTypes').then(res => {
for (let ipt of res.data) { for (let ipt of res.data) {
itemPackingTypes.push({ itemPackingTypes.push({
id: ipt.id, description: this.$t(ipt.description),
code: ipt.code, code: ipt.code,
name: this.$t(ipt.code)
}); });
} }
this.itemPackingTypes = itemPackingTypes; this.itemPackingTypes = itemPackingTypes;

View File

@ -1,9 +1 @@
Future tickets: Tickets a futuro Future tickets: Tickets a futuro
FREE: Free
DELIVERED: Delivered
ON_PREPARATION: On preparation
PACKED: Packed
F: Fruits and vegetables
V: Vertical
H: Horizontal
P: Feed

View File

@ -11,13 +11,4 @@ With problems: Con problemas
Warehouse: Almacén Warehouse: Almacén
Origin Grouped State: Estado agrupado origen Origin Grouped State: Estado agrupado origen
Destination Grouped State: Estado agrupado destino Destination Grouped State: Estado agrupado destino
FREE: Libre
DELIVERED: Servido
ON_PREPARATION: En preparacion
PACKED: Encajado
F: Frutas y verduras
V: Vertical
H: Horizontal
P: Pienso
ETD: Tiempo estimado de entrega
IPT: Encajado IPT: Encajado

View File

@ -1,7 +1,7 @@
<vn-crud-model <vn-crud-model
vn-id="model" vn-id="model"
url="Tickets/getTicketsFuture" url="Tickets/getTicketsFuture"
limit="20"> auto-load="false">
</vn-crud-model> </vn-crud-model>
<vn-portal slot="topbar"> <vn-portal slot="topbar">
<vn-searchbar <vn-searchbar
@ -30,6 +30,11 @@
<slot-table> <slot-table>
<table> <table>
<thead> <thead>
<tr second-header>
<td></td>
<th colspan="7" translate>Origin</th>
<th colspan="4" translate>Destination</th>
</tr>
<tr> <tr>
<th shrink> <th shrink>
<vn-multi-check <vn-multi-check
@ -38,39 +43,39 @@
check-field="checked"> check-field="checked">
</vn-multi-check> </vn-multi-check>
</th> </th>
<th field="problems"> <th field="totalProblems">
<span translate>Problems</span> <span translate>Problems</span>
</th> </th>
<th field="id"> <th field="id">
<span translate>Origin ID</span> <span translate>ID</span>
</th> </th>
<th field="originETD"> <th field="shipped">
<span translate>Origin ETD</span> <span translate>Date</span>
</th>
<th field="ipt" title="Item Packing Type">
<span>IPT</span>
</th> </th>
<th field="state"> <th field="state">
<span translate>Origin State</span> <span translate>State</span>
</th> </th>
<th field="ipt"> <th field="liters">
<span>IPT</span>
</th>
<th field="litersMax">
<span translate>Liters</span> <span translate>Liters</span>
</th> </th>
<th field="linesMax"> <th shrink field="lines">
<span translate>Available Lines</span> <span translate>Available Lines</span>
</th> </th>
<th field="ticketFuture"> <th field="futureId" separator>
<span translate>Destination ID</span> <span translate>ID</span>
</th> </th>
<th field="destETD"> <th field="futureShipped">
<span translate>Destination ETD</span> <span translate>Date</span>
</th> </th>
<th field="tfState"> <th field="futureIpt" title="Item Packing Type">
<span translate>Destination State</span>
</th>
<th field="tfIpt">
<span>IPT</span> <span>IPT</span>
</th> </th>
<th shrink field="futureState">
<span translate>State</span>
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -125,38 +130,38 @@
{{::ticket.id}} {{::ticket.id}}
</span></td> </span></td>
<td shrink-date> <td shrink-date>
<span class="chip {{$ctrl.compareDate(ticket.originETD)}}"> <span class="chip {{$ctrl.compareDate(ticket.shipped)}}">
{{::ticket.originETD | date: 'dd/MM/yyyy'}} {{::ticket.shipped | date: 'dd/MM/yyyy'}}
</span> </span>
</td> </td>
<td>{{::ticket.ipt}}</td>
<td> <td>
<span <span
class="chip {{$ctrl.stateColor(ticket.state)}}"> class="chip {{$ctrl.stateColor(ticket.state)}}">
{{::ticket.state}} {{::ticket.state}}
</span> </span>
</td> </td>
<td>{{::ticket.ipt}}</td>
<td>{{::ticket.liters}}</td> <td>{{::ticket.liters}}</td>
<td>{{::ticket.lines}}</td> <td>{{::ticket.lines}}</td>
<td> <td>
<span <span
ng-click="ticketDescriptor.show($event, ticket.ticketFuture)" ng-click="ticketDescriptor.show($event, ticket.futureId)"
class="link"> class="link">
{{::ticket.ticketFuture}} {{::ticket.futureId}}
</span> </span>
</td> </td>
<td shrink-date> <td shrink-date>
<span class="chip {{$ctrl.compareDate(ticket.destETD)}}"> <span class="chip {{$ctrl.compareDate(ticket.futureShipped)}}">
{{::ticket.destETD | date: 'dd/MM/yyyy'}} {{::ticket.futureShipped | date: 'dd/MM/yyyy'}}
</span> </span>
</td> </td>
<td>{{::ticket.futureIpt}}</td>
<td> <td>
<span <span
class="chip {{$ctrl.stateColor(ticket.tfState)}}"> class="chip {{$ctrl.stateColor(ticket.futureState)}}">
{{::ticket.tfState}} {{::ticket.futureState}}
</span> </span>
</td> </td>
<td>{{::ticket.tfIpt}}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -11,15 +11,15 @@ export default class Controller extends Section {
search: true, search: true,
}, },
columns: [{ columns: [{
field: 'problems', field: 'totalProblems',
searchable: false,
},
{
field: 'shipped',
searchable: false searchable: false
}, },
{ {
field: 'originETD', field: 'futureShipped',
searchable: false
},
{
field: 'destETD',
searchable: false searchable: false
}, },
{ {
@ -27,7 +27,7 @@ export default class Controller extends Section {
searchable: false searchable: false
}, },
{ {
field: 'tfState', field: 'futureState',
searchable: false searchable: false
}, },
{ {
@ -39,7 +39,7 @@ export default class Controller extends Section {
} }
}, },
{ {
field: 'tfIpt', field: 'futureIpt',
autocomplete: { autocomplete: {
url: 'ItemPackingTypes', url: 'ItemPackingTypes',
showField: 'description', showField: 'description',
@ -48,6 +48,9 @@ export default class Controller extends Section {
}, },
] ]
}; };
}
$postLink() {
this.setDefaultFilter(); this.setDefaultFilter();
} }
@ -57,10 +60,9 @@ export default class Controller extends Section {
this.filterParams = { this.filterParams = {
originDated: today, originDated: today,
futureDated: today, futureDated: today,
linesMax: '9999', warehouseFk: this.vnConfig.warehouseFk
litersMax: '9999',
warehouseFk: 1
}; };
this.$.model.applyFilter(null, this.filterParams);
} }
compareDate(date) { compareDate(date) {
@ -113,7 +115,17 @@ export default class Controller extends Section {
} }
moveTicketsFuture() { moveTicketsFuture() {
let params = { tickets: this.checked }; let ticketsToMove = [];
this.checked.forEach(ticket => {
ticketsToMove.push({
originId: ticket.id,
destinationId: ticket.futureId,
originShipped: ticket.shipped,
destinationShipped: ticket.futureShipped,
workerFk: ticket.workerFk
});
});
let params = {tickets: ticketsToMove};
return this.$http.post('Tickets/merge', params) return this.$http.post('Tickets/merge', params)
.then(() => { .then(() => {
this.$.model.refresh(); this.$.model.refresh();
@ -123,18 +135,18 @@ export default class Controller extends Section {
exprBuilder(param, value) { exprBuilder(param, value) {
switch (param) { switch (param) {
case 'id': case 'id':
return { 'id': value }; return {'id': value};
case 'ticketFuture': case 'futureId':
return { 'ticketFuture': value }; return {'futureId': value};
case 'litersMax': case 'liters':
return { 'liters': value }; return {'liters': value};
case 'linesMax': case 'lines':
return { 'lines': value }; return {'lines': value};
case 'ipt': case 'ipt':
return { 'ipt': value }; return {'ipt': value};
case 'tfIpt': case 'futureIpt':
return { 'tfIpt': value }; return {'futureIpt': value};
} }
} }
} }

View File

@ -2,33 +2,30 @@ import './index.js';
import crudModel from 'core/mocks/crud-model'; import crudModel from 'core/mocks/crud-model';
describe('Component vnTicketFuture', () => { describe('Component vnTicketFuture', () => {
const today = new Date();
let controller; let controller;
let $httpBackend; let $httpBackend;
let $window;
beforeEach(ngModule('ticket') beforeEach(ngModule('ticket'));
);
beforeEach(inject(($componentController, _$window_, _$httpBackend_) => { beforeEach(inject(($componentController, _$httpBackend_) => {
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
$window = _$window_;
const $element = angular.element('<vn-ticket-future></vn-ticket-future>'); const $element = angular.element('<vn-ticket-future></vn-ticket-future>');
controller = $componentController('vnTicketFuture', { $element }); controller = $componentController('vnTicketFuture', {$element});
controller.$.model = crudModel; controller.$.model = crudModel;
controller.$.model.data = [{ controller.$.model.data = [{
id: 1, id: 1,
checked: true, checked: true,
state: "OK" state: 'OK'
}, { }, {
id: 2, id: 2,
checked: true, checked: true,
state: "Libre" state: 'Libre'
}]; }];
})); }));
describe('compareDate()', () => { describe('compareDate()', () => {
it('should return warning when the date is the present', () => { it('should return warning when the date is the present', () => {
let today = new Date();
let result = controller.compareDate(today); let result = controller.compareDate(today);
expect(result).toEqual('warning'); expect(result).toEqual('warning');
@ -67,6 +64,7 @@ describe('Component vnTicketFuture', () => {
it('should return success to the OK tickets', () => { it('should return success to the OK tickets', () => {
const ok = controller.stateColor(controller.$.model.data[0].state); const ok = controller.stateColor(controller.$.model.data[0].state);
const notOk = controller.stateColor(controller.$.model.data[1].state); const notOk = controller.stateColor(controller.$.model.data[1].state);
expect(ok).toEqual('success'); expect(ok).toEqual('success');
expect(notOk).not.toEqual('success'); expect(notOk).not.toEqual('success');
}); });
@ -74,6 +72,7 @@ describe('Component vnTicketFuture', () => {
it('should return success to the FREE tickets', () => { it('should return success to the FREE tickets', () => {
const notFree = controller.stateColor(controller.$.model.data[0].state); const notFree = controller.stateColor(controller.$.model.data[0].state);
const free = controller.stateColor(controller.$.model.data[1].state); const free = controller.stateColor(controller.$.model.data[1].state);
expect(free).toEqual('notice'); expect(free).toEqual('notice');
expect(notFree).not.toEqual('notice'); expect(notFree).not.toEqual('notice');
}); });
@ -81,18 +80,14 @@ describe('Component vnTicketFuture', () => {
describe('dateRange()', () => { describe('dateRange()', () => {
it('should return two dates with the hours at the start and end of the given date', () => { it('should return two dates with the hours at the start and end of the given date', () => {
const now = new Date(); const dateRange = controller.dateRange(today);
const today = now.getDate();
const dateRange = controller.dateRange(now);
const start = dateRange[0].toString(); const start = dateRange[0].toString();
const end = dateRange[1].toString(); const end = dateRange[1].toString();
expect(start).toContain(today); expect(start).toContain(today.getDate());
expect(start).toContain('00:00:00'); expect(start).toContain('00:00:00');
expect(end).toContain(today); expect(end).toContain(today.getDate());
expect(end).toContain('23:59:59'); expect(end).toContain('23:59:59');
}); });
}); });

View File

@ -1,6 +1,2 @@
Move confirmation: Do you want to move {{checked}} tickets to the future? Move confirmation: Do you want to move {{checked}} tickets to the future?
FREE: Free
DELIVERED: Delivered
ON_PREPARATION: On preparation
PACKED: Packed
Success: Tickets moved successfully! Success: Tickets moved successfully!

View File

@ -3,20 +3,14 @@ Search tickets: Buscar tickets
Search future tickets by date: Buscar tickets por fecha Search future tickets by date: Buscar tickets por fecha
Problems: Problemas Problems: Problemas
Origin ID: ID origen Origin ID: ID origen
Closing: Cierre
Origin State: Estado origen Origin State: Estado origen
Destination State: Estado destino Destination State: Estado destino
Liters: Litros Liters: Litros
Available Lines: Líneas disponibles Available Lines: Líneas disponibles
Destination ID: ID destino Destination ID: ID destino
Destination ETD: ETD Destino
Origin ETD: ETD Origen
Move tickets: Mover tickets Move tickets: Mover tickets
Move confirmation: ¿Desea mover {{checked}} tickets hacia el futuro? Move confirmation: ¿Desea mover {{checked}} tickets hacia el futuro?
Success: Tickets movidos correctamente Success: Tickets movidos correctamente
ETD: Tiempo estimado de entrega
IPT: Encajado IPT: Encajado
FREE: Libre Origin Date: Fecha origen
DELIVERED: Servido Destination Date: Fecha destino
ON_PREPARATION: En preparacion
PACKED: Encajado

View File

@ -32,7 +32,6 @@ import './weekly';
import './dms/index'; import './dms/index';
import './dms/create'; import './dms/create';
import './dms/edit'; import './dms/edit';
import './sms';
import './boxing'; import './boxing';
import './future'; import './future';
import './future-search-panel'; import './future-search-panel';

View File

@ -1,45 +0,0 @@
<vn-dialog
vn-id="SMSDialog"
on-accept="$ctrl.onResponse()"
message="Send SMS">
<tpl-body>
<section class="SMSDialog">
<vn-horizontal>
<vn-textfield
vn-one
label="Destination"
ng-model="$ctrl.sms.destination"
required="true"
rule>
</vn-textfield>
</vn-horizontal>
<vn-horizontal >
<vn-textarea vn-one
vn-id="message"
label="Message"
ng-model="$ctrl.sms.message"
info="Special characters like accents counts as a multiple"
rows="5"
required="true"
rule>
</vn-textarea>
</vn-horizontal>
<vn-horizontal>
<span>
{{'Characters remaining' | translate}}:
<vn-chip translate-attr="{title: 'Packing'}" ng-class="{
'colored': $ctrl.charactersRemaining() > 25,
'warning': $ctrl.charactersRemaining() <= 25,
'alert': $ctrl.charactersRemaining() < 0,
}">
{{$ctrl.charactersRemaining()}}
</vn-chip>
</span>
</vn-horizontal>
</section>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Send</button>
</tpl-buttons>
</vn-dialog>

View File

@ -1,71 +0,0 @@
import './index';
describe('Ticket', () => {
describe('Component vnTicketSms', () => {
let controller;
let $httpBackend;
beforeEach(ngModule('ticket'));
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
$httpBackend = _$httpBackend_;
let $scope = $rootScope.$new();
const $element = angular.element('<vn-dialog></vn-dialog>');
controller = $componentController('vnTicketSms', {$element, $scope});
controller.$.message = {
input: {
value: 'My SMS'
}
};
}));
describe('onResponse()', () => {
it('should perform a POST query and show a success snackbar', () => {
let params = {ticketId: 11, destinationFk: 1101, destination: 111111111, message: 'My SMS'};
controller.sms = {ticketId: 11, destinationFk: 1101, destination: 111111111, message: 'My SMS'};
jest.spyOn(controller.vnApp, 'showMessage');
$httpBackend.expect('POST', `Tickets/11/sendSms`, params).respond(200, params);
controller.onResponse();
$httpBackend.flush();
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('SMS sent!');
});
it('should call onResponse without the destination and show an error snackbar', () => {
controller.sms = {destinationFk: 1101, message: 'My SMS'};
jest.spyOn(controller.vnApp, 'showError');
controller.onResponse();
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The destination can't be empty`);
});
it('should call onResponse without the message and show an error snackbar', () => {
controller.sms = {destinationFk: 1101, destination: 222222222};
jest.spyOn(controller.vnApp, 'showError');
controller.onResponse();
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The message can't be empty`);
});
});
describe('charactersRemaining()', () => {
it('should return the characters remaining in a element', () => {
controller.$.message = {
input: {
value: 'My message 0€'
}
};
let result = controller.charactersRemaining();
expect(result).toEqual(145);
});
});
});
});

View File

@ -1,9 +0,0 @@
Send SMS: Enviar SMS
Destination: Destinatario
Message: Mensaje
SMS sent!: ¡SMS enviado!
Characters remaining: Carácteres restantes
The destination can't be empty: El destinatario no puede estar vacio
The message can't be empty: El mensaje no puede estar vacio
The message it's too long: El mensaje es demasiado largo
Special characters like accents counts as a multiple: Carácteres especiales como los acentos cuentan como varios

View File

@ -1,5 +0,0 @@
@import "variables";
.SMSDialog {
min-width: 400px
}

View File

@ -159,7 +159,8 @@ module.exports = Self => {
`SELECT `SELECT
e.id, e.id,
e.travelFk, e.travelFk,
e.ref, e.reference,
e.invoiceNumber,
e.loadPriority, e.loadPriority,
s.id AS supplierFk, s.id AS supplierFk,
s.name AS supplierName, s.name AS supplierName,
@ -168,7 +169,7 @@ module.exports = Self => {
e.notes, e.notes,
CAST(SUM(b.weight * b.stickers) AS DECIMAL(10,0)) as loadedkg, CAST(SUM(b.weight * b.stickers) AS DECIMAL(10,0)) as loadedkg,
CAST(SUM(vc.aerealVolumetricDensity * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000) AS DECIMAL(10,0)) as volumeKg CAST(SUM(vc.aerealVolumetricDensity * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000) AS DECIMAL(10,0)) as volumeKg
FROM tmp.travel tr FROM tmp.travel tr
JOIN entry e ON e.travelFk = tr.id JOIN entry e ON e.travelFk = tr.id
JOIN buy b ON b.entryFk = e.id JOIN buy b ON b.entryFk = e.id
JOIN packaging pkg ON pkg.id = b.packageFk JOIN packaging pkg ON pkg.id = b.packageFk

View File

@ -1,4 +1,4 @@
/* eslint max-len: ["error", { "code": 150 }]*/
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => { module.exports = Self => {
Self.remoteMethod('getEntries', { Self.remoteMethod('getEntries', {
@ -25,27 +25,34 @@ module.exports = Self => {
let stmt; let stmt;
stmt = new ParameterizedSQL(` stmt = new ParameterizedSQL(`
SELECT e.travelFk, e.id, e.isConfirmed, e.ref, e.notes, e.evaNotes AS observation, SELECT
s.name AS supplierName, e.travelFk,
CAST((SUM(IF(p.volume > 0,p.volume,p.width * p.depth * IF(p.height, p.height, i.size + pconfig.upperGap)) e.id,
* b.stickers)/1000000)/((pcc.width*pcc.depth*pcc.height)/1000000) AS DECIMAL(10,2)) cc, e.isConfirmed,
CAST((SUM(IF(p.volume > 0,p.volume,p.width * p.depth * IF(p.height, p.height, i.size + pconfig.upperGap)) e.invoiceNumber,
* b.stickers)/1000000)/((ppallet.width*ppallet.depth*ppallet.height)/1000000) AS DECIMAL(10,2)) pallet, e.reference,
CAST((SUM(IF(p.volume > 0,p.volume,p.width * p.depth * IF(p.height, p.height, i.size + pconfig.upperGap)) e.notes,
* b.stickers)/1000000) AS DECIMAL(10,2)) m3, e.evaNotes AS observation,
TRUNCATE(SUM(b.stickers)/(COUNT( b.id) / COUNT( DISTINCT b.id)),0) hb, s.name AS supplierName,
CAST(SUM(b.freightValue*b.quantity) AS DECIMAL(10,2)) freightValue, CAST((SUM(IF(p.volume > 0,p.volume,p.width * p.depth * IF(p.height, p.height, i.size + pconfig.upperGap))
CAST(SUM(b.packageValue*b.quantity) AS DECIMAL(10,2)) packageValue * b.stickers)/1000000)/((pcc.width*pcc.depth*pcc.height)/1000000) AS DECIMAL(10,2)) cc,
CAST((SUM(IF(p.volume > 0,p.volume,p.width * p.depth * IF(p.height, p.height, i.size + pconfig.upperGap))
* b.stickers)/1000000)/((ppallet.width*ppallet.depth*ppallet.height)/1000000) AS DECIMAL(10,2)) pallet,
CAST((SUM(IF(p.volume > 0,p.volume,p.width * p.depth * IF(p.height, p.height, i.size + pconfig.upperGap))
* b.stickers)/1000000) AS DECIMAL(10,2)) m3,
TRUNCATE(SUM(b.stickers)/(COUNT( b.id) / COUNT( DISTINCT b.id)),0) hb,
CAST(SUM(b.freightValue*b.quantity) AS DECIMAL(10,2)) freightValue,
CAST(SUM(b.packageValue*b.quantity) AS DECIMAL(10,2)) packageValue
FROM vn.travel t FROM vn.travel t
LEFT JOIN vn.entry e ON t.id = e.travelFk LEFT JOIN vn.entry e ON t.id = e.travelFk
LEFT JOIN vn.buy b ON b.entryFk = e.id LEFT JOIN vn.buy b ON b.entryFk = e.id
LEFT JOIN vn.supplier s ON e.supplierFk = s.id LEFT JOIN vn.supplier s ON e.supplierFk = s.id
JOIN vn.item i ON i.id = b.itemFk JOIN vn.item i ON i.id = b.itemFk
LEFT JOIN vn.packaging p ON p.id = b.packageFk LEFT JOIN vn.packaging p ON p.id = b.packageFk
JOIN vn.packaging pcc ON pcc.id = 'cc' JOIN vn.packaging pcc ON pcc.id = 'cc'
JOIN vn.packaging ppallet ON ppallet.id = 'pallet 100' JOIN vn.packaging ppallet ON ppallet.id = 'pallet 100'
JOIN vn.packagingConfig pconfig JOIN vn.packagingConfig pconfig
WHERE t.id = ? WHERE t.id = ?
GROUP BY e.id;`, [ GROUP BY e.id;`, [
id id
]); ]);

View File

@ -1,28 +1,34 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('travel getEntries()', () => { describe('travel getEntries()', () => {
const travelId = 1; const travelId = 1;
it('should check the response contains the id', async() => { it('should check the response contains the id', async() => {
const entries = await app.models.Travel.getEntries(travelId); const entries = await models.Travel.getEntries(travelId);
expect(entries.length).toEqual(1); expect(entries.length).toEqual(1);
expect(entries[0].id).toEqual(1); expect(entries[0].id).toEqual(1);
}); });
it('should check the response contains the travelFk', async() => { it('should check the response contains the travelFk', async() => {
const entries = await app.models.Travel.getEntries(travelId); const entries = await models.Travel.getEntries(travelId);
expect(entries[0].travelFk).toEqual(1); expect(entries[0].travelFk).toEqual(1);
}); });
it('should check the response contains the ref', async() => { it('should check the response contains the reference', async() => {
const entries = await app.models.Travel.getEntries(travelId); const entries = await models.Travel.getEntries(travelId);
expect(entries[0].ref).toEqual('Movement 1'); expect(entries[0].reference).toEqual('Movement 1');
});
it('should check the response contains the invoiceNumber', async() => {
const entries = await models.Travel.getEntries(travelId);
expect(entries[0].invoiceNumber).toEqual('IN2001');
}); });
it('should check the response contains the m3', async() => { it('should check the response contains the m3', async() => {
const entries = await app.models.Travel.getEntries(travelId); const entries = await models.Travel.getEntries(travelId);
expect(entries[0].m3).toEqual(0.22); expect(entries[0].m3).toEqual(0.22);
}); });

View File

@ -1,6 +1,6 @@
<vn-card class="summary"> <vn-card class="summary">
<h5> <h5>
<a <a
ng-if="::$ctrl.travelData.id" ng-if="::$ctrl.travelData.id"
vn-tooltip="Go to the travel" vn-tooltip="Go to the travel"
ui-sref="travel.card.summary({id: {{::$ctrl.travelData.id}}})" ui-sref="travel.card.summary({id: {{::$ctrl.travelData.id}}})"
@ -13,15 +13,15 @@
<vn-horizontal> <vn-horizontal>
<vn-one> <vn-one>
<vn-label-value <vn-label-value
label="Shipped" label="Shipped"
value="{{$ctrl.travelData.shipped | date: 'dd/MM/yyyy'}}"> value="{{$ctrl.travelData.shipped | date: 'dd/MM/yyyy'}}">
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Warehouse Out" label="Warehouse Out"
value="{{$ctrl.travelData.warehouseOut.name}}"> value="{{$ctrl.travelData.warehouseOut.name}}">
</vn-label-value> </vn-label-value>
<vn-check <vn-check
label="Delivered" label="Delivered"
ng-model="$ctrl.travelData.isDelivered" ng-model="$ctrl.travelData.isDelivered"
disabled="true"> disabled="true">
</vn-check> </vn-check>
@ -36,7 +36,7 @@
value="{{$ctrl.travelData.warehouseIn.name}}"> value="{{$ctrl.travelData.warehouseIn.name}}">
</vn-label-value> </vn-label-value>
<vn-check <vn-check
label="Received" label="Received"
ng-model="$ctrl.travelData.isReceived" ng-model="$ctrl.travelData.isReceived"
disabled="true"> disabled="true">
</vn-check> </vn-check>
@ -80,7 +80,7 @@
<vn-tbody> <vn-tbody>
<vn-tr ng-repeat="entry in $ctrl.entries"> <vn-tr ng-repeat="entry in $ctrl.entries">
<vn-td shrink> <vn-td shrink>
<vn-check <vn-check
ng-model="entry.isConfirmed" ng-model="entry.isConfirmed"
disabled="true"> disabled="true">
</vn-check> </vn-check>
@ -99,7 +99,7 @@
<vn-td shrink>{{entry.cc}}</vn-td> <vn-td shrink>{{entry.cc}}</vn-td>
<vn-td shrink>{{entry.pallet}}</vn-td> <vn-td shrink>{{entry.pallet}}</vn-td>
<vn-td shrink>{{entry.m3}}</vn-td> <vn-td shrink>{{entry.m3}}</vn-td>
<vn-td shrink> <vn-td shrink>
<vn-icon <vn-icon
ng-if="entry.notes.length" ng-if="entry.notes.length"
vn-tooltip="{{entry.notes}}" vn-tooltip="{{entry.notes}}"
@ -134,13 +134,13 @@
</vn-auto> </vn-auto>
<vn-auto ng-if="$ctrl.travelThermographs.length != 0"> <vn-auto ng-if="$ctrl.travelThermographs.length != 0">
<h4 ng-show="$ctrl.isBuyer"> <h4 ng-show="$ctrl.isBuyer">
<a <a
ui-sref="travel.card.thermograph.index({id:$ctrl.travelData.id})" ui-sref="travel.card.thermograph.index({id:$ctrl.travelData.id})"
target="_self"> target="_self">
<span translate vn-tooltip="Go to">Thermograph</span> <span translate vn-tooltip="Go to">Thermograph</span>
</a> </a>
</h4> </h4>
<h4 <h4
translate translate
ng-show="!$ctrl.isBuyer"> ng-show="!$ctrl.isBuyer">
Thermograph Thermograph
@ -168,6 +168,6 @@
</vn-auto> </vn-auto>
</vn-horizontal> </vn-horizontal>
</vn-card> </vn-card>
<vn-entry-descriptor-popover <vn-entry-descriptor-popover
vn-id="entryDescriptor"> vn-id="entryDescriptor">
</vn-entry-descriptor-popover> </vn-entry-descriptor-popover>

View File

@ -410,6 +410,8 @@ describe('workerTimeControl add/delete timeEntry()', () => {
describe('12h rest', () => { describe('12h rest', () => {
it('should throw an error when the 12h rest is not fulfilled yet', async() => { it('should throw an error when the 12h rest is not fulfilled yet', async() => {
pending('https://redmine.verdnatura.es/issues/4707');
activeCtx.accessToken.userId = salesBossId; activeCtx.accessToken.userId = salesBossId;
const workerId = hankPymId; const workerId = hankPymId;

40058
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
const Stylesheet = require(`vn-print/core/stylesheet`);
const path = require('path');
const vnPrintPath = path.resolve('print');
module.exports = new Stylesheet([
`${vnPrintPath}/common/css/spacing.css`,
`${vnPrintPath}/common/css/misc.css`,
`${vnPrintPath}/common/css/layout.css`,
`${vnPrintPath}/common/css/email.css`])
.mergeStyles();

View File

@ -0,0 +1,3 @@
subject: Pay method updated
title: Pay method updated
description: The pay method of the supplier {0} has been updated from {1} to {2}

View File

@ -0,0 +1,3 @@
subject: Método de pago actualizado
title: Método de pago actualizado
description: Se ha actualizado el método de pago del proveedor {0} de {1} a {2}

View File

@ -0,0 +1,8 @@
<email-body v-bind="$props">
<div class="grid-row">
<div class="grid-block vn-pa-ml">
<h1>{{ $t('title') }}</h1>
<p v-html="$t('description', [name, oldPayMethod, newPayMethod])"></p>
</div>
</div>
</email-body>

View File

@ -0,0 +1,23 @@
const Component = require(`vn-print/core/component`);
const emailBody = new Component('email-body');
module.exports = {
name: 'supplier-pay-method-update',
components: {
'email-body': emailBody.build(),
},
props: {
name: {
type: String,
required: true
},
oldPayMethod: {
type: String,
required: true
},
newPayMethod: {
type: String,
required: true
}
}
};

View File

@ -13,11 +13,12 @@ html {
font-size: 29px; font-size: 29px;
margin-left: -13px; margin-left: -13px;
} }
.outline { #outline {
border: 1px solid black; border: 1px solid black;
padding: 5px; padding: 5px;
height: 37px; height: 37px;
width: 100px; width: 100px;
max-width: 100px;
} }
#nickname { #nickname {
font-size: 22px; font-size: 22px;

View File

@ -12,13 +12,13 @@
</tr> </tr>
<tr> <tr>
<td rowspan="3"><div v-html="getBarcode(labelData.ticketFk)" id="barcode"></div></td> <td rowspan="3"><div v-html="getBarcode(labelData.ticketFk)" id="barcode"></div></td>
<td class="outline">{{labelData.workerCode || '---'}}</td> <td id="outline" class="ellipsize">{{labelData.workerCode || '---'}}</td>
</tr> </tr>
<tr> <tr>
<td class="outline">{{labelData.labelCount || 0}}</td> <td id="outline" class="ellipsize">{{labelCount || labelData.labelCount || 0}}</td>
</tr> </tr>
<tr> <tr>
<td class="outline">{{labelData.code == 'V' ? (labelData.size || 0) + 'cm' : (labelData.volume || 0) + 'm³'}}</td> <td id="outline" class="ellipsize">{{labelData.code == 'V' ? (labelData.size || 0) + 'cm' : (labelData.volume || 0) + 'm³'}}</td>
</tr> </tr>
<tr> <tr>
<td><div id="agencyDescripton" class="ellipsize">{{labelData.agencyDescription ? labelData.agencyDescription.toUpperCase() : '---'}}</div></td> <td><div id="agencyDescripton" class="ellipsize">{{labelData.agencyDescription ? labelData.agencyDescription.toUpperCase() : '---'}}</div></td>

View File

@ -11,6 +11,11 @@ module.exports = {
type: Number, type: Number,
required: true, required: true,
description: 'The ticket or collection id' description: 'The ticket or collection id'
},
labelCount: {
type: Number,
required: false,
description: 'The number of labels'
} }
}, },
async serverPrefetch() { async serverPrefetch() {

View File

@ -12,8 +12,8 @@ SELECT c.itemPackingTypeFk code,
TIME_FORMAT(t.shipped, '%H:%i') shippedHour, TIME_FORMAT(t.shipped, '%H:%i') shippedHour,
TIME_FORMAT(zo.`hour`, '%H:%i') zoneHour, TIME_FORMAT(zo.`hour`, '%H:%i') zoneHour,
DATE_FORMAT(t.shipped, '%d/%m/%y') shipped, DATE_FORMAT(t.shipped, '%d/%m/%y') shipped,
t.nickName,
tt.labelCount, tt.labelCount,
t.nickName,
COUNT(*) lineCount COUNT(*) lineCount
FROM vn.ticket t FROM vn.ticket t
JOIN vn.ticketCollection tc ON tc.ticketFk = t.id JOIN vn.ticketCollection tc ON tc.ticketFk = t.id

View File

@ -20,7 +20,7 @@
</tr> </tr>
<tr> <tr>
<td class="font gray uppercase">{{$t('ref')}}</td> <td class="font gray uppercase">{{$t('ref')}}</td>
<th>{{entry.ref}}</th> <th>{{entry.invoiceNumber}}</th>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -1,10 +1,10 @@
SELECT SELECT
e.id, e.id,
e.ref, e.invoiceNumber,
e.notes, e.notes,
c.code companyCode, c.code companyCode,
t.landed t.landed
FROM entry e FROM entry e
JOIN travel t ON t.id = e.travelFk JOIN travel t ON t.id = e.travelFk
JOIN company c ON c.id = e.companyFk JOIN company c ON c.id = e.companyFk
WHERE e.id = ? WHERE e.id = ?

Some files were not shown because too many files have changed in this diff Show More