Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 2404-catalog_color

This commit is contained in:
Carlos Jimenez Ruiz 2020-09-10 14:38:48 +02:00
commit 270e665291
113 changed files with 3925 additions and 959 deletions

View File

@ -1,2 +0,0 @@
UPDATE `salix`.`ACL` SET `model` = 'Calendar' WHERE (`id` = '155');
UPDATE `salix`.`ACL` SET `model` = 'Calendar' WHERE (`id` = '157');

View File

@ -1,44 +0,0 @@
USE `vn`;
DROP procedure IF EXISTS `vn`.`itemLastEntries`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `itemLastEntries__`(IN `vItem` INT, IN `vDays` DATE)
BEGIN
SELECT
w.id AS warehouseFk,
w.name AS warehouse,
tr.landed,
b.entryFk,
b.isIgnored,
b.price2,
b.price3,
b.stickers,
b.packing,
b.`grouping`,
b.groupingMode,
b.weight,
i.stems,
b.quantity,
b.buyingValue,
b.packageFk ,
s.id AS supplierFk,
s.name AS supplier
FROM itemType it
RIGHT JOIN (entry e
LEFT JOIN supplier s ON s.id = e.supplierFk
RIGHT JOIN buy b ON b.entryFk = e.id
LEFT JOIN item i ON i.id = b.itemFk
LEFT JOIN ink ON ink.id = i.inkFk
LEFT JOIN travel tr ON tr.id = e.travelFk
LEFT JOIN warehouse w ON w.id = tr.warehouseInFk
LEFT JOIN origin o ON o.id = i.originFk
) ON it.id = i.typeFk
LEFT JOIN edi.ekt ek ON b.ektFk = ek.id
WHERE b.itemFk = vItem And tr.shipped BETWEEN vDays AND DATE_ADD(CURDATE(), INTERVAl + 10 DAY)
ORDER BY tr.landed DESC , b.id DESC;
END$$
DELIMITER ;
;

View File

@ -1,47 +0,0 @@
USE `vn`;
CREATE
OR REPLACE ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn`.`zoneEstimatedDelivery` AS
SELECT
`t`.`zoneFk` AS `zoneFk`,
CAST((CURDATE() + INTERVAL ((HOUR(`zc`.`hour`) * 60) + MINUTE(`zc`.`hour`)) MINUTE)
AS TIME) AS `hourTheoretical`,
CAST(SUM(`sv`.`volume`) AS DECIMAL (5 , 1 )) AS `totalVolume`,
CAST(SUM(IF((`s`.`alertLevel` < 2),
`sv`.`volume`,
0))
AS DECIMAL (5 , 1 )) AS `remainingVolume`,
GREATEST(IFNULL(`lhp`.`m3`, 0),
IFNULL(`dl`.`minSpeed`, 0)) AS `speed`,
CAST((`zc`.`hour` + INTERVAL ((-(SUM(IF((`s`.`alertLevel` < 2),
`sv`.`volume`,
0))) * 60) / GREATEST(IFNULL(`lhp`.`m3`, 0),
IFNULL(`dl`.`minSpeed`, 0))) MINUTE)
AS TIME) AS `hourEffective`,
FLOOR(((-(SUM(IF((`s`.`alertLevel` < 2),
`sv`.`volume`,
0))) * 60) / GREATEST(IFNULL(`lhp`.`m3`, 0),
IFNULL(`dl`.`minSpeed`, 0)))) AS `minutesLess`,
CAST((`zc`.`hour` + INTERVAL ((-(SUM(IF((`s`.`alertLevel` < 2),
`sv`.`volume`,
0))) * 60) / GREATEST(IFNULL(`lhp`.`m3`, 0),
IFNULL(`dl`.`minSpeed`, 0))) MINUTE)
AS TIME) AS `etc`
FROM
((((((((`ticket` `t`
JOIN `ticketStateToday` `tst` ON ((`tst`.`ticket` = `t`.`id`)))
JOIN `state` `s` ON ((`s`.`id` = `tst`.`state`)))
JOIN `saleVolume` `sv` ON ((`sv`.`ticketFk` = `t`.`id`)))
LEFT JOIN `lastHourProduction` `lhp` ON ((`lhp`.`warehouseFk` = `t`.`warehouseFk`)))
JOIN `warehouse` `w` ON ((`w`.`id` = `t`.`warehouseFk`)))
JOIN `warehouseAlias` `wa` ON ((`wa`.`id` = `w`.`aliasFk`)))
LEFT JOIN `zoneClosure` `zc` ON (((`zc`.`zoneFk` = `t`.`zoneFk`)
AND (`zc`.`dated` = CURDATE()))))
LEFT JOIN `cache`.`departure_limit` `dl` ON (((`dl`.`warehouse_id` = `t`.`warehouseFk`)
AND (`dl`.`fecha` = CURDATE()))))
WHERE
((`wa`.`name` = 'Silla')
AND (CAST(`t`.`shipped` AS DATE) = CURDATE()))
GROUP BY `t`.`zoneFk`;

View File

@ -1,16 +0,0 @@
CREATE
OR REPLACE ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn`.`zone_ETD` AS
SELECT
`zed`.`zoneFk` AS `zoneFk`,
`zed`.`hourTheoretical` AS `HoraTeórica`,
`zed`.`totalVolume` AS `volumenTotal`,
`zed`.`remainingVolume` AS `volumenPendiente`,
`zed`.`speed` AS `velocidad`,
`zed`.`hourEffective` AS `HoraPráctica`,
`zed`.`minutesLess` AS `minutesLess`,
`zed`.`etc` AS `etc`
FROM
`vn`.`zoneEstimatedDelivery` `zed`

View File

@ -1,2 +1,2 @@
ALTER TABLE `vn`.`accountingType` ALTER TABLE `vn`.`accountingType`
ADD COLUMN `receiptDescription` VARCHAR(50) NULL AFTER `description`; ADD COLUMN `receiptDescription` VARCHAR(50) NULL COMMENT 'Descripción por defecto al crear nuevo recibo' AFTER `description`;

View File

@ -0,0 +1,119 @@
USE `vn`;
DROP procedure IF EXISTS `ticket_close`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticket_close`(vTicketFk INT)
BEGIN
/**
* Realiza el cierre de todos los
* tickets de la tabla ticketClosure.
*
* @param vTicketFk Id del ticket
*/
DECLARE vDone BOOL;
DECLARE vClientFk INT;
DECLARE vCurTicketFk INT;
DECLARE vIsTaxDataChecked BOOL;
DECLARE vCompanyFk INT;
DECLARE vShipped DATE;
DECLARE vNewInvoiceId INT;
DECLARE vHasDailyInvoice BOOL;
DECLARE vWithPackage BOOL;
DECLARE vHasToInvoice BOOL;
DECLARE cur CURSOR FOR
SELECT ticketFk FROM tmp.ticketClosure;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN
RESIGNAL;
END;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
CREATE TEMPORARY TABLE tmp.ticketClosure
SELECT vTicketFk AS ticketFk;
INSERT INTO tmp.ticketClosure
SELECT id FROM stowaway s
WHERE s.shipFk = vTicketFk;
OPEN cur;
proc: LOOP
SET vDone = FALSE;
FETCH cur INTO vCurTicketFk;
IF vDone THEN
LEAVE proc;
END IF;
-- ticketClosure start
SELECT
c.id,
c.isTaxDataChecked,
t.companyFk,
t.shipped,
co.hasDailyInvoice,
w.isManaged,
c.hasToInvoice
INTO vClientFk,
vIsTaxDataChecked,
vCompanyFk,
vShipped,
vHasDailyInvoice,
vWithPackage,
vHasToInvoice
FROM ticket t
JOIN `client` c ON c.id = t.clientFk
JOIN province p ON p.id = c.provinceFk
JOIN country co ON co.id = p.countryFk
JOIN warehouse w ON w.id = t.warehouseFk
WHERE t.id = vCurTicketFk;
INSERT INTO ticketPackaging (ticketFk, packagingFk, quantity)
(SELECT vCurTicketFk, p.id, COUNT(*)
FROM expedition e
JOIN packaging p ON p.itemFk = e.itemFk
WHERE e.ticketFk = vCurTicketFk AND p.isPackageReturnable
AND vWithPackage
GROUP BY p.itemFk);
-- No retornables o no catalogados
INSERT INTO sale (itemFk, ticketFk, concept, quantity, price, isPriceFixed)
(SELECT e.itemFk, vCurTicketFk, i.name, COUNT(*) AS amount, getSpecialPrice(e.itemFk, vClientFk), 1
FROM expedition e
JOIN item i ON i.id = e.itemFk
LEFT JOIN packaging p ON p.itemFk = i.id
WHERE e.ticketFk = vCurTicketFk AND IFNULL(p.isPackageReturnable, 0) = 0
AND getSpecialPrice(e.itemFk, vClientFk) > 0
GROUP BY e.itemFk);
CALL vn.zonePromo_Make();
IF(vHasDailyInvoice) AND vHasToInvoice THEN
-- Facturacion rapida
CALL ticketTrackingAdd(vCurTicketFk, 'DELIVERED', NULL);
-- Facturar si está contabilizado
IF vIsTaxDataChecked THEN
CALL invoiceOut_newFromClient(
vClientFk,
(SELECT invoiceSerial(vClientFk, vCompanyFk, 'M')),
vShipped,
vCompanyFk,
NULL,
vNewInvoiceId);
END IF;
ELSE
CALL ticketTrackingAdd(vCurTicketFk, (SELECT vn.getAlert3State(vCurTicketFk)), NULL);
END IF;
END LOOP;
CLOSE cur;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
END$$
DELIMITER ;

File diff suppressed because one or more lines are too long

View File

@ -540,6 +540,32 @@ INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agen
(6, NULL, 57, CURDATE(), 5, 7, 'sixth route', 1.7, 60, CURDATE(), CURDATE(), 3), (6, NULL, 57, CURDATE(), 5, 7, 'sixth route', 1.7, 60, CURDATE(), CURDATE(), 3),
(7, NULL, 57, CURDATE(), 6, 8, 'seventh route', 0, 70, CURDATE(), CURDATE(), 5); (7, NULL, 57, CURDATE(), 6, 8, 'seventh route', 0, 70, CURDATE(), CURDATE(), 5);
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`,`zonePrice`, `zoneBonus`, `created`)
VALUES
(1 , 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Bat cave', 121, 'T1111111', 0, 1, 5, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(2 , 1, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T1111111', 0, 1, 5, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(3 , 1, 7, 1, 6, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T2222222', 0, 3, 5, 1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
(4 , 3, 2, 1, 2, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T3333333', 0, 9, 5, 1, DATE_ADD(CURDATE(), INTERVAL -3 MONTH)),
(5 , 3, 3, 3, 3, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T4444444', 0, 10, 5, 1, DATE_ADD(CURDATE(), INTERVAL -4 MONTH)),
(6 , 1, 3, 3, 3, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Mountain Drive Gotham', 1, 'A1111111', 0, 10, 5, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(7 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Mountain Drive Gotham', 1, NULL, 0, 3, 5, 1, CURDATE()),
(8 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Bat cave', 121, NULL, 0, 3, 5, 1, CURDATE()),
(9 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Stark tower', 124, NULL, 0, 3, 5, 1, CURDATE()),
(10, 1, 1, 5, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'Ingram Street', 2, NULL, 0, 1, 5, 1, CURDATE()),
(11, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'NY roofs', 122, NULL, 0, 3, 5, 1, CURDATE()),
(12, 1, 1, 1, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 1, 5, 1, CURDATE()),
(13, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 3, 5, 1, CURDATE()),
(14, 1, 2, 1, NULL, CURDATE(), CURDATE(), 104, 'Malibu Point', 4, NULL, 0, 9, 5, 1, CURDATE()),
(15, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 105, 'Plastic Cell', 125, NULL, 0, 3, 5, 1, CURDATE()),
(16, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, 5, 1, CURDATE()),
(17, 1, 7, 2, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, 5, 1, CURDATE()),
(18, 1, 4, 4, 4, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 108, 'Cerebro', 128, NULL, 0, 12, 5, 1, CURDATE()),
(19, 1, 5, 5, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 1, NULL, 5, 1, CURDATE()),
(20, 1, 5, 5, 3, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 0, 13, 5, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
(21, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Holland', 102, NULL, 0, 13, 5, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
(22, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Japan', 103, NULL, 0, 13, 5, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
(23, NULL, 8, 1, 7, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'address 21', 121, NULL, 0, 5, 5, 1, CURDATE()),
(24 ,NULL, 8, 1, 7, CURDATE(), CURDATE(), 101, 'Bruce Wayne', 1, NULL, 0, 5, 5, 1, CURDATE());
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `created`) INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `created`)
VALUES VALUES
(1 , 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Bat cave', 121, 'T1111111', 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)), (1 , 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Bat cave', 121, 'T1111111', 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
@ -688,11 +714,13 @@ INSERT INTO `vn`.`itemType`(`id`, `code`, `name`, `categoryFk`, `life`,`workerFk
(5, 'CON', 'Container', 3, NULL, 35, 1), (5, 'CON', 'Container', 3, NULL, 35, 1),
(6, 'ALS', 'Alstroemeria', 1, 31, 35, 0); (6, 'ALS', 'Alstroemeria', 1, 31, 35, 0);
INSERT INTO `vn`.`ink`(`id`, `name`, `picture`, `showOrder`) INSERT INTO `vn`.`ink`(`id`, `name`, `picture`, `showOrder`, `hex`)
VALUES VALUES
('YEL', 'Yellow', 1, 1), ('YEL', 'Yellow', 1, 1, 'F4D03F'),
('BLU', 'Blue', 1, 2), ('BLU', 'Blue', 1, 2, '5DADE2'),
('RED', 'Red', 1, 3); ('RED', 'Red', 1, 3, 'EC7063'),
('SLV', 'Silver', 1, 4, 'CACFD2'),
('BRW', 'Brown', 1, 5, 'DC7633');
INSERT INTO `vn`.`origin`(`id`,`code`, `name`) INSERT INTO `vn`.`origin`(`id`,`code`, `name`)
VALUES VALUES
@ -766,25 +794,9 @@ INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `create
(9, 3, 6, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 18), (9, 3, 6, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 18),
(10, 7, 7, 71, CURDATE(), 1, 1, 1, 18); (10, 7, 7, 71, CURDATE(), 1, 1, 1, 18);
INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `isOnOffer`, `expenceFk`, `isBargain`, `comment`, `relevancy`, `image`, `taxClassFk`, `subName`) INSERT INTO `vn`.`expeditionBoxVol`(`boxFk`, `m3`, `ratio`)
VALUES VALUES
(1, 2, 70, 'AMA', 1, 1, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 67, 1, NULL), (71,0.141,1);
(2, 2, 70, 'AZL', 1, 2, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 66, 1, NULL),
(3, 1, 60, 'AMR', 1, 3, NULL, 1, 05080000, 0, 4751000000, 0, NULL, 0, 65, 1, NULL),
(4, 1, 60, 'AMR', 1, 1, NULL, 1, 05080000, 1, 4751000000, 0, NULL, 0, 69, 2, NULL),
(5, 3, 30, 'GRE', 1, 2, NULL, 2, 06021010, 1, 4751000000, 0, NULL, 0, 74, 2, NULL),
(6, 5, 30, 'GRE', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 62, 2, NULL),
(7, 5, 90, 'AZL', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 64, 2, NULL),
(8, 2, 70, 'AMA', 1, 1, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 75, 1, NULL),
(9, 2, 70, 'AZL', 1, 2, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 76, 1, NULL),
(10, 1, 60, 'AMR', 1, 3, NULL, 1, 05080000, 0, 4751000000, 0, NULL, 0, 77, 1, NULL),
(11, 1, 60, 'AMR', 1, 1, NULL, 1, 05080000, 1, 4751000000, 0, NULL, 0, 78, 2, NULL),
(12, 3, 30, 'GRE', 1, 2, NULL, 2, 06021010, 1, 4751000000, 0, NULL, 0, 82, 2, NULL),
(13, 5, 30, 'GRE', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 83, 2, NULL),
(14, 5, 90, 'AZL', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 84, 2, NULL),
(15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
(16, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
(71, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 1, 4751000000, 0, NULL, 0, 88, 2, NULL);
INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPackageReturnable`, `created`, `itemFk`, `price`) INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPackageReturnable`, `created`, `itemFk`, `price`)
VALUES VALUES
@ -797,18 +809,7 @@ INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPack
('cc', 1640038.00, 56.00, 220.00, 128.00, 1, CURDATE(), 15, 90.00), ('cc', 1640038.00, 56.00, 220.00, 128.00, 1, CURDATE(), 15, 90.00),
('pallet 100', 2745600.00, 100.00, 220.00, 120.00, 1, CURDATE(), 16, 0.00); ('pallet 100', 2745600.00, 100.00, 220.00, 120.00, 1, CURDATE(), 16, 0.00);
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `workerFk`, `packagingFk`)
VALUES
(1, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1),
(2, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 1),
(3, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 3, 1, 1),
(4, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 1),
(5, 1, 2, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1),
(6, 7, 3, 71, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 1, 1, 1),
(7, 2, 4, 71, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), 1, 1, 1, 1),
(8, 3, 5, 71, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), 1, 1, 1, 1),
(9, 3, 6, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1),
(10, 7, 7, 71, CURDATE(), 1, 1, 1, 1);
INSERT INTO `vn`.`ticketPackaging`(`id`, `ticketFk`, `packagingFk`, `quantity`, `created`, `pvp`) INSERT INTO `vn`.`ticketPackaging`(`id`, `ticketFk`, `packagingFk`, `quantity`, `created`, `pvp`)
VALUES VALUES

File diff suppressed because it is too large Load Diff

View File

@ -199,7 +199,7 @@ export default {
}, },
dms: { dms: {
deleteFileButton: 'vn-client-dms-index vn-tr:nth-child(1) vn-icon-button[icon="delete"]', deleteFileButton: 'vn-client-dms-index vn-tr:nth-child(1) vn-icon-button[icon="delete"]',
firstDocWorker: 'vn-client-dms-index vn-td:nth-child(7) > span', firstDocWorker: 'vn-client-dms-index vn-td:nth-child(8) > span',
firstDocWorkerDescriptor: '.vn-popover.shown vn-worker-descriptor' firstDocWorkerDescriptor: '.vn-popover.shown vn-worker-descriptor'
}, },
clientContacts: { clientContacts: {
@ -521,11 +521,11 @@ export default {
zone: 'vn-autocomplete[ng-model="$ctrl.zoneId"]', zone: 'vn-autocomplete[ng-model="$ctrl.zoneId"]',
nextStepButton: 'vn-step-control .buttons > section:last-child vn-button', nextStepButton: 'vn-step-control .buttons > section:last-child vn-button',
finalizeButton: 'vn-step-control .buttons > section:last-child button[type=submit]', finalizeButton: 'vn-step-control .buttons > section:last-child button[type=submit]',
stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two vn-tfoot > vn-tr > :nth-child(6)', stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > vn-side-menu div:nth-child(4)',
chargesReason: 'vn-ticket-basic-data-step-two div:nth-child(3) > vn-radio', chargesReason: 'vn-ticket-basic-data-step-two div:nth-child(3) > vn-radio',
}, },
ticketComponents: { ticketComponents: {
base: 'vn-ticket-components [name="base-sum"]' base: 'vn-ticket-components > vn-side-menu div:nth-child(1) > div:nth-child(2)'
}, },
ticketRequests: { ticketRequests: {
addRequestButton: 'vn-ticket-request-index > a > vn-float-button > button', addRequestButton: 'vn-ticket-request-index > a > vn-float-button > button',
@ -894,6 +894,7 @@ export default {
header: 'vn-entry-summary > vn-card > h5', header: 'vn-entry-summary > vn-card > h5',
reference: 'vn-entry-summary vn-label-value[label="Reference"]', reference: 'vn-entry-summary vn-label-value[label="Reference"]',
confirmed: 'vn-entry-summary vn-check[label="Confirmed"]', confirmed: 'vn-entry-summary vn-check[label="Confirmed"]',
anyBuyLine: 'vn-entry-summary tr.dark-row'
}, },
entryDescriptor: { entryDescriptor: {
agency: 'vn-entry-descriptor div.body vn-label-value:nth-child(1) span', agency: 'vn-entry-descriptor div.body vn-label-value:nth-child(1) span',
@ -909,5 +910,12 @@ export default {
newValueInput: 'vn-textfield[ng-model="$ctrl.editedColumn.newValue"]', newValueInput: 'vn-textfield[ng-model="$ctrl.editedColumn.newValue"]',
latestBuysSectionButton: 'a[ui-sref="entry.latestBuys"]', latestBuysSectionButton: 'a[ui-sref="entry.latestBuys"]',
acceptEditBuysDialog: 'button[response="accept"]' acceptEditBuysDialog: 'button[response="accept"]'
},
entryIndex: {
createEntryButton: 'vn-entry-index vn-button[icon="add"]',
newEntrySupplier: 'vn-entry-create vn-autocomplete[ng-model="$ctrl.entry.supplierFk"]',
newEntryTravel: 'vn-entry-create vn-autocomplete[ng-model="$ctrl.entry.travelFk"]',
newEntryCompany: 'vn-entry-create vn-autocomplete[ng-model="$ctrl.entry.companyFk"]',
saveNewEntry: 'vn-entry-create button[type="submit"]'
} }
}; };

View File

@ -24,7 +24,6 @@ describe('Ticket List components path', () => {
await page.waitPropertyLength(selectors.ticketComponents.base, 'innerText', minLength); await page.waitPropertyLength(selectors.ticketComponents.base, 'innerText', minLength);
const base = await page.waitToGetProperty(selectors.ticketComponents.base, 'innerText'); const base = await page.waitToGetProperty(selectors.ticketComponents.base, 'innerText');
expect(base).toContain('Base'); expect(base).toContain('Base');
expect(base.length).toBeGreaterThan(minLength); expect(base.length).toBeGreaterThan(minLength);
}); });

View File

@ -9,7 +9,7 @@ describe('Entry summary path', () => {
browser = await getBrowser(); browser = await getBrowser();
page = browser.page; page = browser.page;
await page.loginAndModule('buyer', 'entry'); await page.loginAndModule('buyer', 'entry');
await page.waitToClick('vn-entry-index vn-tbody > a:nth-child(2)'); await page.accessToSearchResult('4');
}); });
afterAll(async() => { afterAll(async() => {
@ -30,7 +30,7 @@ describe('Entry summary path', () => {
it('should display some entry details like the reference', async() => { it('should display some entry details like the reference', async() => {
const result = await page.waitToGetProperty(selectors.entrySummary.reference, 'innerText'); const result = await page.waitToGetProperty(selectors.entrySummary.reference, 'innerText');
expect(result).toContain('Movement 2'); expect(result).toContain('Movement 4');
}); });
it('should display other entry details like the confirmed', async() => { it('should display other entry details like the confirmed', async() => {
@ -38,4 +38,10 @@ describe('Entry summary path', () => {
expect(result).toContain('unchecked'); expect(result).toContain('unchecked');
}); });
it('should display all buys for the entry', async() => {
const result = await page.countElement(selectors.entrySummary.anyBuyLine);
expect(result).toEqual(4);
});
}); });

View File

@ -0,0 +1,33 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Entry create path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'entry');
});
afterAll(async() => {
await browser.close();
});
it('should click the create entry button to open the form', async() => {
await page.waitToClick(selectors.entryIndex.createEntryButton);
await page.waitForState('entry.create');
});
it('should fill the form to create a valid entry', async() => {
await page.autocompleteSearch(selectors.entryIndex.newEntrySupplier, '2');
await page.autocompleteSearch(selectors.entryIndex.newEntryTravel, 'Warehouse Three');
await page.autocompleteSearch(selectors.entryIndex.newEntryCompany, 'ORN');
await page.waitToClick(selectors.entryIndex.saveNewEntry);
});
it('should be redirected to entry basic data', async() => {
await page.waitForState('entry.card.basicData');
});
});

View File

@ -1,6 +1,7 @@
@import "variables"; @import "variables";
.vn-radio { .vn-radio {
& > .btn { & > .btn {
border-radius: 50%; border-radius: 50%;
@ -25,4 +26,8 @@
&.disabled.checked > .btn > .mark { &.disabled.checked > .btn > .mark {
background-color: $color-font-secondary; background-color: $color-font-secondary;
} }
> div {
text-overflow: ellipsis;
overflow: hidden;
}
} }

View File

@ -2,6 +2,6 @@
<div class="focus-mark"></div> <div class="focus-mark"></div>
<div class="mark"></div> <div class="mark"></div>
</div> </div>
<span translate> <div translate>
{{::$ctrl.label}} {{::$ctrl.label}}
</span> </div>

View File

@ -106,7 +106,7 @@ module.exports = Self => {
let stmt; let stmt;
stmt = new ParameterizedSQL( stmt = new ParameterizedSQL(
`SELECT cl.id, c.name, cl.clientFk, cl.workerFk, u.nickName, cs.description, cl.created `SELECT cl.id, c.name, cl.clientFk, cl.workerFk, u.name AS userName, cs.description, cl.created
FROM claim cl FROM claim cl
LEFT JOIN client c ON c.id = cl.clientFk LEFT JOIN client c ON c.id = cl.clientFk
LEFT JOIN worker w ON w.id = cl.workerFk LEFT JOIN worker w ON w.id = cl.workerFk

View File

@ -12,7 +12,7 @@ class Controller extends ModuleCard {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
} }
} }

View File

@ -32,20 +32,32 @@
value="{{$ctrl.claim.created | date: 'dd/MM/yyyy HH:mm'}}"> value="{{$ctrl.claim.created | date: 'dd/MM/yyyy HH:mm'}}">
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Salesperson" label="Salesperson">
value="{{$ctrl.claim.client.salesPersonUser.nickname}}"> <span
ng-click="workerDescriptor.show($event, $ctrl.claim.client.salesPersonFk)"
class="link">
{{$ctrl.claim.client.salesPersonUser.name}}
</span>
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Attended by" label="Attended by">
value="{{$ctrl.claim.worker.user.nickname}}"> <span
ng-click="workerDescriptor.show($event, $ctrl.claim.worker.userFk)"
class="link">
{{$ctrl.claim.worker.user.name}}
</span>
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Agency" label="Agency"
value="{{$ctrl.claim.ticket.agencyMode.name}}"> value="{{$ctrl.claim.ticket.agencyMode.name}}">
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Ticket" label="Ticket">
value="{{$ctrl.claim.ticketFk}}"> <span
ng-click="ticketDescriptor.show($event, $ctrl.claim.ticketFk)"
class="link">
{{$ctrl.claim.ticketFk}}
</span>
</vn-label-value> </vn-label-value>
</div> </div>
<div class="quicklinks"> <div class="quicklinks">
@ -79,3 +91,9 @@
question="Delete claim" question="Delete claim"
message="Are you sure you want to delete this claim?"> message="Are you sure you want to delete this claim?">
</vn-confirm> </vn-confirm>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>
<vn-ticket-descriptor-popover
vn-id="ticketDescriptor">
</vn-ticket-descriptor-popover>

View File

@ -34,7 +34,7 @@
<span <span
vn-click-stop="workerDescriptor.show($event, claim.workerFk)" vn-click-stop="workerDescriptor.show($event, claim.workerFk)"
class="link" > class="link" >
{{::claim.nickName}} {{::claim.userName}}
</span> </span>
</vn-td> </vn-td>
<vn-td> <vn-td>

View File

@ -7,6 +7,6 @@ describe('Client get', () => {
expect(result.id).toEqual(101); expect(result.id).toEqual(101);
expect(result.name).toEqual('Bruce Wayne'); expect(result.name).toEqual('Bruce Wayne');
expect(result.debt).toEqual(879.38); expect(result.debt).toEqual(889.38);
}); });
}); });

