Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 7283-itemsMigration3
gitea/salix/pipeline/pr-dev This commit looks good
Details
gitea/salix/pipeline/pr-dev This commit looks good
Details
This commit is contained in:
commit
f786996e2c
|
@ -1544,7 +1544,7 @@ INSERT INTO `bs`.`waste`(`buyerFk`, `year`, `week`, `itemFk`, `itemTypeFk`, `sal
|
|||
('103', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 6, 1, '186', '0', '51', '53.12', '56.20', '56.20', '56.20'),
|
||||
('103', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 7, 1, '277', '0', '53.12', '56.20', '56.20', '56.20', '56.20');
|
||||
|
||||
INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packagingFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`, `printedStickers`,`isChecked`,`isIgnored`,`weight`, `created`)
|
||||
INSERT INTO vn.buy(id,entryFk,itemFk,buyingValue,quantity,packagingFk,stickers,freightValue,packageValue,comissionValue,packing,grouping,groupingMode,location,price1,price2,price3,printedStickers,isChecked,isIgnored,weight,created)
|
||||
VALUES
|
||||
(1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'packing', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 2 MONTH),
|
||||
(2, 2, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'packing', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 1 MONTH),
|
||||
|
@ -1560,7 +1560,8 @@ INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packagi
|
|||
(12, 6, 4, 1.25, 0, 3, 1, 2.500, 2.500, 0.000, 10, 10, 'grouping', NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
|
||||
(13, 7, 1, 50, 0, 3, 1, 2.000, 2.000, 0.000, 1, 1, 'packing', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 4, util.VN_CURDATE()),
|
||||
(14, 7, 2, 5, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 'grouping', NULL, 0.00, 7.30, 7.00, 0, 1, 0, 4, util.VN_CURDATE()),
|
||||
(15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 'grouping', NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE());
|
||||
(15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 'grouping', NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
|
||||
(16, 99,1,50.0000, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'packing', NULL, 0.00, 99.60, 99.40, 0, 1, 0, 1.00, '2024-07-30 08:13:51.000');
|
||||
|
||||
INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_id`, `agency_id`, `address_id`, `company_id`, `note`, `source_app`, `confirmed`,`total`, `date_make`, `first_row_stamp`, `confirm_date`)
|
||||
VALUES
|
||||
|
@ -2441,30 +2442,32 @@ INSERT INTO `vn`.`workerTimeControl`(`userFk`, `timed`, `manual`, `direction`, `
|
|||
(1107, CONCAT(util.VN_CURDATE(), ' 10:20'), TRUE, 'middle', 1),
|
||||
(1107, CONCAT(util.VN_CURDATE(), ' 14:50'), TRUE, 'out', 1);
|
||||
|
||||
INSERT INTO `vn`.`dmsType`(`id`, `name`, `readRoleFk`, `writeRoleFk`, `code`)
|
||||
INSERT INTO `vn`.`dmsType`
|
||||
(`id`, `name`, `readRoleFk`, `writeRoleFk`, `code`)
|
||||
VALUES
|
||||
(1, 'Facturas Recibidas', NULL, NULL, 'invoiceIn'),
|
||||
(2, 'Doc oficial', NULL, NULL, 'officialDoc'),
|
||||
(3, 'Laboral', 37, 37, 'hhrrData'),
|
||||
(4, 'Albaranes recibidos', NULL, NULL, 'deliveryNote'),
|
||||
(5, 'Otros', 1, 1, 'miscellaneous'),
|
||||
(6, 'Pruebas', NULL, NULL, 'tests'),
|
||||
(7, 'IAE Clientes', 1, 1, 'economicActivitiesTax'),
|
||||
(8, 'Fiscal', NULL, NULL, 'fiscal'),
|
||||
(9, 'Vehiculos', NULL, NULL, 'vehicles'),
|
||||
(10, 'Plantillas', NULL, NULL, 'templates'),
|
||||
(11, 'Contratos', NULL, NULL, 'contracts'),
|
||||
(12, 'ley de pagos', 1, 1, 'paymentsLaw'),
|
||||
(13, 'Basura', 1, 1, 'trash'),
|
||||
(14, 'Ticket', 1, 1, 'ticket'),
|
||||
(15, 'Presupuestos', NULL, NULL, 'budgets'),
|
||||
(16, 'Logistica', NULL, NULL, 'logistics'),
|
||||
(17, 'cmr', 1, 1, 'cmr'),
|
||||
(18, 'dua', NULL, NULL, 'dua'),
|
||||
(19, 'inmovilizado', NULL, NULL, 'fixedAssets'),
|
||||
(20, 'Reclamación', 1, 1, 'claim'),
|
||||
(21, 'Entrada', 1, 1, 'entry'),
|
||||
(22, 'Proveedor', 1, 1, 'supplier');
|
||||
(1, 'Facturas Recibidas', NULL, NULL, 'invoiceIn'),
|
||||
(2, 'Doc oficial', NULL, NULL, 'officialDoc'),
|
||||
(3, 'Laboral', 37, 37, 'hhrrData'),
|
||||
(4, 'Albaranes recibidos', NULL, NULL, 'deliveryNote'),
|
||||
(5, 'Otros', 1, 1, 'miscellaneous'),
|
||||
(6, 'Pruebas', NULL, NULL, 'tests'),
|
||||
(7, 'IAE Clientes', 1, 1, 'economicActivitiesTax'),
|
||||
(8, 'Fiscal', NULL, NULL, 'fiscal'),
|
||||
(9, 'Vehiculos', NULL, NULL, 'vehicles'),
|
||||
(10, 'Plantillas', NULL, NULL, 'templates'),
|
||||
(11, 'Contratos', NULL, NULL, 'contracts'),
|
||||
(12, 'ley de pagos', 1, 1, 'paymentsLaw'),
|
||||
(13, 'Basura', 1, 1, 'trash'),
|
||||
(14, 'Ticket', 1, 1, 'ticket'),
|
||||
(15, 'Presupuestos', NULL, NULL, 'budgets'),
|
||||
(16, 'Logistica', NULL, NULL, 'logistics'),
|
||||
(17, 'cmr', 1, 1, 'cmr'),
|
||||
(18, 'dua', NULL, NULL, 'dua'),
|
||||
(19, 'inmovilizado', NULL, NULL, 'fixedAssets'),
|
||||
(20, 'Reclamación', 1, 1, 'claim'),
|
||||
(21, 'Entrada', 1, 1, 'entry'),
|
||||
(22, 'Proveedor', 1, 1, 'supplier'),
|
||||
(23, 'Termografos', 35, 35, 'thermograph');
|
||||
|
||||
INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `warehouseFk`, `companyFk`, `hardCopyNumber`, `hasFile`, `reference`, `description`, `created`)
|
||||
VALUES
|
||||
|
@ -2472,7 +2475,7 @@ INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `wa
|
|||
(2, 5, '2.txt', 'text/plain', 5, 1, 442, 1, TRUE, 'Client:104', 'Client:104 dms for the client', util.VN_CURDATE()),
|
||||
(3, 5, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Client: 104', 'Client:104 readme', util.VN_CURDATE()),
|
||||
(4, 3, '4.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Worker: 106', 'Worker:106 readme', util.VN_CURDATE()),
|
||||
(5, 5, '5.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'travel: 1', 'dmsForThermograph', util.VN_CURDATE()),
|
||||
(5, 23, '5.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'travel: 1', 'dmsForThermograph', util.VN_CURDATE()),
|
||||
(6, 5, '6.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'NotExists', 'DoesNotExists', util.VN_CURDATE()),
|
||||
(7, 20, '7.jpg', 'image/jpeg', 9, 1, 442, NULL, FALSE, '1', 'TICKET ID DEL CLIENTE BRUCE WAYNE ID 1101', util.VN_CURDATE()),
|
||||
(8, 20, '8.mp4', 'video/mp4', 9, 1, 442, NULL, FALSE, '1', 'TICKET ID DEL CLIENTE BRUCE WAYNE ID 1101', util.VN_CURDATE()),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` EVENT `vn`.`travel_setDelivered`
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` EVENT `vn`.`travel_setDelivered`
|
||||
ON SCHEDULE EVERY 1 DAY
|
||||
STARTS '2024-07-12 00:10:00.000'
|
||||
ON COMPLETION PRESERVE
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`buy_getUltimate`(
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`buy_getUltimate`(
|
||||
vItemFk INT,
|
||||
vWarehouseFk SMALLINT,
|
||||
vDated DATE
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`buy_getUltimateFromInterval`(
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`buy_getUltimateFromInterval`(
|
||||
vItemFk INT,
|
||||
vWarehouseFk SMALLINT,
|
||||
vStarted DATE,
|
||||
|
|
|
@ -59,7 +59,7 @@ BEGIN
|
|||
DELETE b FROM buy b
|
||||
JOIN entryConfig e ON e.defaultEntry = b.entryFk
|
||||
WHERE b.created < v2Months;
|
||||
DELETE FROM stockBuyed WHERE creationDate < v2Months;
|
||||
DELETE FROM stockBought WHERE dated < v2Months;
|
||||
DELETE FROM printQueue WHERE statusCode = 'printed' AND created < v2Months;
|
||||
-- Equipos duplicados
|
||||
DELETE w.*
|
||||
|
|
|
@ -55,24 +55,20 @@ BEGIN
|
|||
SELECT ts.saleFk,
|
||||
ts.itemFk,
|
||||
CAST(0 AS DECIMAL(10,0)) saleOrder,
|
||||
IF(ish.visible > 0 OR iss.id, 1, 100000) *
|
||||
IFNULL(p2.pickingOrder, p.pickingOrder) `order`,
|
||||
TO_SECONDS(IF(iss.id,
|
||||
iss.created - INTERVAL vCurrentYear YEAR,
|
||||
ish.created - INTERVAL YEAR(ish.created) YEAR)) priority,
|
||||
(IF(ish.visible > 0 OR iss.id, 1, 100000) *
|
||||
COALESCE(p2.pickingOrder, p.pickingOrder)) `order`,
|
||||
TO_SECONDS(COALESCE(iss.created, ish.created)) - TO_SECONDS(MAKEDATE(IFNULL(YEAR(iss.created), YEAR(ish.created)), 1)) priority,
|
||||
CONCAT(
|
||||
IF(iss.id,
|
||||
CONCAT('< ', IFNULL(wk.`code`, '---'),' > '),
|
||||
''),
|
||||
p.`code`) COLLATE utf8_general_ci placement,
|
||||
IF(iss.id, CONCAT('< ', COALESCE(wk.`code`, '---'),' > '), ''),
|
||||
p.`code`
|
||||
) COLLATE utf8_general_ci placement,
|
||||
sh.priority shelvingPriority,
|
||||
sh.code COLLATE utf8_general_ci shelving,
|
||||
ish.created,
|
||||
ish.visible,
|
||||
IFNULL(
|
||||
IF(st.code = 'previousByPacking', ish.packing, g.`grouping`),
|
||||
1) `grouping`,
|
||||
st.code = 'previousPrepared' isPreviousPrepared,
|
||||
COALESCE(
|
||||
IF(st.code = 'previousByPacking', ish.packing, g.`grouping`),1) `grouping`,
|
||||
(st.code = 'previousPrepared') isPreviousPrepared,
|
||||
iss.id itemShelvingSaleFk,
|
||||
ts.ticketFk,
|
||||
iss.id,
|
||||
|
@ -80,11 +76,12 @@ BEGIN
|
|||
iss.userFk,
|
||||
ts.quantity
|
||||
FROM tSale ts
|
||||
LEFT JOIN (SELECT DISTINCT saleFk
|
||||
FROM saleTracking st
|
||||
JOIN state s ON s.id = st.stateFk
|
||||
WHERE st.isChecked
|
||||
AND s.semaphore = 1) st ON st.saleFk = ts.saleFk
|
||||
LEFT JOIN (SELECT st.saleFk
|
||||
FROM saleTracking st
|
||||
JOIN state s ON s.id = st.stateFk
|
||||
WHERE st.isChecked
|
||||
AND s.semaphore = 1
|
||||
GROUP BY st.saleFk) st ON st.saleFk = ts.saleFk
|
||||
JOIN itemShelving ish ON ish.itemFk = ts.itemFk
|
||||
JOIN shelving sh ON sh.code = ish.shelvingFk
|
||||
JOIN parking p ON p.id = sh.parkingFk
|
||||
|
@ -93,14 +90,14 @@ BEGIN
|
|||
JOIN warehouse w ON w.id = sc.warehouseFk
|
||||
LEFT JOIN tGrouping g ON g.itemFk = ts.itemFk
|
||||
LEFT JOIN itemShelvingSale iss ON iss.saleFk = ts.saleFk
|
||||
AND iss.itemShelvingFk = ish.id
|
||||
AND iss.itemShelvingFk = ish.id
|
||||
LEFT JOIN worker wk ON wk.id = iss.userFk
|
||||
LEFT JOIN saleGroupDetail sgd ON sgd.saleFk = ts.saleFk
|
||||
LEFT JOIN saleGroup sg ON sg.id = sgd.saleGroupFk
|
||||
LEFT JOIN parking p2 ON p2.id = sg.parkingFk
|
||||
WHERE w.id = vWarehouseFk
|
||||
AND NOT sc.isHideForPickers
|
||||
HAVING (iss.id AND st.saleFk) OR salePreviousPrepared IS NULL;
|
||||
AND NOT sc.isHideForPickers
|
||||
AND ((iss.id AND st.saleFk) OR st.saleFk IS NULL);
|
||||
|
||||
CREATE OR REPLACE TEMPORARY TABLE tSalePlacementList2
|
||||
(INDEX(saleFk), INDEX(olderPriority))
|
||||
|
|
|
@ -23,7 +23,7 @@ BEGIN
|
|||
JOIN vn.ticketCollection tc ON tc.ticketFk = tob.ticketFk
|
||||
LEFT JOIN vn.observationType ot ON ot.id = tob.observationTypeFk
|
||||
WHERE ot.`code` = 'itemPicker'
|
||||
AND tc.collectionFk = vParamFk
|
||||
AND tc.collectionFk = vParamFk OR tc.ticketFk = vParamFk
|
||||
)
|
||||
SELECT t.id ticketFk,
|
||||
IF(!(vItemPackingTypeFk <=> 'V'), cc.code, CONCAT(SUBSTRING('ABCDEFGH', tc.wagon, 1), '-', tc.`level`)) `level`,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`collection_mergeSales`(vCollectionFk INT)
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`collection_mergeSales`(vCollectionFk INT)
|
||||
BEGIN
|
||||
DECLARE vDone BOOL;
|
||||
DECLARE vTicketFk INT;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemMinimumQuantity_check`(
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`itemMinimumQuantity_check`(
|
||||
vSelf INT,
|
||||
vItemFk INT,
|
||||
vStarted DATE,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelvingSale_addBySaleGroup`(
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`itemShelvingSale_addBySaleGroup`(
|
||||
vSaleGroupFk INT(11)
|
||||
)
|
||||
BEGIN
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getSimilar`(
|
||||
vSelf INT,
|
||||
vWarehouseFk INT,
|
||||
vDated DATE,
|
||||
vShowType BOOL,
|
||||
vDaysInForward INT
|
||||
vSelf INT,
|
||||
vWarehouseFk INT,
|
||||
vDated DATE,
|
||||
vShowType BOOL,
|
||||
vDaysInForward INT
|
||||
)
|
||||
BEGIN
|
||||
/**
|
||||
|
@ -17,48 +17,48 @@ BEGIN
|
|||
* @param vShowType Mostrar tipos
|
||||
* @param vDaysInForward Días de alcance para las ventas
|
||||
*/
|
||||
DECLARE vAvailableCalcFk INT;
|
||||
DECLARE vPriority INT DEFAULT 1;
|
||||
DECLARE vAvailableCalcFk INT;
|
||||
DECLARE vPriority INT DEFAULT 1;
|
||||
|
||||
CALL cache.available_refresh(vAvailableCalcFk, FALSE, vWarehouseFk, vDated);
|
||||
CALL cache.available_refresh(vAvailableCalcFk, FALSE, vWarehouseFk, vDated);
|
||||
|
||||
WITH itemTags AS (
|
||||
SELECT i.id,
|
||||
typeFk,
|
||||
tag5,
|
||||
value5,
|
||||
tag6,
|
||||
value6,
|
||||
tag7,
|
||||
value7,
|
||||
tag8,
|
||||
value8,
|
||||
t.name,
|
||||
it.value
|
||||
WITH itemTags AS (
|
||||
SELECT i.id,
|
||||
typeFk,
|
||||
tag5,
|
||||
value5,
|
||||
tag6,
|
||||
value6,
|
||||
tag7,
|
||||
value7,
|
||||
tag8,
|
||||
value8,
|
||||
t.name,
|
||||
it.value
|
||||
FROM vn.item i
|
||||
LEFT JOIN vn.itemTag it ON it.itemFk = i.id
|
||||
AND it.priority = vPriority
|
||||
LEFT JOIN vn.tag t ON t.id = it.tagFk
|
||||
WHERE i.id = vSelf
|
||||
),
|
||||
stock AS (
|
||||
SELECT itemFk, SUM(visible) stock
|
||||
),
|
||||
stock AS (
|
||||
SELECT itemFk, SUM(visible) stock
|
||||
FROM vn.itemShelvingStock
|
||||
WHERE warehouseFk = vWarehouseFk
|
||||
GROUP BY itemFk
|
||||
),
|
||||
sold AS (
|
||||
SELECT SUM(s.quantity) quantity, s.itemFk
|
||||
),
|
||||
sold AS (
|
||||
SELECT SUM(s.quantity) quantity, s.itemFk
|
||||
FROM vn.sale s
|
||||
JOIN vn.ticket t ON t.id = s.ticketFk
|
||||
LEFT JOIN vn.itemShelvingSale iss ON iss.saleFk = s.id
|
||||
WHERE t.shipped BETWEEN CURDATE() AND CURDATE() + INTERVAL vDaysInForward DAY
|
||||
WHERE t.shipped >= CURDATE() + INTERVAL vDaysInForward DAY
|
||||
AND iss.saleFk IS NULL
|
||||
AND t.warehouseFk = vWarehouseFk
|
||||
GROUP BY s.itemFk
|
||||
)
|
||||
SELECT i.id itemFk,
|
||||
CAST(sd.quantity AS INT) advanceable,
|
||||
)
|
||||
SELECT i.id itemFk,
|
||||
LEAST(CAST(sd.quantity AS INT), sk.stock) advanceable,
|
||||
i.longName,
|
||||
i.subName,
|
||||
i.tag5,
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`stockBought_calculate`(
|
||||
vDated DATE
|
||||
)
|
||||
proc: BEGIN
|
||||
/**
|
||||
* Calculate the stock of the auction warehouse from the inventory date to vDated
|
||||
* without taking into account the outputs of the same day vDated
|
||||
*
|
||||
* @param vDated Date to calculate the stock.
|
||||
*/
|
||||
IF vDated < util.VN_CURDATE() THEN
|
||||
LEAVE proc;
|
||||
END IF;
|
||||
|
||||
CREATE OR REPLACE TEMPORARY TABLE tStockBought
|
||||
SELECT workerFk, reserve
|
||||
FROM stockBought
|
||||
WHERE dated = vDated
|
||||
AND reserve;
|
||||
|
||||
DELETE FROM stockBought WHERE dated = vDated;
|
||||
|
||||
CALL item_calculateStock(vDated);
|
||||
|
||||
INSERT INTO stockBought(workerFk, bought, dated)
|
||||
SELECT it.workerFk,
|
||||
ROUND(SUM(
|
||||
(ti.quantity / b.packing) *
|
||||
buy_getVolume(b.id)
|
||||
) / vc.palletM3 / 1000000, 1) bought,
|
||||
vDated
|
||||
FROM itemType it
|
||||
JOIN item i ON i.typeFk = it.id
|
||||
LEFT JOIN tmp.item ti ON ti.itemFk = i.id
|
||||
JOIN itemCategory ic ON ic.id = it.categoryFk
|
||||
JOIN warehouse wh ON wh.code = 'VNH'
|
||||
JOIN tmp.buyUltimate bu ON bu.itemFk = i.id
|
||||
AND bu.warehouseFk = wh.id
|
||||
JOIN buy b ON b.id = bu.buyFk
|
||||
JOIN volumeConfig vc
|
||||
WHERE ic.display
|
||||
GROUP BY it.workerFk
|
||||
HAVING bought;
|
||||
|
||||
UPDATE stockBought s
|
||||
JOIN tStockBought ts ON ts.workerFk = s.workerFk
|
||||
SET s.reserve = ts.reserve
|
||||
WHERE s.dated = vDated;
|
||||
|
||||
INSERT INTO stockBought (workerFk, reserve, dated)
|
||||
SELECT ts.workerFk, ts.reserve, vDated
|
||||
FROM tStockBought ts
|
||||
WHERE ts.workerFk NOT IN (
|
||||
SELECT workerFk
|
||||
FROM stockBought
|
||||
WHERE dated = vDated
|
||||
);
|
||||
|
||||
DROP TEMPORARY TABLE tStockBought, tmp.item, tmp.buyUltimate;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,74 +0,0 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`stockBuyedByWorker`(
|
||||
vDated DATE,
|
||||
vWorker INT
|
||||
)
|
||||
BEGIN
|
||||
/**
|
||||
* Inserta el volumen de compra de un comprador
|
||||
* en stockBuyed de acuerdo con la fecha.
|
||||
*
|
||||
* @param vDated Fecha de compra
|
||||
* @param vWorker Id de trabajador
|
||||
*/
|
||||
CREATE OR REPLACE TEMPORARY TABLE tStockBuyed
|
||||
(INDEX (userFk))
|
||||
ENGINE = MEMORY
|
||||
SELECT requested, reserved, userFk
|
||||
FROM stockBuyed
|
||||
WHERE dated = vDated
|
||||
AND userFk = vWorker;
|
||||
|
||||
DELETE FROM stockBuyed
|
||||
WHERE dated = vDated
|
||||
AND userFk = vWorker;
|
||||
|
||||
CALL item_calculateStock(vDated);
|
||||
|
||||
INSERT INTO stockBuyed(userFk, buyed, `dated`, reserved, requested, description)
|
||||
SELECT it.workerFk,
|
||||
SUM((ti.quantity / b.packing) * buy_getVolume(b.id)) / vc.palletM3 / 1000000,
|
||||
vDated,
|
||||
sb.reserved,
|
||||
sb.requested,
|
||||
u.name
|
||||
FROM itemType it
|
||||
JOIN item i ON i.typeFk = it.id
|
||||
LEFT JOIN tmp.item ti ON ti.itemFk = i.id
|
||||
JOIN itemCategory ic ON ic.id = it.categoryFk
|
||||
JOIN warehouse wh ON wh.code = 'VNH'
|
||||
JOIN tmp.buyUltimate bu ON bu.itemFk = i.id
|
||||
AND bu.warehouseFk = wh.id
|
||||
JOIN buy b ON b.id = bu.buyFk
|
||||
JOIN volumeConfig vc
|
||||
JOIN account.`user` u ON u.id = it.workerFk
|
||||
LEFT JOIN tStockBuyed sb ON sb.userFk = it.workerFk
|
||||
WHERE ic.display
|
||||
AND it.workerFk = vWorker;
|
||||
|
||||
SELECT b.entryFk Id_Entrada,
|
||||
i.id Id_Article,
|
||||
i.name Article,
|
||||
ti.quantity Cantidad,
|
||||
(ac.conversionCoefficient * (ti.quantity / b.packing) * buy_getVolume(b.id))
|
||||
/ (vc.trolleyM3 * 1000000) buyed,
|
||||
b.packagingFk id_cubo,
|
||||
b.packing
|
||||
FROM tmp.item ti
|
||||
JOIN item i ON i.id = ti.itemFk
|
||||
JOIN itemType it ON i.typeFk = it.id
|
||||
JOIN itemCategory ic ON ic.id = it.categoryFk
|
||||
JOIN worker w ON w.id = it.workerFk
|
||||
JOIN auctionConfig ac
|
||||
JOIN tmp.buyUltimate bu ON bu.itemFk = i.id
|
||||
AND bu.warehouseFk = ac.warehouseFk
|
||||
JOIN buy b ON b.id = bu.buyFk
|
||||
JOIN volumeConfig vc
|
||||
WHERE ic.display
|
||||
AND w.id = vWorker;
|
||||
|
||||
DROP TEMPORARY TABLE tmp.buyUltimate,
|
||||
tmp.item,
|
||||
tStockBuyed;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,70 +0,0 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`stockBuyed_add`(
|
||||
vDated DATE
|
||||
)
|
||||
BEGIN
|
||||
/**
|
||||
* Inserta el volumen de compra por comprador
|
||||
* en stockBuyed de acuerdo con la fecha.
|
||||
*
|
||||
* @param vDated Fecha de compra
|
||||
*/
|
||||
CREATE OR REPLACE TEMPORARY TABLE tStockBuyed
|
||||
(INDEX (userFk))
|
||||
ENGINE = MEMORY
|
||||
SELECT requested, reserved, userFk
|
||||
FROM stockBuyed
|
||||
WHERE dated = vDated;
|
||||
|
||||
DELETE FROM stockBuyed WHERE dated = vDated;
|
||||
|
||||
CALL item_calculateStock(vDated);
|
||||
|
||||
INSERT INTO stockBuyed(userFk, buyed, `dated`, description)
|
||||
SELECT it.workerFk,
|
||||
SUM((ti.quantity / b.packing) * buy_getVolume(b.id)) / vc.palletM3 / 1000000,
|
||||
vDated,
|
||||
u.name
|
||||
FROM itemType it
|
||||
JOIN item i ON i.typeFk = it.id
|
||||
LEFT JOIN tmp.item ti ON ti.itemFk = i.id
|
||||
JOIN itemCategory ic ON ic.id = it.categoryFk
|
||||
JOIN warehouse wh ON wh.code = 'VNH'
|
||||
JOIN tmp.buyUltimate bu ON bu.itemFk = i.id AND bu.warehouseFk = wh.id
|
||||
JOIN buy b ON b.id = bu.buyFk
|
||||
JOIN volumeConfig vc
|
||||
JOIN account.`user` u ON u.id = it.workerFk
|
||||
JOIN workerDepartment wd ON wd.workerFk = u.id
|
||||
JOIN department d ON d.id = wd.departmentFk
|
||||
WHERE ic.display
|
||||
AND d.code IN ('shopping', 'logistic', 'franceTeam')
|
||||
GROUP BY it.workerFk;
|
||||
|
||||
INSERT INTO stockBuyed(buyed, dated, description)
|
||||
SELECT SUM(ic.cm3 * ito.quantity / vc.palletM3 / 1000000),
|
||||
vDated,
|
||||
IF(c.code = 'ES', p.name, c.name) destiny
|
||||
FROM itemTicketOut ito
|
||||
JOIN ticket t ON t.id = ito.ticketFk
|
||||
JOIN `address` a ON a.id = t.addressFk
|
||||
JOIN province p ON p.id = a.provinceFk
|
||||
JOIN country c ON c.id = p.countryFk
|
||||
JOIN warehouse wh ON wh.id = t.warehouseFk
|
||||
JOIN itemCost ic ON ic.itemFk = ito.itemFk
|
||||
AND ic.warehouseFk = t.warehouseFk
|
||||
JOIN volumeConfig vc
|
||||
WHERE ito.shipped BETWEEN vDated AND util.dayend(vDated)
|
||||
AND wh.code = 'VNH'
|
||||
GROUP BY destiny;
|
||||
|
||||
UPDATE stockBuyed s
|
||||
JOIN tStockBuyed ts ON ts.userFk = s.userFk
|
||||
SET s.requested = ts.requested,
|
||||
s.reserved = ts.reserved
|
||||
WHERE s.dated = vDated;
|
||||
|
||||
DROP TEMPORARY TABLE tmp.buyUltimate,
|
||||
tmp.item,
|
||||
tStockBuyed;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE vn.supplier_statementWithEntries(
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE vn.supplier_statementWithEntries(
|
||||
vSupplierFk INT,
|
||||
vCurrencyFk INT,
|
||||
vCompanyFk INT,
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticketRefund_upsert`(
|
||||
vRefundTicketFk INT,
|
||||
vOriginalTicketFk INT
|
||||
)
|
||||
READS SQL DATA
|
||||
BEGIN
|
||||
/**
|
||||
* Common code for ticketRefund triggers
|
||||
*
|
||||
* @param vRefundTicketFk
|
||||
* @param vOriginalTicketFk
|
||||
*/
|
||||
DECLARE vIsDeleted BOOL;
|
||||
|
||||
SELECT COUNT(*) INTO vIsDeleted
|
||||
FROM ticket
|
||||
WHERE id IN (vRefundTicketFk, vOriginalTicketFk)
|
||||
AND isDeleted;
|
||||
|
||||
IF vIsDeleted THEN
|
||||
CALL util.throw('The refund ticket cannot be deleted tickets');
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_mergeSales`(
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticket_mergeSales`(
|
||||
vSelf INT
|
||||
)
|
||||
BEGIN
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_setProblemRiskByClient`(
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticket_setProblemRiskByClient`(
|
||||
vClientFk INT
|
||||
)
|
||||
BEGIN
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_setVolume`(
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticket_setVolume`(
|
||||
vSelf INT
|
||||
)
|
||||
BEGIN
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_setVolumeItemCost`(
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`ticket_setVolumeItemCost`(
|
||||
vItemFk INT
|
||||
)
|
||||
BEGIN
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`host_beforeInsert`
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`host_beforeInsert`
|
||||
BEFORE INSERT ON `host`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`roadmap_beforeInsert`
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmap_beforeInsert`
|
||||
BEFORE INSERT ON `roadmap`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`roadmap_beforeUpdate`
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`roadmap_beforeUpdate`
|
||||
BEFORE UPDATE ON `roadmap`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`saleGroupDetail_beforeInsert`
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`saleGroupDetail_beforeInsert`
|
||||
BEFORE INSERT ON `saleGroupDetail`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`saleGroupDetail_afterDelete`
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`saleGroupDetail_afterDelete`
|
||||
AFTER DELETE ON `saleGroupDetail`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`saleGroupDetail_beforeUpdate`
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`saleGroupDetail_beforeUpdate`
|
||||
BEFORE UPDATE ON `saleGroupDetail`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
|
|
|
@ -3,6 +3,8 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`ticketRefund_beforeInse
|
|||
BEFORE INSERT ON `ticketRefund`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
CALL ticketRefund_upsert(NEW.refundTicketFk, NEW.originalTicketFk);
|
||||
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -3,6 +3,8 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`ticketRefund_beforeUpda
|
|||
BEFORE UPDATE ON `ticketRefund`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
CALL ticketRefund_upsert(NEW.refundTicketFk, NEW.originalTicketFk);
|
||||
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -4,5 +4,14 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`travelThermograph_befor
|
|||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
|
||||
IF NEW.travelFk IS NULL AND
|
||||
(SELECT COUNT(*) FROM travelThermograph
|
||||
WHERE thermographFk = NEW.thermographFk
|
||||
AND travelFk IS NULL
|
||||
AND id <> NEW.id) > 0
|
||||
THEN
|
||||
CALL util.throw('Duplicate thermographFk without travelFk not allowed.');
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -4,5 +4,14 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`travelThermograph_befor
|
|||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
|
||||
IF NEW.travelFk IS NULL AND
|
||||
(SELECT COUNT(*) FROM travelThermograph
|
||||
WHERE thermographFk = NEW.thermographFk
|
||||
AND travelFk IS NULL
|
||||
AND id <> NEW.id) > 0
|
||||
THEN
|
||||
CALL util.throw('Duplicate thermographFk without travelFk not allowed.');
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
-- Place your SQL code here
|
||||
-- vn.stockBought definition
|
||||
|
||||
CREATE TABLE IF NOT EXISTS vn.stockBought (
|
||||
id INT UNSIGNED auto_increment NOT NULL,
|
||||
workerFk int(10) unsigned NOT NULL,
|
||||
bought decimal(10,2) NOT NULL COMMENT 'purchase volume in m3 for the day',
|
||||
reserve decimal(10,2) NULL COMMENT 'reserved volume in m3 for the day',
|
||||
dated DATE NOT NULL DEFAULT current_timestamp(),
|
||||
CONSTRAINT stockBought_pk PRIMARY KEY (id),
|
||||
CONSTRAINT stockBought_unique UNIQUE KEY (workerFk,dated),
|
||||
CONSTRAINT stockBought_worker_FK FOREIGN KEY (workerFk) REFERENCES vn.worker(id)
|
||||
)
|
||||
ENGINE=InnoDB
|
||||
DEFAULT CHARSET=utf8mb3
|
||||
COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
|
||||
INSERT IGNORE vn.stockBought (workerFk, bought, reserve, dated)
|
||||
SELECT userFk, SUM(buyed), SUM(IFNULL(reserved,0)), dated
|
||||
FROM vn.stockBuyed
|
||||
WHERE userFk IS NOT NULL
|
||||
AND buyed IS NOT NULL
|
||||
GROUP BY userFk, dated;
|
||||
|
||||
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
|
||||
VALUES ('StockBought','*','READ','ALLOW','ROLE','buyer'),
|
||||
('StockBought','*','WRITE','ALLOW','ROLE','buyer'),
|
||||
('Buyer','*','READ','ALLOW','ROLE','buyer');
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
-- Place your SQL code here
|
||||
RENAME TABLE vn.stockBuyed TO vn.stockBuyed__;
|
||||
ALTER TABLE vn.stockBuyed__
|
||||
COMMENT='@deprecated 2024-10-01 rename and refactor to stockBought';
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE vn.address MODIFY COLUMN isEqualizated tinyint(1) DEFAULT FALSE NOT NULL;
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE vn.autonomy MODIFY COLUMN isUeeMember tinyint(1) DEFAULT FALSE NOT NULL;
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE vn.chat MODIFY COLUMN checkUserStatus tinyint(1) DEFAULT FALSE NOT NULL;
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE vn.warehouse
|
||||
MODIFY COLUMN isOrigin tinyint(1) DEFAULT FALSE NOT NULL,
|
||||
MODIFY COLUMN isDestiny tinyint(1) DEFAULT FALSE NOT NULL;
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE vn.zoneIncluded MODIFY COLUMN isIncluded tinyint(1) DEFAULT FALSE NOT NULL;
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE bs.defaulter MODIFY COLUMN hasChanged tinyint(1) DEFAULT FALSE NOT NULL;
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE account.user MODIFY COLUMN emailVerified tinyint(1) DEFAULT FALSE NOT NULL;
|
|
@ -1,68 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('SmartTable SearchBar integration', () => {
|
||||
let browser;
|
||||
let page;
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('salesPerson', 'item');
|
||||
await page.waitToClick(selectors.globalItems.searchButton);
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should search by type in searchBar, reload page and have same results', async() => {
|
||||
await page.waitToClick(selectors.itemsIndex.openAdvancedSearchButton);
|
||||
await page.autocompleteSearch(selectors.itemsIndex.advancedSearchItemType, 'Anthurium');
|
||||
await page.waitToClick(selectors.itemsIndex.advancedSearchButton);
|
||||
await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 4);
|
||||
|
||||
await page.reload({
|
||||
waitUntil: 'networkidle2'
|
||||
});
|
||||
|
||||
await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 4);
|
||||
|
||||
await page.write(selectors.itemsIndex.advancedSmartTableGrouping, '1');
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 2);
|
||||
|
||||
await page.reload({
|
||||
waitUntil: 'networkidle2'
|
||||
});
|
||||
|
||||
await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1);
|
||||
});
|
||||
|
||||
it('should filter in section without smart-table and search in searchBar go to zone section', async() => {
|
||||
await page.loginAndModule('salesPerson', 'zone');
|
||||
await page.waitToClick(selectors.globalItems.searchButton);
|
||||
|
||||
await page.doSearch('A');
|
||||
const firstCount = await page.countElement(selectors.zoneIndex.searchResult);
|
||||
|
||||
await page.doSearch('A');
|
||||
const secondCount = await page.countElement(selectors.zoneIndex.searchResult);
|
||||
|
||||
expect(firstCount).toEqual(7);
|
||||
expect(secondCount).toEqual(7);
|
||||
});
|
||||
|
||||
it('should order orders by first id and order by last id, reload page and have same order', async() => {
|
||||
await page.loginAndModule('developer', 'item');
|
||||
await page.accessToSection('item.fixedPrice');
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
await page.waitForTextInField(selectors.itemFixedPrice.firstItemID, '1');
|
||||
|
||||
await page.waitToClick(selectors.itemFixedPrice.orderColumnId);
|
||||
await page.reload({
|
||||
waitUntil: 'networkidle2'
|
||||
});
|
||||
await page.waitForTextInField(selectors.itemFixedPrice.firstItemID, '3');
|
||||
});
|
||||
});
|
|
@ -1,104 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Zone basic data path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
|
||||
await page.loginAndModule('deliveryAssistant',
|
||||
'zone'); // turns up the zone module name and route aint the same lol
|
||||
await page.accessToSearchResult('10');
|
||||
await page.accessToSection('zone.card.basicData');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should reach the basic data section', async() => {
|
||||
await page.waitForState('zone.card.basicData');
|
||||
});
|
||||
|
||||
it('should edit de form and then save', async() => {
|
||||
await page.clearInput(selectors.zoneBasicData.name);
|
||||
await page.write(selectors.zoneBasicData.name, 'Brimstone teleportation');
|
||||
await page.autocompleteSearch(selectors.zoneBasicData.agency, 'Quantum break device');
|
||||
await page.clearInput(selectors.zoneBasicData.maxVolume);
|
||||
await page.write(selectors.zoneBasicData.maxVolume, '10');
|
||||
await page.clearInput(selectors.zoneBasicData.travelingDays);
|
||||
await page.write(selectors.zoneBasicData.travelingDays, '1');
|
||||
await page.clearInput(selectors.zoneBasicData.closing);
|
||||
await page.pickTime(selectors.zoneBasicData.closing, '21:00');
|
||||
await page.clearInput(selectors.zoneBasicData.price);
|
||||
await page.write(selectors.zoneBasicData.price, '999');
|
||||
await page.clearInput(selectors.zoneBasicData.bonus);
|
||||
await page.write(selectors.zoneBasicData.bonus, '100');
|
||||
await page.clearInput(selectors.zoneBasicData.inflation);
|
||||
await page.write(selectors.zoneBasicData.inflation, '200');
|
||||
await page.waitToClick(selectors.zoneBasicData.volumetric);
|
||||
await page.waitToClick(selectors.zoneBasicData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should now reload the section', async() => {
|
||||
await page.reloadSection('zone.card.basicData');
|
||||
});
|
||||
|
||||
it('should confirm the name was updated', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.zoneBasicData.name, 'value');
|
||||
|
||||
expect(result).toEqual('Brimstone teleportation');
|
||||
});
|
||||
|
||||
it('should confirm the agency was updated', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.zoneBasicData.agency, 'value');
|
||||
|
||||
expect(result).toEqual('Quantum break device');
|
||||
});
|
||||
|
||||
it('should confirm the max volume was updated', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.zoneBasicData.maxVolume, 'value');
|
||||
|
||||
expect(result).toEqual('10');
|
||||
});
|
||||
|
||||
it('should confirm the traveling days were updated', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.zoneBasicData.travelingDays, 'value');
|
||||
|
||||
expect(result).toEqual('1');
|
||||
});
|
||||
|
||||
it('should confirm the closing hour was updated', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.zoneBasicData.closing, 'value');
|
||||
|
||||
expect(result).toEqual('21:00');
|
||||
});
|
||||
|
||||
it('should confirm the price was updated', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.zoneBasicData.price, 'value');
|
||||
|
||||
expect(result).toEqual('999');
|
||||
});
|
||||
|
||||
it('should confirm the bonus was updated', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.zoneBasicData.bonus, 'value');
|
||||
|
||||
expect(result).toEqual('100');
|
||||
});
|
||||
|
||||
it('should confirm the inflation was updated', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.zoneBasicData.inflation, 'value');
|
||||
|
||||
expect(result).toEqual('200');
|
||||
});
|
||||
|
||||
it('should confirm the volumetric checkbox was checked', async() => {
|
||||
await page.waitForClassPresent(selectors.zoneBasicData.volumetric, 'checked');
|
||||
});
|
||||
});
|
|
@ -1,32 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Zone descriptor path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('deliveryAssistant', 'zone');
|
||||
await page.accessToSearchResult('13');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should eliminate the zone using the descriptor option', async() => {
|
||||
await page.waitToClick(selectors.zoneDescriptor.menu);
|
||||
await page.waitToClick(selectors.zoneDescriptor.deleteZone);
|
||||
await page.respondToDialog('accept');
|
||||
await page.waitForState('zone.index');
|
||||
});
|
||||
|
||||
it('should search for the deleted zone to find no results', async() => {
|
||||
await page.doSearch('13');
|
||||
const count = await page.countElement(selectors.zoneIndex.searchResult);
|
||||
|
||||
expect(count).toEqual(0);
|
||||
});
|
||||
});
|
|
@ -106,10 +106,15 @@ module.exports = Self => {
|
|||
description: `The to shipped date filter`
|
||||
},
|
||||
{
|
||||
arg: 'days',
|
||||
arg: 'daysOnward',
|
||||
type: 'number',
|
||||
description: `N days interval`
|
||||
},
|
||||
{
|
||||
arg: 'daysAgo',
|
||||
type: 'number',
|
||||
description: `N days ago interval`
|
||||
},
|
||||
{
|
||||
arg: 'invoiceAmount',
|
||||
type: 'number',
|
||||
|
@ -216,16 +221,29 @@ module.exports = Self => {
|
|||
JOIN vn.currency cu ON cu.id = e.currencyFk`
|
||||
);
|
||||
|
||||
if (ctx.args.days) {
|
||||
stmt.merge({
|
||||
sql: `
|
||||
AND t.shipped <= util.VN_CURDATE() + INTERVAL ? DAY
|
||||
AND t.shipped >= util.VN_CURDATE()
|
||||
`,
|
||||
params: [ctx.args.days]
|
||||
});
|
||||
stmt.merge(conn.makeWhere(filter.where));
|
||||
|
||||
const {daysAgo, daysOnward} = ctx.args;
|
||||
if (daysOnward || daysAgo) {
|
||||
const params = [];
|
||||
let today = 'util.VN_CURDATE()';
|
||||
let from = today;
|
||||
let to = today;
|
||||
|
||||
if (daysAgo) {
|
||||
from += ' - INTERVAL ? DAY';
|
||||
params.push(daysAgo);
|
||||
}
|
||||
if (daysOnward) {
|
||||
to += ' + INTERVAL ? DAY';
|
||||
params.push(daysOnward);
|
||||
}
|
||||
|
||||
const whereDays = (filter.where ? 'AND' : 'WHERE') + ` t.shipped BETWEEN ${from} AND ${to}`;
|
||||
stmt.merge({sql: whereDays, params});
|
||||
}
|
||||
stmt.merge(conn.makeSuffix(filter));
|
||||
|
||||
stmt.merge(conn.makePagination(filter));
|
||||
const itemsIndex = stmts.push(stmt) - 1;
|
||||
|
||||
const sql = ParameterizedSQL.join(stmts, ';');
|
||||
|
|
|
@ -49,13 +49,13 @@ describe('Entry filter()', () => {
|
|||
});
|
||||
|
||||
describe('should return the entry matching the supplier', () => {
|
||||
it('when userId is supplier ', async() => {
|
||||
it('when userId is supplier and searching days onward', async() => {
|
||||
const tx = await models.Entry.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
|
||||
try {
|
||||
const ctx = {
|
||||
args: {days: 6},
|
||||
args: {daysOnward: 6},
|
||||
req: {accessToken: {userId: 1102}}
|
||||
};
|
||||
|
||||
|
@ -70,6 +70,27 @@ describe('Entry filter()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('when userId is supplier and searching days ago', async() => {
|
||||
const tx = await models.Entry.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
|
||||
try {
|
||||
const ctx = {
|
||||
args: {daysAgo: 31},
|
||||
req: {accessToken: {userId: 1102}}
|
||||
};
|
||||
|
||||
const result = await models.Entry.filter(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(6);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('when userId is supplier fetching other supplier', async() => {
|
||||
const tx = await models.Entry.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('getStockBought', {
|
||||
description: 'Returns the stock bought for a given date',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'workerFk',
|
||||
type: 'number',
|
||||
description: 'The id for a buyer',
|
||||
},
|
||||
{
|
||||
arg: 'dated',
|
||||
type: 'date',
|
||||
description: 'The date to filter',
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: ['object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/getStockBought`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.getStockBought = async(workerFk, dated = Date.vnNew()) => {
|
||||
const models = Self.app.models;
|
||||
const today = Date.vnNew();
|
||||
dated.setHours(0, 0, 0, 0);
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
await models.StockBought.rawSql(`CALL vn.stockBought_calculate(?)`, [dated]);
|
||||
|
||||
const filter = {
|
||||
where: {dated},
|
||||
include: [
|
||||
{
|
||||
fields: ['workerFk', 'reserve', 'bought'],
|
||||
relation: 'worker',
|
||||
scope: {
|
||||
include: [
|
||||
{
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
if (workerFk) filter.where.workerFk = workerFk;
|
||||
|
||||
return models.StockBought.find(filter);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,74 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('getStockBoughtDetail', {
|
||||
description: 'Returns the detail of stock bought for a given date and a worker',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'workerFk',
|
||||
type: 'number',
|
||||
description: 'The worker to filter',
|
||||
required: true,
|
||||
}, {
|
||||
arg: 'dated',
|
||||
type: 'string',
|
||||
description: 'The date to filter',
|
||||
required: true,
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: ['object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/getStockBoughtDetail`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.getStockBoughtDetail = async(workerFk, dated) => {
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
let result;
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
try {
|
||||
await models.StockBought.rawSql(`CALL vn.item_calculateStock(?)`, [dated], myOptions);
|
||||
result = await Self.rawSql(
|
||||
`SELECT b.entryFk entryFk,
|
||||
i.id itemFk,
|
||||
i.name itemName,
|
||||
ti.quantity,
|
||||
(ac.conversionCoefficient * (ti.quantity / b.packing) * buy_getVolume(b.id))
|
||||
/ (vc.trolleyM3 * 1000000) volume,
|
||||
b.packagingFk packagingFk,
|
||||
b.packing
|
||||
FROM tmp.item ti
|
||||
JOIN item i ON i.id = ti.itemFk
|
||||
JOIN itemType it ON i.typeFk = it.id
|
||||
JOIN itemCategory ic ON ic.id = it.categoryFk
|
||||
JOIN worker w ON w.id = it.workerFk
|
||||
JOIN auctionConfig ac
|
||||
JOIN tmp.buyUltimate bu ON bu.itemFk = i.id
|
||||
AND bu.warehouseFk = ac.warehouseFk
|
||||
JOIN buy b ON b.id = bu.buyFk
|
||||
JOIN volumeConfig vc
|
||||
WHERE ic.display
|
||||
AND w.id = ?`,
|
||||
[workerFk], myOptions
|
||||
);
|
||||
await Self.rawSql(`DROP TEMPORARY TABLE tmp.item, tmp.buyUltimate;`, [], myOptions);
|
||||
if (tx) await tx.commit();
|
||||
return result;
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -25,5 +25,8 @@
|
|||
},
|
||||
"EntryType": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"StockBought": {
|
||||
"dataSource": "vn"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
module.exports = Self => {
|
||||
require('../methods/stock-bought/getStockBought')(Self);
|
||||
require('../methods/stock-bought/getStockBoughtDetail')(Self);
|
||||
Self.rewriteDbError(function(err) {
|
||||
if (err.code === 'ER_DUP_ENTRY')
|
||||
return new UserError(`This buyer has already made a reservation for this date`);
|
||||
return err;
|
||||
});
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "StockBought",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "stockBought"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "number",
|
||||
"id": true
|
||||
},
|
||||
"workerFk": {
|
||||
"type": "number"
|
||||
},
|
||||
"bought": {
|
||||
"type": "number"
|
||||
},
|
||||
"reserve": {
|
||||
"type": "number"
|
||||
},
|
||||
"dated": {
|
||||
"type": "date"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"worker": {
|
||||
"type": "belongsTo",
|
||||
"model": "Worker",
|
||||
"foreignKey": "workerFk"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -142,12 +142,19 @@ module.exports = Self => {
|
|||
ctx.args.addressId = ticket.addressFk;
|
||||
|
||||
const newTicket = await models.Ticket.new(ctx, myOptions);
|
||||
|
||||
await models.TicketRefund.create({
|
||||
originalTicketFk: ticketId,
|
||||
refundTicketFk: newTicket.id
|
||||
}, myOptions);
|
||||
|
||||
const existingRefund = await models.TicketRefund.findOne({
|
||||
where: {
|
||||
originalTicketFk: ticketId,
|
||||
refundTicketFk: newTicket.id
|
||||
},
|
||||
myOptions
|
||||
});
|
||||
if (!existingRefund) {
|
||||
await models.TicketRefund.create({
|
||||
originalTicketFk: ticketId,
|
||||
refundTicketFk: newTicket.id
|
||||
}, myOptions);
|
||||
}
|
||||
return newTicket;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -117,7 +117,8 @@ module.exports = Self => {
|
|||
result: state,
|
||||
maxTemperature,
|
||||
minTemperature,
|
||||
temperatureFk
|
||||
temperatureFk,
|
||||
warehouseFk: warehouseId,
|
||||
}, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
|
|
@ -4,7 +4,7 @@ describe('Thermograph saveThermograph()', () => {
|
|||
const ctx = beforeAll.getCtx();
|
||||
const travelFk = 1;
|
||||
const thermographId = '138350-0';
|
||||
const warehouseFk = '1';
|
||||
const warehouseFk = 1;
|
||||
const state = 'COMPLETED';
|
||||
const maxTemperature = 30;
|
||||
const minTemperature = 10;
|
||||
|
@ -41,7 +41,7 @@ describe('Thermograph saveThermograph()', () => {
|
|||
maxTemperature,
|
||||
minTemperature,
|
||||
temperatureFk,
|
||||
null,
|
||||
warehouseFk,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
|
|
|
@ -82,7 +82,7 @@ module.exports = Self => {
|
|||
const getDataOperator = await models.Operator.findOne({
|
||||
where: {workerFk: user.id},
|
||||
fields: ['numberOfWagons', 'warehouseFk', 'itemPackingTypeFk', 'sectorFk', 'sector',
|
||||
'trainFk', 'train', 'labelerFk', 'printer'],
|
||||
'trainFk', 'train', 'labelerFk', 'printer', 'isOnReservationMode'],
|
||||
include: [
|
||||
{
|
||||
relation: 'sector',
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
<mg-ajax path="Zones/{{patch.params.id}}" options="vnPatch"></mg-ajax>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.zone"
|
||||
form="form"
|
||||
save="patch">
|
||||
</vn-watcher>
|
||||
<form
|
||||
name="form"
|
||||
ng-submit="$ctrl.onSubmit()"
|
||||
class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
label="Name"
|
||||
ng-model="$ctrl.zone.name"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-model="$ctrl.zone.agencyModeFk"
|
||||
url="AgencyModes"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Agency"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-autocomplete>
|
||||
<vn-input-number
|
||||
vn-one
|
||||
label="Max m³"
|
||||
ng-model="$ctrl.zone.itemMaxSize"
|
||||
min="0"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
vn-one
|
||||
label="Maximum m³"
|
||||
ng-model="$ctrl.zone.m3Max"
|
||||
min="0"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-number
|
||||
label="Traveling days"
|
||||
ng-model="$ctrl.zone.travelingDays"
|
||||
min="0"
|
||||
step="1"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-time
|
||||
label="Closing"
|
||||
ng-model="$ctrl.zone.hour"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-time>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-number
|
||||
label="Price"
|
||||
ng-model="$ctrl.zone.price"
|
||||
min="0"
|
||||
step="0.01"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
label="Bonus"
|
||||
ng-model="$ctrl.zone.bonus"
|
||||
step="0.01"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-number
|
||||
vn-one
|
||||
label="Inflation"
|
||||
ng-model="$ctrl.zone.inflation"
|
||||
min="0"
|
||||
step="0.01"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="Volumetric"
|
||||
ng-model="$ctrl.zone.isVolumetric"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
vn-acl="deliveryAssistant"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Undo changes"
|
||||
disabled="!watcher.dataChanged()"
|
||||
ng-click="watcher.loadOriginalData()">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -1,21 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
class Controller extends Section {
|
||||
onSubmit() {
|
||||
this.$.watcher.submit().then(() =>
|
||||
this.card.reload()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnZoneBasicData', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
zone: '<'
|
||||
},
|
||||
require: {
|
||||
card: '^vnZoneCard'
|
||||
}
|
||||
});
|
|
@ -1,33 +0,0 @@
|
|||
<vn-card>
|
||||
<div class="header">
|
||||
<vn-button
|
||||
icon="navigate_before"
|
||||
ng-click="$ctrl.step(-1)"
|
||||
class="flat">
|
||||
</vn-button>
|
||||
<div>
|
||||
<span translate>{{$ctrl.firstDay | date:'MMMM'}}</span>
|
||||
<span>{{$ctrl.firstDay | date:'yyyy'}} -</span>
|
||||
<span translate>{{$ctrl.lastDay | date:'MMMM'}}</span>
|
||||
<span>{{$ctrl.lastDay | date:'yyyy'}}</span>
|
||||
</div>
|
||||
<vn-button
|
||||
icon="navigate_next"
|
||||
ng-click="$ctrl.step(1)"
|
||||
class="flat">
|
||||
</vn-button>
|
||||
</div>
|
||||
<div class="calendars vn-pa-md">
|
||||
<vn-calendar
|
||||
ng-repeat="date in $ctrl.months track by date.getTime()"
|
||||
default-date="date"
|
||||
display-controls="false"
|
||||
hide-contiguous="true"
|
||||
has-events="$ctrl.hasEvents($day)"
|
||||
get-class="$ctrl.getClass($day)"
|
||||
on-selection="$ctrl.onSelection($event, $days, $type, $weekday)"
|
||||
class="vn-pa-md"
|
||||
style="min-width: 250px; flex: 1;">
|
||||
</vn-calendar>
|
||||
</div>
|
||||
</vn-card>
|
|
@ -1,191 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Component from 'core/lib/component';
|
||||
import './style.scss';
|
||||
|
||||
class Controller extends Component {
|
||||
constructor($element, $, vnWeekDays) {
|
||||
super($element, $);
|
||||
this.vnWeekDays = vnWeekDays;
|
||||
this.nMonths = 4;
|
||||
|
||||
let date = Date.vnNew();
|
||||
date.setDate(1);
|
||||
date.setHours(0, 0, 0, 0);
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
get date() {
|
||||
return this._date;
|
||||
}
|
||||
|
||||
set date(value) {
|
||||
this._date = value;
|
||||
let stamp = value.getTime();
|
||||
|
||||
let firstDay = new Date(stamp);
|
||||
firstDay.setDate(1);
|
||||
this.firstDay = firstDay;
|
||||
|
||||
let lastDay = new Date(stamp);
|
||||
lastDay.setMonth(lastDay.getMonth() + this.nMonths);
|
||||
lastDay.setDate(0);
|
||||
this.lastDay = lastDay;
|
||||
|
||||
this.months = [];
|
||||
for (let i = 0; i < this.nMonths; i++) {
|
||||
let monthDate = new Date(stamp);
|
||||
monthDate.setMonth(value.getMonth() + i);
|
||||
this.months.push(monthDate);
|
||||
}
|
||||
|
||||
this.refreshEvents();
|
||||
}
|
||||
|
||||
step(direction) {
|
||||
let date = new Date(this.date.getTime());
|
||||
date.setMonth(date.getMonth() + (this.nMonths * direction));
|
||||
this.date = date;
|
||||
|
||||
this.emit('step');
|
||||
}
|
||||
|
||||
get data() {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
set data(value) {
|
||||
this._data = value;
|
||||
|
||||
value = value || {};
|
||||
|
||||
this.events = value.events;
|
||||
|
||||
function toStamp(date) {
|
||||
return date && new Date(date).setHours(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
this.exclusions = {};
|
||||
let exclusions = value.exclusions;
|
||||
|
||||
if (exclusions) {
|
||||
for (let exclusion of exclusions) {
|
||||
let stamp = toStamp(exclusion.dated);
|
||||
if (!this.exclusions[stamp]) this.exclusions[stamp] = [];
|
||||
this.exclusions[stamp].push(exclusion);
|
||||
}
|
||||
}
|
||||
|
||||
this.geoExclusions = {};
|
||||
let geoExclusions = value.geoExclusions;
|
||||
|
||||
if (geoExclusions) {
|
||||
for (let geoExclusion of geoExclusions) {
|
||||
let stamp = toStamp(geoExclusion.dated);
|
||||
if (!this.geoExclusions[stamp]) this.geoExclusions[stamp] = [];
|
||||
this.geoExclusions[stamp].push(geoExclusion);
|
||||
}
|
||||
}
|
||||
|
||||
let events = value.events;
|
||||
|
||||
if (events) {
|
||||
for (let event of events) {
|
||||
event.dated = toStamp(event.dated);
|
||||
event.ended = toStamp(event.ended);
|
||||
event.started = toStamp(event.started);
|
||||
event.wdays = this.vnWeekDays.fromSet(event.weekDays);
|
||||
}
|
||||
}
|
||||
|
||||
this.refreshEvents();
|
||||
|
||||
let calendars = this.element.querySelectorAll('vn-calendar');
|
||||
for (let calendar of calendars)
|
||||
calendar.$ctrl.repaint();
|
||||
}
|
||||
|
||||
refreshEvents() {
|
||||
this.days = {};
|
||||
if (!this.data) return;
|
||||
|
||||
let day = new Date(this.firstDay.getTime());
|
||||
|
||||
while (day <= this.lastDay) {
|
||||
let stamp = day.getTime();
|
||||
let wday = day.getDay();
|
||||
let dayEvents = [];
|
||||
let exclusions = this.exclusions[stamp] || [];
|
||||
|
||||
if (this.events) {
|
||||
for (let event of this.events) {
|
||||
let match;
|
||||
|
||||
switch (event.type) {
|
||||
case 'day':
|
||||
match = event.dated == stamp;
|
||||
break;
|
||||
default:
|
||||
match = event.wdays[wday]
|
||||
&& (!event.started || stamp >= event.started)
|
||||
&& (!event.ended || stamp <= event.ended);
|
||||
break;
|
||||
}
|
||||
|
||||
if (match && !exclusions.find(e => e.zoneFk == event.zoneFk))
|
||||
dayEvents.push(event);
|
||||
}
|
||||
}
|
||||
|
||||
if (dayEvents.length)
|
||||
this.days[stamp] = dayEvents;
|
||||
|
||||
day.setDate(day.getDate() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
onSelection($event, $days, $type, $weekday) {
|
||||
let $events = [];
|
||||
let $exclusions = [];
|
||||
let $geoExclusions = [];
|
||||
|
||||
for (let day of $days) {
|
||||
let stamp = day.getTime();
|
||||
$events = $events.concat(this.days[stamp] || []);
|
||||
$exclusions = $exclusions.concat(this.exclusions[stamp] || []);
|
||||
$geoExclusions = $geoExclusions.concat(this.geoExclusions[stamp] || []);
|
||||
}
|
||||
|
||||
this.emit('selection', {
|
||||
$event,
|
||||
$days,
|
||||
$type,
|
||||
$weekday,
|
||||
$events,
|
||||
$exclusions,
|
||||
$geoExclusions
|
||||
});
|
||||
}
|
||||
|
||||
hasEvents(day) {
|
||||
let stamp = day.getTime();
|
||||
return this.days[stamp] || this.exclusions[stamp] || this.geoExclusions[stamp];
|
||||
}
|
||||
|
||||
getClass(day) {
|
||||
let stamp = day.getTime();
|
||||
if (this.geoExclusions[stamp])
|
||||
return 'geoExcluded';
|
||||
else if (this.exclusions[stamp])
|
||||
return 'excluded';
|
||||
else return '';
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$element', '$scope', 'vnWeekDays'];
|
||||
|
||||
ngModule.vnComponent('vnZoneCalendar', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
data: '<?'
|
||||
}
|
||||
});
|
|
@ -1,172 +0,0 @@
|
|||
import './index';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
|
||||
describe('component vnZoneCalendar', () => {
|
||||
let $scope;
|
||||
let controller;
|
||||
|
||||
beforeEach(ngModule('zone'));
|
||||
|
||||
beforeEach(inject(($componentController, $rootScope) => {
|
||||
$scope = $rootScope.$new();
|
||||
const $element = angular.element(`<vn-zone-calendar></vn-zone-calendar>`);
|
||||
controller = $componentController('vnZoneCalendar', {$element, $scope});
|
||||
controller.$.model = crudModel;
|
||||
controller.zone = {id: 1};
|
||||
controller.days = [];
|
||||
controller.exclusions = [];
|
||||
controller.geoExclusions = [];
|
||||
}));
|
||||
|
||||
describe('date() setter', () => {
|
||||
it('should set the month property and then call the refreshEvents() method', () => {
|
||||
jest.spyOn(controller, 'refreshEvents').mockReturnThis();
|
||||
|
||||
controller.date = Date.vnNew();
|
||||
|
||||
expect(controller.refreshEvents).toHaveBeenCalledWith();
|
||||
expect(controller.months.length).toEqual(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('step()', () => {
|
||||
it('should set the date month to 4 months backwards', () => {
|
||||
const now = Date.vnNew();
|
||||
now.setDate(15);
|
||||
now.setMonth(now.getMonth() - 4);
|
||||
|
||||
controller.step(-1);
|
||||
|
||||
const expectedMonth = now.getMonth();
|
||||
const currentMonth = controller.date.getMonth();
|
||||
|
||||
expect(currentMonth).toEqual(expectedMonth);
|
||||
});
|
||||
|
||||
it('should set the date month to 4 months forwards', () => {
|
||||
const now = Date.vnNew();
|
||||
now.setDate(15);
|
||||
now.setMonth(now.getMonth() + 4);
|
||||
|
||||
controller.step(1);
|
||||
|
||||
const expectedMonth = now.getMonth();
|
||||
const currentMonth = controller.date.getMonth();
|
||||
|
||||
expect(currentMonth).toEqual(expectedMonth);
|
||||
});
|
||||
});
|
||||
|
||||
describe('data() setter', () => {
|
||||
it('should set the events, exclusions and geoExclusions and then call the refreshEvents() method', () => {
|
||||
jest.spyOn(controller, 'refreshEvents').mockReturnThis();
|
||||
|
||||
controller.data = {
|
||||
exclusions: [{
|
||||
dated: Date.vnNew()
|
||||
}],
|
||||
events: [{
|
||||
dated: Date.vnNew()
|
||||
}],
|
||||
geoExclusions: [{
|
||||
dated: Date.vnNew()
|
||||
}],
|
||||
};
|
||||
|
||||
expect(controller.refreshEvents).toHaveBeenCalledWith();
|
||||
expect(controller.events).toBeDefined();
|
||||
expect(controller.events.length).toEqual(1);
|
||||
expect(controller.exclusions).toBeDefined();
|
||||
expect(controller.geoExclusions).toBeDefined();
|
||||
expect(Object.keys(controller.exclusions).length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('refreshEvents()', () => {
|
||||
it('should fill the days property with the events.', () => {
|
||||
controller.data = [];
|
||||
controller.firstDay = Date.vnNew();
|
||||
|
||||
const lastDay = Date.vnNew();
|
||||
lastDay.setDate(lastDay.getDate() + 10);
|
||||
controller.lastDay = lastDay;
|
||||
|
||||
const firstEventStamp = controller.firstDay.getTime();
|
||||
const lastEventStamp = controller.lastDay.getTime();
|
||||
controller.events = [{
|
||||
type: 'day',
|
||||
dated: firstEventStamp
|
||||
},
|
||||
{
|
||||
type: 'day',
|
||||
dated: lastEventStamp
|
||||
}];
|
||||
|
||||
controller.refreshEvents();
|
||||
const expectedDays = Object.keys(controller.days);
|
||||
|
||||
expect(expectedDays.length).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSelection()', () => {
|
||||
it('should call the emit() method', () => {
|
||||
jest.spyOn(controller, 'emit');
|
||||
|
||||
const $event = {};
|
||||
const $days = [Date.vnNew()];
|
||||
const $type = 'day';
|
||||
const $weekday = 1;
|
||||
|
||||
controller.onSelection($event, $days, $type, $weekday);
|
||||
|
||||
expect(controller.emit).toHaveBeenCalledWith('selection',
|
||||
{
|
||||
$days: $days,
|
||||
$event: {},
|
||||
$events: [],
|
||||
$exclusions: [],
|
||||
$type: 'day',
|
||||
$weekday: 1,
|
||||
$geoExclusions: [],
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasEvents()', () => {
|
||||
it('should return true for an existing event on a date', () => {
|
||||
const dated = Date.vnNew();
|
||||
|
||||
controller.days[dated.getTime()] = true;
|
||||
|
||||
const result = controller.hasEvents(dated);
|
||||
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getClass()', () => {
|
||||
it('should return the className "excluded" for an excluded date', () => {
|
||||
const dated = Date.vnNew();
|
||||
|
||||
controller.exclusions = [];
|
||||
controller.exclusions[dated.getTime()] = true;
|
||||
|
||||
const result = controller.getClass(dated);
|
||||
|
||||
expect(result).toEqual('excluded');
|
||||
});
|
||||
|
||||
it('should return the className "geoExcluded" for a date with geo excluded', () => {
|
||||
const dated = Date.vnNew();
|
||||
|
||||
controller.geoExclusions = [];
|
||||
controller.geoExclusions[dated.getTime()] = true;
|
||||
|
||||
const result = controller.getClass(dated);
|
||||
|
||||
expect(result).toEqual('geoExcluded');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,43 +0,0 @@
|
|||
@import "variables";
|
||||
|
||||
vn-zone-calendar {
|
||||
display: block;
|
||||
|
||||
& > vn-card {
|
||||
& > .header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background-color: $color-main;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
height: 45px;
|
||||
|
||||
& > .vn-button {
|
||||
color: inherit;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
& > .calendars {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
|
||||
& > .vn-calendar {
|
||||
max-width: 288px;
|
||||
|
||||
#days-container .day {
|
||||
&.event .day-number {
|
||||
background-color: $color-success;
|
||||
}
|
||||
&.excluded .day-number {
|
||||
background-color: $color-alert;
|
||||
}
|
||||
&.geoExcluded .day-number {
|
||||
background-color: $color-main;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<vn-portal slot="menu">
|
||||
<vn-zone-descriptor zone="$ctrl.zone"></vn-zone-descriptor>
|
||||
<vn-left-menu source="card"></vn-left-menu>
|
||||
</vn-portal>
|
||||
<ui-view></ui-view>
|
|
@ -1,21 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import ModuleCard from 'salix/components/module-card';
|
||||
|
||||
class Controller extends ModuleCard {
|
||||
reload() {
|
||||
let filter = {
|
||||
include: {
|
||||
relation: 'agencyMode',
|
||||
scope: {fields: ['name']}
|
||||
}
|
||||
};
|
||||
|
||||
this.$http.get(`Zones/${this.$params.id}`, {filter})
|
||||
.then(res => this.zone = res.data);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnZoneCard', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,26 +0,0 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Zone Component vnZoneCard', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
let data = {id: 1, name: 'fooName'};
|
||||
|
||||
beforeEach(ngModule('zone'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_, $stateParams) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
|
||||
let $element = angular.element('<div></div>');
|
||||
controller = $componentController('vnZoneCard', {$element});
|
||||
|
||||
$stateParams.id = data.id;
|
||||
$httpBackend.whenRoute('GET', 'Zones/:id').respond(data);
|
||||
}));
|
||||
|
||||
it('should request data and set it on the controller', () => {
|
||||
controller.reload();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.zone).toEqual(data);
|
||||
});
|
||||
});
|
|
@ -1,98 +0,0 @@
|
|||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
url="Zones"
|
||||
data="$ctrl.zone"
|
||||
insert-mode="true"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses"
|
||||
order="name">
|
||||
</vn-crud-model>
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="AgencyModes/isActive"
|
||||
data="activeAgencyModes"
|
||||
order="name">
|
||||
</vn-crud-model>
|
||||
<form
|
||||
name="form"
|
||||
vn-http-submit="$ctrl.onSubmit()"
|
||||
class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
label="Name"
|
||||
ng-model="$ctrl.zone.name"
|
||||
rule
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
label="Warehouse"
|
||||
ng-model="$ctrl.zone.warehouseFk"
|
||||
data="warehouses"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Warehouse"
|
||||
rule>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
label="Agency"
|
||||
ng-model="$ctrl.zone.agencyModeFk"
|
||||
data="activeAgencyModes"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Agency"
|
||||
rule>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-number
|
||||
label="Traveling days"
|
||||
ng-model="$ctrl.zone.travelingDays"
|
||||
min="0"
|
||||
step="1"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-time
|
||||
label="Closing hour"
|
||||
ng-model="$ctrl.zone.hour"
|
||||
rule>
|
||||
</vn-input-time>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-number
|
||||
label="Price"
|
||||
ng-model="$ctrl.zone.price"
|
||||
min="0"
|
||||
step="0.01"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
label="Bonus"
|
||||
ng-model="$ctrl.zone.bonus"
|
||||
min="0"
|
||||
step="0.01"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-check ng-model="$ctrl.zone.isVolumetric" label="Volumetric"></vn-check>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
label="Create">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Cancel"
|
||||
ui-sref="zone.index">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -1,24 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
$onInit() {
|
||||
this.zone = {
|
||||
travelingDays: 0,
|
||||
price: 0.20,
|
||||
bonus: 0.20,
|
||||
hour: Date.vnNew()
|
||||
};
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
return this.$.watcher.submit().then(res =>
|
||||
this.$state.go('zone.card.location', {id: res.data.id})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnZoneCreate', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,40 +0,0 @@
|
|||
import './index';
|
||||
import watcher from 'core/mocks/watcher';
|
||||
|
||||
describe('Zone Component vnZoneCreate', () => {
|
||||
let $scope;
|
||||
let $state;
|
||||
let controller;
|
||||
|
||||
beforeEach(ngModule('zone'));
|
||||
|
||||
beforeEach(inject(($componentController, $rootScope, _$state_) => {
|
||||
$scope = $rootScope.$new();
|
||||
$state = _$state_;
|
||||
$scope.watcher = watcher;
|
||||
$scope.watcher.submit = () => {
|
||||
return {
|
||||
then: callback => {
|
||||
callback({data: {id: 1234}});
|
||||
}
|
||||
};
|
||||
};
|
||||
const $element = angular.element('<vn-zone-create></vn-zone-create>');
|
||||
controller = $componentController('vnZoneCreate', {$element, $scope});
|
||||
}));
|
||||
|
||||
describe('onSubmit()', () => {
|
||||
it(`should call submit() on the watcher then expect a callback`, () => {
|
||||
jest.spyOn($state, 'go');
|
||||
|
||||
controller.zone = {
|
||||
name: 'Zone One'
|
||||
};
|
||||
|
||||
controller.onSubmit();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('zone.card.location', Object({id: 1234}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
Traveling days: Días de viaje
|
||||
Closing hour: Hora de cierre
|
||||
Bonus: Bonificación
|
|
@ -1,102 +0,0 @@
|
|||
<div class="vn-w-md">
|
||||
<vn-zone-calendar
|
||||
data="data"
|
||||
on-selection="$ctrl.onSelection($event, $events, $days)">
|
||||
</vn-zone-calendar>
|
||||
</div>
|
||||
<vn-side-menu side="right">
|
||||
<form ng-submit="$ctrl.fetchData()" class="vn-pa-md">
|
||||
<vn-radio
|
||||
label="Pick up"
|
||||
val="pickUp"
|
||||
ng-model="$ctrl.deliveryMethodFk"
|
||||
on-change="$ctrl.agencyModeFk = null"
|
||||
tabindex="-1">
|
||||
</vn-radio>
|
||||
<vn-radio
|
||||
label="Delivery"
|
||||
val="delivery"
|
||||
ng-model="$ctrl.deliveryMethodFk"
|
||||
on-change="$ctrl.agencyModeFk = null"
|
||||
class="vn-mb-sm"
|
||||
tabindex="-1">
|
||||
</vn-radio>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-if="$ctrl.deliveryMethodFk === 'delivery'"
|
||||
vn-focus
|
||||
label="Postcode"
|
||||
ng-model="$ctrl.geoFk"
|
||||
url="Postcodes/location"
|
||||
fields="['code','townFk']"
|
||||
order="code, townFk"
|
||||
value-field="geoFk"
|
||||
show-field="code">
|
||||
<tpl-item>
|
||||
<div>
|
||||
{{code}} {{town.name}}
|
||||
</div>
|
||||
<div class="text-caption text-secondary">
|
||||
{{town.province.name}}, {{town.province.country.name}}
|
||||
</div>
|
||||
</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
label="{{$ctrl.deliveryMethodFk == 'delivery' ? 'Agency' : 'Warehouse'}}"
|
||||
ng-model="$ctrl.agencyModeFk"
|
||||
url="AgencyModes/isActive"
|
||||
where="$ctrl.agencyFilter"
|
||||
vn-id="agencymode">
|
||||
</vn-autocomplete>
|
||||
<vn-submit label="Query" class="vn-mt-sm"></vn-submit>
|
||||
</form>
|
||||
</vn-side-menu>
|
||||
|
||||
<!-- Zone Popover -->
|
||||
<vn-popover vn-id="zoneEvents">
|
||||
<div class="zoneEvents">
|
||||
<div class="header vn-pa-sm" translate>Zones</div>
|
||||
<vn-data-viewer
|
||||
data="::$ctrl.zoneClosing"
|
||||
class="vn-w-md vn-mb-xl">
|
||||
<vn-card>
|
||||
<vn-table>
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th field="id" number>Id</vn-th>
|
||||
<vn-th field="name" expand>Name</vn-th>
|
||||
<vn-th field="agencyModeFk">Agency</vn-th>
|
||||
<vn-th field="hour" shrink>Closing</vn-th>
|
||||
<vn-th field="price" number>Price</vn-th>
|
||||
<vn-th shrink></vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr
|
||||
ng-repeat="zone in $ctrl.zoneClosing"
|
||||
ui-sref="zone.card.summary({id: zone.id})"
|
||||
class="clickable search-result">
|
||||
<vn-td number>{{::zone.id}}</vn-td>
|
||||
<vn-td expand>{{::zone.name}}</vn-td>
|
||||
<vn-td>{{::zone.agencyModeName}}</vn-td>
|
||||
<vn-td shrink>{{::zone.hour | date: 'HH:mm'}}</vn-td>
|
||||
<vn-td number>{{::zone.price | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-horizontal class="buttons">
|
||||
<vn-icon-button
|
||||
vn-click-stop="$ctrl.preview(zone)"
|
||||
vn-tooltip="Preview"
|
||||
icon="preview">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
</div>
|
||||
</vn-popover>
|
||||
<vn-popup vn-id="summary">
|
||||
<vn-zone-summary zone="$ctrl.selectedZone"></vn-zone-summary>
|
||||
</vn-popup>
|
|
@ -1,95 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
import './style.scss';
|
||||
|
||||
class Controller extends Section {
|
||||
$onInit() {
|
||||
this.setParams();
|
||||
}
|
||||
|
||||
$postLink() {
|
||||
this.deliveryMethodFk = 'delivery';
|
||||
}
|
||||
|
||||
setParams() {
|
||||
const hasParams = this.$params.deliveryMethodFk || this.$params.geoFk || this.$params.agencyModeFk;
|
||||
if (hasParams) {
|
||||
if (this.$params.deliveryMethodFk)
|
||||
this.deliveryMethodFk = this.$params.deliveryMethodFk;
|
||||
|
||||
if (this.$params.geoFk)
|
||||
this.geoFk = this.$params.geoFk;
|
||||
|
||||
if (this.$params.agencyModeFk)
|
||||
this.agencyModeFk = this.$params.agencyModeFk;
|
||||
|
||||
this.fetchData();
|
||||
}
|
||||
}
|
||||
|
||||
fetchData() {
|
||||
const params = {
|
||||
deliveryMethodFk: this.deliveryMethodFk,
|
||||
geoFk: this.geoFk,
|
||||
agencyModeFk: this.agencyModeFk
|
||||
};
|
||||
this.$.data = null;
|
||||
this.$http.get(`Zones/getEvents`, {params})
|
||||
.then(res => {
|
||||
let data = res.data;
|
||||
this.$.data = data;
|
||||
if (!data.events.length)
|
||||
this.vnApp.showMessage(this.$t('No service for the specified zone'));
|
||||
|
||||
this.$state.go(this.$state.current.name, params);
|
||||
});
|
||||
}
|
||||
|
||||
get deliveryMethodFk() {
|
||||
return this._deliveryMethodFk;
|
||||
}
|
||||
|
||||
set deliveryMethodFk(value) {
|
||||
this._deliveryMethodFk = value;
|
||||
|
||||
let filter;
|
||||
|
||||
if (value === 'pickUp')
|
||||
filter = {where: {code: 'PICKUP'}};
|
||||
else
|
||||
filter = {where: {code: {inq: ['DELIVERY', 'AGENCY']}}};
|
||||
|
||||
this.$http.get(`DeliveryMethods`, {filter}).then(res => {
|
||||
const deliveryMethods = res.data.map(deliveryMethod => deliveryMethod.id);
|
||||
this.agencyFilter = {deliveryMethodFk: {inq: deliveryMethods}};
|
||||
});
|
||||
}
|
||||
|
||||
onSelection($event, $events, $days) {
|
||||
if (!$events.length) return;
|
||||
|
||||
const day = $days[0];
|
||||
const zoneIds = [];
|
||||
for (let event of $events)
|
||||
zoneIds.push(event.zoneFk);
|
||||
|
||||
const params = {
|
||||
zoneIds: zoneIds,
|
||||
date: day
|
||||
};
|
||||
|
||||
this.$http.post(`Zones/getZoneClosing`, params)
|
||||
.then(res => this.zoneClosing = res.data)
|
||||
.then(() => this.$.zoneEvents.show($event.target));
|
||||
}
|
||||
|
||||
preview(zone) {
|
||||
this.selectedZone = zone;
|
||||
this.$.summary.show();
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnZoneDeliveryDays', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,126 +0,0 @@
|
|||
import './index.js';
|
||||
import popover from 'core/mocks/popover';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
|
||||
describe('Zone Component vnZoneDeliveryDays', () => {
|
||||
let $httpBackend;
|
||||
let controller;
|
||||
let $element;
|
||||
|
||||
beforeEach(ngModule('zone'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$element = angular.element('<vn-zone-delivery-days></vn-zone-delivery-days');
|
||||
controller = $componentController('vnZoneDeliveryDays', {$element});
|
||||
controller.$.zoneEvents = popover;
|
||||
controller.$.params = {};
|
||||
controller.$.zoneModel = crudModel;
|
||||
}));
|
||||
|
||||
describe('deliveryMethodFk() setter', () => {
|
||||
it('should set the deliveryMethodFk property as pickup and then perform a query that sets the filter', () => {
|
||||
$httpBackend.expect('GET', 'DeliveryMethods').respond([{id: 999}]);
|
||||
controller.deliveryMethodFk = 'pickUp';
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.agencyFilter).toEqual({deliveryMethodFk: {inq: [999]}});
|
||||
});
|
||||
});
|
||||
|
||||
describe('setParams()', () => {
|
||||
it('should do nothing when no params are received', () => {
|
||||
controller.setParams();
|
||||
|
||||
expect(controller.deliveryMethodFk).toBeUndefined();
|
||||
expect(controller.geoFk).toBeUndefined();
|
||||
expect(controller.agencyModeFk).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should set the controller properties when the params are provided', () => {
|
||||
controller.$params = {
|
||||
deliveryMethodFk: 3,
|
||||
geoFk: 2,
|
||||
agencyModeFk: 1
|
||||
};
|
||||
controller.setParams();
|
||||
|
||||
expect(controller.deliveryMethodFk).toEqual(controller.$params.deliveryMethodFk);
|
||||
expect(controller.geoFk).toEqual(controller.$params.geoFk);
|
||||
expect(controller.agencyModeFk).toEqual(controller.$params.agencyModeFk);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchData()', () => {
|
||||
it('should make an HTTP GET query and then call the showMessage() method', () => {
|
||||
jest.spyOn(controller.vnApp, 'showMessage');
|
||||
jest.spyOn(controller.$state, 'go');
|
||||
|
||||
controller.agencyModeFk = 1;
|
||||
controller.deliveryMethodFk = 2;
|
||||
controller.geoFk = 3;
|
||||
controller.$state.current.name = 'myState';
|
||||
|
||||
const expectedData = {events: []};
|
||||
|
||||
const url = 'Zones/getEvents?agencyModeFk=1&deliveryMethodFk=2&geoFk=3';
|
||||
|
||||
$httpBackend.when('GET', 'DeliveryMethods').respond([]);
|
||||
$httpBackend.expect('GET', url).respond({events: []});
|
||||
controller.fetchData();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$.data).toEqual(expectedData);
|
||||
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('No service for the specified zone');
|
||||
expect(controller.$state.go).toHaveBeenCalledWith(
|
||||
controller.$state.current.name,
|
||||
{
|
||||
agencyModeFk: 1,
|
||||
deliveryMethodFk: 2,
|
||||
geoFk: 3
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSelection()', () => {
|
||||
it('should not call the show popover method if events array is empty', () => {
|
||||
jest.spyOn(controller.$.zoneEvents, 'show');
|
||||
|
||||
const event = new Event('click');
|
||||
const target = document.createElement('div');
|
||||
target.dispatchEvent(event);
|
||||
const events = [];
|
||||
controller.onSelection(event, events);
|
||||
|
||||
expect(controller.$.zoneEvents.show).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call the show() method and call getZoneClosing() with the expected ids', () => {
|
||||
jest.spyOn(controller.$.zoneEvents, 'show');
|
||||
|
||||
const event = new Event('click');
|
||||
const target = document.createElement('div');
|
||||
target.dispatchEvent(event);
|
||||
|
||||
const day = Date.vnNew();
|
||||
const events = [
|
||||
{zoneFk: 1},
|
||||
{zoneFk: 2},
|
||||
{zoneFk: 8}
|
||||
];
|
||||
const params = {
|
||||
zoneIds: [1, 2, 8],
|
||||
date: [day][0]
|
||||
};
|
||||
const response = [{id: 1, hour: ''}];
|
||||
|
||||
$httpBackend.when('POST', 'Zones/getZoneClosing', params).respond({response});
|
||||
controller.onSelection(event, events, [day]);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$.zoneEvents.show).toHaveBeenCalledWith(target);
|
||||
expect(controller.zoneClosing.id).toEqual(response.id);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,36 +0,0 @@
|
|||
@import "variables";
|
||||
|
||||
vn-zone-delivery-days {
|
||||
vn-zone-calendar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
& > vn-calendar {
|
||||
min-width: 264px;
|
||||
}
|
||||
}
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.zoneEvents {
|
||||
width: 700px;
|
||||
max-height: 450px;
|
||||
|
||||
vn-data-viewer {
|
||||
margin-bottom: 0;
|
||||
vn-pagination {
|
||||
padding: 0
|
||||
}
|
||||
}
|
||||
|
||||
& > .header {
|
||||
background-color: $color-main;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
text-align: center
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
<slot-descriptor>
|
||||
<vn-zone-descriptor>
|
||||
</vn-zone-descriptor>
|
||||
</slot-descriptor>
|
|
@ -1,9 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import DescriptorPopover from 'salix/components/descriptor-popover';
|
||||
|
||||
class Controller extends DescriptorPopover {}
|
||||
|
||||
ngModule.vnComponent('vnZoneDescriptorPopover', {
|
||||
slotTemplate: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,57 +0,0 @@
|
|||
<vn-descriptor-content
|
||||
module="zone"
|
||||
description="$ctrl.zone.name"
|
||||
summary="$ctrl.$.summary">
|
||||
<slot-menu>
|
||||
<vn-item class="vn-item"
|
||||
ng-click="$ctrl.onDelete()"
|
||||
translate>
|
||||
Delete
|
||||
</vn-item>
|
||||
<vn-item
|
||||
ng-click="clone.show()"
|
||||
name="cloneZone"
|
||||
translate>
|
||||
Clone
|
||||
</vn-item>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<vn-label-value
|
||||
label="Agency"
|
||||
value="{{$ctrl.zone.agencyMode.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Closing hour"
|
||||
value="{{$ctrl.zone.hour | date: 'HH:mm'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Traveling days"
|
||||
value="{{$ctrl.zone.travelingDays}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Price"
|
||||
value="{{$ctrl.zone.price | currency: 'EUR': 2}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Bonus"
|
||||
value="{{$ctrl.zone.bonus | currency: 'EUR': 2}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-popup vn-id="summary">
|
||||
<vn-zone-summary zone="$ctrl.zone"></vn-zone-summary>
|
||||
</vn-popup>
|
||||
|
||||
<vn-confirm
|
||||
vn-id="deleteZone"
|
||||
on-accept="$ctrl.deleteZone()"
|
||||
message="This zone will be removed">
|
||||
</vn-confirm>
|
||||
<vn-confirm
|
||||
vn-id="clone"
|
||||
on-accept="$ctrl.onCloneAccept()"
|
||||
question="Do you want to clone this zone?"
|
||||
message="All it's properties will be copied">
|
||||
</vn-confirm>
|
|
@ -1,65 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
get zone() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
set zone(value) {
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'agencyMode',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Zones/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
|
||||
onDelete() {
|
||||
const $t = this.$translate.instant;
|
||||
const today = Date.vnNew();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
const filter = {where: {zoneFk: this.id, shipped: {gte: today}}};
|
||||
this.$http.get(`Tickets`, {filter}).then(res => {
|
||||
const ticketsAmount = res.data.length;
|
||||
if (ticketsAmount) {
|
||||
const params = {ticketsAmount};
|
||||
const question = $t('This zone contains tickets', params, null, null, 'sanitizeParameters');
|
||||
this.$.deleteZone.question = question;
|
||||
this.$.deleteZone.show();
|
||||
} else
|
||||
this.deleteZone();
|
||||
});
|
||||
}
|
||||
|
||||
deleteZone() {
|
||||
return this.$http.post(`Zones/${this.id}/deleteZone`).then(() => {
|
||||
this.$state.go('zone.index');
|
||||
this.vnApp.showSuccess(this.$t('Zone deleted'));
|
||||
});
|
||||
}
|
||||
|
||||
onCloneAccept() {
|
||||
return this.$http.post(`Zones/${this.id}/clone`).
|
||||
then(res => this.$state.go('zone.card.basicData', {id: res.data.id}));
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnZoneDescriptor', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
zone: '<'
|
||||
}
|
||||
});
|
|
@ -1,74 +0,0 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Zone descriptor', () => {
|
||||
let $httpBackend;
|
||||
let controller;
|
||||
let $element;
|
||||
|
||||
beforeEach(ngModule('zone'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$element = angular.element('<vn-zone-descriptor></vn-zone-descriptor');
|
||||
controller = $componentController('vnZoneDescriptor', {$element});
|
||||
controller.zone = {id: 1};
|
||||
controller.id = 1;
|
||||
controller.$.deleteZone = {
|
||||
hide: () => {},
|
||||
show: () => {}
|
||||
};
|
||||
}));
|
||||
|
||||
describe('onDelete()', () => {
|
||||
it('should make an HTTP POST query and then call the deleteZone show() method', () => {
|
||||
jest.spyOn(controller.$.deleteZone, 'show');
|
||||
|
||||
const expectedData = [{id: 16}];
|
||||
$httpBackend.when('GET', 'Tickets').respond(expectedData);
|
||||
controller.onDelete();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$.deleteZone.show).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('should make an HTTP POST query and then call the deleteZone() method', () => {
|
||||
jest.spyOn(controller, 'deleteZone').mockReturnThis();
|
||||
|
||||
const expectedData = [];
|
||||
$httpBackend.when('GET', 'Tickets').respond(expectedData);
|
||||
controller.onDelete();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.deleteZone).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteZone()', () => {
|
||||
it('should make an HTTP POST query and then call the showMessage() method', () => {
|
||||
jest.spyOn(controller.$state, 'go').mockReturnThis();
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
|
||||
const stateName = 'zone.index';
|
||||
$httpBackend.when('POST', 'Zones/1/deleteZone').respond(200);
|
||||
controller.deleteZone();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith(stateName);
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Zone deleted');
|
||||
});
|
||||
});
|
||||
|
||||
describe('onCloneAccept()', () => {
|
||||
it('should make an HTTP POST query and then call the state go() method', () => {
|
||||
jest.spyOn(controller.$state, 'go').mockReturnThis();
|
||||
|
||||
const stateName = 'zone.card.basicData';
|
||||
const expectedData = {id: 1};
|
||||
$httpBackend.when('POST', 'Zones/1/clone').respond(expectedData);
|
||||
controller.onCloneAccept();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith(stateName, expectedData);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,4 +0,0 @@
|
|||
This zone contains tickets: Esta zona contiene {{ticketsAmount}} tickets por servir. ¿Seguro que quieres eliminar esta zona?
|
||||
Do you want to clone this zone?: ¿Quieres clonar esta zona?
|
||||
All it's properties will be copied: Todas sus propiedades serán copiadas
|
||||
Zone deleted: Zona eliminada
|
|
@ -1,277 +0,0 @@
|
|||
<vn-zone-calendar
|
||||
id="calendar"
|
||||
vn-id="calendar"
|
||||
data="data"
|
||||
on-selection="$ctrl.onSelection($days, $type, $weekday, $events, $exclusions, $geoExclusions)"
|
||||
on-step="$ctrl.refresh()"
|
||||
class="vn-w-md">
|
||||
</vn-zone-calendar>
|
||||
<vn-side-menu side="right">
|
||||
<div class="vn-pa-md">
|
||||
<h6
|
||||
class="text-secondary"
|
||||
style="font-weight: normal;"
|
||||
translate>
|
||||
Edit mode
|
||||
</h6>
|
||||
<vn-vertical>
|
||||
<vn-radio
|
||||
label="Include"
|
||||
val="include"
|
||||
ng-model="$ctrl.editMode">
|
||||
</vn-radio>
|
||||
<vn-radio
|
||||
label="Exclude"
|
||||
val="exclude"
|
||||
ng-model="$ctrl.editMode">
|
||||
</vn-radio>
|
||||
</vn-vertical>
|
||||
</div>
|
||||
<h6
|
||||
class="text-secondary vn-px-md"
|
||||
style="font-weight: normal;"
|
||||
translate>
|
||||
Events
|
||||
</h6>
|
||||
<vn-data-viewer
|
||||
data="data.events"
|
||||
is-loading="!data.events">
|
||||
<div class="vn-list separated">
|
||||
<a
|
||||
ng-repeat="row in data.events"
|
||||
translate-attr="{title: 'Edit'}"
|
||||
ng-click="$ctrl.onEditClick(row, $event)"
|
||||
class="vn-item">
|
||||
<vn-item-section>
|
||||
<div
|
||||
ng-if="::row.type == 'day'"
|
||||
class="vn-mb-sm">
|
||||
{{::row.dated | date:'dd/MM/yy'}}
|
||||
</div>
|
||||
<div
|
||||
ng-if="::row.type != 'day'"
|
||||
class="vn-mb-sm ellipsize">
|
||||
<span ng-if="row.weekDays">
|
||||
{{::$ctrl.formatWdays(row.weekDays)}}
|
||||
</span>
|
||||
<span ng-if="row.type == 'range'">
|
||||
({{::row.started | date:'dd/MM/yy'}} - {{::row.ended | date:'dd/MM/yy'}})
|
||||
</span>
|
||||
</div>
|
||||
<vn-label-value
|
||||
label="Closing"
|
||||
value="{{::row.hour | date:'HH:mm'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Traveling days"
|
||||
value="{{::row.travelingDays}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Price"
|
||||
value="{{::row.price | currency:'EUR':2}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Bonus"
|
||||
value="{{::row.bonus | currency:'EUR':2}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Max m³"
|
||||
value="{{::row.m3Max}}">
|
||||
</vn-label-value>
|
||||
</vn-item-section>
|
||||
<vn-item-section side>
|
||||
<vn-icon-button
|
||||
icon="delete"
|
||||
translate-attr="{title: 'Delete'}"
|
||||
ng-click="$ctrl.onDeleteClick(row.id, $event)">
|
||||
</vn-icon-button>
|
||||
</vn-item-section>
|
||||
</a>
|
||||
</div>
|
||||
</vn-data-viewer>
|
||||
</vn-side-menu>
|
||||
<vn-float-button
|
||||
ng-click="$ctrl.createInclusion('weekday')"
|
||||
icon="add"
|
||||
vn-tooltip="Add event"
|
||||
vn-bind="+"
|
||||
fixed-bottom-right>
|
||||
</vn-float-button>
|
||||
<vn-dialog
|
||||
vn-id="includeDialog"
|
||||
on-response="$ctrl.onIncludeResponse($response)"
|
||||
message="{{$ctrl.isNew ? 'Add event' : 'Edit event'}}">
|
||||
<tpl-body>
|
||||
<vn-vertical>
|
||||
<vn-vertical class="vn-pb-md">
|
||||
<vn-radio
|
||||
ng-model="$ctrl.selected.type"
|
||||
label="One day"
|
||||
val="day">
|
||||
</vn-radio>
|
||||
<vn-radio
|
||||
ng-model="$ctrl.selected.type"
|
||||
label="Indefinitely"
|
||||
val="indefinitely">
|
||||
</vn-radio>
|
||||
<vn-radio
|
||||
ng-model="$ctrl.selected.type"
|
||||
label="Range of dates"
|
||||
val="range">
|
||||
</vn-radio>
|
||||
</vn-vertical>
|
||||
<vn-wday-picker
|
||||
ng-if="$ctrl.selected.type != 'day'"
|
||||
ng-model="$ctrl.selected.wdays"
|
||||
class="vn-mt-sm vn-mb-md">
|
||||
</vn-wday-picker>
|
||||
<vn-date-picker
|
||||
ng-if="$ctrl.selected.type == 'day'"
|
||||
label="Day"
|
||||
ng-model="$ctrl.selected.dated">
|
||||
</vn-date-picker>
|
||||
<vn-horizontal
|
||||
ng-if="$ctrl.selected.type == 'range'">
|
||||
<vn-date-picker
|
||||
label="From"
|
||||
ng-model="$ctrl.selected.started">
|
||||
</vn-date-picker>
|
||||
<vn-date-picker
|
||||
label="To"
|
||||
ng-model="$ctrl.selected.ended">
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-time
|
||||
label="Closing"
|
||||
ng-model="$ctrl.selected.hour">
|
||||
</vn-input-time>
|
||||
<vn-input-number
|
||||
label="Traveling days"
|
||||
ng-model="$ctrl.selected.travelingDays"
|
||||
min="0"
|
||||
step="1">
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-number
|
||||
label="Price"
|
||||
ng-model="$ctrl.selected.price"
|
||||
min="0"
|
||||
step="0.01">
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
label="Bonus"
|
||||
ng-model="$ctrl.selected.bonus"
|
||||
min="0"
|
||||
step="0.01">
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-input-number
|
||||
label="Max m³"
|
||||
ng-model="$ctrl.selected.m3Max"
|
||||
min="0"
|
||||
step="0.01">
|
||||
</vn-input-number>
|
||||
</vn-vertical>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
<input
|
||||
type="button"
|
||||
response="cancel"
|
||||
translate-attr="{value: 'Cancel'}">
|
||||
</input>
|
||||
<input
|
||||
type="button"
|
||||
ng-if="!$ctrl.isNew"
|
||||
response="delete"
|
||||
translate-attr="{value: 'Delete'}">
|
||||
</input>
|
||||
<button response="accept">
|
||||
<span ng-if="$ctrl.isNew" translate>Add</span>
|
||||
<span ng-if="!$ctrl.isNew" translate>Save</span>
|
||||
</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
||||
<vn-confirm
|
||||
vn-id="confirm"
|
||||
message="This item will be deleted"
|
||||
question="Are you sure you want to continue?">
|
||||
</vn-confirm>
|
||||
<vn-dialog
|
||||
vn-id="excludeDialog"
|
||||
on-response="$ctrl.onExcludeResponse($response)"
|
||||
message="{{$ctrl.isNew ? 'Add exclusion' : 'Edit exclusion'}}"
|
||||
on-open="$ctrl.onSearch($params)"
|
||||
on-close="$ctrl.resetExclusions()">
|
||||
<tpl-body>
|
||||
<vn-date-picker
|
||||
label="Day"
|
||||
ng-model="$ctrl.excludeSelected.dated">
|
||||
</vn-date-picker>
|
||||
<vn-vertical class="width">
|
||||
<vn-vertical class="vn-pb-md">
|
||||
<vn-radio
|
||||
ng-model="$ctrl.excludeSelected.type"
|
||||
label="All"
|
||||
on-change="$ctrl.test()"
|
||||
val="all">
|
||||
</vn-radio>
|
||||
<vn-radio
|
||||
ng-model="$ctrl.excludeSelected.type"
|
||||
label="Specific locations"
|
||||
on-change="$ctrl.onSearch($params)"
|
||||
val="specificLocations">
|
||||
</vn-radio>
|
||||
</vn-vertical>
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="Zones/{{$ctrl.$params.id}}/getLeaves"
|
||||
filter="$ctrl.filter">
|
||||
</vn-crud-model>
|
||||
<div ng-if="$ctrl.excludeSelected.type == 'specificLocations'">
|
||||
<vn-textfield
|
||||
label="Search"
|
||||
ng-keydown="$ctrl.onKeyDown($event)"
|
||||
ng-model="$ctrl.excludeSearch">
|
||||
<prepend>
|
||||
<vn-icon icon="search"></vn-icon>
|
||||
</prepend>
|
||||
</vn-textfield>
|
||||
<div class="treeview">
|
||||
<vn-treeview
|
||||
vn-id="treeview"
|
||||
root-label="Locations where it is not distributed"
|
||||
fetch-func="$ctrl.onFetch($item)"
|
||||
sort-func="$ctrl.onSort($a, $b)">
|
||||
<vn-check
|
||||
ng-model="item.checked"
|
||||
ng-click="$event.preventDefault()"
|
||||
on-change="$ctrl.onItemCheck(item.id, value)"
|
||||
label="{{::item.name}}">
|
||||
</vn-check>
|
||||
</vn-treeview>
|
||||
</div>
|
||||
</div>
|
||||
</vn-vertical>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
<input
|
||||
type="button"
|
||||
response="cancel"
|
||||
translate-attr="{value: 'Cancel'}"
|
||||
tabindex="0">
|
||||
</input>
|
||||
<input
|
||||
type="button"
|
||||
ng-if="!$ctrl.isNew"
|
||||
response="delete"
|
||||
translate-attr="{value: 'Delete'}"
|
||||
tabindex="0">
|
||||
</input>
|
||||
<button response="accept">
|
||||
<span ng-if="$ctrl.isNew" translate>Add</span>
|
||||
<span ng-if="!$ctrl.isNew" translate>Save</span>
|
||||
</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
|
@ -1,316 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
import './style.scss';
|
||||
|
||||
class Controller extends Section {
|
||||
constructor($element, $, vnWeekDays) {
|
||||
super($element, $);
|
||||
this.vnWeekDays = vnWeekDays;
|
||||
this.editMode = 'include';
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
get path() {
|
||||
return `Zones/${this.$params.id}/events`;
|
||||
}
|
||||
|
||||
get exclusionsPath() {
|
||||
return `Zones/${this.$params.id}/exclusions`;
|
||||
}
|
||||
|
||||
get checked() {
|
||||
const geos = this.$.model.data || [];
|
||||
const checkedLines = [];
|
||||
for (let geo of geos) {
|
||||
if (geo.checked)
|
||||
checkedLines.push(geo);
|
||||
}
|
||||
return checkedLines;
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.$.data = null;
|
||||
this.$.$applyAsync(() => {
|
||||
const params = {
|
||||
zoneFk: this.$params.id,
|
||||
started: this.$.calendar.firstDay,
|
||||
ended: this.$.calendar.lastDay
|
||||
};
|
||||
|
||||
this.$http.get(`Zones/getEventsFiltered`, {params}).then(res => {
|
||||
const data = res.data;
|
||||
this.$.data = data;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
formatWdays(weekDays) {
|
||||
if (!weekDays) return;
|
||||
|
||||
let abrWdays = weekDays
|
||||
.split(',')
|
||||
.map(wday => this.vnWeekDays.map[wday].localeAbr);
|
||||
|
||||
return abrWdays.length < 7
|
||||
? abrWdays.join(', ')
|
||||
: this.$t('Everyday');
|
||||
}
|
||||
|
||||
onSelection(days, type, weekday, events, exclusions, exclusionGeos) {
|
||||
if (this.editMode == 'include') {
|
||||
if (events.length)
|
||||
return this.editInclusion(events[0]);
|
||||
return this.createInclusion(type, days, weekday);
|
||||
} else if (this.editMode == 'exclude') {
|
||||
if (exclusions.length || exclusionGeos.length)
|
||||
return this.editExclusion(exclusions[0] || {}, exclusionGeos);
|
||||
return this.createExclusion(days);
|
||||
}
|
||||
}
|
||||
|
||||
editExclusion(exclusion, exclusionGeos) {
|
||||
this.isNew = false;
|
||||
this.excludeSelected = angular.copy(exclusion);
|
||||
this.excludeSelected.type = exclusionGeos.length ?
|
||||
'specificLocations' : 'all';
|
||||
|
||||
this.exclusionGeos = new Set();
|
||||
if (exclusionGeos.length) {
|
||||
this.excludeSelected.id = exclusionGeos[0].zoneExclusionFk;
|
||||
exclusionGeos.forEach(x => this.exclusionGeos.add(x.geoFk));
|
||||
}
|
||||
|
||||
this.$.excludeDialog.show();
|
||||
}
|
||||
|
||||
createExclusion(days) {
|
||||
this.isNew = true;
|
||||
this.excludeSelected = {
|
||||
type: 'all',
|
||||
dated: days[0]
|
||||
};
|
||||
this.exclusionGeos = new Set();
|
||||
this.$.excludeDialog.show();
|
||||
}
|
||||
|
||||
onEditClick(row, event) {
|
||||
if (event.defaultPrevented) return;
|
||||
this.editInclusion(row);
|
||||
}
|
||||
|
||||
editInclusion(row) {
|
||||
this.isNew = false;
|
||||
this.selected = angular.copy(row);
|
||||
this.selected.wdays = this.vnWeekDays.fromSet(row.weekDays);
|
||||
this.$.includeDialog.show();
|
||||
}
|
||||
|
||||
createInclusion(type, days, weekday) {
|
||||
this.isNew = true;
|
||||
|
||||
if (type == 'weekday') {
|
||||
let wdays = [];
|
||||
if (weekday) wdays[weekday] = true;
|
||||
|
||||
this.selected = {
|
||||
type: 'indefinitely',
|
||||
wdays
|
||||
};
|
||||
} else {
|
||||
this.selected = {
|
||||
type: 'day',
|
||||
dated: days[0]
|
||||
};
|
||||
}
|
||||
|
||||
this.$.includeDialog.show();
|
||||
}
|
||||
|
||||
onIncludeResponse(response) {
|
||||
switch (response) {
|
||||
case 'accept': {
|
||||
let selected = this.selected;
|
||||
let type = selected.type;
|
||||
|
||||
selected.weekDays = this.vnWeekDays.toSet(selected.wdays);
|
||||
|
||||
if (type == 'day')
|
||||
selected.weekDays = '';
|
||||
else
|
||||
selected.dated = null;
|
||||
|
||||
if (type != 'range') {
|
||||
selected.started = null;
|
||||
selected.ended = null;
|
||||
}
|
||||
|
||||
let req;
|
||||
|
||||
if (this.isNew)
|
||||
req = this.$http.post(this.path, selected);
|
||||
else
|
||||
req = this.$http.put(`${this.path}/${selected.id}`, selected);
|
||||
|
||||
return req.then(() => {
|
||||
this.selected = null;
|
||||
this.isNew = null;
|
||||
this.refresh();
|
||||
});
|
||||
}
|
||||
case 'delete':
|
||||
return this.onDelete(this.selected.id)
|
||||
.then(response => response == 'accept');
|
||||
}
|
||||
}
|
||||
|
||||
onExcludeResponse(response) {
|
||||
const type = this.excludeSelected.type;
|
||||
switch (response) {
|
||||
case 'accept': {
|
||||
if (type == 'all')
|
||||
return this.exclusionCreate();
|
||||
return this.exclusionGeoCreate();
|
||||
}
|
||||
case 'delete':
|
||||
return this.exclusionDelete(this.excludeSelected);
|
||||
}
|
||||
}
|
||||
|
||||
onDeleteClick(id, event) {
|
||||
if (event.defaultPrevented) return;
|
||||
event.preventDefault();
|
||||
this.onDelete(id);
|
||||
}
|
||||
|
||||
onDelete(id) {
|
||||
return this.$.confirm.show(
|
||||
response => this.onDeleteResponse(response, id));
|
||||
}
|
||||
|
||||
onDeleteResponse(response, id) {
|
||||
if (response != 'accept' || !id) return;
|
||||
return this.$http.delete(`${this.path}/${id}`)
|
||||
.then(() => this.refresh());
|
||||
}
|
||||
|
||||
exclusionCreate() {
|
||||
const excludeSelected = this.excludeSelected;
|
||||
const dated = excludeSelected.dated;
|
||||
let req;
|
||||
|
||||
if (this.isNew)
|
||||
req = this.$http.post(this.exclusionsPath, [{dated}]);
|
||||
if (!this.isNew)
|
||||
req = this.$http.put(`${this.exclusionsPath}/${excludeSelected.id}`, {dated});
|
||||
|
||||
return req.then(() => {
|
||||
this.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
exclusionGeoCreate() {
|
||||
const excludeSelected = this.excludeSelected;
|
||||
let req;
|
||||
const geoIds = [];
|
||||
this.exclusionGeos.forEach(id => geoIds.push(id));
|
||||
|
||||
if (this.isNew) {
|
||||
const params = {
|
||||
zoneFk: parseInt(this.$params.id),
|
||||
date: excludeSelected.dated,
|
||||
geoIds
|
||||
};
|
||||
req = this.$http.post(`Zones/exclusionGeo`, params);
|
||||
} else {
|
||||
const params = {
|
||||
zoneExclusionFk: this.excludeSelected.id,
|
||||
geoIds
|
||||
};
|
||||
req = this.$http.post(`Zones/updateExclusionGeo`, params);
|
||||
}
|
||||
return req.then(() => this.refresh());
|
||||
}
|
||||
|
||||
exclusionDelete(exclusion) {
|
||||
const path = `${this.exclusionsPath}/${exclusion.id}`;
|
||||
return this.$http.delete(path)
|
||||
.then(() => this.refresh());
|
||||
}
|
||||
|
||||
set excludeSearch(value) {
|
||||
this._excludeSearch = value;
|
||||
if (!value) this.onSearch();
|
||||
}
|
||||
|
||||
get excludeSearch() {
|
||||
return this._excludeSearch;
|
||||
}
|
||||
|
||||
onKeyDown(event) {
|
||||
if (event.key == 'Enter') {
|
||||
event.preventDefault();
|
||||
this.onSearch();
|
||||
}
|
||||
}
|
||||
|
||||
onSearch() {
|
||||
const params = {search: this._excludeSearch};
|
||||
if (this.excludeSelected.type == 'specificLocations') {
|
||||
this.$.model.applyFilter({}, params).then(() => {
|
||||
const data = this.$.model.data;
|
||||
this.getChecked(data);
|
||||
this.$.treeview.data = data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onFetch(item) {
|
||||
const params = item ? {parentId: item.id} : null;
|
||||
return this.$.model.applyFilter({}, params).then(() => {
|
||||
const data = this.$.model.data;
|
||||
this.getChecked(data);
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
onSort(a, b) {
|
||||
if (b.selected !== a.selected) {
|
||||
if (a.selected == null)
|
||||
return 1;
|
||||
if (b.selected == null)
|
||||
return -1;
|
||||
return b.selected - a.selected;
|
||||
}
|
||||
|
||||
return a.name.localeCompare(b.name);
|
||||
}
|
||||
|
||||
getChecked(data) {
|
||||
for (let geo of data) {
|
||||
geo.checked = this.exclusionGeos.has(geo.id);
|
||||
if (geo.childs) this.getChecked(geo.childs);
|
||||
}
|
||||
}
|
||||
|
||||
onItemCheck(geoId, checked) {
|
||||
if (checked)
|
||||
this.exclusionGeos.add(geoId);
|
||||
else
|
||||
this.exclusionGeos.delete(geoId);
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$element', '$scope', 'vnWeekDays'];
|
||||
|
||||
ngModule.vnComponent('vnZoneEvents', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
zone: '<'
|
||||
},
|
||||
require: {
|
||||
card: '^vnZoneCard'
|
||||
}
|
||||
});
|
|
@ -1,340 +0,0 @@
|
|||
import './index';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
|
||||
describe('component vnZoneEvents', () => {
|
||||
let $scope;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('zone'));
|
||||
|
||||
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$scope = $rootScope.$new();
|
||||
const $element = angular.element(`<vn-zone-events></vn-zone-events>`);
|
||||
controller = $componentController('vnZoneEvents', {$element, $scope});
|
||||
controller.$params = {id: 1};
|
||||
}));
|
||||
|
||||
describe('refresh()', () => {
|
||||
it('should set the zone and then call both getSummary() and getWarehouses()', () => {
|
||||
const date = '2021-10-01';
|
||||
|
||||
controller.$params.id = 999;
|
||||
controller.$.calendar = {
|
||||
firstDay: date,
|
||||
lastDay: date
|
||||
};
|
||||
|
||||
const params = {
|
||||
zoneFk: controller.$params.id,
|
||||
started: date,
|
||||
ended: date
|
||||
};
|
||||
|
||||
const query = `Zones/getEventsFiltered?ended=${date}&started=${date}&zoneFk=${params.zoneFk}`;
|
||||
const response = {
|
||||
events: 'myEvents',
|
||||
exclusions: 'myExclusions',
|
||||
geoExclusions: 'myGeoExclusions',
|
||||
};
|
||||
$httpBackend.whenGET(query).respond(response);
|
||||
controller.refresh();
|
||||
$httpBackend.flush();
|
||||
|
||||
const data = controller.$.data;
|
||||
|
||||
expect(data.events).toBeDefined();
|
||||
expect(data.exclusions).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSelection()', () => {
|
||||
it('should call the editInclusion() method', () => {
|
||||
jest.spyOn(controller, 'editInclusion').mockReturnThis();
|
||||
|
||||
const weekday = {};
|
||||
const days = [];
|
||||
const type = 'EventType';
|
||||
const events = [{name: 'Event'}];
|
||||
const exclusions = [];
|
||||
const exclusionsGeo = [];
|
||||
controller.editMode = 'include';
|
||||
controller.onSelection(days, type, weekday, events, exclusions, exclusionsGeo);
|
||||
|
||||
expect(controller.editInclusion).toHaveBeenCalledWith({name: 'Event'});
|
||||
});
|
||||
|
||||
it('should call the createInclusion() method', () => {
|
||||
jest.spyOn(controller, 'createInclusion').mockReturnThis();
|
||||
|
||||
const weekday = {dated: Date.vnNew()};
|
||||
const days = [weekday];
|
||||
const type = 'EventType';
|
||||
const events = [];
|
||||
const exclusions = [];
|
||||
const exclusionsGeo = [];
|
||||
controller.editMode = 'include';
|
||||
controller.onSelection(days, type, weekday, events, exclusions, exclusionsGeo);
|
||||
|
||||
expect(controller.createInclusion).toHaveBeenCalledWith(type, days, weekday);
|
||||
});
|
||||
|
||||
it('should call the editExclusion() method with exclusions', () => {
|
||||
jest.spyOn(controller, 'editExclusion').mockReturnThis();
|
||||
|
||||
const weekday = {};
|
||||
const days = [];
|
||||
const type = 'EventType';
|
||||
const events = [];
|
||||
const exclusions = [{name: 'Exclusion'}];
|
||||
const exclusionsGeo = [];
|
||||
controller.editMode = 'exclude';
|
||||
controller.onSelection(days, type, weekday, events, exclusions, exclusionsGeo);
|
||||
|
||||
expect(controller.editExclusion).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call the editExclusion() method with exclusionsGeo', () => {
|
||||
jest.spyOn(controller, 'editExclusion').mockReturnThis();
|
||||
|
||||
const weekday = {};
|
||||
const days = [];
|
||||
const type = 'EventType';
|
||||
const events = [];
|
||||
const exclusions = [];
|
||||
const exclusionsGeo = [{name: 'GeoExclusion'}];
|
||||
controller.editMode = 'exclude';
|
||||
controller.onSelection(days, type, weekday, events, exclusions, exclusionsGeo);
|
||||
|
||||
expect(controller.editExclusion).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call the createExclusion() method', () => {
|
||||
jest.spyOn(controller, 'createExclusion').mockReturnThis();
|
||||
|
||||
const weekday = {};
|
||||
const days = [{dated: Date.vnNew()}];
|
||||
const type = 'EventType';
|
||||
const events = [];
|
||||
const exclusions = [];
|
||||
const exclusionsGeo = [];
|
||||
controller.editMode = 'exclude';
|
||||
controller.onSelection(days, type, weekday, events, exclusions, exclusionsGeo);
|
||||
|
||||
expect(controller.createExclusion).toHaveBeenCalledWith(days);
|
||||
});
|
||||
});
|
||||
|
||||
describe('editExclusion()', () => {
|
||||
it('shoud set the excludeSelected.type = "specificLocations" and then call the excludeDialog show() method', () => {
|
||||
controller.$.excludeDialog = {show: jest.fn()};
|
||||
|
||||
const exclusionGeos = [{id: 1}];
|
||||
const exclusions = [];
|
||||
|
||||
controller.editExclusion(exclusions, exclusionGeos);
|
||||
|
||||
expect(controller.excludeSelected.type).toEqual('specificLocations');
|
||||
expect(controller.$.excludeDialog.show).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('shoud set the excludeSelected.type = "all" and then call the excludeDialog show() method', () => {
|
||||
controller.$.excludeDialog = {show: jest.fn()};
|
||||
|
||||
const exclusionGeos = [];
|
||||
const exclusions = [{id: 1}];
|
||||
|
||||
controller.editExclusion(exclusions, exclusionGeos);
|
||||
|
||||
expect(controller.excludeSelected.type).toEqual('all');
|
||||
expect(controller.$.excludeDialog.show).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('createExclusion()', () => {
|
||||
it('shoud set the excludeSelected property and then call the excludeDialog show() method', () => {
|
||||
controller.$.excludeDialog = {show: jest.fn()};
|
||||
|
||||
const days = [Date.vnNew()];
|
||||
controller.createExclusion(days);
|
||||
|
||||
expect(controller.excludeSelected).toBeDefined();
|
||||
expect(controller.isNew).toBeTruthy();
|
||||
expect(controller.$.excludeDialog.show).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('createInclusion()', () => {
|
||||
it('shoud set the selected property and then call the includeDialog show() method', () => {
|
||||
controller.$.includeDialog = {show: jest.fn()};
|
||||
|
||||
const type = 'weekday';
|
||||
const days = [Date.vnNew()];
|
||||
const weekday = 1;
|
||||
controller.createInclusion(type, days, weekday);
|
||||
|
||||
const selection = controller.selected;
|
||||
const firstWeekday = selection.wdays[weekday];
|
||||
|
||||
expect(selection.type).toEqual('indefinitely');
|
||||
expect(firstWeekday).toBeTruthy();
|
||||
expect(controller.isNew).toBeTruthy();
|
||||
expect(controller.$.includeDialog.show).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('shoud set the selected property with the first day and then call the includeDialog show() method', () => {
|
||||
controller.$.includeDialog = {show: jest.fn()};
|
||||
|
||||
const type = 'nonListedType';
|
||||
const days = [Date.vnNew()];
|
||||
const weekday = 1;
|
||||
controller.createInclusion(type, days, weekday);
|
||||
|
||||
const selection = controller.selected;
|
||||
|
||||
expect(selection.type).toEqual('day');
|
||||
expect(selection.dated).toEqual(days[0]);
|
||||
expect(controller.isNew).toBeTruthy();
|
||||
expect(controller.$.includeDialog.show).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onIncludeResponse()', () => {
|
||||
it('shoud call the onDelete() method', () => {
|
||||
jest.spyOn(controller, 'onDelete').mockReturnValue(
|
||||
new Promise(accept => accept())
|
||||
);
|
||||
|
||||
controller.selected = {id: 1};
|
||||
controller.onIncludeResponse('delete');
|
||||
|
||||
expect(controller.onDelete).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
it('shoud make an HTTP POST query to create a new one and then call the refresh() method', () => {
|
||||
jest.spyOn(controller, 'refresh').mockReturnThis();
|
||||
|
||||
controller.selected = {id: 1};
|
||||
controller.isNew = true;
|
||||
|
||||
$httpBackend.when('POST', `Zones/1/events`).respond(200);
|
||||
controller.onIncludeResponse('accept');
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.refresh).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('shoud make an HTTP PUT query and then call the refresh() method', () => {
|
||||
jest.spyOn(controller, 'refresh').mockReturnThis();
|
||||
|
||||
controller.selected = {id: 1};
|
||||
controller.isNew = false;
|
||||
|
||||
const eventId = 1;
|
||||
$httpBackend.when('PUT', `Zones/1/events/${eventId}`).respond(200);
|
||||
controller.onIncludeResponse('accept');
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.refresh).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onExcludeResponse()', () => {
|
||||
it('should call the exclusionCreate() method', () => {
|
||||
jest.spyOn(controller, 'exclusionCreate').mockReturnThis();
|
||||
|
||||
controller.excludeSelected = {type: 'all'};
|
||||
controller.onExcludeResponse('accept');
|
||||
|
||||
expect(controller.exclusionCreate).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('should call the exclusionGeoCreate() method', () => {
|
||||
jest.spyOn(controller, 'exclusionGeoCreate').mockReturnThis();
|
||||
|
||||
controller.excludeSelected = {type: 'specificLocations'};
|
||||
controller.onExcludeResponse('accept');
|
||||
|
||||
expect(controller.exclusionGeoCreate).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('should call the exclusionDelete() method', () => {
|
||||
jest.spyOn(controller, 'exclusionDelete').mockReturnThis();
|
||||
|
||||
controller.excludeSelected = {id: 1, type: 'all'};
|
||||
controller.onExcludeResponse('delete');
|
||||
|
||||
expect(controller.exclusionDelete).toHaveBeenCalledWith(controller.excludeSelected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onDeleteResponse()', () => {
|
||||
it('shoud make an HTTP DELETE query and then call the refresh() method', () => {
|
||||
jest.spyOn(controller, 'refresh').mockReturnThis();
|
||||
|
||||
const eventId = 1;
|
||||
$httpBackend.expect('DELETE', `Zones/1/events/1`).respond({id: 1});
|
||||
controller.onDeleteResponse('accept', eventId);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.refresh).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('exclusionCreate()', () => {
|
||||
it('shoud make an HTTP POST query and then call the refresh() method', () => {
|
||||
jest.spyOn(controller, 'refresh').mockReturnThis();
|
||||
|
||||
controller.excludeSelected = {};
|
||||
controller.isNew = true;
|
||||
$httpBackend.expect('POST', `Zones/1/exclusions`).respond({id: 1});
|
||||
controller.exclusionCreate();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.refresh).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('exclusionDelete()', () => {
|
||||
it('shoud make an HTTP DELETE query once and then call the refresh() method', () => {
|
||||
jest.spyOn(controller, 'refresh').mockReturnThis();
|
||||
|
||||
const exclusions = {id: 1};
|
||||
const firstExclusionId = 1;
|
||||
$httpBackend.expectDELETE(`Zones/1/exclusions/${firstExclusionId}`).respond(200);
|
||||
controller.exclusionDelete(exclusions);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.refresh).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSearch()', () => {
|
||||
it('should call the applyFilter() method and then set the data', () => {
|
||||
jest.spyOn(controller, 'getChecked').mockReturnValue([1, 2, 3]);
|
||||
|
||||
controller.$.treeview = {};
|
||||
controller.$.model = crudModel;
|
||||
controller.excludeSelected = {type: 'specificLocations'};
|
||||
controller._excludeSearch = 'es';
|
||||
|
||||
controller.onSearch();
|
||||
const treeviewData = controller.$.treeview.data;
|
||||
|
||||
expect(treeviewData).toBeDefined();
|
||||
expect(treeviewData.length).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onFetch()', () => {
|
||||
it('should call the applyFilter() method and then return the model data', () => {
|
||||
jest.spyOn(controller, 'getChecked').mockReturnValue([1, 2, 3]);
|
||||
|
||||
controller.$.model = crudModel;
|
||||
const result = controller.onFetch();
|
||||
|
||||
expect(result.length).toEqual(3);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,12 +0,0 @@
|
|||
Edit mode: Modo de edición
|
||||
Include: Incluir
|
||||
Exclude: Excluir
|
||||
Events: Eventos
|
||||
Add event: Añadir evento
|
||||
Edit event: Editar evento
|
||||
All: Todo
|
||||
Specific locations: Localizaciones concretas
|
||||
Locations where it is not distributed: Localizaciones en las que no se reparte
|
||||
You must select a location: Debes seleccionar una localización
|
||||
Add exclusion: Añadir exclusión
|
||||
Edit exclusion: Editar exclusión
|
|
@ -1,11 +0,0 @@
|
|||
@import "variables";
|
||||
|
||||
.width{
|
||||
width: 600px
|
||||
}
|
||||
|
||||
.treeview{
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
|
@ -1,19 +1,3 @@
|
|||
export * from './module';
|
||||
|
||||
import './main';
|
||||
import './index/';
|
||||
import './delivery-days';
|
||||
import './summary';
|
||||
import './card';
|
||||
import './descriptor';
|
||||
import './descriptor-popover';
|
||||
import './search-panel';
|
||||
import './create';
|
||||
import './basic-data';
|
||||
import './warehouses';
|
||||
import './events';
|
||||
import './calendar';
|
||||
import './location';
|
||||
import './calendar';
|
||||
import './upcoming-deliveries';
|
||||
import './log';
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
<vn-auto-search
|
||||
model="model">
|
||||
</vn-auto-search>
|
||||
<vn-data-viewer
|
||||
model="model"
|
||||
class="vn-w-md vn-mb-xl">
|
||||
<vn-card>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th field="id" number>Id</vn-th>
|
||||
<vn-th field="name" expand>Name</vn-th>
|
||||
<vn-th field="agencyModeFk">Agency</vn-th>
|
||||
<vn-th field="hour" shrink>Closing</vn-th>
|
||||
<vn-th field="price" number>Price</vn-th>
|
||||
<vn-th shrink></vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<a
|
||||
ng-repeat="zone in model.data"
|
||||
ui-sref="zone.card.summary({id: zone.id})"
|
||||
class="clickable vn-tr search-result">
|
||||
<vn-td number>{{::zone.id}}</vn-td>
|
||||
<vn-td expand>{{::zone.name}}</vn-td>
|
||||
<vn-td expand>{{::zone.agencyMode.name}}</vn-td>
|
||||
<vn-td shrink>{{::zone.hour | date: 'HH:mm'}}</vn-td>
|
||||
<vn-td number>{{::zone.price | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-horizontal class="buttons">
|
||||
<vn-icon-button
|
||||
vn-click-stop="clone.show(zone)"
|
||||
vn-tooltip="Clone"
|
||||
icon="icon-clone"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
<vn-icon-button
|
||||
vn-click-stop="$ctrl.preview(zone)"
|
||||
vn-tooltip="Preview"
|
||||
icon="preview">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
</vn-td>
|
||||
</a>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
<vn-popup vn-id="summary">
|
||||
<vn-zone-summary zone="$ctrl.selectedZone"></vn-zone-summary>
|
||||
</vn-popup>
|
||||
<vn-confirm
|
||||
vn-id="clone"
|
||||
on-accept="$ctrl.onCloneAccept($data)"
|
||||
question="Do you want to clone this zone?"
|
||||
message="All it's properties will be copied">
|
||||
</vn-confirm>
|
||||
<a ui-sref="zone.create"
|
||||
vn-tooltip="New zone"
|
||||
vn-bind="+"
|
||||
fixed-bottom-right>
|
||||
<vn-float-button
|
||||
icon="add"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-float-button>
|
||||
</a>
|
|
@ -1,21 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
preview(zone) {
|
||||
this.selectedZone = zone;
|
||||
this.$.summary.show();
|
||||
}
|
||||
|
||||
onCloneAccept(zone) {
|
||||
return this.$http.post(`Zones/${zone.id}/clone`)
|
||||
.then(res => {
|
||||
this.$state.go('zone.card.basicData', {id: res.data.id});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnZoneIndex', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,2 +0,0 @@
|
|||
Do you want to clone this zone?: ¿Seguro que quieres clonar esta zona?
|
||||
All it's properties will be copied: Todas sus propiedades serán copiadas
|
|
@ -13,7 +13,7 @@ Indefinitely: Indefinido
|
|||
Inflation: Inflación
|
||||
Locations: Localizaciones
|
||||
Maximum m³: M³ máximo
|
||||
Max m³: Medida máxima
|
||||
Max m³: Medida máxima
|
||||
New zone: Nueva zona
|
||||
One day: Un día
|
||||
Pick up: Recogida
|
||||
|
@ -32,4 +32,4 @@ Warehouses: Almacenes
|
|||
Week days: Días de la semana
|
||||
Zones: Zonas
|
||||
zone: zona
|
||||
Go to the zone: Ir a la zona
|
||||
Go to the zone: Ir a la zona
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="Zones/{{$ctrl.$params.id}}/getLeaves"
|
||||
filter="$ctrl.filter">
|
||||
</vn-crud-model>
|
||||
<vn-portal slot="topbar">
|
||||
<vn-searchbar
|
||||
on-search="$ctrl.onSearch($params)"
|
||||
auto-state="false">
|
||||
</vn-searchbar>
|
||||
</vn-portal>
|
||||
<div class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-treeview
|
||||
vn-id="treeview"
|
||||
root-label="Locations"
|
||||
fetch-func="$ctrl.onFetch($item)"
|
||||
sort-func="$ctrl.onSort($a, $b)">
|
||||
<vn-check acl-role="deliveryAssistant"
|
||||
ng-model="item.selected"
|
||||
on-change="$ctrl.onSelection(value, item)"
|
||||
triple-state="true"
|
||||
ng-click="$event.preventDefault()"
|
||||
label="{{::item.name}}">
|
||||
</vn-check>
|
||||
</vn-treeview>
|
||||
</vn-card>
|
||||
</div>
|
|
@ -1,56 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
import './style.scss';
|
||||
|
||||
class Controller extends Section {
|
||||
onSearch(params) {
|
||||
this.$.model.applyFilter({}, params).then(() => {
|
||||
const data = this.$.model.data;
|
||||
this.$.treeview.data = data;
|
||||
});
|
||||
}
|
||||
|
||||
onFetch(item) {
|
||||
const params = item ? {parentId: item.id} : null;
|
||||
return this.$.model.applyFilter({}, params)
|
||||
.then(() => this.$.model.data);
|
||||
}
|
||||
|
||||
onSort(a, b) {
|
||||
if (b.selected !== a.selected) {
|
||||
if (a.selected == null)
|
||||
return 1;
|
||||
if (b.selected == null)
|
||||
return -1;
|
||||
return b.selected - a.selected;
|
||||
}
|
||||
|
||||
return a.name.localeCompare(b.name);
|
||||
}
|
||||
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return {name: {like: `%${value}%`}};
|
||||
}
|
||||
}
|
||||
|
||||
onSelection(value, item) {
|
||||
if (value == null)
|
||||
value = undefined;
|
||||
const params = {geoId: item.id, isIncluded: value};
|
||||
const path = `zones/${this.zone.id}/toggleIsIncluded`;
|
||||
this.$http.post(path, params);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnZoneLocation', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
zone: '<'
|
||||
},
|
||||
require: {
|
||||
card: '^vnZoneCard'
|
||||
}
|
||||
});
|
|
@ -1,50 +0,0 @@
|
|||
import './index';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
|
||||
describe('component vnZoneLocation', () => {
|
||||
let $scope;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('zone'));
|
||||
|
||||
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$scope = $rootScope.$new();
|
||||
const $element = angular.element(`<vn-zone-location></vn-zone-location>`);
|
||||
controller = $componentController('vnZoneLocation', {$element, $scope});
|
||||
controller.$.model = crudModel;
|
||||
controller.zone = {id: 1};
|
||||
}));
|
||||
|
||||
describe('onSearch()', () => {
|
||||
it('should call the applyFilter() method and then set the data', () => {
|
||||
controller.$.treeview = {};
|
||||
controller.onSearch({});
|
||||
|
||||
const treeviewData = controller.$.treeview.data;
|
||||
|
||||
expect(treeviewData).toBeDefined();
|
||||
expect(treeviewData.length).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onFetch()', () => {
|
||||
it('should call the applyFilter() method and then return the model data', () => {
|
||||
const result = controller.onFetch();
|
||||
|
||||
expect(result.length).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSelection()', () => {
|
||||
it('should make an HTTP POST query', () => {
|
||||
const item = {id: 123};
|
||||
|
||||
const expectedParams = {geoId: 123, isIncluded: true};
|
||||
$httpBackend.expect('POST', `zones/1/toggleIsIncluded`, expectedParams).respond(200);
|
||||
controller.onSelection(true, item);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,21 +0,0 @@
|
|||
@import "variables";
|
||||
|
||||
vn-zone-location {
|
||||
vn-treeview-child {
|
||||
.content > .vn-check:not(.indeterminate):not(.checked) {
|
||||
color: $color-alert;
|
||||
|
||||
& > .btn {
|
||||
border-color: $color-alert;
|
||||
}
|
||||
}
|
||||
.content > .vn-check.checked {
|
||||
color: $color-notice;
|
||||
|
||||
& > .btn {
|
||||
background-color: $color-notice;
|
||||
border-color: $color-notice
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
<vn-log url="ZoneLogs" origin-id="$ctrl.$params.id"></vn-log>
|
|
@ -1,7 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
ngModule.vnComponent('vnZoneLog', {
|
||||
template: require('./index.html'),
|
||||
controller: Section,
|
||||
});
|
|
@ -1,19 +0,0 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="Zones"
|
||||
filter="::$ctrl.filter"
|
||||
limit="20">
|
||||
</vn-crud-model>
|
||||
<vn-portal slot="topbar">
|
||||
<vn-searchbar
|
||||
vn-focus
|
||||
info="Search zone by id or name"
|
||||
panel="vn-zone-search-panel"
|
||||
model="model"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
||||
</vn-searchbar>
|
||||
</vn-portal>
|
||||
<vn-portal slot="menu">
|
||||
<vn-left-menu></vn-left-menu>
|
||||
</vn-portal>
|
||||
<ui-view></ui-view>
|
|
@ -4,25 +4,10 @@ import ModuleMain from 'salix/components/module-main';
|
|||
export default class Zone extends ModuleMain {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.filter = {
|
||||
include: {
|
||||
relation: 'agencyMode',
|
||||
scope: {fields: ['name']}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return /^\d+$/.test(value)
|
||||
? {id: value}
|
||||
: {name: {like: `%${value}%`}};
|
||||
case 'name':
|
||||
return {[param]: {like: `%${value}%`}};
|
||||
case 'agencyModeFk':
|
||||
return {[param]: value};
|
||||
}
|
||||
async $onInit() {
|
||||
this.$state.go('home');
|
||||
window.location.href = await this.vnApp.getUrl(`zone/`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Zone Component vnZone', () => {
|
||||
let controller;
|
||||
|
||||
beforeEach(ngModule('zone'));
|
||||
|
||||
beforeEach(inject($componentController => {
|
||||
const $element = angular.element('<vn-zone></vn-zone>');
|
||||
controller = $componentController('vnZone', {$element});
|
||||
}));
|
||||
|
||||
describe('exprBuilder()', () => {
|
||||
it('should return a formated object with the id in case of search', () => {
|
||||
let param = 'search';
|
||||
let value = 1;
|
||||
let result = controller.exprBuilder(param, value);
|
||||
|
||||
expect(result).toEqual({id: 1});
|
||||
});
|
||||
|
||||
it('should return a formated object with the agencyModeFk in case of agencyModeFk', () => {
|
||||
let param = 'agencyModeFk';
|
||||
let value = 'My Delivery';
|
||||
let result = controller.exprBuilder(param, value);
|
||||
|
||||
expect(result).toEqual({agencyModeFk: 'My Delivery'});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -7,15 +7,6 @@
|
|||
"menus": {
|
||||
"main": [
|
||||
{"state": "zone.index", "icon": "icon-zone"},
|
||||
{"state": "zone.deliveryDays", "icon": "today"},
|
||||
{"state": "zone.upcomingDeliveries", "icon": "today"}
|
||||
],
|
||||
"card": [
|
||||
{"state": "zone.card.basicData", "icon": "settings"},
|
||||
{"state": "zone.card.location", "icon": "my_location"},
|
||||
{"state": "zone.card.warehouses", "icon": "home"},
|
||||
{"state": "zone.card.log", "icon": "history"},
|
||||
{"state": "zone.card.events", "icon": "today"}
|
||||
]
|
||||
},
|
||||
"keybindings": [
|
||||
|
@ -34,79 +25,6 @@
|
|||
"state": "zone.index",
|
||||
"component": "vn-zone-index",
|
||||
"description": "Zones"
|
||||
},
|
||||
{
|
||||
"url": "/delivery-days?q&deliveryMethodFk&geoFk&agencyModeFk",
|
||||
"state": "zone.deliveryDays",
|
||||
"component": "vn-zone-delivery-days",
|
||||
"description": "Delivery days"
|
||||
},
|
||||
{
|
||||
"url": "/upcoming-deliveries",
|
||||
"state": "zone.upcomingDeliveries",
|
||||
"component": "vn-upcoming-deliveries",
|
||||
"description": "Upcoming deliveries"
|
||||
},
|
||||
{
|
||||
"url": "/create",
|
||||
"state": "zone.create",
|
||||
"component": "vn-zone-create",
|
||||
"description": "New zone"
|
||||
},
|
||||
{
|
||||
"url": "/:id",
|
||||
"state": "zone.card",
|
||||
"component": "vn-zone-card",
|
||||
"abstract": true,
|
||||
"description": "Detail"
|
||||
},
|
||||
{
|
||||
"url": "/summary",
|
||||
"state": "zone.card.summary",
|
||||
"component": "vn-zone-summary",
|
||||
"description": "Summary",
|
||||
"params": {
|
||||
"zone": "$ctrl.zone"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "/basic-data",
|
||||
"state": "zone.card.basicData",
|
||||
"component": "vn-zone-basic-data",
|
||||
"description": "Basic data",
|
||||
"params": {
|
||||
"zone": "$ctrl.zone"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "/warehouses",
|
||||
"state": "zone.card.warehouses",
|
||||
"component": "vn-zone-warehouses",
|
||||
"description": "Warehouses"
|
||||
},
|
||||
{
|
||||
"url": "/events?q",
|
||||
"state": "zone.card.events",
|
||||
"component": "vn-zone-events",
|
||||
"description": "Calendar",
|
||||
"params": {
|
||||
"zone": "$ctrl.zone"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "/location?q",
|
||||
"state": "zone.card.location",
|
||||
"component": "vn-zone-location",
|
||||
"description": "Locations",
|
||||
"params": {
|
||||
"zone": "$ctrl.zone"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url" : "/log",
|
||||
"state": "zone.card.log",
|
||||
"component": "vn-zone-log",
|
||||
"description": "Log"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
<div class="search-panel">
|
||||
<form ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="General search"
|
||||
ng-model="filter.search"
|
||||
info="Search zone by id or name"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Name"
|
||||
ng-model="filter.name">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="Agency"
|
||||
ng-model="filter.agencyModeFk"
|
||||
url="AgencyModes/isActive"
|
||||
where="{deliveryMethodFk: {neq: null}}"
|
||||
value-field="id"
|
||||
show-field="name">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-mt-lg">
|
||||
<vn-submit label="Search"></vn-submit>
|
||||
</vn-horizontal>
|
||||
</form>
|
||||
</div>
|
|
@ -1,7 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
||||
|
||||
ngModule.vnComponent('vnZoneSearchPanel', {
|
||||
template: require('./index.html'),
|
||||
controller: SearchPanel
|
||||
});
|
|
@ -1,59 +0,0 @@
|
|||
<vn-card class="summary">
|
||||
<h5>
|
||||
<a
|
||||
ng-if="::$ctrl.summary.id"
|
||||
vn-tooltip="Go to the zone"
|
||||
ui-sref="zone.card.summary({id: {{::$ctrl.summary.id}}})"
|
||||
name="goToSummary">
|
||||
<vn-icon-button icon="launch"></vn-icon-button>
|
||||
</a>
|
||||
<span>#{{$ctrl.summary.id}} - {{$ctrl.summary.name}}</span>
|
||||
</h5>
|
||||
<vn-horizontal class="vn-pa-md">
|
||||
<vn-one>
|
||||
<vn-label-value label="Agency"
|
||||
value="{{$ctrl.summary.agencyMode.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Price"
|
||||
value="{{$ctrl.summary.price | currency: 'EUR': 2}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Bonus"
|
||||
value="{{$ctrl.summary.bonus | currency: 'EUR': 2}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<vn-label-value label="Closing hour"
|
||||
value="{{$ctrl.summary.hour | date: 'HH:mm'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Traveling days"
|
||||
value="{{$ctrl.summary.travelingDays}}">
|
||||
</vn-label-value>
|
||||
<vn-vertical>
|
||||
<vn-check label="Volumetric" disabled="true"
|
||||
ng-model="$ctrl.summary.isVolumetric">
|
||||
</vn-check>
|
||||
</vn-vertical>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-pa-md">
|
||||
<vn-auto>
|
||||
<h4>
|
||||
<a ui-sref="zone.card.warehouses({id:$ctrl.zone.id})">
|
||||
<span translate vn-tooltip="Go to">Warehouse</span>
|
||||
</a>
|
||||
</h4>
|
||||
<vn-table model="model" auto-load="false">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th>Name</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="zoneWarehouse in $ctrl.zoneWarehouses">
|
||||
<vn-td>{{zoneWarehouse.warehouse.name}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-auto>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
|
@ -1,56 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Summary from 'salix/components/summary';
|
||||
|
||||
class Controller extends Summary {
|
||||
get zone() {
|
||||
return this._zone;
|
||||
}
|
||||
|
||||
set zone(value) {
|
||||
this._zone = value;
|
||||
|
||||
if (!value) return;
|
||||
|
||||
this.getSummary();
|
||||
this.getWarehouses();
|
||||
}
|
||||
|
||||
getSummary() {
|
||||
const params = {
|
||||
filter: {
|
||||
include: {
|
||||
relation: 'agencyMode',
|
||||
fields: ['name']
|
||||
},
|
||||
where: {
|
||||
id: this.zone.id
|
||||
}
|
||||
}
|
||||
};
|
||||
this.$http.get(`Zones/findOne`, {params}).then(res => {
|
||||
this.summary = res.data;
|
||||
});
|
||||
}
|
||||
|
||||
getWarehouses() {
|
||||
const params = {
|
||||
filter: {
|
||||
include: {
|
||||
relation: 'warehouse',
|
||||
fields: ['name']
|
||||
}
|
||||
}
|
||||
};
|
||||
this.$http.get(`Zones/${this.zone.id}/warehouses`, {params}).then(res => {
|
||||
this.zoneWarehouses = res.data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnZoneSummary', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
zone: '<'
|
||||
}
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue