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`
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),
(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`)
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)),
@ -688,11 +714,13 @@ INSERT INTO `vn`.`itemType`(`id`, `code`, `name`, `categoryFk`, `life`,`workerFk
(5, 'CON', 'Container', 3, NULL, 35, 1),
(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
('YEL', 'Yellow', 1, 1),
('BLU', 'Blue', 1, 2),
('RED', 'Red', 1, 3);
('YEL', 'Yellow', 1, 1, 'F4D03F'),
('BLU', 'Blue', 1, 2, '5DADE2'),
('RED', 'Red', 1, 3, 'EC7063'),
('SLV', 'Silver', 1, 4, 'CACFD2'),
('BRW', 'Brown', 1, 5, 'DC7633');
INSERT INTO `vn`.`origin`(`id`,`code`, `name`)
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),
(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
(1, 2, 70, 'AMA', 1, 1, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 67, 1, NULL),
(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);
(71,0.141,1);
INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPackageReturnable`, `created`, `itemFk`, `price`)
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),
('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`)
VALUES

File diff suppressed because it is too large Load Diff

View File

@ -199,7 +199,7 @@ export default {
},
dms: {
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'
},
clientContacts: {
@ -521,11 +521,11 @@ export default {
zone: 'vn-autocomplete[ng-model="$ctrl.zoneId"]',
nextStepButton: 'vn-step-control .buttons > section:last-child vn-button',
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',
},
ticketComponents: {
base: 'vn-ticket-components [name="base-sum"]'
base: 'vn-ticket-components > vn-side-menu div:nth-child(1) > div:nth-child(2)'
},
ticketRequests: {
addRequestButton: 'vn-ticket-request-index > a > vn-float-button > button',
@ -894,6 +894,7 @@ export default {
header: 'vn-entry-summary > vn-card > h5',
reference: 'vn-entry-summary vn-label-value[label="Reference"]',
confirmed: 'vn-entry-summary vn-check[label="Confirmed"]',
anyBuyLine: 'vn-entry-summary tr.dark-row'
},
entryDescriptor: {
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"]',
latestBuysSectionButton: 'a[ui-sref="entry.latestBuys"]',
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);
const base = await page.waitToGetProperty(selectors.ticketComponents.base, 'innerText');
expect(base).toContain('Base');
expect(base.length).toBeGreaterThan(minLength);
});

View File

@ -9,7 +9,7 @@ describe('Entry summary path', () => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'entry');
await page.waitToClick('vn-entry-index vn-tbody > a:nth-child(2)');
await page.accessToSearchResult('4');
});
afterAll(async() => {
@ -30,7 +30,7 @@ describe('Entry summary path', () => {
it('should display some entry details like the reference', async() => {
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() => {
@ -38,4 +38,10 @@ describe('Entry summary path', () => {
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";
.vn-radio {
& > .btn {
border-radius: 50%;
@ -25,4 +26,8 @@
&.disabled.checked > .btn > .mark {
background-color: $color-font-secondary;
}
> div {
text-overflow: ellipsis;
overflow: hidden;
}
}

View File

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

View File

@ -106,7 +106,7 @@ module.exports = Self => {
let stmt;
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
LEFT JOIN client c ON c.id = cl.clientFk
LEFT JOIN worker w ON w.id = cl.workerFk

View File

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

View File

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

View File

@ -7,6 +7,6 @@ describe('Client get', () => {
expect(result.id).toEqual(101);
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() => {
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() => {
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() => {

View File

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

View File

@ -23,7 +23,13 @@
<vn-tbody>
<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.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-tr>
</vn-tbody>
@ -39,3 +45,6 @@
vn-bind="+"
fixed-bottom-right>
</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: {
relation: 'user',
scope: {
fields: ['nickname']
fields: ['name']
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,8 +21,12 @@
<vn-label-value label="Email" ellipsize="false"
value="{{$ctrl.summary.email}}">
</vn-label-value>
<vn-label-value label="Sales person"
value="{{$ctrl.summary.salesPerson.user.nickname}}">
<vn-label-value label="Sales person">
<span
ng-click="workerDescriptor.show($event, $ctrl.summary.salesPersonFk)"
class="link">
{{$ctrl.summary.salesPerson.user.name}}
</span>
</vn-label-value>
<vn-label-value label="Channel"
value="{{$ctrl.summary.contactChannel.name}}">
@ -198,3 +202,6 @@
</vn-one>
</vn-horizontal>
</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.price3,
b.ektFk,
b.weight
b.weight,
b.packageFk
FROM cache.last_buy lb
LEFT JOIN cache.visible v ON v.item_id = lb.item_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": {
"type": "number"
},
"stickers": {
"type": "number"
},
"packageFk": {
"type": "number"
},
"groupingMode": {
"type": "number"
},
@ -56,6 +62,12 @@
"model": "Entry",
"foreignKey": "entryFk",
"required": true
},
"item": {
"type": "belongsTo",
"model": "Item",
"foreignKey": "itemFk",
"required": true
}
}
}

View File

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

View File

@ -1,6 +1,6 @@
{
"name": "Entry",
"base": "VnModel",
"base": "Loggable",
"log": {
"model":"EntryLog"
},
@ -62,6 +62,18 @@
},
"loadPriority": {
"type": "number"
},
"supplierFk": {
"type": "number",
"required": true
},
"travelFk": {
"type": "number",
"required": true
},
"companyFk": {
"type": "number",
"required": true
}
},
"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 './index/';
import './create';
import './latest-buys';
import './search-panel';
import './latest-buys-search-panel';

View File

@ -70,3 +70,15 @@
<vn-travel-descriptor-popover
vn-id="travelDescriptor">
</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 field="packing">Packing</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="size">Size</vn-th>
<vn-th field="type">Type</vn-th>
@ -42,7 +43,6 @@
<vn-th field="isActive">Active</vn-th>
<vn-th field="family">Family</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="freightValue">Freight 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="ektFk">Ekt</vn-th>
<vn-th field="weight">Weight</vn-th>
<vn-th field="packageFk" expand>PackageName</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
@ -89,6 +90,7 @@
<span translate>{{::buy.grouping | dashIfEmpty}}</span>
</vn-chip>
</vn-td>
<vn-td number>{{::buy.quantity}}</vn-td>
<vn-td vn-two title="{{::buy.description}}">
{{::buy.description | dashIfEmpty}}
</vn-td>
@ -115,7 +117,6 @@
{{::buy.entryFk}}
</span>
</vn-td>
<vn-td number>{{::buy.quantity}}</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.comissionValue | currency: 'EUR':2}}</vn-td>
@ -126,6 +127,7 @@
<vn-td number>{{::buy.minPrice | currency: 'EUR':2}}</vn-td>
<vn-td number>{{::buy.ektFk | dashIfEmpty}}</vn-td>
<vn-td number>{{::buy.weight}}</vn-td>
<vn-td number>{{::buy.packageFk}}</vn-td>
</a>
</vn-tbody>
</vn-table>

View File

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

View File

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

View File

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

View File

@ -19,8 +19,12 @@
</vn-label-value>
</vn-one>
<vn-one>
<vn-label-value label="Agency"
value="{{$ctrl.entryData.travel.agency.name}}">
<vn-label-value label="Agency">
<span
ng-click="travelDescriptor.show($event, $ctrl.entry.travel.agencyFk)"
class="link">
{{$ctrl.entryData.travel.agency.name}}
</span>
</vn-label-value>
<vn-label-value label="Shipped"
value="{{$ctrl.entryData.travel.shipped | date: 'dd/MM/yyyy'}}">
@ -65,4 +69,89 @@
</vn-vertical>
</vn-one>
</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-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) {
this._entry = value;
if (value && value.id)
if (value && value.id) {
this.getEntryData();
this.getBuys();
}
}
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;
});
}
getBuys() {
return this.$http.get(`Entries/${this.entry.id}/getBuys`).then(response => {
this.buys = response.data;
});
}
}
ngModule.vnComponent('vnEntrySummary', {

View File

@ -38,7 +38,7 @@ describe('component vnEntrySummary', () => {
it('should perform a get and then store data on the controller', () => {
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');
controller.getEntryData();
$httpBackend.flush();
@ -46,4 +46,20 @@ describe('component vnEntrySummary', () => {
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
Virtual: Redada
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 {
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}}">
</vn-label-value>
<vn-label-value
label="Client"
value="{{$ctrl.invoiceOut.client.name}}">
label="Client">
<span
ng-click="clientDescriptor.show($event, $ctrl.invoiceOut.client.id)"
class="link">
{{$ctrl.invoiceOut.client.name}}
</span>
</vn-label-value>
<vn-label-value
label="Company"
@ -75,3 +79,6 @@
on-accept="$ctrl.bookInvoiceOut()"
question="Are you sure you want to book this invoice?">
</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});
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
if (!image) return clearInterval(timer);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -36,8 +36,12 @@
<vn-label-value label="stems"
value="{{$ctrl.summary.item.stems}}">
</vn-label-value>
<vn-label-value label="Buyer"
value="{{$ctrl.summary.item.itemType.worker.user.nickname}}">
<vn-label-value label="Buyer">
<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-one>
<vn-one name="otherData">
@ -106,3 +110,6 @@
</vn-one>
</vn-horizontal>
</vn-card>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

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

View File

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

View File

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

View File

@ -45,7 +45,7 @@ describe('Order', () => {
jest.spyOn(controller, 'buildTagsFilter');
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: [
{tagFk: 4, name: 'Length'},
{tagFk: 5, name: 'Color'}

View File

@ -15,8 +15,12 @@
value="{{$ctrl.$t($ctrl.order.isConfirmed ? 'Confirmed' : 'Not confirmed')}}">
</vn-label-value>
<vn-label-value
label="Sales person"
value="{{$ctrl.order.client.salesPerson.user.nickname}}">
label="Sales person">
<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
label="Landed"
@ -65,3 +69,6 @@
message="You are going to delete this order"
question="continue anyway?">
</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.description,
am.name agencyName,
u.nickname AS workerNickname,
u.name AS workerUserName,
v.numberPlate AS vehiclePlateNumber
FROM route r
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`
);
stmt.merge(conn.makeSuffix(filter));
let itemsIndex = stmts.push(stmt) - 1;

View File

@ -25,7 +25,7 @@ describe('route summary()', () => {
const result = await app.models.Route.summary(1);
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() => {

View File

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

View File

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

View File

@ -14,8 +14,12 @@
<vn-label-value label="Vehicle"
value="{{$ctrl.summary.route.vehicle.numberPlate}}">
</vn-label-value>
<vn-label-value label="Driver"
value="{{$ctrl.summary.route.worker.user.nickname}}">
<vn-label-value label="Driver">
<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 label="Cost"
value="{{$ctrl.summary.route.cost | currency: 'EUR':2}}">
@ -106,3 +110,6 @@
<vn-client-descriptor-popover
vn-id="clientDescriptor">
</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
FROM tmp.filter f
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()`);
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 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() => {

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: {
relation: 'user',
scope: {
fields: ['nickname']
fields: ['name']
}
}
}

View File

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

View File

@ -3,27 +3,12 @@
data="ticketUpdateActions"
auto-load="true">
</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-table>
<vn-thead>
<vn-tr>
<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>Price (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 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-tfoot>
</vn-table>
</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 Component from 'core/lib/component';
import './style.scss';
class Controller extends Component {
$onInit() {

View File

@ -3,3 +3,6 @@ New (PPU): Nuevo (Ud.)
Difference: Diferencia
Charge difference to: Cargar diferencia a
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: {
relation: 'user',
scope: {
fields: ['nickname']
fields: ['name']
}
}
}

View File

@ -7,9 +7,6 @@
auto-load="true">
</vn-crud-model>
<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">
<table class="vn-table">
<thead>
@ -24,7 +21,7 @@
</tr>
</thead>
<tbody ng-repeat="sale in components track by sale.id">
<tr style="height: initial;">
<tr class="initial">
<td rowspan="{{::sale.components.length + 1}}" number>
<span
ng-click="descriptor.show($event, sale.itemFk, sale.id)"
@ -64,6 +61,25 @@
</table>
</vn-card>
</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-id="descriptor"
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() {
let sales = this.$.model.data;
let sum = 0;
if (!sales) return;
for (let sale of sales) {
@ -42,9 +53,29 @@ class Controller extends Section {
sum += sale.quantity * saleComponent.value;
}
}
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', {

View File

@ -4,76 +4,72 @@ import crudModel from 'core/mocks/crud-model';
describe('ticket', () => {
describe('Component vnTicketComponents', () => {
let controller;
let $httpBackend;
beforeEach(ngModule('ticket'));
beforeEach(inject(($componentController, $rootScope, $state) => {
beforeEach(inject(($componentController, $rootScope, $state, _$httpBackend_) => {
$state.params.id = '1';
let $scope = $rootScope.$new();
$httpBackend = _$httpBackend_;
$scope.model = crudModel;
$scope.model.data = [{
quantity: 1,
components: [
{
value: 5,
component: {
name: 'valor de compra',
componentType: {
isBase: 1
}
},
value: 5
}
},
{
value: 5,
component: {
name: 'reparto',
componentType: {
isBase: 0
}
},
value: 5
}
},
{
value: 5,
component: {
name: 'recobro',
componentType: {
isBase: 0
}
},
value: 5
}
],
quantity: 1
}
]
},
{
quantity: 5,
components: [
{
value: 1,
component: {
name: 'valor de compra',
componentType: {
isBase: 1
}
},
value: 1
}
},
{
value: 1,
component: {
name: 'reparto',
componentType: {
isBase: 0
}
},
value: 1
}
},
{
value: 1,
component: {
name: 'recobro',
componentType: {
isBase: 0
}
}
},
value: 1
},
],
quantity: 5
]
}];
const $element = angular.element('<vn-ticket-components></vn-ticket-components>');
controller = $componentController('vnTicketComponents', {$element, $scope});
@ -86,5 +82,55 @@ describe('ticket', () => {
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}}">
</vn-label-value>
<vn-label-value
label="Sales person"
value="{{$ctrl.ticket.client.salesPerson.user.nickname}}">
label="Sales person">
<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
label="Shipped"
@ -296,3 +300,6 @@
<button response="accept" translate>Save</button>
</tpl-buttons>
</vn-dialog>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

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

View File

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

View File

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

View File

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

View File

@ -18,8 +18,12 @@
<vn-label-value label="State"
value="{{$ctrl.summary.ticketState.state.name}}">
</vn-label-value>
<vn-label-value label="Salesperson"
value="{{$ctrl.summary.client.salesPerson.user.nickname}}">
<vn-label-value label="Salesperson">
<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 label="Agency"
value="{{$ctrl.summary.agencyMode.name}}">
@ -240,3 +244,6 @@
<vn-invoice-out-descriptor-popover
vn-id="invoice-out-descriptor">
</vn-invoice-out-descriptor-popover>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>

View File

@ -25,7 +25,7 @@
<span
class="link"
ng-click="workerDescriptor.show($event, tracking.worker.user.id)">
{{::tracking.worker.user.nickname | dashIfEmpty}}
{{::tracking.worker.user.name | dashIfEmpty}}
</span>
</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: {
relation: 'user',
scope: {
fields: ['nickname']
fields: ['name']
}
}
}

View File

@ -112,7 +112,8 @@ module.exports = Self => {
let stmts = [];
let stmt;
stmt = new ParameterizedSQL(
`SELECT
`SELECT * FROM
(SELECT
t.id,
t.shipped,
t.landed,
@ -132,7 +133,7 @@ module.exports = Self => {
FROM vn.travel t
JOIN vn.agencyMode am ON am.id = t.agencyFk
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));

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