View File

@ -4,7 +4,7 @@ describe('client getDebt()', () => {
it('should return the client debt', async() => { it('should return the client debt', async() => {
let result = await app.models.Client.getDebt(101); let result = await app.models.Client.getDebt(101);
expect(result.debt).toEqual(879.38); expect(result.debt).toEqual(889.38);
}); });
}); });

View File

@ -17,7 +17,7 @@ describe('client summary()', () => {
it('should return a summary object containing debt', async() => { it('should return a summary object containing debt', async() => {
let result = await app.models.Client.summary(101); let result = await app.models.Client.summary(101);
expect(result.debt.debt).toEqual(879.38); expect(result.debt.debt).toEqual(889.38);
}); });
it('should return a summary object containing averageInvoiced', async() => { it('should return a summary object containing averageInvoiced', async() => {

View File

@ -48,7 +48,7 @@ module.exports = Self => {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
} }
} }

View File

@ -23,7 +23,13 @@
<vn-tbody> <vn-tbody>
<vn-tr ng-repeat="credit in credits track by credit.id"> <vn-tr ng-repeat="credit in credits track by credit.id">
<vn-td>{{::credit.created | date:'dd/MM/yyyy HH:mm'}}</vn-td> <vn-td>{{::credit.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>
<vn-td>{{::credit.worker.user.nickname}}</vn-td> <vn-td>
<span
ng-click="workerDescriptor.show($event, credit.worker.userFk)"
class="link">
{{::credit.worker.user.name}}
</span>
</vn-td>
<vn-td number>{{::credit.amount | currency:'EUR':2}}</vn-td> <vn-td number>{{::credit.amount | currency:'EUR':2}}</vn-td>
</vn-tr> </vn-tr>
</vn-tbody> </vn-tbody>
@ -39,3 +45,6 @@
vn-bind="+" vn-bind="+"
fixed-bottom-right> fixed-bottom-right>
</vn-float-button> </vn-float-button>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

@ -13,7 +13,7 @@ class Controller extends Section {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
} }
} }

View File

@ -35,8 +35,12 @@
info="Invoices minus payments plus orders not yet invoiced"> info="Invoices minus payments plus orders not yet invoiced">
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Sales person" label="Sales person">
value="{{$ctrl.client.salesPerson.user.nickname}}"> <span
ng-click="workerDescriptor.show($event, $ctrl.client.salesPersonFk)"
class="link">
{{$ctrl.client.salesPerson.user.name}}
</span>
</vn-label-value> </vn-label-value>
</div> </div>
<div class="icons"> <div class="icons">
@ -90,3 +94,6 @@
vn-id="sms" vn-id="sms"
sms="$ctrl.newSMS"> sms="$ctrl.newSMS">
</vn-client-sms> </vn-client-sms>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

@ -53,6 +53,12 @@
{{::document.dms.description}} {{::document.dms.description}}
</span> </span>
</vn-td> </vn-td>
<vn-td shrink>
<vn-check
ng-model="document.dms.hasFile"
disabled="true">
</vn-check>
</vn-td>
<vn-td shrink> <vn-td shrink>
<span title="{{'Download file' | translate}}" class="link" <span title="{{'Download file' | translate}}" class="link"
ng-click="$ctrl.downloadFile(document.dmsFk)"> ng-click="$ctrl.downloadFile(document.dmsFk)">
@ -62,7 +68,7 @@
<vn-td shrink> <vn-td shrink>
<span class="link" <span class="link"
ng-click="workerDescriptor.show($event, document.dms.workerFk)"> ng-click="workerDescriptor.show($event, document.dms.workerFk)">
{{::document.dms.worker.user.nickname | dashIfEmpty}} {{::document.dms.worker.user.name | dashIfEmpty}}
</span></vn-td> </span></vn-td>
<vn-td> <vn-td>
{{::document.dms.created | date:'dd/MM/yyyy HH:mm'}} {{::document.dms.created | date:'dd/MM/yyyy HH:mm'}}

View File

@ -32,7 +32,7 @@ class Controller extends Section {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
}, },
} }

View File

@ -32,7 +32,7 @@
<span <span
ng-click="workerDescriptor.show($event, sample.worker.id)" ng-click="workerDescriptor.show($event, sample.worker.id)"
class="link"> class="link">
{{::sample.worker.user.nickname}} {{::sample.worker.user.name}}
</span> </span>
</vn-td> </vn-td>
<vn-td>{{::sample.company.code}}</vn-td> <vn-td>{{::sample.company.code}}</vn-td>

View File

@ -18,7 +18,7 @@ class Controller extends Section {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
} }
} }

View File

@ -21,8 +21,12 @@
<vn-label-value label="Email" ellipsize="false" <vn-label-value label="Email" ellipsize="false"
value="{{$ctrl.summary.email}}"> value="{{$ctrl.summary.email}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Sales person" <vn-label-value label="Sales person">
value="{{$ctrl.summary.salesPerson.user.nickname}}"> <span
ng-click="workerDescriptor.show($event, $ctrl.summary.salesPersonFk)"
class="link">
{{$ctrl.summary.salesPerson.user.name}}
</span>
</vn-label-value> </vn-label-value>
<vn-label-value label="Channel" <vn-label-value label="Channel"
value="{{$ctrl.summary.contactChannel.name}}"> value="{{$ctrl.summary.contactChannel.name}}">
@ -198,3 +202,6 @@
</vn-one> </vn-one>
</vn-horizontal> </vn-horizontal>
</vn-card> </vn-card>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

@ -0,0 +1,74 @@
module.exports = Self => {
Self.remoteMethod('getBuys', {
description: 'Returns buys for one entry',
accessType: 'READ',
accepts: {
arg: 'id',
type: 'number',
required: true,
description: 'The entry id',
http: {source: 'path'}
},
returns: {
type: ['Object'],
root: true
},
http: {
path: `/:id/getBuys`,
verb: 'GET'
}
});
Self.getBuys = async id => {
let filter = {
where: {entryFk: id},
fields: [
'id',
'itemFk',
'stickers',
'packing',
'grouping',
'quantity',
'packageFk',
'weight',
'buyingValue',
'price2',
'price3'
],
include: {
relation: 'item',
scope: {
fields: [
'id',
'typeFk',
'name',
'size',
'minPrice',
'tag5',
'value5',
'tag6',
'value6',
'tag7',
'value7',
'tag8',
'value8',
'tag9',
'value9',
'tag10',
'value10',
'groupingMode'
],
include: {
relation: 'itemType',
scope: {
fields: ['code', 'description']
}
}
}
}
};
let buys = await Self.app.models.Buy.find(filter);
return buys;
};
};

View File

@ -125,7 +125,8 @@ module.exports = Self => {
b.price2, b.price2,
b.price3, b.price3,
b.ektFk, b.ektFk,
b.weight b.weight,
b.packageFk
FROM cache.last_buy lb FROM cache.last_buy lb
LEFT JOIN cache.visible v ON v.item_id = lb.item_id LEFT JOIN cache.visible v ON v.item_id = lb.item_id
AND v.calc_id = @calc_id AND v.calc_id = @calc_id

View File

@ -0,0 +1,14 @@
const app = require('vn-loopback/server/server');
describe('entry getBuys()', () => {
const entryId = 4;
it('should get the buys and items of an entry', async() => {
const result = await app.models.Entry.getBuys(entryId);
const length = result.length;
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
expect(result.length).toEqual(4);
expect(anyResult.item).toBeDefined();
});
});

View File

@ -31,6 +31,12 @@
"grouping": { "grouping": {
"type": "number" "type": "number"
}, },
"stickers": {
"type": "number"
},
"packageFk": {
"type": "number"
},
"groupingMode": { "groupingMode": {
"type": "number" "type": "number"
}, },
@ -56,6 +62,12 @@
"model": "Entry", "model": "Entry",
"foreignKey": "entryFk", "foreignKey": "entryFk",
"required": true "required": true
},
"item": {
"type": "belongsTo",
"model": "Item",
"foreignKey": "itemFk",
"required": true
} }
} }
} }

View File

