This commit is contained in:
Carlos Jimenez Ruiz 2019-06-26 15:02:22 +02:00
commit c352a12d49
73 changed files with 1001 additions and 4212 deletions

View File

@ -1,5 +1,4 @@
const UserError = require('vn-loopback/util/user-error');
const fs = require('fs-extra');
module.exports = Self => {
Self.remoteMethodCtx('downloadFile', {
@ -8,7 +7,7 @@ module.exports = Self => {
accepts: [
{
arg: 'id',
type: 'String',
type: 'Number',
description: 'The document id',
http: {source: 'path'}
}

View File

@ -1,6 +1,5 @@
const UserError = require('vn-loopback/util/user-error');
const fs = require('fs-extra');
const md5 = require('md5');
module.exports = Self => {
Self.remoteMethodCtx('uploadFile', {

View File

@ -1,15 +0,0 @@
CREATE TABLE `vn`.`device` (
`id` INT NOT NULL,
`sn` VARCHAR(50) NULL,
`model` VARCHAR(50) NULL,
`userFk` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`id`),
INDEX `device_fk1_idx` (`userFk` ASC),
CONSTRAINT `device_fk1`
FOREIGN KEY (`userFk`)
REFERENCES `account`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);
ALTER TABLE `vn`.`device`
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT ;

View File

@ -1,74 +0,0 @@
USE `nst`;
DROP procedure IF EXISTS `nodeAdd`;
DELIMITER $$
USE `nst`$$
CREATE DEFINER=`root`@`%` PROCEDURE `nodeAdd`(IN `vScheme` VARCHAR(45), IN `vTable` VARCHAR(45), IN `vParentFk` INT, IN `vChild` VARCHAR(100))
BEGIN
DECLARE vSql TEXT;
DECLARE vTableClone VARCHAR(45);
SET vTableClone = CONCAT(vTable, 'Clone');
CALL util.exec(CONCAT('DROP TEMPORARY TABLE IF EXISTS tmp.', vTableClone));
CALL util.exec(CONCAT(
'CREATE TEMPORARY TABLE tmp.', vTableClone,
' ENGINE = MEMORY',
' SELECT * FROM ', vScheme, '.', vTable
));
CALL util.exec(CONCAT(
'SELECT COUNT(c.id) INTO @childs',
' FROM ', vScheme, '.', vTable, ' p',
' LEFT JOIN tmp.', vTableClone, ' c ON c.lft',
' BETWEEN p.lft AND p.rgt AND c.id != ', vParentFk,
' WHERE p.id = ', vParentFk
));
IF @childs = 0 THEN
CALL util.exec(CONCAT(
'SELECT lft INTO @vLeft',
' FROM ', vScheme, '.', vTable,
' WHERE id = ', vParentFk
));
ELSE
CALL util.exec(CONCAT(
'SELECT c.rgt INTO @vLeft',
' FROM ', vScheme, '.', vTable, ' p',
' JOIN tmp.', vTableClone, ' c ON c.depth = p.depth + 1'
' AND c.lft BETWEEN p.lft AND p.rgt',
' WHERE p.id = ', vParentFk,
' ORDER BY c.lft',
' DESC LIMIT 1'
));
END IF;
CALL util.exec(CONCAT(
'UPDATE ', vScheme, '.', vTable, ' SET rgt = rgt + 2',
' WHERE rgt > @vLeft',
' ORDER BY rgt DESC'
));
CALL util.exec(CONCAT(
'UPDATE ', vScheme, '.', vTable, ' SET lft = lft + 2',
' WHERE lft > @vLeft',
' ORDER BY lft DESC'
));
SET vChild = REPLACE(vChild, "'", "\\'");
CALL util.exec(CONCAT(
'INSERT INTO ', vScheme, '.', vTable, ' (name, lft, rgt)',
' VALUES ("', vChild, '", @vLeft + 1, @vLeft + 2)'
));
-- CALL util.exec(CONCAT(
-- 'SELECT id, name, lft, rgt, depth, sons',
-- ' FROM ', vScheme, '.', vTable,
-- ' WHERE id = LAST_INSERT_ID()'
-- ));
CALL util.exec(CONCAT('DROP TEMPORARY TABLE tmp.', vTableClone));
END$$
DELIMITER ;

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +0,0 @@
DROP procedure IF EXISTS `vn`.`zoneNest`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zoneNest`()
BEGIN
DROP TEMPORARY TABLE IF EXISTS tmp.zoneGeo;
CREATE TEMPORARY TABLE tmp.zoneGeo
(id INT AUTO_INCREMENT PRIMARY KEY)
ENGINE = MEMORY
SELECT * FROM vn.zoneGeo;
DROP TEMPORARY TABLE IF EXISTS tmp.country;
CREATE TEMPORARY TABLE tmp.country
SELECT id FROM country
WHERE country IN('España exento');
CALL vn.zoneNestCountry();
CALL vn.zoneNestProvince();
CALL vn.zoneNestTown();
CALL vn.zoneNestPostcode();
CALL vn.nestTree('tmp', 'zoneGeo', 'vn', 'zoneGeo');
DROP TEMPORARY TABLE
tmp.zoneGeo,
tmp.country;
END$$
DELIMITER ;

View File

@ -1,55 +0,0 @@
DROP procedure IF EXISTS `vn`.`zoneNestCountry`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zoneNestCountry`()
BEGIN
DECLARE vDone BOOL;
DECLARE vParent INT DEFAULT 1;
DECLARE vGeoFk INT;
DECLARE vChildFk INT;
DECLARE vChildName VARCHAR(100);
DECLARE countryCur CURSOR FOR
SELECT 1, c.id, c.`country`
FROM vn.country c
JOIN tmp.country tc ON tc.id = c.id
ORDER BY c.`country`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
-- Remove existing countries
DELETE zg FROM vn.country c
JOIN tmp.country tc ON tc.id = c.id
JOIN tmp.zoneGeo zg ON zg.id = c.geoFk;
-- Reset country geoFk
UPDATE vn.country c
JOIN tmp.country tc ON tc.id = c.id
SET c.geoFk = NULL
WHERE c.geoFk IS NOT NULL;
-- > Country cursor start
OPEN countryCur;
countryLoop: LOOP
SET vDone = FALSE;
FETCH countryCur INTO vParent, vChildFk, vChildName;
IF vDone THEN
LEAVE countryLoop;
END IF;
CALL nst.nodeAdd('tmp', 'zoneGeo', vParent, vChildName);
END LOOP;
CLOSE countryCur;
-- < Country cursor end
UPDATE country c
JOIN tmp.zoneGeo z ON z.name = c.country
SET c.geoFk = z.id
WHERE c.geoFk IS NULL;
END$$
DELIMITER ;

View File

@ -1,61 +0,0 @@
DROP procedure IF EXISTS `vn`.`zoneNestPostcode`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zoneNestPostcode`()
BEGIN
DECLARE vDone BOOL;
DECLARE vParent INT DEFAULT 1;
DECLARE vGeoFk INT;
DECLARE vChildFk INT;
DECLARE vChildName VARCHAR(100);
DECLARE postcodeCur CURSOR FOR
SELECT t.geoFk, pc.`code`, pc.`code`
FROM vn.postCode pc
JOIN vn.town t ON t.id = pc.townFk
JOIN vn.province p ON p.id = t.provinceFk
JOIN tmp.country tc ON tc.id = p.countryFk
ORDER BY t.geoFk, pc.`code`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
-- Remove existing postCodes from zoneGeo
DELETE zg FROM vn.postCode pc
JOIN vn.town t ON t.id = pc.townFk
JOIN vn.province p ON p.id = t.provinceFk
JOIN tmp.country tc ON tc.id = p.countryFk
JOIN tmp.zoneGeo zg ON zg.id = pc.geoFk;
-- Reset town geoFk
UPDATE vn.postCode pc
JOIN vn.town t ON t.id = pc.townFk
JOIN vn.province p ON p.id = t.provinceFk
JOIN tmp.country tc ON tc.id = p.countryFk
SET pc.geoFk = NULL
WHERE pc.geoFk IS NOT NULL;
-- > Postcode cursor start
OPEN postcodeCur;
postcodeLoop: LOOP
SET vDone = FALSE;
FETCH postcodeCur INTO vParent, vChildFk, vChildName;
IF vDone THEN
LEAVE postcodeLoop;
END IF;
CALL nst.nodeAdd('tmp', 'zoneGeo', vParent, vChildName);
END LOOP;
CLOSE postcodeCur;
-- < Postcode cursor end
UPDATE postCode p
JOIN tmp.zoneGeo z ON z.name = p.code
SET p.geoFk = z.id
WHERE p.geoFk IS NULL;
END$$
DELIMITER ;

View File

@ -1,56 +0,0 @@
DROP procedure IF EXISTS `vn`.`zoneNestProvince`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zoneNestProvince`()
BEGIN
DECLARE vDone BOOL;
DECLARE vParent INT DEFAULT 1;
DECLARE vGeoFk INT;
DECLARE vChildFk INT;
DECLARE vChildName VARCHAR(100);
DECLARE provinceCur CURSOR FOR
SELECT c.geoFk, p.id, p.`name`
FROM province p
JOIN tmp.country tc ON tc.id = p.countryFk
JOIN vn.country c ON c.id = tc.id
ORDER BY c.geoFk, p.`name`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
-- Remove existing provinces from zoneGeo
DELETE zg FROM vn.province p
JOIN tmp.country tc ON tc.id = p.countryFk
JOIN tmp.zoneGeo zg ON zg.id = p.geoFk;
-- Reset country geoFk
UPDATE vn.province p
JOIN tmp.country tc ON tc.id = p.countryFk
SET p.geoFk = NULL
WHERE p.geoFk IS NOT NULL;
-- > Province cursor start
OPEN provinceCur;
provinceLoop: LOOP
SET vDone = FALSE;
FETCH provinceCur INTO vParent, vChildFk, vChildName;
IF vDone THEN
LEAVE provinceLoop;
END IF;
CALL nst.nodeAdd('tmp', 'zoneGeo', vParent, vChildName);
END LOOP;
CLOSE provinceCur;
-- < Province cursor end
UPDATE province p
JOIN tmp.zoneGeo z ON z.name = p.name
SET p.geoFk = z.id
WHERE p.geoFk IS NULL;
END$$
DELIMITER ;

View File

@ -1,59 +0,0 @@
DROP procedure IF EXISTS `vn`.`zoneNestTown`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zoneNestTown`()
BEGIN
DECLARE vDone BOOL;
DECLARE vParent INT DEFAULT 1;
DECLARE vGeoFk INT;
DECLARE vChildFk INT;
DECLARE vChildName VARCHAR(100);
DECLARE townCur CURSOR FOR
SELECT p.geoFk, t.id, t.`name`
FROM vn.town t
JOIN vn.province p ON p.id = t.provinceFk
JOIN tmp.country tc ON tc.id = p.countryFk
ORDER BY p.geoFk, t.`name`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
-- Remove existing towns from zoneGeo
DELETE zg FROM vn.town t
JOIN vn.province p ON p.id = t.provinceFk
JOIN tmp.country tc ON tc.id = p.countryFk
JOIN tmp.zoneGeo zg ON zg.id = t.geoFk;
-- Reset town geoFk
UPDATE vn.town t
JOIN vn.province p ON p.id = t.provinceFk
JOIN tmp.country tc ON tc.id = p.countryFk
SET t.geoFk = NULL
WHERE t.geoFk IS NOT NULL;
-- > Town cursor start
OPEN townCur;
townLoop: LOOP
SET vDone = FALSE;
FETCH townCur INTO vParent, vChildFk, vChildName;
IF vDone THEN
LEAVE townLoop;
END IF;
CALL nst.nodeAdd('tmp', 'zoneGeo', vParent, vChildName);
END LOOP;
CLOSE townCur;
-- < Town cursor end
UPDATE town t
JOIN tmp.zoneGeo z ON z.name = t.name
LEFT JOIN province p ON p.geoFk = z.id
SET t.geoFk = z.id
WHERE p.geoFk IS NULL;
END$$
DELIMITER ;

View File

@ -1,19 +0,0 @@
CREATE
OR REPLACE ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn`.`ticketGetVolume` AS
SELECT
`s`.`ticketFk` AS `ticketFk`,
`t`.`routeFk` AS `routeFk`,
`s`.`id` AS `saleFk`,
`t`.`shipped` AS `Fecha`,
(((`s`.`quantity` * `r`.`cm3`) * `i`.`compression`) / 1000000) AS `volume`
FROM
(((`vn`.`sale` `s`
JOIN `vn`.`item` `i` ON ((`i`.`id` = `s`.`itemFk`)))
JOIN `vn`.`ticket` `t` ON ((`t`.`id` = `s`.`ticketFk`)))
JOIN `bi`.`rotacion` `r` ON (((`r`.`Id_Article` = `s`.`itemFk`)
AND (`r`.`warehouse_id` = `t`.`warehouseFk`))));

View File

@ -1,30 +0,0 @@
DROP function IF EXISTS `vn`.`ticketTotalVolume`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` FUNCTION `ticketTotalVolume`(vTicketId INT) RETURNS decimal(10,3)
READS SQL DATA
BEGIN
-- Devuelte el volumen total del ticket sumado
-- DECLARE vWarehouseId INTEGER;
-- DECLARE vShippedDate DATE;
DECLARE vVolume DECIMAL(10,3);
/*
SELECT warehouseFk, shipped INTO vWarehouseId,vShippedDate FROM vn.ticket WHERE id = vTicketId;
SELECT IFNULL(SUM(s.quantity * i.compression * r.cm3)/1000000,0) INTO vVolume
FROM sale s
JOIN vn.item i ON i.id = s.itemFk
JOIN bi.rotacion r on r.Id_Article = s.itemFk AND r.warehouse_id = vWarehouseId
WHERE s.ticketFk = vTicketId;
*/
SELECT sum(volume) INTO vVolume
FROM ticketGetVolume
WHERE ticketFk = vTicketId;
RETURN vVolume;
END$$
DELIMITER ;

View File

@ -1,61 +0,0 @@
DROP procedure IF EXISTS `vn`.`available_calc`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`available_calc`(
vDate DATE,
vAddress INT,
vAgencyMode INT)
BEGIN
/**
* Calculates the available for all available stores
* according to the given parameters.
*
* @param vDate The delivery date
* @param vAddress The delivery address id
* @param vAgencyMode The shipping agency
* @return tmp.availableCalc(calcFk) The available cache ids
*/
DECLARE vCalcFk INT;
DECLARE vShipment DATE;
DECLARE vWarehouse INT;
DECLARE vDone BOOL;
DECLARE cWarehouses CURSOR FOR
SELECT warehouseFk, shipped FROM tmp.zoneGetShipped;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET vDone = TRUE;
-- Establecemos los almacenes y las fechas que van a entrar al disponible
CALL vn.zoneGetShippedWarehouse(vDate, vAddress, vAgencyMode);
DROP TEMPORARY TABLE IF EXISTS tmp.availableCalc;
CREATE TEMPORARY TABLE tmp.availableCalc(
calcFk INT UNSIGNED,
PRIMARY KEY (calcFk)
)
ENGINE = MEMORY;
OPEN cWarehouses;
l: LOOP
SET vDone = FALSE;
FETCH cWarehouses INTO vWarehouse, vShipment;
IF vDone THEN
LEAVE l;
END IF;
CALL `cache`.available_refresh(vCalcFk, FALSE, vWarehouse, vShipment);
INSERT IGNORE INTO tmp.availableCalc
SET calcFk = vCalcFk;
END LOOP;
CLOSE cWarehouses;
DROP TEMPORARY TABLE tmp.zoneGetShipped;
END$$
DELIMITER ;

View File

@ -1,28 +0,0 @@
DROP procedure IF EXISTS `vn`.`catalog_calcFromItem`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`catalog_calcFromItem`(
vLanded DATE,
vAddressFk INT,
vAgencyModeFk INT,
vItemFk INT)
BEGIN
/**
* Calculates available and price for a single item.
*
* @param vItemFk The item id
* @return tmp.ticketCalculateItem
* @return tmp.ticketComponentPrice
* @return tmp.ticketComponent
* @return tmp.ticketLot
* @return tmp.zoneGetShipped
*/
DROP TEMPORARY TABLE IF EXISTS tmp.item;
CREATE TEMPORARY TABLE tmp.item
ENGINE = MEMORY
SELECT vItemFk itemFk;
CALL ticketCalculate(vLanded, vAddressFk, vAgencyModeFk);
DROP TEMPORARY TABLE tmp.item;
END$$
DELIMITER ;

View File

@ -1,41 +0,0 @@
DROP procedure IF EXISTS `hedera`.`catalog_calcFromMyAddress`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`catalog_calcFromMyAddress`(vDelivery DATE, vAddress INT)
BEGIN
/**
* Gets the available items list.
*
* @param vDelivery Delivery date
* @param vAddress Address id
* @return tmp.ticketCalculateItem
* @return tmp.ticketComponentPrice
* @return tmp.ticketComponent
* @return tmp.ticketLot
* @return tmp.zoneGetShipped
*/
DECLARE vAgencyMode INT;
SELECT a.agencyModeFk
INTO vAgencyMode
FROM myClient c
JOIN vn.address a ON a.clientFk = c.id
WHERE a.id = vAddress;
CALL vn.available_calc(vDelivery, vAddress, vAgencyMode);
DROP TEMPORARY TABLE IF EXISTS tmp.item;
CREATE TEMPORARY TABLE tmp.item
(INDEX (itemFk))
ENGINE = MEMORY
SELECT c.item_id itemFk
FROM `cache`.available c
JOIN tmp.availableCalc a ON a.calcFk = c.calc_id
WHERE c.available > 0
GROUP BY c.item_id;
CALL vn.ticketCalculate(vDelivery, vAddress, vAgencyMode);
DROP TEMPORARY TABLE tmp.item;
END$$
DELIMITER ;

View File

@ -1,398 +0,0 @@
USE `vn2008`;
DROP procedure IF EXISTS `vn2008`.`bionic_available_`;
DELIMITER $$
USE `vn2008`$$
CREATE DEFINER=`root`@`%` PROCEDURE `__bionic_available_`(
vDate DATE,
vAddress INT,
vAgency INT)
BEGIN
/**
* Calcula el disponible para un conjunto de almacenes y fechas
* devueltos por el procedimiento agencyHourGetShipped()
*
* @deprecated Use vn.available_calc()
* @table t_bionic_available Tabla con los ids de cache
*/
DECLARE vAvailableCalc INT;
DECLARE vShipment DATE;
DECLARE vAgencyId INT;
DECLARE vWh INT;
DECLARE vDone BOOL;
DECLARE cTravelTree CURSOR FOR
SELECT warehouseFk, shipped FROM tmp.agencyHourGetShipped;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
-- Establecemos los almacenes y las fechas que van a entrar al disponible
SELECT agency_id INTO vAgencyId
FROM Agencias WHERE Id_Agencia = vAgency;
CALL vn.agencyHourGetShipped (vDate, vAddress, vAgencyId);
DROP TEMPORARY TABLE IF EXISTS t_bionic_available;
CREATE TEMPORARY TABLE t_bionic_available(
calc_id INT UNSIGNED,
PRIMARY KEY (calc_id)
)
ENGINE = MEMORY;
OPEN cTravelTree;
l: LOOP
SET vDone = FALSE;
FETCH cTravelTree INTO vWh, vShipment;
IF vDone THEN
LEAVE l;
END IF;
CALL `cache`.available_refresh (vAvailableCalc, FALSE, vWh, vShipment);
INSERT IGNORE INTO t_bionic_available
SET calc_id = vAvailableCalc;
END LOOP;
CLOSE cTravelTree;
DROP TEMPORARY TABLE tmp.agencyHourGetShipped;
END$$
DELIMITER ;
;
USE `hedera`;
DROP procedure IF EXISTS `hedera`.`bionic_from_item`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `__bionic_from_item`(vItem INT)
BEGIN
DECLARE vDate DATE;
DECLARE vAddress INT;
DECLARE vAgencyMode INT;
SELECT sent, addressFk, agencyModeFk
INTO vDate, vAddress, vAgencyMode
FROM myBasket;
CALL vn2008.bionic_from_item(vDate, vAddress, vAgencyMode, vItem);
END$$
DELIMITER ;
;
USE `vn2008`;
DROP procedure IF EXISTS `vn2008`.`bionic_from_order`;
DELIMITER $$
USE `vn2008`$$
CREATE DEFINER=`root`@`%` PROCEDURE `__bionic_from_order`(
v_date DATE, -- fecha de recepcion de mercancia
v_consigna INT,
v_agencia INT,
v_order INT)
BEGIN
DROP TEMPORARY TABLE IF EXISTS tmp.bionic_calc;
CREATE TEMPORARY TABLE tmp.bionic_calc
(PRIMARY KEY (item_id))
ENGINE = MEMORY
SELECT item_id FROM order_row
WHERE order_id = v_order GROUP BY item_id;
CALL bionic_calc (v_date, v_consigna, v_agencia);
DROP TEMPORARY TABLE tmp.bionic_calc;
END$$
DELIMITER ;
;
USE `hedera`;
DROP procedure IF EXISTS `hedera`.`bionicCalcWithDate`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `__bionicCalcWithDate`(vDate DATE)
BEGIN
DECLARE vMyAddressFk INTEGER;
DECLARE vMyAgencyModeFk INTEGER;
SELECT id, agencyModeFk INTO vMyAddressFk, vMyAgencyModeFk
FROM myAddress
WHERE isDefaultAddress;
CALL vn2008.bionic_calc(vDate, vMyAddressFk, vMyAgencyModeFk);
END$$
DELIMITER ;
;
USE `hedera`;
DROP procedure IF EXISTS `hedera`.`bionic_calc`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `__bionic_calc`()
BEGIN
DECLARE vDate DATE;
DECLARE vAddress INT;
DECLARE vAgencyMode INT;
SELECT sent, addressFk, agencyModeFk
INTO vDate, vAddress, vAgencyMode
FROM myBasket;
CALL vn2008.bionic_calc(vDate, vAddress, vAgencyMode);
IF account.myUserGetName() = 'visitor'
THEN
DROP TEMPORARY TABLE tmp.bionic_component;
UPDATE tmp.bionic_item SET price = NULL;
END IF;
END$$
DELIMITER ;
;
USE `hedera`;
DROP procedure IF EXISTS `hedera`.`itemGetAvailableOrder`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `__itemGetAvailableOrder`(vOrder INT)
BEGIN
/**
* Gets the available items list with an order params.
*
* @table tmp.itemAvailable
*/
DECLARE vDelivery DATE;
DECLARE vAddress INT;
DECLARE vAgency INT;
SELECT landed, addressFk, agencyModeFk
INTO vDelivery, vAddress, vAgency
FROM myOrder
WHERE id = vOrder;
CALL vn2008.bionic_available_ (vDelivery, vAddress, vAgency);
DROP TEMPORARY TABLE IF EXISTS tmp.itemAvailable;
CREATE TEMPORARY TABLE tmp.itemAvailable
(INDEX (id))
ENGINE = MEMORY
SELECT c.item_id id
FROM cache.available c
JOIN vn2008.t_bionic_available a ON c.calc_id = a.calc_id
WHERE c.available > 0
GROUP BY c.item_id;
DROP TEMPORARY TABLE vn2008.t_bionic_available;
END$$
DELIMITER ;
;
USE `hedera`;
DROP procedure IF EXISTS `hedera`.`itemGetAvailable`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `__itemGetAvailable`()
BEGIN
/**
* Gets the available items list.
*
* @table tmp.itemAvailable
*/
DECLARE vDelivery DATE;
DECLARE vAddress INT;
DECLARE vAgency INT;
SELECT sent, addressFk, agencyModeFk
INTO vDelivery, vAddress, vAgency
FROM myBasket;
CALL vn2008.bionic_available_ (vDelivery, vAddress, vAgency);
DROP TEMPORARY TABLE IF EXISTS tmp.itemAvailable;
CREATE TEMPORARY TABLE tmp.itemAvailable
(INDEX (id))
ENGINE = MEMORY
SELECT c.item_id id
FROM cache.available c
JOIN vn2008.t_bionic_available a ON c.calc_id = a.calc_id
WHERE c.available > 0
GROUP BY c.item_id;
DROP TEMPORARY TABLE vn2008.t_bionic_available;
END$$
DELIMITER ;
;
USE `hedera`;
DROP procedure IF EXISTS `hedera`.`myItemGetAvailableFromDate`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `__myItemGetAvailableFromDate`(vDelivery DATE)
BEGIN
/**
* Gets the available items list.
*
* @deprecated Use item_calcCatalogFromMyAddress()
* @param vDelivery Delivery date
*/
DECLARE vAddress INT;
DECLARE vAgencyMode INT;
SELECT a.agencyModeFk, a.id
INTO vAgencyMode, vAddress
FROM myClient c
JOIN vn.address a ON a.id = c.defaultAddressFk;
CALL vn2008.bionic_available_ (vDelivery, vAddress, vAgencyMode);
DROP TEMPORARY TABLE IF EXISTS tmp.item;
CREATE TEMPORARY TABLE tmp.item
(INDEX (itemFk))
ENGINE = MEMORY
SELECT c.item_id itemFk
FROM cache.available c
JOIN vn2008.t_bionic_available a ON c.calc_id = a.calc_id
WHERE c.available > 0
GROUP BY c.item_id;
CALL vn.ticketCalculate(vDelivery, vAddress, vAgencyMode);
-- -------------------
/*SELECT b.itemFk, b.item, b.available, b.price
FROM tmp.ticketCalculateItem b
JOIN vn.item i ON i.id = b.itemFk
WHERE b.available > 0
ORDER BY i.relevancy DESC, i.name, i.size;
select * from tmp.ticketComponentPrice;*/
-- -------------------
DROP TEMPORARY TABLE vn2008.t_bionic_available;
END$$
DELIMITER ;
;
USE `hedera`;
DROP procedure IF EXISTS `hedera`.`myItemGetAvailable`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `__myItemGetAvailable`(vDelivery DATE, vAddress INT)
BEGIN
/**
* Gets the available items list.
*
* @deprecated Use item_calcCatalogFromMyAddress()
* @param vDelivery Delivery date
* @param vAddress Id Address
*/
DECLARE vAgencyMode INT;
SELECT a.agencyModeFk
INTO vAgencyMode
FROM myClient c
JOIN vn.address a ON a.clientFk = c.id
WHERE a.id = vAddress;
CALL vn2008.bionic_available_ (vDelivery, vAddress, vAgencyMode);
DROP TEMPORARY TABLE IF EXISTS tmp.item;
CREATE TEMPORARY TABLE tmp.item
(INDEX (itemFk))
ENGINE = MEMORY
SELECT c.item_id itemFk
FROM cache.available c
JOIN vn2008.t_bionic_available a ON c.calc_id = a.calc_id
WHERE c.available > 0
GROUP BY c.item_id;
CALL vn.ticketCalculate(vDelivery, vAddress, vAgencyMode);
-- -------------------
/*SELECT b.itemFk, b.item, b.available, b.price
FROM tmp.ticketCalculateItem b
JOIN vn.item i ON i.id = b.itemFk
WHERE b.available > 0
ORDER BY i.relevancy DESC, i.name, i.size;
select * from tmp.ticketComponentPrice;*/
-- -------------------
DROP TEMPORARY TABLE vn2008.t_bionic_available;
END$$
DELIMITER ;
;
USE `hedera`;
DROP procedure IF EXISTS `hedera`.`myOrderAddItem`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `__myOrderAddItem`(
vSelf INT,
vWarehouse INT,
vItem INT,
vAmount INT)
BEGIN
/**
* @deprecated Use myOrder_addItem()
*/
CALL myOrder_addItem(vSelf, vWarehouse, vItem, vAmount);
END$$
DELIMITER ;
;
USE `hedera`;
DROP procedure IF EXISTS `hedera`.`myOrderConfirm`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `__myOrderConfirm`(vSelf INT)
BEGIN
/**
* @deprecated Use myOrder_confirm()
*/
CALL myOrder_confirm(vSelf);
END$$
DELIMITER ;
;
USE `hedera`;
DROP procedure IF EXISTS `hedera`.`myOrderNewFromDate`;
DELIMITER $$
USE `hedera`$$
CREATE DEFINER=`root`@`%` PROCEDURE `__myOrderNewFromDate`(
OUT vSelf INT,
vLandingDate DATE)
BEGIN
/**
* @deprecated Use myOrder_newWithDate()
*/
CALL myOrder_newWithDate(vSelf, vLandingDate);
END$$
DELIMITER ;
;

View File

@ -1,19 +0,0 @@
DROP procedure IF EXISTS `hedera`.`myBasket_calcCatalogFromItem`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`myBasket_calcCatalogFromItem`(vItem INT)
BEGIN
/**
* Gets the availability and prices for the given item
* using current user basket parameters.
*
* @table tmp.item(itemFk)
* @return tmp.ticketCalculateItem
* @return tmp.ticketComponentPrice
* @return tmp.ticketComponent
* @return tmp.ticketLot
* @return tmp.zoneGetShipped
*/
CALL order_calcCatalogFromItem(myBasket_getId(), vItem);
END$$
DELIMITER ;

View File

@ -1,19 +0,0 @@
DROP procedure IF EXISTS `hedera`.`myBasket_calcCatalogFull`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`myBasket_calcCatalogFull`()
BEGIN
/**
* Gets the availability and prices for the given items
* using current user basket parameters.
*
* @table tmp.item(itemFk)
* @return tmp.ticketCalculateItem
* @return tmp.ticketComponentPrice
* @return tmp.ticketComponent
* @return tmp.ticketLot
* @return tmp.zoneGetShipped
*/
CALL order_calcCatalogFull(myBasket_getId());
END$$
DELIMITER ;

View File

@ -1,14 +0,0 @@
DROP procedure IF EXISTS `hedera`.`myBasket_getAvailable`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`myBasket_getAvailable`()
BEGIN
/**
* Gets the available items list.
*
* @table tmp.itemAvailable
*/
CALL order_getAvailable(myBasket_getId());
END$$
DELIMITER ;

View File

@ -1,22 +0,0 @@
DROP procedure IF EXISTS `hedera`.`myOrder_getAvailable`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`myOrder_getAvailable`(vSelf INT)
BEGIN
/**
* Gets the available items list.
*
* @param vSelf The order id
* @table tmp.itemAvailable
*/
DECLARE isMine BOOL;
SELECT COUNT(*) INTO isMine
FROM myOrder
WHERE id = vSelf;
IF isMine THEN
CALL order_getAvailable(vSelf);
END IF;
END$$
DELIMITER ;

View File

@ -1,105 +0,0 @@
DROP procedure IF EXISTS `hedera`.`order_addItem`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`order_addItem`(
vSelf INT,
vWarehouse INT,
vItem INT,
vAmount INT)
BEGIN
/**
* Adds an item to the order, checking availability and grouping.
*
* @param vSelf The order id
* @param vWarehouse The warehouse id
* @param vItem The item id
* @param vAmount The amount to add
*/
DECLARE vRow INT;
DECLARE vAdd INT;
DECLARE vAvailable INT;
DECLARE vDone BOOL;
DECLARE vGrouping INT;
DECLARE vRate INT;
DECLARE vShipment DATE;
DECLARE vPrice DECIMAL(10,2);
DECLARE cur CURSOR FOR
SELECT `grouping`, price, rate
FROM tmp.ticketComponentPrice
WHERE warehouseFk = vWarehouse
AND itemFk = vItem
ORDER BY `grouping` DESC;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET vDone = TRUE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
CALL order_calcCatalogFromItem(vSelf, vItem);
START TRANSACTION;
SELECT shipped INTO vShipment
FROM tmp.zoneGetShipped
WHERE warehouseFk = vWarehouse;
SELECT available INTO vAvailable
FROM tmp.ticketLot
WHERE warehouseFk = vWarehouse
AND itemFk = vItem;
IF vAmount > IFNULL(vAvailable, 0) THEN
CALL util.throw ('ORDER_ROW_UNAVAILABLE');
END IF;
OPEN cur;
l: LOOP
SET vDone = FALSE;
FETCH cur INTO vGrouping, vPrice, vRate;
IF vDone THEN
LEAVE l;
END IF;
SET vAdd = vAmount - MOD(vAmount, vGrouping);
SET vAmount = vAmount - vAdd;
IF vAdd = 0 THEN
ITERATE l;
END IF;
INSERT INTO orderRow SET
orderFk = vSelf,
itemFk = vItem,
warehouseFk = vWarehouse,
shipment = vShipment,
rate = vRate,
amount = vAdd,
price = vPrice;
SET vRow = LAST_INSERT_ID();
INSERT INTO orderRowComponent (rowFk, componentFk, price)
SELECT vRow, c.componentFk, c.cost
FROM tmp.ticketComponent c
JOIN vn.component t
ON t.id = c.componentFk
AND (t.classRate IS NULL OR t.classRate = vRate)
WHERE c.warehouseFk = vWarehouse
AND c.itemFk = vItem;
END LOOP;
CLOSE cur;
IF vAmount > 0 THEN
CALL util.throw ('AMOUNT_NOT_MATCH_GROUPING');
END IF;
COMMIT;
CALL vn.ticketCalculatePurge;
END$$
DELIMITER ;

View File

@ -1,36 +0,0 @@
DROP procedure IF EXISTS `hedera`.`order_calcCatalog`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`order_calcCatalog`(vSelf INT)
BEGIN
/**
* Gets the availability and prices for order items.
*
* @param vSelf The order id
* @return tmp.ticketCalculateItem
* @return tmp.ticketComponentPrice
* @return tmp.ticketComponent
* @return tmp.ticketLot
*/
DECLARE vDate DATE;
DECLARE vAddress INT;
DECLARE vAgencyMode INT;
SELECT date_send, address_id, agency_id
INTO vDate, vAddress, vAgencyMode
FROM `order`
WHERE id = vSelf;
DROP TEMPORARY TABLE IF EXISTS tmp.item;
CREATE TEMPORARY TABLE tmp.item
(PRIMARY KEY (itemFk))
ENGINE = MEMORY
SELECT itemFk FROM orderRow
WHERE orderFk = vSelf
GROUP BY itemFk;
CALL vn.ticketCalculate(vDate, vAddress, vAgencyMode);
DROP TEMPORARY TABLE tmp.item;
END$$
DELIMITER ;

View File

@ -1,30 +0,0 @@
DROP procedure IF EXISTS `hedera`.`order_calcCatalogFromItem`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`order_calcCatalogFromItem`(vSelf INT, vItem INT)
BEGIN
/**
* Gets the availability and prices for the given item
* using the order parameters.
*
* @param vSelf The order id
* @table tmp.item(itemFk)
* @return tmp.ticketCalculateItem
* @return tmp.ticketComponentPrice
* @return tmp.ticketComponent
* @return tmp.ticketLot
* @return tmp.zoneGetShipped
*/
DECLARE vDate DATE;
DECLARE vAddress INT;
DECLARE vAgencyMode INT;
SELECT date_send, address_id, agency_id
INTO vDate, vAddress, vAgencyMode
FROM `order`
WHERE id = vSelf;
CALL vn.catalog_calcFromItem(vDate, vAddress, vAgencyMode, vItem);
END$$
DELIMITER ;

View File

@ -1,35 +0,0 @@
DROP procedure IF EXISTS `hedera`.`order_calcCatalogFull`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`order_calcCatalogFull`(vSelf INT)
BEGIN
/**
* Gets the availability and prices for the given items
* using the order parameters.
*
* @param vSelf The order id
* @table tmp.item(itemFk)
* @return tmp.ticketCalculateItem
* @return tmp.ticketComponentPrice
* @return tmp.ticketComponent
* @return tmp.ticketLot
* @return tmp.zoneGetShipped
*/
DECLARE vDate DATE;
DECLARE vAddress INT;
DECLARE vAgencyMode INT;
SELECT date_send, address_id, agency_id
INTO vDate, vAddress, vAgencyMode
FROM `order`
WHERE id = vSelf;
CALL vn.ticketCalculate(vDate, vAddress, vAgencyMode);
IF account.myUserGetName() = 'visitor'
THEN
DROP TEMPORARY TABLE tmp.ticketComponent;
UPDATE tmp.ticketCalculateItem SET price = NULL;
END IF;
END$$
DELIMITER ;

View File

@ -1,34 +0,0 @@
DROP procedure IF EXISTS `hedera`.`order_getAvailable`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`order_getAvailable`(vSelf INT)
BEGIN
/**
* Gets the available items list.
*
* @param vSelf The order id
* @table tmp.itemAvailable
*/
DECLARE vDelivery DATE;
DECLARE vAddress INT;
DECLARE vAgencyMode INT;
SELECT date_send, address_id, agency_id
INTO vDelivery, vAddress, vAgencyMode
FROM `order`
WHERE id = vSelf;
CALL vn.available_calc(vDelivery, vAddress, vAgencyMode);
DROP TEMPORARY TABLE IF EXISTS tmp.itemAvailable;
CREATE TEMPORARY TABLE tmp.itemAvailable
(INDEX (id))
ENGINE = MEMORY
SELECT DISTINCT a.item_id id
FROM `cache`.available a
JOIN tmp.availableCalc c ON c.calcFk = a.calc_id
WHERE a.available > 0;
DROP TEMPORARY TABLE tmp.availableCalc;
END$$
DELIMITER ;

View File

@ -1,71 +0,0 @@
DROP procedure IF EXISTS `hedera`.`order_update`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`order_update`(vSelf INT)
proc: BEGIN
/**
* Actualiza las líneas de un pedido.
*
* @param vSelf Id del pedido
*/
DECLARE vDate DATE;
DECLARE vAddress INT;
DECLARE vAgencyMode INT;
DECLARE vNRows INT;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
SELECT COUNT(*) INTO vNRows
FROM orderRow WHERE orderFk = vSelf;
IF vNRows > 0
THEN
CALL order_calcCatalog(vSelf);
DELETE c
FROM orderRow r
JOIN orderRowComponent c ON c.rowFk = r.id
WHERE r.orderFk = vSelf;
UPDATE orderRow r
LEFT JOIN tmp.ticketComponentPrice p
ON p.warehouseFk = r.warehouseFk
AND p.itemFk = r.itemFk
AND p.rate = r.rate
LEFT JOIN tmp.zoneGetShipped t
ON t.warehouseFk = r.warehouseFk
SET
r.price = p.price,
r.amount = IF(p.itemFk IS NOT NULL,
r.amount + IF(@m := MOD(r.amount, p.`grouping`), p.`grouping` - @m, 0), 0),
r.shipment = t.shipped
WHERE r.orderFk = vSelf;
INSERT INTO orderRowComponent(rowFk, componentFk, price)
SELECT r.id, c.componentFk, c.cost
FROM orderRow r
JOIN tmp.ticketComponent c
ON c.warehouseFk = r.warehouseFk
AND c.itemFk = r.itemFk
JOIN vn.component t
ON t.id = c.componentFk
AND (t.classRate IS NULL OR t.classRate = r.rate)
WHERE r.orderFk = vSelf;
CALL vn.ticketCalculatePurge;
END IF;
UPDATE `order` SET date_make = NOW()
WHERE id = vSelf;
COMMIT;
END$$
DELIMITER ;

View File

@ -1 +0,0 @@
RENAME TABLE hedera.myOrderMyTicket TO hedera.myOrderTicket;

View File

@ -1,10 +0,0 @@
GRANT EXECUTE ON PROCEDURE vn.zoneGetAgency TO `account`@`%`;
GRANT EXECUTE ON PROCEDURE hedera.myBasket_calcCatalogFromItem TO `guest`@`%`;
GRANT EXECUTE ON PROCEDURE hedera.myBasket_calcCatalogFull TO `guest`@`%`;
GRANT EXECUTE ON PROCEDURE hedera.myBasket_getAvailable TO `guest`@`%`;
GRANT EXECUTE ON PROCEDURE hedera.myOrder_getAvailable TO `guest`@`%`;
GRANT EXECUTE ON PROCEDURE hedera.catalog_calcFromMyAddress TO account@'%';
REVOKE SELECT ON TABLE hedera.myOrderMyTicket FROM account@'%';
GRANT SELECT ON TABLE hedera.myOrderTicket TO account@'%';
CALL account.privSync;

View File

@ -0,0 +1,139 @@
DROP procedure IF EXISTS `vn`.`ticketGetProblems`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticketGetProblems`()
BEGIN
DECLARE vWarehouse INT;
DECLARE vDate DATE;
DECLARE vAvailableCache INT;
DECLARE vVisibleCache INT;
DECLARE vDone INT DEFAULT 0;
DECLARE vCursor CURSOR FOR
SELECT DISTINCT tt.warehouseFk, date(tt.shipped)
FROM tmp.ticketGetProblems tt
WHERE DATE(tt.shipped) BETWEEN CURDATE()
AND TIMESTAMPADD(DAY, 1.9, CURDATE());
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketProblems;
CREATE TEMPORARY TABLE tmp.ticketProblems (
ticketFk INT(11) PRIMARY KEY,
isFreezed INTEGER(1) DEFAULT 0,
risk DECIMAL(10,2) DEFAULT 0,
hasTicketRequest INTEGER(1) DEFAULT 0,
isAvailable INTEGER(1) DEFAULT 1
) ENGINE = MEMORY;
DROP TEMPORARY TABLE IF EXISTS tmp.ticketList;
CREATE TEMPORARY TABLE tmp.ticketList
(PRIMARY KEY (ticketFk))
ENGINE = MEMORY
SELECT tp.ticketFk, c.id clientFk
FROM tmp.ticketGetProblems tp
JOIN vn.client c ON c.id = tp.clientFk;
INSERT INTO tmp.ticketProblems(ticketFk, isFreezed)
SELECT DISTINCT tl.ticketFk, 1
FROM tmp.ticketList tl
JOIN vn.client c ON c.id = tl.clientFk
WHERE c.isFreezed;
DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt;
CREATE TEMPORARY TABLE tmp.clientGetDebt
(PRIMARY KEY (clientFk))
ENGINE = MEMORY
SELECT DISTINCT clientFk
FROM tmp.ticketList;
CALL clientGetDebt(CURDATE());
INSERT INTO tmp.ticketProblems(ticketFk, risk)
SELECT DISTINCT tl.ticketFk, r.risk
FROM tmp.ticketList tl
JOIN vn.ticket t ON t.id = tl.ticketFk
JOIN vn.agencyMode a ON t.agencyModeFk = a.id
JOIN tmp.risk r ON r.clientFk = t.clientFk
JOIN vn.client c ON c.id = t.clientFk
WHERE r.risk > c.credit + 10
AND a.deliveryMethodFk != 3
ON DUPLICATE KEY UPDATE
risk = r.risk;
INSERT INTO tmp.ticketProblems(ticketFk, hasTicketRequest)
SELECT DISTINCT tl.ticketFk, 1
FROM tmp.ticketList tl
JOIN vn.ticketRequest tr ON tr.ticketFk = tl.ticketFk
WHERE tr.isOK IS NULL
ON DUPLICATE KEY UPDATE
hasTicketRequest = 1;
OPEN vCursor;
WHILE NOT vDone
DO
FETCH vCursor INTO vWarehouse, vDate;
CALL cache.visible_refresh(vVisibleCache, FALSE, vWarehouse);
CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouse, vDate);
INSERT INTO tmp.ticketProblems(ticketFk, isAvailable)
SELECT tl.ticketFk, 0
FROM tmp.ticketList tl
JOIN vn.ticket t ON t.id = tl.ticketFk
LEFT JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk
JOIN vn.itemType it on it.id = i.typeFk
LEFT JOIN cache.available av ON av.item_id = i.id
AND av.calc_id = vAvailableCache
WHERE date(t.shipped) = vDate
AND categoryFk != 6
AND IFNULL(av.available, 0) < 0
AND s.isPicked = FALSE
AND NOT i.generic
AND vWarehouse = t.warehouseFk
GROUP BY tl.ticketFk
ON DUPLICATE KEY UPDATE
isAvailable = 0;
INSERT INTO tmp.ticketProblems(ticketFk, isAvailable)
SELECT tl.ticketFk, 0
FROM tmp.ticketList tl
JOIN vn.ticket t ON t.id = tl.ticketFk
LEFT JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk
JOIN vn.itemType it on it.id = i.typeFk
LEFT JOIN cache.visible v ON i.id = v.item_id AND v.calc_id = vVisibleCache
LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache
WHERE IFNULL(av.available, 0) >= 0
AND s.quantity > IFNULL(v.visible, 0)
AND s.isPicked = FALSE
AND s.reserved = FALSE
AND it.categoryFk != 6
AND date(t.shipped) = vDate
AND NOT i.generic
AND CURDATE() = vDate
AND t.warehouseFk = vWarehouse
GROUP BY tl.ticketFk
ON DUPLICATE KEY UPDATE
isAvailable = 0;
END WHILE;
CLOSE vCursor;
SELECT * FROM tmp.ticketProblems;
DROP TEMPORARY TABLE
tmp.clientGetDebt,
tmp.ticketList;
END$$
DELIMITER ;

View File

@ -0,0 +1,3 @@
ALTER TABLE `vn`.`zoneCalendar`
ADD COLUMN `price` DOUBLE NOT NULL AFTER `delivered`,
ADD COLUMN `bonus` DOUBLE NOT NULL AFTER `price`;

View File

@ -190,7 +190,7 @@ INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city
(102, 'Petter Parker', '87945234L', 'Spider-Man', 'Aunt May', '20 Ingram Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'PetterParker@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1),
(103, 'Clark Kent', '06815934E', 'Super-Man', 'lois lane', '344 Clinton Street', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'ClarkKent@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 0, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1),
(104, 'Tony Stark', '06089160W', 'Iron-Man', 'Pepper Potts', '10880 Malibu Point', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'TonyStark@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1),
(105, 'Max Eisenhardt', '251628698', 'Magneto', 'Rogue', 'Unknown Whereabouts', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'MaxEisenhardt@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, NULL, 0, 1),
(105, 'Max Eisenhardt', '251628698', 'Magneto', 'Rogue', 'Unknown Whereabouts', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'MaxEisenhardt@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 18, 0, 1),
(106, 'DavidCharlesHaller', '53136686Q', 'Legion', 'Charles Xavier', 'Evil hideout', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'DavidCharlesHaller@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 1, 0, NULL, 0, 0, 19, 0, 1),
(107, 'Hank Pym', '09854837G', 'Ant-Man', 'Hawk', 'Anthill', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'HankPym@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 0, 0, NULL, 0, 0, 19, 0, 1),
(108, 'Charles Xavier', '22641921P', 'Professor X', 'Beast', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1),
@ -352,7 +352,7 @@ INSERT INTO `vn`.`creditInsurance`(`id`, `creditClassification`, `credit`, `crea
INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agencyModeFk`, `description`, `m3`, `cost`, `started`, `finished`)
VALUES
(1, '1899-12-30 12:15:00', 56, CURDATE(), 1, 7, 'first route', 0.1, 10, CURDATE(), CURDATE()),
(1, '1899-12-30 12:15:00', 56, CURDATE(), 1, 7, 'first route', 0.3, 10, CURDATE(), CURDATE()),
(2, '1899-12-30 13:20:00', 56, CURDATE(), 1, 7, 'second route', 0.1, 20, CURDATE(), CURDATE()),
(3, '1899-12-30 14:30:00', 56, CURDATE(), 2, 7, 'third route', 0.1, 30, CURDATE(), CURDATE()),
(4, '1899-12-30 15:45:00', 56, CURDATE(), 3, 7, 'fourth route', 0.1, 40, CURDATE(), CURDATE()),
@ -425,8 +425,8 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF
VALUES
(1 , 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Bat cave', 121, 'T1111111', 0, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(2 , 1, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T1111111', 0, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(3 , 1, 2, 2, 1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T2222222', 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
(4 , 3, 2, 2, 1, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T3333333', 0, DATE_ADD(CURDATE(), INTERVAL -3 MONTH)),
(3 , 1, 2, 1, 1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T2222222', 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
(4 , 3, 2, 1, 1, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T3333333', 0, DATE_ADD(CURDATE(), INTERVAL -3 MONTH)),
(5 , 3, 3, 3, 1, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T4444444', 0, DATE_ADD(CURDATE(), INTERVAL -4 MONTH)),
(6 , 1, 3, 3, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Mountain Drive Gotham', 1, 'A1111111', 0, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(7 , NULL, 7, 1, 2, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Mountain Drive Gotham', 1, NULL, 0, CURDATE()),
@ -435,8 +435,8 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF
(10, 1, 1, 5, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'Ingram Street', 2, NULL, 0, CURDATE()),
(11, 1, 7, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'NY roofs', 122, NULL, 0, CURDATE()),
(12, 1, 1, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, CURDATE()),
(13, 1, 1, 2, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, CURDATE()),
(14, 1, 2, 2, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Malibu Point', 4, NULL, 0, CURDATE()),
(13, 1, 1, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, CURDATE()),
(14, 1, 2, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Malibu Point', 4, NULL, 0, CURDATE()),
(15, 1, 7, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 105, 'Plastic Cell', 125, NULL, 0, CURDATE()),
(16, 1, 7, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, CURDATE()),
(17, 1, 7, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, CURDATE()),
@ -1027,15 +1027,20 @@ INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseO
(1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 2, 1, 100.00, 1000),
(2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 150, 2000),
(3, CURDATE(), CURDATE(), 1, 2, 1, 0.00, 0.00),
(4, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 50.00, 500);
(4, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 50.00, 500),
(5, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 2, 1, 50.00, 500),
(6, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 2, 1, 50.00, 500),
(7, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 2, 1, 50.00, 500);
INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `companyFk`,`ref`)
VALUES
(1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 442, 'Movimiento 1'),
(2, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 442, 'Movimiento 2'),
(3, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 442, 'Movimiento 3'),
(4, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 69, 'Movimiento 4');
(4, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 69, 'Movimiento 4'),
(5, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 442, 'Movimiento 5'),
(6, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 6, 442, 'Movimiento 6'),
(7, 2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 7, 442, 'Movimiento 7');
INSERT INTO `bi`.`claims_ratio`(`id_Cliente`, `Consumo`, `Reclamaciones`, `Ratio`, `recobro`, `inflacion`)
VALUES
@ -1046,14 +1051,21 @@ INSERT INTO `bi`.`claims_ratio`(`id_Cliente`, `Consumo`, `Reclamaciones`, `Ratio
INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`,`minPrice`,`producer`,`printedStickers`,`isChecked`,`isIgnored`, `created`)
VALUES
(1, 1, 1, 2.5, 5000, 1, 1, 0.350, 0.050, 0.000, 10, 10, 1, NULL, 0.00, 1.30, 1.25, 1.00, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
(2, 2, 1, 20 , 100, 1, 1, 0.700, 0.020, 0.000, 5, 5, 1, NULL, 0.00, 2.50, 2.00, 0.50, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(3, 3, 1, 20 , 100, 1, 1, 0.700, 0.020, 0.000, 1, 1, 0, NULL, 0.00, 2.50, 2.00, 0.50, NULL, 0, 1, 0, CURDATE()),
(4, 2, 2, 5 , 450, 1, 1, 0.500, 0.100, 0.000, 10, 10, 0, NULL, 0.00, 1.30, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(5, 3, 3, 10 , 500, 1, 1, 1.000, 0.050, 0.000, 10, 10, 0, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(6, 4, 8, 20 , 1000, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(7, 4, 9, 20 , 1000, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(8, 4, 4, 20 , 1000, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE());
(1, 1, 1, 2.5, 5000, 1, 1, 0.350, 0.050, 0.000, 10, 10, 1, NULL, 0.00, 1.30, 1.25, 1.00, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
(2, 2, 1, 20, 100, 1, 1, 0.700, 0.020, 0.000, 5, 5, 1, NULL, 0.00, 2.50, 2.00, 0.50, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
(3, 3, 1, 20, 100, 1, 1, 0.700, 0.020, 0.000, 1, 1, 0, NULL, 0.00, 2.50, 2.00, 0.50, NULL, 0, 1, 0, CURDATE()),
(4, 2, 2, 5, 450, 1, 1, 0.500, 0.100, 0.000, 10, 10, 0, NULL, 0.00, 1.30, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(5, 3, 3, 10, 500, 1, 1, 1.000, 0.050, 0.000, 10, 10, 0, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(6, 4, 8, 20, 1000, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(7, 4, 9, 20, 1000, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(8, 4, 4, 20, 1000, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(9, 4, 4, 20, 1000, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(10, 5, 1, 2, 10, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(11, 5, 4, 3, 10, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(12, 6, 4, 2, 1000, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(13, 7, 1, 2, 1000, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(14, 7, 2, 5, 1000, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE()),
(15, 7, 4, 1, 1000, 1, 1, 0.700, 0.020, 0.000, 10, 10, 1, NULL, 0.00, 2.50, 1.00, 0.00, NULL, 0, 1, 0, CURDATE());
INSERT INTO `vn2008`.`tblContadores`(`id`,`FechaInventario`)
VALUES

View File

@ -385,6 +385,7 @@ describe('Worker time control path', () => {
it('should Hank Pym check his hours are alright', async() => {
const wholeWeekHours = await nightmare
.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '56:00 Hours')
.waitToGetProperty(selectors.workerTimeControl.weekWorkedHours, 'innerText');
expect(wholeWeekHours).toEqual('56:00 Hours');

View File

@ -26,37 +26,55 @@
<vn-vertical class="body">
<vn-horizontal class="weekdays">
<section class="day" ng-click="$ctrl.selectAll(1)">
<section title="{{'Monday' | translate}}"
ng-click="$ctrl.selectAll(1)">
<span>L</span>
</section>
<section class="day" ng-click="$ctrl.selectAll(2)">
<section title="{{'Tuesday' | translate}}"
ng-click="$ctrl.selectAll(2)">
<span>M</span>
</section>
<section class="day" ng-click="$ctrl.selectAll(3)">
<section title="{{'Wednesday' | translate}}"
ng-click="$ctrl.selectAll(3)">
<span>X</span>
</section>
<section class="day" ng-click="$ctrl.selectAll(4)">
<section title="{{'Thursday' | translate}}"
ng-click="$ctrl.selectAll(4)">
<span>J</span>
</section>
<section class="day" ng-click="$ctrl.selectAll(5)">
<section title="{{'Friday' | translate}}"
ng-click="$ctrl.selectAll(5)">
<span>V</span>
</section>
<section class="day" ng-click="$ctrl.selectAll(6)">
<section title="{{'Saturday' | translate}}"
ng-click="$ctrl.selectAll(6)">
<span>S</span>
</section>
<section class="day" ng-click="$ctrl.selectAll(0)">
<section title="{{'Sunday' | translate}}"
ng-click="$ctrl.selectAll(0)">
<span>D</span>
</section>
</vn-horizontal>
<vn-horizontal class="days">
<section ng-repeat="day in $ctrl.days" class="day {{day.event.className || day.className}}"
ng-click="$ctrl.select($index)"
ng-style="{'color': day.event.style.color}">
<span ng-if="day.event" vn-tooltip="{{day.event.title}}"
ng-style="{'background-color': day.event.style.background}">
{{::day.dated | date: 'd'}}
</span>
<span ng-if="!day.event">{{::day.dated | date: 'd'}}</span>
<section ng-repeat="day in $ctrl.days" class="day"
ng-class="{'primary': day.events.length > 0}">
<div class="content">
<div class="day-number"
title="{{(day.events[0].description || day.events[0].name) | translate}}"
ng-style="$ctrl.renderStyle(day.style || day.events[0].style)"
ng-click="$ctrl.select($index)">
{{::day.dated | date: 'd'}}
</div>
<div ng-if="day.events" class="events">
<div ng-repeat="event in day.events" class="event"
title="{{(event.description || event.name) | translate}}">
<span class="chip ellipsize"
ng-style="::$ctrl.renderStyle(event.style)">
{{::event.name}}
</span>
</div>
</div>
</div>
</section>
</vn-horizontal>
</vn-vertical>

View File

@ -13,6 +13,23 @@ export default class Calendar extends Component {
this.defaultDate = new Date();
this.displayControls = true;
this.skip = 1;
this.window.addEventListener('resize', () => {
this.checkSize();
});
}
/**
* Resizes the calendar
* based on component height
*/
checkSize() {
const height = this.$element[0].clientHeight;
if (height < 530)
this.$element.addClass('small');
else
this.$element.removeClass('small');
}
/**
@ -49,8 +66,10 @@ export default class Calendar extends Component {
this.addEvent(event);
});
if (value.length && this.defaultDate)
if (value.length && this.defaultDate) {
this.repaint();
this.checkSize();
}
}
/**
@ -165,16 +184,28 @@ export default class Calendar extends Component {
* @param {Date} dated - Date of month
* @param {String} className - Default class style
*/
insertDay(dated, className = '') {
let event = this.events.find(event => {
insertDay(dated) {
let events = this.events.filter(event => {
return event.dated >= dated && event.dated <= dated;
});
// Weeekends
if (dated.getMonth() === this.currentMonth.getMonth() && dated.getDay() == 0)
className = 'red';
const params = {dated, events};
this.days.push({dated, className, event});
const isSaturday = dated.getDay() === 6;
const isSunday = dated.getDay() === 0;
const isCurrentMonth = dated.getMonth() === this.currentMonth.getMonth();
const hasEvents = events.length > 0;
if (isCurrentMonth && isSunday && !hasEvents)
params.style = {color: '#f42121'};
if (isCurrentMonth && isSaturday && !hasEvents)
params.style = {color: '#666666'};
if (!isCurrentMonth && !hasEvents)
params.style = {color: '#9b9b9b'};
this.days.push(params);
}
/**
@ -182,7 +213,7 @@ export default class Calendar extends Component {
*
* @param {Object} options - Event params
* @param {Date} options.dated - Day to add event
* @param {String} options.title - Tooltip description
* @param {String} options.name - Tooltip description
* @param {String} options.className - ClassName style
* @param {Object} options.style - Style properties
* @param {Boolean} options.isRemovable - True if is removable by users
@ -194,12 +225,7 @@ export default class Calendar extends Component {
options.dated = new Date(options.dated);
options.dated.setHours(0, 0, 0, 0);
const event = this.events.findIndex(event => {
return event.dated >= options.dated && event.dated <= options.dated;
});
if (event < 0)
this.events.push(options);
this.events.push(options);
}
/**
@ -274,6 +300,16 @@ export default class Calendar extends Component {
}
this.emit('selection', {values: selected});
}
renderStyle(style) {
if (style) {
return {
'background-color': style.backgroundColor,
'font-weight': style.fontWeight,
'color': style.color
};
}
}
}
Calendar.$inject = ['$element', '$scope'];

View File

@ -20,8 +20,8 @@ describe('Component vnCalendar', () => {
let currentDate = new Date().toString();
controller.data = [
{dated: currentDate, title: 'Event 1'},
{dated: currentDate, title: 'Event 2'},
{dated: currentDate, name: 'Event 1'},
{dated: currentDate, name: 'Event 2'},
];
expect(controller.events[0].dated instanceof Object).toBeTruthy();
@ -34,12 +34,11 @@ describe('Component vnCalendar', () => {
controller.events = [];
controller.addEvent({
dated: new Date(),
title: 'My event',
className: 'color'
name: 'My event'
});
const firstEvent = controller.events[0];
expect(firstEvent.title).toEqual('My event');
expect(firstEvent.name).toEqual('My event');
expect(firstEvent.isRemovable).toBeDefined();
expect(firstEvent.isRemovable).toBeTruthy();
});
@ -50,19 +49,17 @@ describe('Component vnCalendar', () => {
controller.events = [{
dated: curDate,
title: 'My event 1',
className: 'color'
name: 'My event 1'
}];
controller.addEvent({
dated: curDate,
title: 'My event 2',
className: 'color'
name: 'My event 2'
});
const firstEvent = controller.events[0];
expect(controller.events.length).toEqual(1);
expect(firstEvent.title).toEqual('My event 1');
expect(controller.events.length).toEqual(2);
expect(firstEvent.name).toEqual('My event 1');
});
});
@ -71,7 +68,7 @@ describe('Component vnCalendar', () => {
const curDate = new Date();
controller._events = [{
dated: curDate,
title: 'My event 1',
name: 'My event 1',
className: 'color'
}];
controller.removeEvent(curDate);

View File

@ -1,143 +1,123 @@
@import "variables";
vn-calendar.small {
.events {
display: none
}
}
vn-calendar {
display: block;
max-width: 250px;
.header vn-one {
text-align: center;
padding: 0.2em 0
padding: 0.2em 0;
height: 1.5em
}
.body {
.days {
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
.weekdays {
color: $color-font-secondary;
margin-bottom: 0.5em;
padding: 0.5em 0;
font-weight: bold;
font-size: 0.8em;
}
.weekdays section {
cursor: pointer
}
.weekdays section, .day {
position: relative;
text-align: center;
box-sizing: border-box;
width: 14.28%;
outline: 0;
}
.days {
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
}
.day {
.content {
position: absolute;
bottom: 0;
right: 0;
left: 0;
top: 0
}
.weekdays {
border-bottom: 1px solid $color-hover-cd;
border-top: 1px solid $color-hover-cd;
color: $color-font-secondary;
font-weight: bold
.day-number {
transition: background-color 0.3s;
text-align:center;
float:inline-end;
margin: 0 auto;
border-radius: 50%;
font-size: 0.85em;
width:2.2em;
height: 1.2em;
padding: 0.5em 0;
cursor: pointer;
outline: 0
}
.day {
box-sizing: border-box;
padding: 0.1em;
width: 14.2857143%;
line-height: 1.5em;
outline: 0;
span {
transition: background-color 0.3s;
text-align: center;
font-size: .8em;
border-radius: 50%;
display: block;
padding: 0.2em;
cursor: pointer
}
.day-number:hover {
background-color: lighten($color-font-secondary, 20%);
opacity: 0.8
}
}
.day:hover span {
background-color: #DDD
.day::after {
content: "";
display: block;
padding-top: 100%;
}
.day.primary .day-number {
background-color: $color-main;
color: $color-font-bg;
}
.events {
margin-top: 0.5em;
font-size: 0.6em
}
.events {
color: $color-font-secondary;
.event {
margin-bottom: .1em;
}
}
.day.gray {
.chip {
background-color: $color-main;
color: $color-font-bg;
display: inline-block;
border-radius: .3em;
padding: 0.3em .8em;
max-width: 5em;
}
.day.gray {
.day-number {
color: $color-font-secondary
}
}
.day.orange {
font-weight: bold;
color: $color-main;
}
.day.orange-circle {
color: $color-font;
& > span {
background-color: $color-main
}
}
.day.orange-circle:hover {
& > span {
background-color: $color-main-medium
}
}
.day.light-orange {
color: $color-main-medium
}
.day.green {
font-weight: bold;
color: $color-success;
}
.day.green-circle {
color: $color-font;
& > span {
background-color: $color-success
}
}
.day.green-circle:hover {
& > span {
background-color: $color-success-medium
}
}
.day.light-green {
font-weight: bold;
color: $color-success-medium
}
.day.blue {
font-weight: bold;
color: $color-notice;
}
.day.blue-circle {
color: $color-font;
& > span {
background-color: $color-notice
}
}
.day.blue-circle:hover {
& > span {
background-color: $color-notice-medium
}
}
.day.light-blue {
font-weight: bold;
color: $color-notice-medium
}
.day.red {
font-weight: bold;
color: $color-alert
}
.day.red-circle {
color: $color-font;
& > span {
background-color: $color-alert
}
}
.day.red-circle:hover {
& > span {
background-color: $color-alert-medium
}
}
.day.light-red {
font-weight: bold;
color: $color-alert-medium;
.day.sunday {
.day-number {
color: $color-alert;
font-weight: bold
}
}
}

View File

@ -45,8 +45,7 @@ export default class Dialog extends Component {
this.element.style.display = 'flex';
this.transitionTimeout = setTimeout(() => this.$element.addClass('shown'), 30);
if (this.onOpen)
this.onOpen();
this.emit('open');
}
/**
@ -55,6 +54,7 @@ export default class Dialog extends Component {
hide() {
this.fireResponse();
this.realHide();
this.emit('close');
}
/**
@ -120,7 +120,6 @@ ngModule.component('vnDialog', {
buttons: '?tplButtons'
},
bindings: {
onOpen: '&?',
onResponse: '&?'
},
controller: Dialog

View File

@ -7,7 +7,7 @@ describe('Component vnDialog', () => {
beforeEach(angular.mock.inject($componentController => {
$element = angular.element('<vn-dialog></vn-dialog>');
controller = $componentController('vnDialog', {$element, $transclude: null});
controller.onOpen = jasmine.createSpy('onOpen');
controller.emit = jasmine.createSpy('emit');
}));
describe('show()', () => {
@ -17,15 +17,15 @@ describe('Component vnDialog', () => {
controller.show();
expect(controller.element.style.display).toEqual('none');
expect(controller.onOpen).not.toHaveBeenCalledWith();
expect(controller.emit).not.toHaveBeenCalledWith('open');
});
it(`should set shown on the controller, set style.display on the element and call onOpen()`, () => {
it(`should set shown on the controller, set style.display on the element and emit onOpen() event`, () => {
controller.show();
expect(controller.element.style.display).toEqual('flex');
expect(controller.shown).toBeTruthy();
expect(controller.onOpen).toHaveBeenCalledWith();
expect(controller.emit).toHaveBeenCalledWith('open');
});
});

View File

@ -20,7 +20,7 @@ import './multi-check/multi-check';
import './date-picker/date-picker';
import './button/button';
import './check/check';
import './radio/radio';
import './radio-group/radio-group';
import './textarea/textarea';
import './icon-button/icon-button';
import './submit/submit';

View File

@ -22,7 +22,10 @@
ng-focus="$ctrl.hasFocus = true"
ng-blur="$ctrl.hasFocus = false"
tabindex="{{$ctrl.input.tabindex}}"/>
<label class="label" translate>{{::$ctrl.label}}</label>
<label class="label">
<span translate>{{::$ctrl.label}}</span>
<span translate ng-show="::$ctrl.required">*</span>
</label>
</div>
<div class="underline"></div>
<div class="selected underline"></div>

View File

@ -192,6 +192,7 @@ ngModule.component('vnInputNumber', {
label: '@?',
name: '@?',
disabled: '<?',
required: '@?',
min: '<?',
max: '<?',
step: '<?',

View File

@ -0,0 +1,8 @@
<md-radio-group ng-model="$ctrl.model">
<md-radio-button aria-label="::option.label"
ng-repeat="option in $ctrl.options"
ng-value="option.value"
ng-disabled="$ctrl.disabled">
<span translate>{{::option.label}}</span>
</md-radio-button>
</md-radio-group>

View File

@ -0,0 +1,41 @@
import ngModule from '../../module';
import Component from '../../lib/component';
import './style.scss';
export default class Controller extends Component {
constructor($element, $scope, $attrs) {
super($element, $scope);
this.hasInfo = Boolean($attrs.info);
this.info = $attrs.info || null;
}
get model() {
return this._model;
}
set model(value) {
this._model = value;
}
get field() {
return this._model;
}
set field(value) {
this._model = value;
}
}
Controller.$inject = ['$element', '$scope', '$attrs'];
ngModule.component('vnRadioGroup', {
template: require('./radio-group.html'),
controller: Controller,
bindings: {
field: '=?',
options: '<?',
disabled: '<?',
checked: '<?'
}
});

View File

@ -0,0 +1,11 @@
@import "variables";
md-radio-group md-radio-button.md-checked .md-container {
.md-on {
background-color: $color-main
}
.md-off {
border-color: $color-main
}
}

View File

@ -1,7 +0,0 @@
<input
type="radio"
class="*[className]*"
name="*[name]*"
ng-model="*[model]*.*[name]*"
*[enabled]*>
<span class="mdl-radio__label" translate>*[text]*</span>

View File

@ -1,15 +0,0 @@
import ngModule from '../../module';
import template from './radio.html';
directive.$inject = ['vnTemplate'];
export default function directive(vnTemplate) {
return {
restrict: 'E',
template: (_, $attrs) =>
vnTemplate.get(template, $attrs, {
enabled: 'true',
className: 'mdl-radio mdl-js-radio mdl-js-ripple-effect'
})
};
}
ngModule.directive('vnRadio', directive);

View File

@ -16,7 +16,7 @@
tabindex="{{$ctrl.input.tabindex}}"/>
<label class="label">
<span translate>{{::$ctrl.label}}</span>
<span translate ng-show="::$ctrl.required">(*)</span>
<span translate vn-tooltip="Required" ng-show="::$ctrl.required">*</span>
</label>
</div>
<div class="underline"></div>

View File

@ -52,6 +52,8 @@ $color-hover-cd: rgba(0, 0, 0, .1);
$color-hover-dc: .7;
$color-disabled: .6;
$color-font-link-medium: lighten($color-font-link, 20%);
$color-font-link-light: lighten($color-font-link, 35%);
$color-main-medium: lighten($color-main, 20%);
$color-main-light: lighten($color-main, 35%);
$color-success-medium: lighten($color-success, 20%);

View File

@ -0,0 +1,81 @@
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
module.exports = Self => {
Self.remoteMethod('editPrices', {
description: 'Changes the price and bonus of a delivery day',
accessType: 'WRITE',
accepts: [{
arg: 'id',
type: 'Number',
description: 'The zone id',
http: {source: 'path'}
},
{
arg: 'delivered',
type: 'Date',
required: true,
},
{
arg: 'price',
type: 'Number',
required: true,
},
{
arg: 'bonus',
type: 'Number',
required: true,
},
{
arg: 'option',
type: 'String',
required: true,
}],
returns: {
type: 'object',
root: true
},
http: {
path: `/:id/editPrices`,
verb: 'POST'
}
});
Self.editPrices = async(id, delivered, price, bonus, option) => {
const models = Self.app.models;
let filter = {
where: {
zoneFk: id
}
};
let where;
let shouldPropagate = true;
if (option == 'Only this day') {
shouldPropagate = false;
where = {delivered};
} else if (option == 'From this day') {
where = {
delivered: {
gte: delivered
}
};
}
filter = mergeFilters(filter, {where});
const days = await models.ZoneCalendar.find(filter);
const areAllFromSameZone = days.every(day => day.zoneFk === id);
if (!areAllFromSameZone)
throw new UserError('All delivery days must belong to the same zone');
if (shouldPropagate) {
const zone = await models.Zone.findById(id);
zone.updateAttributes({price, bonus});
}
return models.ZoneCalendar.updateAll(filter.where, {price, bonus});
};
};

View File

@ -0,0 +1,84 @@
const app = require('vn-loopback/server/server');
describe('agency editPrices()', () => {
const zoneId = 1;
let originalZone;
beforeAll(async done => {
originalZone = await app.models.Zone.findById(zoneId);
done();
});
afterAll(async done => {
await await app.models.ZoneCalendar.updateAll({zoneFk: zoneId}, {
price: originalZone.price,
bonus: originalZone.bonus
});
done();
});
it('should apply price and bonus for a selected day', async() => {
const delivered = new Date();
delivered.setHours(0, 0, 0, 0);
delivered.setDate(delivered.getDate() + 1);
await app.models.Zone.editPrices(zoneId, delivered, 4.00, 2.00, 'Only this day');
const editedDays = await app.models.ZoneCalendar.find({
where: {
zoneFk: zoneId,
delivered: delivered
}
});
const firstEditedDay = editedDays[0];
expect(editedDays.length).toEqual(1);
expect(firstEditedDay.price).toEqual(4.00);
expect(firstEditedDay.bonus).toEqual(2.00);
});
it('should apply price and bonus for all delivery days starting from selected day', async() => {
const delivered = new Date();
delivered.setHours(0, 0, 0, 0);
delivered.setDate(delivered.getDate() + 1);
await app.models.Zone.editPrices(1, delivered, 5.50, 1.00, 'From this day');
const editedDays = await app.models.ZoneCalendar.find({
where: {
zoneFk: zoneId,
delivered: {
gte: delivered
}
}
});
const firstEditedDay = editedDays[0];
const lastEditedDay = editedDays[editedDays.length - 1];
expect(editedDays.length).toEqual(4);
expect(firstEditedDay.price).toEqual(5.50);
expect(firstEditedDay.bonus).toEqual(1.00);
expect(lastEditedDay.price).toEqual(5.50);
expect(lastEditedDay.bonus).toEqual(1.00);
});
it('should apply price and bonus for all delivery days', async() => {
const delivered = new Date();
delivered.setHours(0, 0, 0, 0);
delivered.setDate(delivered.getDate() + 1);
await app.models.Zone.editPrices(1, delivered, 7.00, 0.00, 'All days');
const editedDays = await app.models.ZoneCalendar.find({
where: {
zoneFk: zoneId
}
});
const firstEditedDay = editedDays[0];
const lastEditedDay = editedDays[editedDays.length - 1];
expect(editedDays.length).toEqual(5);
expect(firstEditedDay.price).toEqual(7.00);
expect(firstEditedDay.bonus).toEqual(0.00);
expect(lastEditedDay.price).toEqual(7.00);
expect(lastEditedDay.bonus).toEqual(0.00);
});
});

View File

@ -14,6 +14,12 @@
"delivered": {
"id": true,
"type": "Date"
},
"price": {
"type": "Number"
},
"bonus": {
"type": "Number"
}
},
"relations": {

View File

@ -1,5 +1,6 @@
module.exports = Self => {
require('../methods/zone/clone')(Self);
require('../methods/zone/editPrices')(Self);
Self.validatesPresenceOf('warehouseFk', {
message: `Warehouse cannot be blank`

View File

@ -1,21 +1,74 @@
<vn-crud-model
vn-id="model"
url="/agency/api/ZoneCalendars"
fields="['zoneFk', 'delivered']"
link="{zoneFk: $ctrl.$stateParams.id}"
data="$ctrl.data"
primary-key="zoneFk"
auto-load="true">
</vn-crud-model>
<vn-calendar pad-small vn-id="stMonth" skip="2"
data="$ctrl.events"
on-selection="$ctrl.onSelection(stMonth, values)"
on-move-next="$ctrl.onMoveNext(ndMonth)"
on-move-previous="$ctrl.onMovePrevious(ndMonth)">
</vn-calendar>
<vn-calendar pad-small vn-id="ndMonth" skip="2"
data="$ctrl.events"
display-controls="false"
on-selection="$ctrl.onSelection(ndMonth, values)"
default-date="$ctrl.ndMonthDate">
</vn-calendar>
<vn-watcher
vn-id="watcher"
data="$ctrl.selectedDay">
</vn-watcher>
<vn-card pad-large>
<vn-horizontal pad-medium style="justify-content: space-between;">
<vn-icon-button icon="keyboard_arrow_left"
ng-click="$ctrl.onMovePrevious([stMonth, ndMonth])"
vn-tooltip="Previous">
</vn-icon-button>
<vn-icon-button icon="keyboard_arrow_right"
ng-click="$ctrl.onMoveNext([stMonth, ndMonth])"
vn-tooltip="Next">
</vn-icon-button>
</vn-horizontal>
<vn-horizontal>
<vn-calendar vn-id="stMonth" vn-one pad-medium
data="$ctrl.events"
display-controls="false"
on-selection="$ctrl.onSelection(values)"
skip="2">
</vn-calendar>
<vn-calendar vn-id="ndMonth" vn-one pad-medium
data="$ctrl.events"
display-controls="false"
on-selection="$ctrl.onSelection(values)"
default-date="$ctrl.ndMonthDate"
skip="2">
</vn-calendar>
</vn-horizontal>
</vn-card>
<!-- Edit price dialog -->
<vn-dialog class="edit"
vn-id="priceDialog"
on-close="$ctrl.onClose()"
on-response="$ctrl.onResponse(response)">
<tpl-body>
<h5 pad-small-v translate>Edit price</h5>
<vn-horizontal>
<vn-input-number vn-one
label="Price"
model="$ctrl.selectedDay.price"
min="0" step="0.01"
required="true">
</vn-input-number>
<vn-input-number vn-one
label="Bonus"
model="$ctrl.selectedDay.bonus"
min="0" step="0.01"
required="true">
</vn-input-number>
</vn-horizontal>
<vn-horizontal>
<vn-radio-group vn-one
field="$ctrl.selectedDay.option"
options="$ctrl.options">
</vn-radio-group>
</vn-horizontal>
</tpl-body>
<tpl-buttons>
<input type="button" response="CANCEL" translate-attr="{value: 'Cancel'}"/>
<button response="ACCEPT" translate>Save</button>
</tpl-buttons>
</vn-dialog>

View File

@ -1,49 +1,26 @@
import ngModule from '../module';
import './style.scss';
class Controller {
constructor($element, $scope, $stateParams, $http) {
constructor($element, $scope, $http, $filter, $translate, $stateParams, vnApp) {
this.$element = $element;
this.$stateParams = $stateParams;
this.$scope = $scope;
this.$ = $scope;
this.$http = $http;
this.$filter = $filter;
this.$translate = $translate;
this.$stateParams = $stateParams;
this.vnApp = vnApp;
this.stMonthDate = new Date();
this.ndMonthDate = new Date();
this.ndMonthDate.setMonth(this.ndMonthDate.getMonth() + 1);
this.selectedDay = {};
}
$postLink() {
this.stMonth = this.$scope.stMonth;
this.ndMonth = this.$scope.ndMonth;
this.stMonth = this.$.stMonth;
this.ndMonth = this.$.ndMonth;
}
// Disabled until implementation
// of holidays by node
/* get zone() {
return this._zone;
}
set zone(value) {
this._zone = value;
if (!value) return;
let query = '/agency/api/LabourHolidays/getByWarehouse';
this.$http.get(query, {params: {warehouseFk: value.warehouseFk}}).then(res => {
if (!res.data) return;
const events = [];
res.data.forEach(holiday => {
events.push({
date: holiday.dated,
className: 'red',
title: holiday.description || holiday.name,
isRemovable: false
});
});
this.events = this.events.concat(events);
});
} */
get data() {
return this._data;
}
@ -52,97 +29,106 @@ class Controller {
this._data = value;
if (!value) return;
const events = [];
value.forEach(event => {
events.push({
name: `P: ${this.$filter('currency')(event.price)}`,
description: 'Price',
dated: event.delivered,
className: 'green-circle',
title: 'Has delivery'
style: {backgroundColor: '#a3d131'},
data: {price: event.price}
});
events.push({
name: `B: ${this.$filter('currency')(event.bonus)}`,
description: 'Bonus',
dated: event.delivered,
data: {bonus: event.bonus}
});
});
this.events = events;
}
onSelection(calendar, values) {
let totalEvents = 0;
values.forEach(day => {
const exists = calendar.events.findIndex(event => {
return event.dated >= day.dated && event.dated <= day.dated
&& event.isRemovable;
});
onSelection(values) {
if (values.length > 1) return false;
if (exists > -1) totalEvents++;
this.options = [
{label: 'Only this day', value: 'Only this day'},
{label: 'From this day', value: 'From this day'},
{label: 'All days', value: 'All days'}
];
const selection = values[0];
const events = selection.events;
const hasEvents = events.length > 0;
if (!hasEvents)
return this.vnApp.showMessage(this.$translate.instant(`There's no delivery for this day`));
this.selectedDay = {
delivered: selection.dated,
option: 'Only this day'
};
events.forEach(event => {
this.selectedDay = Object.assign(this.selectedDay, event.data);
});
if (totalEvents > (values.length / 2))
this.removeEvents(calendar, values);
else
this.insertEvents(calendar, values);
this.$.priceDialog.show();
}
insertEvents(calendar, days) {
days.forEach(day => {
const event = calendar.events.find(event => {
return event.dated >= day.dated && event.dated <= day.dated;
});
onResponse(response) {
if (response == 'ACCEPT') {
try {
const data = {
delivered: this.selectedDay.delivered,
price: this.selectedDay.price,
bonus: this.selectedDay.bonus,
option: this.selectedDay.option
};
if (event) return false;
this.$.watcher.check();
this.$scope.model.insert({
zoneFk: this.zone.id,
delivered: day.dated
});
calendar.addEvent({
dated: day.dated,
className: 'green-circle',
title: 'Has delivery'
});
});
this.$scope.model.save().then(() => {
this.events = calendar.events;
});
}
removeEvents(calendar, days) {
let dates = [];
days.forEach(day => {
const event = calendar.events.find(event => {
return event.dated >= day.dated && event.dated <= day.dated;
});
if (event && !event.isRemovable)
const path = `/api/Zones/${this.zone.id}/editPrices`;
this.$http.post(path, data).then(() => {
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
this.$.model.refresh();
this.card.reload();
});
} catch (e) {
this.vnApp.showError(this.$translate.instant(e.message));
return false;
}
}
dates.push(day.dated);
return this.onClose();
}
calendar.removeEvent(day.dated);
});
onClose() {
this.$.watcher.updateOriginalData();
}
if (dates.length == 0) return;
const params = {zoneFk: this.zone.id, dates};
this.$http.post('/agency/api/zoneCalendars/removeByDate', params).then(() => {
this.events = calendar.events;
onMoveNext(calendars) {
calendars.forEach(calendar => {
calendar.moveNext(2);
});
}
onMoveNext(calendar) {
calendar.moveNext(2);
}
onMovePrevious(calendar) {
calendar.movePrevious(2);
onMovePrevious(calendars) {
calendars.forEach(calendar => {
calendar.movePrevious(2);
});
}
}
Controller.$inject = ['$element', '$scope', '$stateParams', '$http'];
Controller.$inject = ['$element', '$scope', '$http', '$filter', '$translate', '$stateParams', 'vnApp'];
ngModule.component('vnZoneCalendar', {
template: require('./index.html'),
controller: Controller,
bindings: {
zone: '<'
},
require: {
card: '^vnZoneCard'
}
});

View File

@ -0,0 +1,6 @@
Prices: Precios
Edit price: Modificar precio
Only this day: Solo este día
From this day: A partir de este día
All days: Todos los días
There's no delivery for this day: No hay reparto para este día

View File

@ -0,0 +1,3 @@
vn-calendar:nth-child(2n + 1) {
border-right:1px solid #ddd
}

View File

@ -8,4 +8,5 @@ import './search-panel';
import './create';
import './basic-data';
import './location';
import './location/calendar';
import './calendar';

View File

@ -0,0 +1,21 @@
<vn-crud-model
vn-id="model"
url="/agency/api/ZoneCalendars"
fields="['zoneFk', 'delivered']"
link="{zoneFk: $ctrl.$stateParams.id}"
data="$ctrl.data"
primary-key="zoneFk"
auto-load="true">
</vn-crud-model>
<vn-calendar pad-small vn-id="stMonth" skip="2"
data="$ctrl.events"
on-selection="$ctrl.onSelection(values, stMonth)"
on-move-next="$ctrl.onMoveNext(ndMonth)"
on-move-previous="$ctrl.onMovePrevious(ndMonth)">
</vn-calendar>
<vn-calendar pad-small vn-id="ndMonth" skip="2"
data="$ctrl.events"
display-controls="false"
on-selection="$ctrl.onSelection(values, ndMonth)"
default-date="$ctrl.ndMonthDate">
</vn-calendar>

View File

@ -0,0 +1,150 @@
import ngModule from '../module';
class Controller {
constructor($element, $scope, $stateParams, $http) {
this.$element = $element;
this.$stateParams = $stateParams;
this.$scope = $scope;
this.$http = $http;
this.stMonthDate = new Date();
this.ndMonthDate = new Date();
this.ndMonthDate.setMonth(this.ndMonthDate.getMonth() + 1);
}
$postLink() {
this.stMonth = this.$scope.stMonth;
this.ndMonth = this.$scope.ndMonth;
}
// Disabled until implementation
// of holidays by node
/* get zone() {
return this._zone;
}
set zone(value) {
this._zone = value;
if (!value) return;
let query = '/agency/api/LabourHolidays/getByWarehouse';
this.$http.get(query, {params: {warehouseFk: value.warehouseFk}}).then(res => {
if (!res.data) return;
const events = [];
res.data.forEach(holiday => {
events.push({
date: holiday.dated,
className: 'red',
title: holiday.description || holiday.name,
isRemovable: false
});
});
this.events = this.events.concat(events);
});
} */
get data() {
return this._data;
}
set data(value) {
this._data = value;
if (!value) return;
const events = [];
value.forEach(event => {
events.push({
name: 'Has delivery',
dated: event.delivered,
style: {backgroundColor: '#a3d131'}
});
});
this.events = events;
}
onSelection(values, calendar) {
let totalEvents = 0;
values.forEach(day => {
const exists = calendar.events.findIndex(event => {
return event.dated >= day.dated && event.dated <= day.dated
&& event.isRemovable;
});
if (exists > -1) totalEvents++;
});
if (totalEvents > (values.length / 2))
this.removeEvents(calendar, values);
else
this.insertEvents(calendar, values);
}
insertEvents(calendar, days) {
days.forEach(day => {
const event = calendar.events.find(event => {
return event.dated >= day.dated && event.dated <= day.dated;
});
if (event) return false;
this.$scope.model.insert({
zoneFk: this.zone.id,
delivered: day.dated,
price: this.zone.price,
bonus: this.zone.bonus
});
calendar.addEvent({
name: 'Has delivery',
dated: day.dated,
style: {backgroundColor: '#a3d131'}
});
});
this.$scope.model.save().then(() => {
this.events = calendar.events;
});
}
removeEvents(calendar, days) {
let dates = [];
days.forEach(day => {
const event = calendar.events.find(event => {
return event.dated >= day.dated && event.dated <= day.dated;
});
if (event && !event.isRemovable)
return false;
dates.push(day.dated);
calendar.removeEvent(day.dated);
});
if (dates.length == 0) return;
const params = {zoneFk: this.zone.id, dates};
this.$http.post('/agency/api/zoneCalendars/removeByDate', params).then(() => {
this.events = calendar.events;
});
}
onMoveNext(calendar) {
calendar.moveNext(2);
}
onMovePrevious(calendar) {
calendar.movePrevious(2);
}
}
Controller.$inject = ['$element', '$scope', '$stateParams', '$http'];
ngModule.component('vnZoneLocationCalendar', {
template: require('./calendar.html'),
controller: Controller,
bindings: {
zone: '<'
}
});

View File

@ -18,6 +18,6 @@
</vn-treeview>
</vn-card>
<vn-side-menu side="right">
<vn-zone-calendar zone="::$ctrl.zone"></vn-zone-calendar>
<vn-zone-location-calendar zone="::$ctrl.zone"></vn-zone-location-calendar>
</vn-side-menu>
</div>

View File

@ -6,7 +6,8 @@
"dependencies": ["worker"],
"menu": [
{"state": "zone.card.basicData", "icon": "settings"},
{"state": "zone.card.location", "icon": "my_location"}
{"state": "zone.card.location", "icon": "my_location"},
{"state": "zone.card.calendar"}
],
"routes": [
{
@ -15,27 +16,31 @@
"abstract": true,
"component": "ui-view",
"description": "Zones"
}, {
},
{
"url": "/index?q",
"state": "zone.index",
"component": "vn-zone-index",
"description": "Zones"
}, {
},
{
"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": "/location?q",
"state": "zone.card.location",
"component": "vn-zone-location",
"description": "Locations",
},
{
"url": "/summary",
"state": "zone.card.summary",
"component": "vn-zone-summary",
"description": "Summary",
"params": {
"zone": "$ctrl.zone"
}
@ -50,10 +55,19 @@
}
},
{
"url": "/summary",
"state": "zone.card.summary",
"component": "vn-zone-summary",
"description": "Summary",
"url": "/location?q",
"state": "zone.card.location",
"component": "vn-zone-location",
"description": "Locations",
"params": {
"zone": "$ctrl.zone"
}
},
{
"url": "/calendar",
"state": "zone.card.calendar",
"component": "vn-zone-calendar",
"description": "Prices",
"params": {
"zone": "$ctrl.zone"
}

View File

@ -27,6 +27,5 @@
"model": "Client",
"foreignKey": "clientFk"
}
},
"scope" : {"where": {"amount": {"gt": 0}}}
}
}

View File

@ -186,7 +186,7 @@
info="Invoices minus payments">
</vn-label-value>
<vn-label-value label="Balance due"
value="{{$ctrl.summary.defaulters[0].amount | currency: 'EUR':2}}"
value="{{($ctrl.summary.defaulters[0].amount >= 0 ? $ctrl.summary.defaulters[0].amount : '-') | currency: 'EUR':2}}"
ng-class="{alert: $ctrl.summary.defaulters[0].amount}"
info="Deviated invoices minus payments">
</vn-label-value>

View File

@ -1,11 +1,14 @@
const app = require('vn-loopback/server/server');
describe('item getDiary()', () => {
it('should return 2 entries, the first one with the property balance -100', async() => {
it('should check the property balance of the 4 resultant entries', async() => {
let params = {where: {itemFk: 1, warehouseFk: 2}};
let result = await app.models.Item.getDiary(params);
expect(result.length).toBe(2);
expect(result[0].balance).toBe(-100);
expect(result.length).toBe(4);
expect(result[0].balance).toBe(-1000);
expect(result[1].balance).toBe(-1100);
expect(result[2].balance).toBe(-1110);
expect(result[3].balance).toBe(-1210);
});
});

View File

@ -9,7 +9,7 @@ describe('item getLastEntries()', () => {
expect(result.length).toEqual(1);
});
it('should return three entries for a given item', async() => {
it('should return five entries for a given item', async() => {
let date = new Date();
date.setMonth(date.getMonth() - 2, 1);
@ -17,6 +17,6 @@ describe('item getLastEntries()', () => {
let filter = {where: {itemFk: 1, date: date}};
let result = await app.models.Item.getLastEntries(filter);
expect(result.length).toEqual(3);
expect(result.length).toEqual(5);
});
});

View File

@ -51,7 +51,7 @@ describe('Route filter()', () => {
let result = await app.models.Route.filter(ctx);
expect(result.length).toEqual(4);
expect(result.length).toEqual(3);
});
it('should return the routes matching "description"', async() => {

View File

@ -10,7 +10,7 @@ describe('route updateVolume()', () => {
afterAll(async done => {
await originalRoute.updateAttributes({m3: 0.1});
await originalRoute.updateAttributes({m3: 0.3});
await ticketToRestore.updateAttributes({routeFk: 2});
await app.models.RouteLog.destroyById(logIdToDestroy);
done();
@ -19,7 +19,7 @@ describe('route updateVolume()', () => {
it('should confirm the original volume of the route is the expected', async() => {
originalRoute = await app.models.Route.findById(routeId);
expect(originalRoute.m3).toEqual(0.1);
expect(originalRoute.m3).toEqual(0.3);
});
it('should confirm the route volume is updated when a ticket is added', async() => {
@ -37,7 +37,7 @@ describe('route updateVolume()', () => {
it('should confirm the change is logged', async() => {
let logs = await app.models.RouteLog.find({fields: ['id', 'newInstance']});
let m3Log = logs.filter(log => {
return log.newInstance.m3 === 0.2;
return log.newInstance.m3 === 0.4;
});
logIdToDestroy = m3Log[0].id;

View File

@ -4,7 +4,7 @@ describe('ticket getSalesPersonMana()', () => {
it('should get the mana of a salesperson of a given ticket', async() => {
let mana = await app.models.Ticket.getSalesPersonMana(1);
expect(mana).toEqual(261);
expect(mana).toEqual(301);
});
it('should return 0 if the given ticket does not exist', async() => {

View File

@ -4,7 +4,7 @@ describe('workerMana getCurrentWorkerMana()', () => {
it('should get the mana of the logged worker', async() => {
let mana = await app.models.WorkerMana.getCurrentWorkerMana({req: {accessToken: {userId: 18}}});
expect(mana).toEqual(261);
expect(mana).toEqual(301);
});
it('should return 0 if the user doesnt uses mana', async() => {

View File

@ -3,7 +3,7 @@
data="$ctrl.absenceTypes" auto-load="true">
</vn-crud-model>
<div class="main-with-right-menu">
<vn-card compact pad-large>
<vn-card pad-large>
<vn-horizontal class="calendar-list">
<section class="calendar" ng-repeat="month in $ctrl.months">
<vn-calendar

View File

@ -45,10 +45,11 @@ class Controller {
const holidayName = holidayDetail || holidayType;
events.push({
name: holidayName,
description: holidayName,
dated: holiday.dated,
className: 'red',
title: holidayName,
isRemovable: false
isRemovable: false,
style: {backgroundColor: '#FFFF00'}
});
});
this.events = this.events.concat(events);
@ -62,11 +63,10 @@ class Controller {
absences.forEach(absence => {
const absenceType = absence.absenceType;
events.push({
name: absenceType.name,
description: absenceType.name,
dated: absence.dated,
title: absenceType.name,
style: {
background: absenceType.rgb
}
style: {backgroundColor: absenceType.rgb}
});
});
this.events = this.events.concat(events);

View File

@ -93,7 +93,7 @@ describe('Worker', () => {
controller.setHolidays(data);
expect(controller.events.length).toEqual(2);
expect(controller.events[0].title).toEqual('New year');
expect(controller.events[0].name).toEqual('New year');
expect(controller.events[0].isRemovable).toEqual(false);
});
});
@ -107,9 +107,9 @@ describe('Worker', () => {
controller.setWorkerCalendar(data);
expect(controller.events.length).toEqual(2);
expect(controller.events[0].title).toEqual('Holiday');
expect(controller.events[0].name).toEqual('Holiday');
expect(controller.events[0].style).toBeDefined();
expect(controller.events[1].title).toEqual('Leave');
expect(controller.events[1].name).toEqual('Leave');
expect(controller.events[1].style).toBeDefined();
});
});

View File

@ -1,5 +1,13 @@
@import "variables";
.calendar-list .calendar {
border-bottom:1px solid #ddd
}
.calendar-list .calendar:nth-child(2n + 1) {
border-right:1px solid #ddd
}
.calendar-list {
align-items: flex-start;
flex-wrap: wrap;
@ -9,7 +17,7 @@
box-sizing: border-box;
padding: $pad-medium;
overflow: hidden;
width: 20em
width: 50%
}
}