@ -1,4 +1,5 @@
module.exports = Self => { module.exports = Self => {
require('../methods/entry/filter')(Self); require('../methods/entry/filter')(Self);
require('../methods/entry/getEntry')(Self); require('../methods/entry/getEntry')(Self);
require('../methods/entry/getBuys')(Self);
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "Entry", "name": "Entry",
"base": "VnModel", "base": "Loggable",
"log": { "log": {
"model":"EntryLog" "model":"EntryLog"
}, },
@ -62,6 +62,18 @@
}, },
"loadPriority": { "loadPriority": {
"type": "number" "type": "number"
},
"supplierFk": {
"type": "number",
"required": true
},
"travelFk": {
"type": "number",
"required": true
},
"companyFk": {
"type": "number",
"required": true
} }
}, },
"relations": { "relations": {

View File

@ -0,0 +1,10 @@
import ngModule from '../module';
import Section from 'salix/components/section';
ngModule.vnComponent('vnEntryBasicData', {
template: require('./index.html'),
controller: Section,
bindings: {
entry: '<'
}
});

View File

@ -0,0 +1,61 @@
<mg-ajax path="Entries" options="vnPost"></mg-ajax>
<vn-watcher
vn-id="watcher"
data="$ctrl.entry"
form="form"
save="post">
</vn-watcher>
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-icon color-marginal
icon="info"
vn-tooltip="Required fields (*)">
</vn-icon>
<vn-horizontal>
<vn-autocomplete
vn-one
ng-model="$ctrl.entry.supplierFk"
url="Suppliers"
show-field="nickname"
search-function="{or: [{id: $search}, {nickname: {like: '%'+ $search +'%'}}]}"
value-field="id"
order="nickname"
label="Supplier"
required="true">
<tpl-item>
{{::id}} - {{::nickname}}
</tpl-item>
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete
vn-one
ng-model="$ctrl.entry.travelFk"
url="Travels/filter"
search-function="$ctrl.searchFunction($search)"
value-field="id"
order="id"
label="Travel"
required="true">
<tpl-item>
{{::agencyModeName}} - {{::warehouseInName}} ({{::shipped | date: 'dd/MM/yyyy'}}) &#x2192;
{{::warehouseOutName}} ({{::landed | date: 'dd/MM/yyyy'}})
</tpl-item>
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete
url="Companies"
label="Company"
show-field="code"
value-field="id"
ng-model="$ctrl.entry.companyFk"
required="true">
</vn-autocomplete>
</vn-horizontal>
</vn-card>
<vn-button-bar>
<vn-submit label="Create"></vn-submit>
<vn-button ui-sref="entry.index" label="Cancel"></vn-button>
</vn-button-bar>
</form>

View File

@ -0,0 +1,43 @@
import ngModule from '../module';
import Section from 'salix/components/section';
import './style.scss';
export default class Controller extends Section {
constructor($element, $) {
super($element, $);
this.entry = {
companyFk: this.vnConfig.companyFk
};
if (this.$params && this.$params.supplierFk)
this.entry.supplierFk = parseInt(this.$params.supplierFk);
if (this.$params && this.$params.travelFk)
this.entry.travelFk = parseInt(this.$params.travelFk);
if (this.$params && this.$params.companyFk)
this.entry.companyFk = parseInt(this.$params.companyFk);
}
onSubmit() {
this.$.watcher.submit().then(
res => this.$state.go('entry.card.basicData', {id: res.data.id})
);
}
searchFunction($search) {
return {or: [
{'agencyModeName': {like: `%${$search}%`}},
{'warehouseInName': {like: `%${$search}%`}},
{'warehouseOutName': {like: `%${$search}%`}},
{'shipped': new Date($search)},
{'landed': new Date($search)}
]};
}
}
Controller.$inject = ['$element', '$scope'];
ngModule.vnComponent('vnEntryCreate', {
template: require('./index.html'),
controller: Controller
});

View File

@ -0,0 +1,2 @@
New entry: Nueva entrada
Required fields (*): Campos requeridos (*)

View File

@ -0,0 +1,10 @@
vn-entry-create {
vn-card {
position: relative
}
vn-icon[icon="info"] {
position: absolute;
top: 16px;
right: 16px
}
}

View File

@ -2,6 +2,7 @@ export * from './module';
import './main'; import './main';
import './index/'; import './index/';
import './create';
import './latest-buys'; import './latest-buys';
import './search-panel'; import './search-panel';
import './latest-buys-search-panel'; import './latest-buys-search-panel';

View File

@ -70,3 +70,15 @@
<vn-travel-descriptor-popover <vn-travel-descriptor-popover
vn-id="travelDescriptor"> vn-id="travelDescriptor">
</vn-travel-descriptor-popover> </vn-travel-descriptor-popover>
<div fixed-bottom-right>
<vn-vertical style="align-items: center;">
<a ui-sref="entry.create" vn-bind="+">
<vn-button class="round md vn-mb-sm"
icon="add"
vn-tooltip="New entry"
tooltip-position="left">
</vn-button>
</a>
</vn-vertical>
</div>

View File

@ -33,6 +33,7 @@
<vn-th smart-table-ignore field="id">Id</vn-th> <vn-th smart-table-ignore field="id">Id</vn-th>
<vn-th field="packing">Packing</vn-th> <vn-th field="packing">Packing</vn-th>
<vn-th field="grouping">Grouping</vn-th> <vn-th field="grouping">Grouping</vn-th>
<vn-th field="quantity">Quantity</vn-th>
<vn-th field="description" style="text-align: center">Description</vn-th> <vn-th field="description" style="text-align: center">Description</vn-th>
<vn-th field="size">Size</vn-th> <vn-th field="size">Size</vn-th>
<vn-th field="type">Type</vn-th> <vn-th field="type">Type</vn-th>
@ -42,7 +43,6 @@
<vn-th field="isActive">Active</vn-th> <vn-th field="isActive">Active</vn-th>
<vn-th field="family">Family</vn-th> <vn-th field="family">Family</vn-th>
<vn-th field="entryFk">Entry</vn-th> <vn-th field="entryFk">Entry</vn-th>
<vn-th field="quantity">Quantity</vn-th>
<vn-th field="buyingValue">Buying value</vn-th> <vn-th field="buyingValue">Buying value</vn-th>
<vn-th field="freightValue">Freight value</vn-th> <vn-th field="freightValue">Freight value</vn-th>
<vn-th field="comissionValue" expand>Commission value</vn-th> <vn-th field="comissionValue" expand>Commission value</vn-th>
@ -53,6 +53,7 @@
<vn-th field="minPrice">Min price</vn-th> <vn-th field="minPrice">Min price</vn-th>
<vn-th field="ektFk">Ekt</vn-th> <vn-th field="ektFk">Ekt</vn-th>
<vn-th field="weight">Weight</vn-th> <vn-th field="weight">Weight</vn-th>
<vn-th field="packageFk" expand>PackageName</vn-th>
</vn-tr> </vn-tr>
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
@ -89,6 +90,7 @@
<span translate>{{::buy.grouping | dashIfEmpty}}</span> <span translate>{{::buy.grouping | dashIfEmpty}}</span>
</vn-chip> </vn-chip>
</vn-td> </vn-td>
<vn-td number>{{::buy.quantity}}</vn-td>
<vn-td vn-two title="{{::buy.description}}"> <vn-td vn-two title="{{::buy.description}}">
{{::buy.description | dashIfEmpty}} {{::buy.description | dashIfEmpty}}
</vn-td> </vn-td>
@ -115,7 +117,6 @@
{{::buy.entryFk}} {{::buy.entryFk}}
</span> </span>
</vn-td> </vn-td>
<vn-td number>{{::buy.quantity}}</vn-td>
<vn-td number>{{::buy.buyingValue | currency: 'EUR':2}}</vn-td> <vn-td number>{{::buy.buyingValue | currency: 'EUR':2}}</vn-td>
<vn-td number>{{::buy.freightValue | currency: 'EUR':2}}</vn-td> <vn-td number>{{::buy.freightValue | currency: 'EUR':2}}</vn-td>
<vn-td number>{{::buy.comissionValue | currency: 'EUR':2}}</vn-td> <vn-td number>{{::buy.comissionValue | currency: 'EUR':2}}</vn-td>
@ -126,6 +127,7 @@
<vn-td number>{{::buy.minPrice | currency: 'EUR':2}}</vn-td> <vn-td number>{{::buy.minPrice | currency: 'EUR':2}}</vn-td>
<vn-td number>{{::buy.ektFk | dashIfEmpty}}</vn-td> <vn-td number>{{::buy.ektFk | dashIfEmpty}}</vn-td>
<vn-td number>{{::buy.weight}}</vn-td> <vn-td number>{{::buy.weight}}</vn-td>
<vn-td number>{{::buy.packageFk}}</vn-td>
</a> </a>
</vn-tbody> </vn-tbody>
</vn-table> </vn-table>

View File

@ -1 +1,2 @@
Minimun amount: Minimun purchase quantity Minimun amount: Minimun purchase quantity
PackageName: Package

View File

@ -11,3 +11,4 @@ Ekt: Ekt
Weight: Peso Weight: Peso
Minimun amount: Cantidad mínima de compra Minimun amount: Cantidad mínima de compra
Field to edit: Campo a editar Field to edit: Campo a editar
PackageName: Cubo

View File

@ -10,6 +10,7 @@
{"state": "entry.latestBuys", "icon": "icon-latestBuys"} {"state": "entry.latestBuys", "icon": "icon-latestBuys"}
], ],
"card": [ "card": [
{"state": "entry.card.basicData", "icon": "settings"},
{"state": "entry.card.buy", "icon": "icon-lines"}, {"state": "entry.card.buy", "icon": "icon-lines"},
{"state": "entry.card.log", "icon": "history"} {"state": "entry.card.log", "icon": "history"}
] ]
@ -33,6 +34,12 @@
"component": "vn-entry-latest-buys", "component": "vn-entry-latest-buys",
"description": "Latest buys", "description": "Latest buys",
"acl": ["buyer"] "acl": ["buyer"]
}, {
"url": "/create?supplierFk&travelFk&companyFk",
"state": "entry.create",
"component": "vn-entry-create",
"description": "New entry",
"acl": ["buyer"]
}, { }, {
"url": "/:id", "url": "/:id",
"state": "entry.card", "state": "entry.card",
@ -46,6 +53,14 @@
"params": { "params": {
"entry": "$ctrl.entry" "entry": "$ctrl.entry"
} }
}, {
"url": "/basic-data",
"state": "entry.card.basicData",
"component": "vn-entry-basic-data",
"description": "Basic data",
"params": {
"entry": "$ctrl.entry"
}
}, { }, {
"url" : "/log", "url" : "/log",
"state": "entry.card.log", "state": "entry.card.log",

View File

@ -19,8 +19,12 @@
</vn-label-value> </vn-label-value>
</vn-one> </vn-one>
<vn-one> <vn-one>
<vn-label-value label="Agency" <vn-label-value label="Agency">
value="{{$ctrl.entryData.travel.agency.name}}"> <span
ng-click="travelDescriptor.show($event, $ctrl.entry.travel.agencyFk)"
class="link">
{{$ctrl.entryData.travel.agency.name}}
</span>
</vn-label-value> </vn-label-value>
<vn-label-value label="Shipped" <vn-label-value label="Shipped"
value="{{$ctrl.entryData.travel.shipped | date: 'dd/MM/yyyy'}}"> value="{{$ctrl.entryData.travel.shipped | date: 'dd/MM/yyyy'}}">
@ -65,4 +69,89 @@
</vn-vertical> </vn-vertical>
</vn-one> </vn-one>
</vn-horizontal> </vn-horizontal>
<vn-horizontal>
<vn-auto name="buys">
<h4 translate>Buys</h4>
<table class="vn-table">
<thead>
<tr>
<th translate center field="quantity">Quantity</th>
<th translate center field="sticker">Stickers</th>
<th translate center field="packageFk">Package</th>
<th translate center field="weight">Weight</th>
<th translate center field="packing">Packing</th>
<th translate center field="grouping">Grouping</th>
<th translate center field="buyingValue">Buying value</th>
<th translate center field="price3">Import</th>
<th translate center expand field="price2">Grouping price</th>
<th translate center expand field="price3">Packing price</th>
</tr>
</thead>
<tbody ng-repeat="line in $ctrl.buys">
<tr>
<td center title="{{::line.quantity}}">{{::line.quantity}}</td>
<td center title="{{::line.stickers | dashIfEmpty}}">{{::line.stickers | dashIfEmpty}}</td>
<td center title="{{::line.packageFk | dashIfEmpty}}">{{::line.packageFk | dashIfEmpty}}</td>
<td center title="{{::line.weight}}">{{::line.weight}}</td>
<td center>
<vn-chip translate-attr="line.groupingMode == 2 ? {title: 'Minimun amount'} : {title: 'Packing'}" ng-class="{'message': line.groupingMode == 2}">
<span translate>{{::line.packing | dashIfEmpty}}</span>
</vn-chip>
</td>
<td center>
<vn-chip translate-attr="line.groupingMode == 1 ? {title: 'Minimun amount'} : {title: 'Grouping'}" ng-class="{'message': line.groupingMode == 1}">
<span translate>{{::line.grouping | dashIfEmpty}}</span>
</vn-chip>
</vn-td>
<td center title="{{::line.buyingValue | currency: 'EUR':2}}">{{::line.buyingValue | currency: 'EUR':2}}</td>
<td center title="{{::line.quantity * line.buyingValue | currency: 'EUR':2}}">{{::line.quantity * line.buyingValue | currency: 'EUR':2}}</td>
<td center title="{{::line.price2 | currency: 'EUR':2}}">{{::line.price2 | currency: 'EUR':2}}</td>
<td center title="{{::line.price3 | currency: 'EUR':2}}">{{::line.price3 | currency: 'EUR':2}}</td>
</tr>
<tr class="dark-row">
<td shrink>
<span
translate-attr="{title: 'Item type'}">
{{::line.item.itemType.code}}
</span>
</td>
<td shrink>
<span
ng-click="itemDescriptor.show($event, line.item.id)"
class="link">
{{::line.item.id | zeroFill:6}}
</span>
</td>
<td number shrink>
<span
translate-attr="{title: 'Item size'}">
{{::line.item.size}}
</span>
</td>
<td center>
<span
translate-attr="{title: 'Minimum price'}">
{{::line.item.minPrice | currency: 'EUR':2}}
</span>
</td>
<td expand colspan="6">
<vn-fetched-tags
expand
item="::line.item"
name="::line.item.name"
sub-name="::line.item.subName">
</vn-fetched-tags>
</td>
</tr>
</tbody>
</table>
</vn-auto>
</vn-horizontal>
</vn-card> </vn-card>
<vn-item-descriptor-popover
vn-id="itemDescriptor">
</vn-item-descriptor-popover>
<vn-travel-descriptor-popover
vn-id="travelDescriptor">
</vn-travel-descriptor-popover>

View File

@ -10,15 +10,23 @@ class Controller extends Section {
set entry(value) { set entry(value) {
this._entry = value; this._entry = value;
if (value && value.id) if (value && value.id) {
this.getEntryData(); this.getEntryData();
this.getBuys();
}
} }
getEntryData() { getEntryData() {
return this.$http.get(`/api/Entries/${this.entry.id}/getEntry`).then(response => { return this.$http.get(`Entries/${this.entry.id}/getEntry`).then(response => {
this.entryData = response.data; this.entryData = response.data;
}); });
} }
getBuys() {
return this.$http.get(`Entries/${this.entry.id}/getBuys`).then(response => {
this.buys = response.data;
});
}
} }
ngModule.vnComponent('vnEntrySummary', { ngModule.vnComponent('vnEntrySummary', {

View File

@ -38,7 +38,7 @@ describe('component vnEntrySummary', () => {
it('should perform a get and then store data on the controller', () => { it('should perform a get and then store data on the controller', () => {
controller._entry = {id: 999}; controller._entry = {id: 999};
const query = `/api/Entries/${controller._entry.id}/getEntry`; const query = `Entries/${controller._entry.id}/getEntry`;
$httpBackend.expectGET(query).respond('I am the entryData'); $httpBackend.expectGET(query).respond('I am the entryData');
controller.getEntryData(); controller.getEntryData();
$httpBackend.flush(); $httpBackend.flush();
@ -46,4 +46,20 @@ describe('component vnEntrySummary', () => {
expect(controller.entryData).toEqual('I am the entryData'); expect(controller.entryData).toEqual('I am the entryData');
}); });
}); });
describe('getBuys()', () => {
it('should perform a get asking for the buys of an entry', () => {
controller._entry = {id: 999};
const thatQuery = `Entries/${controller._entry.id}/getEntry`;
const query = `Entries/${controller._entry.id}/getBuys`;
$httpBackend.whenGET(thatQuery).respond('My Entries');
$httpBackend.expectGET(query).respond('Some buys');
controller.getBuys();
$httpBackend.flush();
expect(controller.buys).toEqual('Some buys');
});
});
}); });

View File

@ -1,3 +1,8 @@
Inventory: Inventario Inventory: Inventario
Virtual: Redada Virtual: Redada
Entry: Entrada Entry: Entrada
Stickers: Etiquetas
Item size: Tamaño
Item type: Tipo
Minimum price: Precio mínimo
Buys: Compras

View File

@ -3,4 +3,18 @@
vn-entry-summary .summary { vn-entry-summary .summary {
max-width: $width-lg; max-width: $width-lg;
.dark-row {
background-color: lighten($color-marginal, 10%);
}
tbody {
border: 2px solid $color-marginal;
}
tr {
margin-bottom: 10px;
}
} }
$color-font-link-medium: lighten($color-font-link, 20%)

View File

@ -37,8 +37,12 @@
value="{{$ctrl.invoiceOut.amount | currency: 'EUR': 2}}"> value="{{$ctrl.invoiceOut.amount | currency: 'EUR': 2}}">
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Client" label="Client">
value="{{$ctrl.invoiceOut.client.name}}"> <span
ng-click="clientDescriptor.show($event, $ctrl.invoiceOut.client.id)"
class="link">
{{$ctrl.invoiceOut.client.name}}
</span>
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Company" label="Company"
@ -75,3 +79,6 @@
on-accept="$ctrl.bookInvoiceOut()" on-accept="$ctrl.bookInvoiceOut()"
question="Are you sure you want to book this invoice?"> question="Are you sure you want to book this invoice?">
</vn-confirm> </vn-confirm>
<vn-client-descriptor-popover
vn-id="clientDescriptor">
</vn-client-descriptor-popover>

View File

@ -26,7 +26,9 @@ module.exports = Self => {
await fs.mkdir(tempPath, {recursive: true}); await fs.mkdir(tempPath, {recursive: true});
const timer = setInterval(async() => { const timer = setInterval(async() => {
const image = await Self.findOne({where: {error: null}}); const image = await Self.findOne({
where: {error: null, url: {neq: null}}
});
// Exit loop // Exit loop
if (!image) return clearInterval(timer); if (!image) return clearInterval(timer);

View File

@ -113,7 +113,7 @@ module.exports = Self => {
i.isActive, i.isActive,
t.name type, t.name type,
t.workerFk buyerFk, t.workerFk buyerFk,
u.nickname userNickname, u.name userName,
intr.description AS intrastat, intr.description AS intrastat,
i.stems, i.stems,
ori.code AS origin, ori.code AS origin,

View File

@ -37,7 +37,7 @@ module.exports = Self => {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
} }
} }

View File

@ -38,7 +38,7 @@ module.exports = Self => {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
} }
} }

View File

@ -33,13 +33,13 @@
"retAccount": { "retAccount": {
"type": "Number" "type": "Number"
}, },
"commision": { "commission": {
"type": "Boolean" "type": "Boolean"
}, },
"created": { "created": {
"type": "Date" "type": "Date"
}, },
"poscodeFk": { "postcodeFk": {
"type": "Number" "type": "Number"
}, },
"isActive": { "isActive": {

View File

@ -44,8 +44,12 @@
<slot-body> <slot-body>
<div class="attributes"> <div class="attributes">
<vn-label-value <vn-label-value
label="Buyer" label="Buyer">
value="{{$ctrl.item.itemType.worker.user.nickname}}"> <span
ng-click="workerDescriptor.show($event, $ctrl.item.itemType.worker.userFk)"
class="link">
{{$ctrl.item.itemType.worker.user.name}}
</span>
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
ng-repeat="tag in $ctrl.item.tags | limitTo:4" ng-repeat="tag in $ctrl.item.tags | limitTo:4"
@ -96,3 +100,6 @@
question="Do you want to clone this item?" question="Do you want to clone this item?"
message="All it's properties will be copied"> message="All it's properties will be copied">
</vn-confirm> </vn-confirm>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

@ -70,11 +70,11 @@
{{::item.intrastat}} {{::item.intrastat}}
</vn-td> </vn-td>
<vn-td shrink>{{::item.origin}}</vn-td> <vn-td shrink>{{::item.origin}}</vn-td>
<vn-td shrink title="{{::item.userNickname}}"> <vn-td shrink title="{{::item.userName}}">
<span <span
class="link" class="link"
vn-click-stop="workerDescriptor.show($event, item.buyerFk)"> vn-click-stop="workerDescriptor.show($event, item.buyerFk)">
{{::item.userNickname}} {{::item.userName}}
</span> </span>
</vn-td> </vn-td>
<vn-td shrink>{{::item.density}}</vn-td> <vn-td shrink>{{::item.density}}</vn-td>

View File

@ -36,8 +36,12 @@
<vn-label-value label="stems" <vn-label-value label="stems"
value="{{$ctrl.summary.item.stems}}"> value="{{$ctrl.summary.item.stems}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Buyer" <vn-label-value label="Buyer">
value="{{$ctrl.summary.item.itemType.worker.user.nickname}}"> <span
ng-click="workerDescriptor.show($event, $ctrl.summary.item.itemType.worker.userFk)"
class="link">
{{$ctrl.summary.item.itemType.worker.user.name}}
</span>
</vn-label-value> </vn-label-value>
</vn-one> </vn-one>
<vn-one name="otherData"> <vn-one name="otherData">
@ -106,3 +110,6 @@
</vn-one> </vn-one>
</vn-horizontal> </vn-horizontal>
</vn-card> </vn-card>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

@ -37,7 +37,7 @@ class Controller extends ModuleCard {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
} }
} }

View File

@ -63,7 +63,7 @@
ng-model="$ctrl.orderField" ng-model="$ctrl.orderField"
selection="$ctrl.orderSelection" selection="$ctrl.orderSelection"
translate-fields="['name']" translate-fields="['name']"
order="name" order="priority DESC"
show-field="name" show-field="name"
value-field="field" value-field="field"
label="Order by" label="Order by"

View File

@ -14,10 +14,10 @@ class Controller extends Section {
{way: 'DESC', name: 'Descendant'}, {way: 'DESC', name: 'Descendant'},
]; ];
this.defaultOrderFields = [ this.defaultOrderFields = [
{field: 'relevancy DESC, name', name: 'Relevancy'}, {field: 'relevancy DESC, name', name: 'Relevancy', priority: 999},
{field: 'showOrder, price', name: 'Color and price'}, {field: 'showOrder, price', name: 'Color and price', priority: 999},
{field: 'name', name: 'Name'}, {field: 'name', name: 'Name', priority: 999},
{field: 'price', name: 'Price'} {field: 'price', name: 'Price', priority: 999}
]; ];
this.orderFields = [].concat(this.defaultOrderFields); this.orderFields = [].concat(this.defaultOrderFields);
this._orderWay = this.orderWays[0].way; this._orderWay = this.orderWays[0].way;
@ -312,9 +312,11 @@ class Controller extends Section {
tags.push({ tags.push({
name: itemTag.name, name: itemTag.name,
field: itemTag.tagFk, field: itemTag.tagFk,
isTag: true isTag: true,
priority: 1
}); });
} } else
tags[alreadyAdded].priority += 1;
}); });
}); });
let newFilterList = [].concat(this.defaultOrderFields); let newFilterList = [].concat(this.defaultOrderFields);

View File

@ -45,7 +45,7 @@ describe('Order', () => {
jest.spyOn(controller, 'buildTagsFilter'); jest.spyOn(controller, 'buildTagsFilter');
jest.spyOn(controller, 'buildOrderFilter'); jest.spyOn(controller, 'buildOrderFilter');
const expectedResult = [{field: 'showOrder, price', name: 'Color and price'}]; const expectedResult = [{field: 'showOrder, price', name: 'Color and price', priority: 999}];
const items = [{id: 1, name: 'My Item', tags: [ const items = [{id: 1, name: 'My Item', tags: [
{tagFk: 4, name: 'Length'}, {tagFk: 4, name: 'Length'},
{tagFk: 5, name: 'Color'} {tagFk: 5, name: 'Color'}

View File

@ -15,8 +15,12 @@
value="{{$ctrl.$t($ctrl.order.isConfirmed ? 'Confirmed' : 'Not confirmed')}}"> value="{{$ctrl.$t($ctrl.order.isConfirmed ? 'Confirmed' : 'Not confirmed')}}">
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Sales person" label="Sales person">
value="{{$ctrl.order.client.salesPerson.user.nickname}}"> <span
ng-click="workerDescriptor.show($event, $ctrl.order.client.salesPersonFk)"
class="link">
{{$ctrl.order.client.salesPerson.user.name}}
</span>
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Landed" label="Landed"
@ -65,3 +69,6 @@
message="You are going to delete this order" message="You are going to delete this order"
question="continue anyway?"> question="continue anyway?">
</vn-confirm> </vn-confirm>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

@ -119,7 +119,7 @@ module.exports = Self => {
r.m3, r.m3,
r.description, r.description,
am.name agencyName, am.name agencyName,
u.nickname AS workerNickname, u.name AS workerUserName,
v.numberPlate AS vehiclePlateNumber v.numberPlate AS vehiclePlateNumber
FROM route r FROM route r
LEFT JOIN agencyMode am ON am.id = r.agencyModeFk LEFT JOIN agencyMode am ON am.id = r.agencyModeFk
@ -128,7 +128,6 @@ module.exports = Self => {
LEFT JOIN account.user u ON u.id = w.userFk` LEFT JOIN account.user u ON u.id = w.userFk`
); );
stmt.merge(conn.makeSuffix(filter)); stmt.merge(conn.makeSuffix(filter));
let itemsIndex = stmts.push(stmt) - 1; let itemsIndex = stmts.push(stmt) - 1;

View File

@ -25,7 +25,7 @@ describe('route summary()', () => {
const result = await app.models.Route.summary(1); const result = await app.models.Route.summary(1);
const worker = result.route.worker().user(); const worker = result.route.worker().user();
expect(worker.nickname).toEqual('deliveryNick'); expect(worker.name).toEqual('delivery');
}); });
it(`should return a summary object containing data from the tickets`, async() => { it(`should return a summary object containing data from the tickets`, async() => {

View File

@ -38,7 +38,7 @@ module.exports = Self => {
{ {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['id', 'nickname'] fields: ['id', 'name']
} }
} }
] ]

View File

@ -38,7 +38,7 @@
<span <span
class="link" class="link"
vn-click-stop="workerDescriptor.show($event, route.workerFk)"> vn-click-stop="workerDescriptor.show($event, route.workerFk)">
{{::route.workerNickname}} {{::route.workerUserName}}
</span> </span>
</vn-td> </vn-td>
<vn-td>{{::route.agencyName | dashIfEmpty}}</vn-td> <vn-td>{{::route.agencyName | dashIfEmpty}}</vn-td>
@ -79,10 +79,9 @@
tooltip-position="left"> tooltip-position="left">
</vn-button> </vn-button>
<a ui-sref="route.create"> <a ui-sref="route.create" vn-bind="+">
<vn-button class="round md vn-mb-sm" <vn-button class="round md vn-mb-sm"
icon="add" icon="add"
vn-bind="+"
vn-tooltip="New route" vn-tooltip="New route"
tooltip-position="left"> tooltip-position="left">
</vn-button> </vn-button>

View File

@ -14,8 +14,12 @@
<vn-label-value label="Vehicle" <vn-label-value label="Vehicle"
value="{{$ctrl.summary.route.vehicle.numberPlate}}"> value="{{$ctrl.summary.route.vehicle.numberPlate}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Driver" <vn-label-value label="Driver">
value="{{$ctrl.summary.route.worker.user.nickname}}"> <span
ng-click="workerDescriptor.show($event, $ctrl.summary.route.workerFk)"
class="link">
{{$ctrl.summary.route.worker.user.name}}
</span>
</vn-label-value> </vn-label-value>
<vn-label-value label="Cost" <vn-label-value label="Cost"
value="{{$ctrl.summary.route.cost | currency: 'EUR':2}}"> value="{{$ctrl.summary.route.cost | currency: 'EUR':2}}">
@ -106,3 +110,6 @@
<vn-client-descriptor-popover <vn-client-descriptor-popover
vn-id="clientDescriptor"> vn-id="clientDescriptor">
</vn-client-descriptor-popover> </vn-client-descriptor-popover>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

@ -245,7 +245,7 @@ module.exports = Self => {
SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped
FROM tmp.filter f FROM tmp.filter f
LEFT JOIN alertLevel al ON al.alertLevel = f.alertLevel LEFT JOIN alertLevel al ON al.alertLevel = f.alertLevel
WHERE (f.alertLevelCode = 'FREE' OR f.alertLevel IS NULL) WHERE (al.code = 'FREE' OR f.alertLevel IS NULL)
AND f.shipped >= CURDATE()`); AND f.shipped >= CURDATE()`);
stmts.push('CALL ticketGetProblems()'); stmts.push('CALL ticketGetProblems()');

View File

@ -0,0 +1,26 @@
module.exports = Self => {
Self.remoteMethod('freightCost', {
description: 'Returns the freight cost of a ticket',
accessType: 'READ',
accepts: {
arg: 'id',
type: 'number',
required: true,
description: 'ticket id',
http: {source: 'path'}
},
returns: {
type: 'Number',
root: true
},
http: {
path: `/:id/freightCost`,
verb: 'GET'
}
});
Self.freightCost = async ticketFk => {
const [freightCost] = await Self.rawSql(`SELECT vn.ticket_getFreightCost(?) total`, [ticketFk]);
return freightCost.total;
};
};

View File

@ -0,0 +1,53 @@
module.exports = Self => {
Self.remoteMethod('getComponentsSum', {
description: 'Returns a list of component and their sum from a ticket',
accessType: 'READ',
accepts: {
arg: 'id',
type: 'number',
required: true,
description: 'ticket id',
http: {source: 'path'}
},
returns: {
type: 'Number',
root: true
},
http: {
path: `/:id/getComponentsSum`,
verb: 'GET'
}
});
Self.getComponentsSum = async id => {
const models = Self.app.models;
let salesComponents = [];
let componentsSum = [];
let sales = await models.Sale.find({where: {ticketFk: id}});
let components = await models.Component.find();
if (sales.length > 0) {
for (let sale of sales) {
let myComponents = await models.SaleComponent.find({where: {saleFk: sale.id}});
salesComponents = salesComponents.concat(myComponents);
}
salesComponents.reduce((acumulator, currentValue) => {
if (!acumulator[currentValue.componentFk]) {
let defaultValue = 0;
let tarjetComponent = components.find(component => component.id === currentValue.componentFk);
acumulator[currentValue.componentFk] = {
componentFk: currentValue.componentFk,
value: defaultValue,
name: tarjetComponent.name
};
componentsSum.push(acumulator[currentValue.componentFk]);
}
acumulator[currentValue.componentFk].value += currentValue.value;
return acumulator;
});
}
return componentsSum;
};
};

View File

@ -42,7 +42,7 @@ describe('ticket filter()', () => {
const filter = {}; const filter = {};
const result = await app.models.Ticket.filter(ctx, filter); const result = await app.models.Ticket.filter(ctx, filter);
expect(result.length).toEqual(11); expect(result.length).toEqual(10);
}); });
it('should return the tickets matching the problems on null', async() => { it('should return the tickets matching the problems on null', async() => {

View File

@ -0,0 +1,17 @@
const app = require('vn-loopback/server/server');
describe('ticket freightCost()', () => {
it('should return the freight cost of a given ticket', async() => {
let ticketId = 7;
let freightCost = await app.models.Ticket.freightCost(ticketId);
expect(freightCost).toBe(4);
});
it('should return null if the ticket does not exist', async() => {
let ticketId = 99;
let freightCost = await app.models.Ticket.freightCost(ticketId);
expect(freightCost).toBeNull();
});
});

View File

@ -0,0 +1,20 @@
const app = require('vn-loopback/server/server');
describe('ticket getComponentsSum()', () => {
it('should get the list of component for the ticket sales', async() => {
const ticketId = 7;
const components = await app.models.Ticket.getComponentsSum(ticketId);
const length = components.length;
const anyComponent = components[Math.floor(Math.random() * Math.floor(length))];
expect(components.length).toBeGreaterThan(0);
expect(anyComponent.componentFk).toBeDefined();
});
it('should return 0 if the given ticket does not have sales', async() => {
const ticketWithoutSales = 21;
const components = await app.models.Ticket.getComponentsSum(ticketWithoutSales);
expect(components.length).toEqual(0);
});
});

View File

@ -63,7 +63,7 @@ module.exports = Self => {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
} }
} }

View File

@ -30,6 +30,8 @@ module.exports = Self => {
require('../methods/ticket/deleteStowaway')(Self); require('../methods/ticket/deleteStowaway')(Self);
require('../methods/ticket/sendSms')(Self); require('../methods/ticket/sendSms')(Self);
require('../methods/ticket/isLocked')(Self); require('../methods/ticket/isLocked')(Self);
require('../methods/ticket/freightCost')(Self);
require('../methods/ticket/getComponentsSum')(Self);
Self.observe('before save', async function(ctx) { Self.observe('before save', async function(ctx) {
if (ctx.isNewInstance) return; if (ctx.isNewInstance) return;

View File

@ -3,27 +3,12 @@
data="ticketUpdateActions" data="ticketUpdateActions"
auto-load="true"> auto-load="true">
</vn-crud-model> </vn-crud-model>
<vn-card ng-show="::$ctrl.totalPriceDifference" class="vn-w-lg vn-pa-md vn-mb-md">
<h6
class="text-secondary"
style="font-weight: normal;"
translate>
Charge difference to
</h6>
<div ng-repeat="action in ticketUpdateActions">
<vn-radio
ng-model="$ctrl.ticket.option"
label="{{::action.description}}"
val={{::action.id}}>
</vn-radio>
</div>
</vn-card>
<vn-card class="vn-w-lg"> <vn-card class="vn-w-lg">
<vn-table> <vn-table>
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>
<vn-th number>Item</vn-th> <vn-th number>Item</vn-th>
<vn-th style="text-align:center">Description</vn-th> <vn-th class="align-center">Description</vn-th>
<vn-th number>Quantity</vn-th> <vn-th number>Quantity</vn-th>
<vn-th number>Price (PPU)</vn-th> <vn-th number>Price (PPU)</vn-th>
<vn-th number>New (PPU)</vn-th> <vn-th number>New (PPU)</vn-th>
@ -51,10 +36,31 @@
<vn-td></vn-td> <vn-td></vn-td>
<vn-td></vn-td> <vn-td></vn-td>
<vn-td></vn-td> <vn-td></vn-td>
<vn-td number><strong>{{$ctrl.totalPrice | currency: 'EUR': 2}}</strong></vn-td>
<vn-td number><strong>{{$ctrl.totalNewPrice | currency: 'EUR': 2}}</strong></vn-td>
<vn-td number><strong>{{$ctrl.totalPriceDifference | currency: 'EUR': 2}}</strong></vn-td>
</vn-tr> </vn-tr>
</vn-tfoot> </vn-tfoot>
</vn-table> </vn-table>
</vn-card> </vn-card>
<vn-side-menu side="right">
<div class="vn-pa-md">
<div class="totalBox align-left">
<h6 class="align-center" translate>Total</h6>
<div> <vn-label translate>Price</vn-label> {{$ctrl.totalPrice | currency: 'EUR': 2}} </div>
<div> <vn-label translate>New price</vn-label> {{$ctrl.totalNewPrice | currency: 'EUR': 2}} </div>
<div> <vn-label translate>Difference</vn-label> {{$ctrl.totalPriceDifference | currency: 'EUR': 2}} </div>
</div>
<vn-card ng-show="::$ctrl.totalPriceDifference">
<div class="totalBox align-left" >
<h6 class="align-center" translate>Charge difference to</h6>
<div ng-repeat="action in ticketUpdateActions">
<vn-radio
ng-model="$ctrl.ticket.option"
label="{{::action.description}}"
val={{::action.id}}>
</vn-radio>
</div>
</div>
</vn-card>
</div>
</vn-side-menu>

View File

@ -1,5 +1,6 @@
import ngModule from '../../module'; import ngModule from '../../module';
import Component from 'core/lib/component'; import Component from 'core/lib/component';
import './style.scss';
class Controller extends Component { class Controller extends Component {
$onInit() { $onInit() {

View File

@ -3,3 +3,6 @@ New (PPU): Nuevo (Ud.)
Difference: Diferencia Difference: Diferencia
Charge difference to: Cargar diferencia a Charge difference to: Cargar diferencia a
The ticket has been unrouted: El ticket ha sido desenrutado The ticket has been unrouted: El ticket ha sido desenrutado
Price: Precio
New price: Nuevo precio
Price difference: Diferencia de precio

View File

@ -0,0 +1,9 @@
@import "variables";
.align-left {
text-align: left
}
.align-center {
text-align: center
}

View File

@ -44,7 +44,7 @@ class Controller extends ModuleCard {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
} }
} }

View File

@ -7,9 +7,6 @@
auto-load="true"> auto-load="true">
</vn-crud-model> </vn-crud-model>
<vn-data-viewer model="model" class="vn-w-xl"> <vn-data-viewer model="model" class="vn-w-xl">
<vn-card class="vn-pa-lg text-right" name="base-sum">
<span translate>Base to commission</span> {{$ctrl.base() | currency: 'EUR':3}}
</vn-card>
<vn-card class="vn-mt-md"> <vn-card class="vn-mt-md">
<table class="vn-table"> <table class="vn-table">
<thead> <thead>
@ -24,7 +21,7 @@
</tr> </tr>
</thead> </thead>
<tbody ng-repeat="sale in components track by sale.id"> <tbody ng-repeat="sale in components track by sale.id">
<tr style="height: initial;"> <tr class="initial">
<td rowspan="{{::sale.components.length + 1}}" number> <td rowspan="{{::sale.components.length + 1}}" number>
<span <span
ng-click="descriptor.show($event, sale.itemFk, sale.id)" ng-click="descriptor.show($event, sale.itemFk, sale.id)"
@ -64,6 +61,25 @@
</table> </table>
</vn-card> </vn-card>
</vn-data-viewer> </vn-data-viewer>
<vn-side-menu side="right">
<div class="totalBox align-left">
<h6 class="align-center" translate>Total</h6>
<div> <vn-label translate>Base to commission</vn-label> {{$ctrl.base() | currency: 'EUR':2}} </div>
<div> <vn-label translate>Total without VAT</vn-label> {{$ctrl.getTotal() | currency: 'EUR': 3}} </div>
</div>
<div class="totalBox align-left">
<h6 class="align-center" translate>Components</h6>
<section ng-repeat="component in $ctrl.componentsList">
<div>
<vn-label>{{component.name}}</vn-label> {{component.value | currency: 'EUR': 3}}
</div>
</section>
</div>
<div class="totalBox align-left">
<h6 class="align-center" translate>Theorical cost</h6>
<div> <vn-label translate>Price</vn-label> {{$ctrl.theoricalCost | currency: 'EUR': 2}} </div>
</div>
</vn-side-menu>
<vn-item-descriptor-popover <vn-item-descriptor-popover
vn-id="descriptor" vn-id="descriptor"
warehouse-fk="$ctrl.ticket.warehouseFk"> warehouse-fk="$ctrl.ticket.warehouseFk">

View File

@ -29,11 +29,22 @@ class Controller extends Section {
}] }]
}; };
} }
get ticket() {
return this._ticket;
}
set ticket(value) {
this._ticket = value;
if (!value) return;
this.getTheoricalCost();
this.getComponentsSum();
}
base() { base() {
let sales = this.$.model.data; let sales = this.$.model.data;
let sum = 0; let sum = 0;
if (!sales) return; if (!sales) return;
for (let sale of sales) { for (let sale of sales) {
@ -42,9 +53,29 @@ class Controller extends Section {
sum += sale.quantity * saleComponent.value; sum += sale.quantity * saleComponent.value;
} }
} }
return sum; return sum;
} }
getTotal() {
const sales = this.$.model.data;
let total = 0;
if (!sales) return;
for (let sale of sales) {
for (let saleComponent of sale.components)
total += sale.quantity * saleComponent.value;
}
return total;
}
getTheoricalCost() {
this.$http.get(`Tickets/${this.ticket.id}/freightCost`)
.then(res => this.theoricalCost = res.data);
}
getComponentsSum() {
this.$http.get(`Tickets/${this.ticket.id}/getComponentsSum`)
.then(res => this.componentsList = res.data);
}
} }
ngModule.vnComponent('vnTicketComponents', { ngModule.vnComponent('vnTicketComponents', {

View File

@ -4,76 +4,72 @@ import crudModel from 'core/mocks/crud-model';
describe('ticket', () => { describe('ticket', () => {
describe('Component vnTicketComponents', () => { describe('Component vnTicketComponents', () => {
let controller; let controller;
let $httpBackend;
beforeEach(ngModule('ticket')); beforeEach(ngModule('ticket'));
beforeEach(inject(($componentController, $rootScope, $state) => { beforeEach(inject(($componentController, $rootScope, $state, _$httpBackend_) => {
$state.params.id = '1'; $state.params.id = '1';
let $scope = $rootScope.$new(); let $scope = $rootScope.$new();
$httpBackend = _$httpBackend_;
$scope.model = crudModel; $scope.model = crudModel;
$scope.model.data = [{ $scope.model.data = [{
quantity: 1,
components: [ components: [
{ {
value: 5,
component: { component: {
name: 'valor de compra',
componentType: { componentType: {
isBase: 1 isBase: 1
} }
}, }
value: 5
}, },
{ {
value: 5,
component: { component: {
name: 'reparto',
componentType: { componentType: {
isBase: 0 isBase: 0
} }
}, }
value: 5
}, },
{ {
value: 5,
component: { component: {
name: 'recobro',
componentType: { componentType: {
isBase: 0 isBase: 0
} }
}, }
value: 5
} }
], ]
quantity: 1
}, },
{ {
quantity: 5,
components: [ components: [
{ {
value: 1,
component: { component: {
name: 'valor de compra',
componentType: { componentType: {
isBase: 1 isBase: 1
} }
}, }
value: 1
}, },
{ {
value: 1,
component: { component: {
name: 'reparto',
componentType: { componentType: {
isBase: 0 isBase: 0
} }
}, }
value: 1
}, },
{ {
value: 1,
component: { component: {
name: 'recobro',
componentType: { componentType: {
isBase: 0 isBase: 0
} }
}, }
value: 1
}, },
], ]
quantity: 5
}]; }];
const $element = angular.element('<vn-ticket-components></vn-ticket-components>'); const $element = angular.element('<vn-ticket-components></vn-ticket-components>');
controller = $componentController('vnTicketComponents', {$element, $scope}); controller = $componentController('vnTicketComponents', {$element, $scope});
@ -86,5 +82,55 @@ describe('ticket', () => {
expect(result).toEqual(10); expect(result).toEqual(10);
}); });
}); });
describe('ticket setter', () => {
it('should set the ticket data and then call getTheoricalCost() and getComponentsSum()', () => {
jest.spyOn(controller, 'getTheoricalCost');
jest.spyOn(controller, 'getComponentsSum');
controller._ticket = undefined;
controller.ticket = {
id: 7
};
expect(controller.ticket).toBeDefined();
expect(controller.getTheoricalCost).toHaveBeenCalledWith();
expect(controller.getComponentsSum).toHaveBeenCalledWith();
});
});
describe('getTotal()', () => {
it('should return the total sum of a ticket', () => {
let result = controller.getTotal();
expect(result).toEqual(30);
});
});
describe('getTheoricalCost()', () => {
it('should make a request to get the theorical cost of a ticket', () => {
controller._ticket = {
id: 7
};
$httpBackend.expect('GET', `Tickets/${controller._ticket.id}/freightCost`).respond('My freight cost');
controller.getTheoricalCost();
$httpBackend.flush();
expect(controller.theoricalCost).toBe('My freight cost');
});
});
describe('getComponentsSum()', () => {
it('should make a request to get the component list', () => {
controller._ticket = {
id: 7
};
$httpBackend.expect('GET', `Tickets/${controller._ticket.id}/getComponentsSum`).respond('My component list');
controller.getComponentsSum();
$httpBackend.flush();
expect(controller.componentsList).toBe('My component list');
});
});
}); });
}); });

View File

@ -0,0 +1,2 @@
Theorical cost: Porte teorico
Total without VAT: Total sin IVA

View File

@ -24,4 +24,19 @@ vn-ticket-components {
} }
} }
} }
.totalBox {
max-width: none;
}
.align-left {
text-align: left
}
.align-center {
text-align: center
}
.initial {
height: initial
}
} }

View File

@ -90,8 +90,12 @@
value="{{$ctrl.ticket.ticketState.state.name}}"> value="{{$ctrl.ticket.ticketState.state.name}}">
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Sales person" label="Sales person">
value="{{$ctrl.ticket.client.salesPerson.user.nickname}}"> <span
ng-click="workerDescriptor.show($event, $ctrl.ticket.client.salesPersonFk)"
class="link">
{{$ctrl.ticket.client.salesPerson.user.name}}
</span>
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Shipped" label="Shipped"
@ -296,3 +300,6 @@
<button response="accept" translate>Save</button> <button response="accept" translate>Save</button>
</tpl-buttons> </tpl-buttons>
</vn-dialog> </vn-dialog>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

@ -210,7 +210,7 @@ class Controller extends Descriptor {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
} }
} }

View File

@ -51,6 +51,12 @@
{{::document.dms.description}} {{::document.dms.description}}
</span> </span>
</vn-td> </vn-td>
<vn-td shrink>
<vn-check
ng-model="document.dms.hasFile"
disabled="true">
</vn-check>
</vn-td>
<vn-td shrink> <vn-td shrink>
<span title="{{'Download file' | translate}}" class="link" <span title="{{'Download file' | translate}}" class="link"
ng-click="$ctrl.downloadFile(document.dmsFk)"> ng-click="$ctrl.downloadFile(document.dmsFk)">
@ -60,8 +66,9 @@
<vn-td shrink> <vn-td shrink>
<span class="link" <span class="link"
ng-click="workerDescriptor.show($event, document.dms.workerFk)"> ng-click="workerDescriptor.show($event, document.dms.workerFk)">
{{::document.dms.worker.user.nickname | dashIfEmpty}} {{::document.dms.worker.user.name | dashIfEmpty}}
</span></vn-td> </span>
</vn-td>
<vn-td> <vn-td>
{{::document.dms.created | date:'dd/MM/yyyy HH:mm'}} {{::document.dms.created | date:'dd/MM/yyyy HH:mm'}}
</vn-td> </vn-td>

View File

@ -33,7 +33,7 @@ class Controller extends Section {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
}, },
} }

View File

@ -143,10 +143,9 @@
vn-tooltip="Payment on account..." vn-tooltip="Payment on account..."
tooltip-position="left"> tooltip-position="left">
</vn-button> </vn-button>
<a ui-sref="ticket.create"> <a ui-sref="ticket.create" vn-bind="+">
<vn-button class="round md vn-mb-sm" <vn-button class="round md vn-mb-sm"
icon="add" icon="add"
vn-bind="+"
vn-tooltip="New ticket" vn-tooltip="New ticket"
tooltip-position="left"> tooltip-position="left">
</vn-button> </vn-button>

View File

@ -18,8 +18,12 @@
<vn-label-value label="State" <vn-label-value label="State"
value="{{$ctrl.summary.ticketState.state.name}}"> value="{{$ctrl.summary.ticketState.state.name}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Salesperson" <vn-label-value label="Salesperson">
value="{{$ctrl.summary.client.salesPerson.user.nickname}}"> <span
ng-click="workerDescriptor.show($event, $ctrl.summary.client.salesPersonFk)"
class="link">
{{$ctrl.summary.client.salesPerson.user.name}}
</span>
</vn-label-value> </vn-label-value>
<vn-label-value label="Agency" <vn-label-value label="Agency"
value="{{$ctrl.summary.agencyMode.name}}"> value="{{$ctrl.summary.agencyMode.name}}">
@ -240,3 +244,6 @@
<vn-invoice-out-descriptor-popover <vn-invoice-out-descriptor-popover
vn-id="invoice-out-descriptor"> vn-id="invoice-out-descriptor">
</vn-invoice-out-descriptor-popover> </vn-invoice-out-descriptor-popover>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

@ -25,7 +25,7 @@
<span <span
class="link" class="link"
ng-click="workerDescriptor.show($event, tracking.worker.user.id)"> ng-click="workerDescriptor.show($event, tracking.worker.user.id)">
{{::tracking.worker.user.nickname | dashIfEmpty}} {{::tracking.worker.user.name | dashIfEmpty}}
</span> </span>
</vn-td> </vn-td>
<vn-td>{{::tracking.created | date:'dd/MM/yyyy HH:mm'}}</vn-td> <vn-td>{{::tracking.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>

View File

@ -13,7 +13,7 @@ class Controller extends Section {
include: { include: {
relation: 'user', relation: 'user',
scope: { scope: {
fields: ['nickname'] fields: ['name']
} }
} }
} }

View File

@ -112,7 +112,8 @@ module.exports = Self => {
let stmts = []; let stmts = [];
let stmt; let stmt;
stmt = new ParameterizedSQL( stmt = new ParameterizedSQL(
`SELECT `SELECT * FROM
(SELECT
t.id, t.id,
t.shipped, t.shipped,
t.landed, t.landed,
@ -132,7 +133,7 @@ module.exports = Self => {
FROM vn.travel t FROM vn.travel t
JOIN vn.agencyMode am ON am.id = t.agencyFk JOIN vn.agencyMode am ON am.id = t.agencyFk
JOIN vn.warehouse win ON win.id = t.warehouseInFk JOIN vn.warehouse win ON win.id = t.warehouseInFk
JOIN vn.warehouse wout ON wout.id = t.warehouseOutFk` JOIN vn.warehouse wout ON wout.id = t.warehouseOutFk) AS t`
); );
stmt.merge(conn.makeSuffix(filter)); stmt.merge(conn.makeSuffix(filter));

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