3430-ticket_step-two ticket without negatives #823
|
@ -120,7 +120,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
body: params
|
form: params
|
||||||
};
|
};
|
||||||
|
|
||||||
if (options) Object.assign(defaultOptions, options);
|
if (options) Object.assign(defaultOptions, options);
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
DELETE FROM `salix`.`ACL` WHERE id = 48;
|
|
||||||
DELETE FROM `salix`.`ACL` WHERE id = 49;
|
|
||||||
DELETE FROM `salix`.`ACL` WHERE id = 50;
|
|
||||||
DELETE FROM `salix`.`ACL` WHERE id = 107;
|
|
|
@ -1,197 +0,0 @@
|
||||||
drop procedure `vn`.`sale_getProblems`;
|
|
||||||
|
|
||||||
DELIMITER $$
|
|
||||||
$$
|
|
||||||
create
|
|
||||||
definer = root@`%` procedure `vn`.`sale_getProblems`(IN vIsTodayRelative tinyint(1))
|
|
||||||
BEGIN
|
|
||||||
/**
|
|
||||||
* Calcula los problemas de cada venta
|
|
||||||
* para un conjunto de tickets.
|
|
||||||
*
|
|
||||||
* @table tmp.sale_getProblems(ticketFk, clientFk, warehouseFk, shipped) Identificadores de los tickets a calcular
|
|
||||||
* @return tmp.sale_problems
|
|
||||||
*/
|
|
||||||
DECLARE vWarehouse INT;
|
|
||||||
DECLARE vDate DATE;
|
|
||||||
DECLARE vAvailableCache INT;
|
|
||||||
DECLARE vDone INT DEFAULT 0;
|
|
||||||
DECLARE vComponentCount INT;
|
|
||||||
|
|
||||||
DECLARE vCursor CURSOR FOR
|
|
||||||
SELECT DISTINCT tt.warehouseFk, IF(vIsTodayRelative, CURDATE(), date(tt.shipped))
|
|
||||||
FROM tmp.sale_getProblems tt
|
|
||||||
WHERE DATE(tt.shipped) BETWEEN CURDATE()
|
|
||||||
AND TIMESTAMPADD(DAY, IF(vIsTodayRelative, 9.9, 1.9), CURDATE());
|
|
||||||
|
|
||||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tmp.sale_problems;
|
|
||||||
CREATE TEMPORARY TABLE tmp.sale_problems (
|
|
||||||
ticketFk INT(11),
|
|
||||||
saleFk INT(11),
|
|
||||||
isFreezed INTEGER(1) DEFAULT 0,
|
|
||||||
risk DECIMAL(10,2) DEFAULT 0,
|
|
||||||
hasHighRisk TINYINT(1) DEFAULT 0,
|
|
||||||
hasTicketRequest INTEGER(1) DEFAULT 0,
|
|
||||||
isAvailable INTEGER(1) DEFAULT 1,
|
|
||||||
itemShortage VARCHAR(250),
|
|
||||||
isTaxDataChecked INTEGER(1) DEFAULT 1,
|
|
||||||
itemDelay VARCHAR(250),
|
|
||||||
hasComponentLack INTEGER(1),
|
|
||||||
PRIMARY KEY (ticketFk, saleFk)
|
|
||||||
) ENGINE = MEMORY;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticket_list;
|
|
||||||
CREATE TEMPORARY TABLE tmp.ticket_list
|
|
||||||
(PRIMARY KEY (ticketFk))
|
|
||||||
ENGINE = MEMORY
|
|
||||||
SELECT tp.ticketFk, c.id clientFk
|
|
||||||
FROM tmp.sale_getProblems tp
|
|
||||||
JOIN vn.client c ON c.id = tp.clientFk;
|
|
||||||
|
|
||||||
SELECT COUNT(*) INTO vComponentCount
|
|
||||||
FROM vn.component c
|
|
||||||
WHERE c.isRequired;
|
|
||||||
|
|
||||||
INSERT INTO tmp.sale_problems(ticketFk, hasComponentLack, saleFk)
|
|
||||||
SELECT tl.ticketFk, (COUNT(DISTINCT s.id) * vComponentCount > COUNT(c.id)), s.id
|
|
||||||
FROM tmp.ticket_list tl
|
|
||||||
JOIN vn.sale s ON s.ticketFk = tl.ticketFk
|
|
||||||
LEFT JOIN vn.saleComponent sc ON sc.saleFk = s.id
|
|
||||||
LEFT JOIN vn.component c ON c.id = sc.componentFk AND c.isRequired
|
|
||||||
JOIN vn.ticket t ON t.id = tl.ticketFk
|
|
||||||
JOIN vn.agencyMode am ON am.id = t.agencyModeFk
|
|
||||||
JOIN vn.deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
|
||||||
WHERE dm.code IN('AGENCY','DELIVERY','PICKUP')
|
|
||||||
GROUP BY tl.ticketFk, s.id;
|
|
||||||
|
|
||||||
INSERT INTO tmp.sale_problems(ticketFk, isFreezed)
|
|
||||||
SELECT DISTINCT tl.ticketFk, TRUE
|
|
||||||
FROM tmp.ticket_list tl
|
|
||||||
JOIN vn.client c ON c.id = tl.clientFk
|
|
||||||
WHERE c.isFreezed
|
|
||||||
ON DUPLICATE KEY UPDATE
|
|
||||||
isFreezed = c.isFreezed;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt;
|
|
||||||
CREATE TEMPORARY TABLE tmp.clientGetDebt
|
|
||||||
(PRIMARY KEY (clientFk))
|
|
||||||
ENGINE = MEMORY
|
|
||||||
SELECT DISTINCT clientFk
|
|
||||||
FROM tmp.ticket_list;
|
|
||||||
|
|
||||||
CALL clientGetDebt(CURDATE());
|
|
||||||
|
|
||||||
INSERT INTO tmp.sale_problems(ticketFk, risk, hasHighRisk)
|
|
||||||
SELECT DISTINCT tl.ticketFk, r.risk, ((r.risk - cc.riskTolerance) > c.credit + 10)
|
|
||||||
FROM tmp.ticket_list 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
|
|
||||||
JOIN vn.clientConfig cc
|
|
||||||
WHERE r.risk > c.credit + 10
|
|
||||||
AND a.isRiskFree = FALSE
|
|
||||||
ON DUPLICATE KEY UPDATE
|
|
||||||
risk = r.risk, hasHighRisk = ((r.risk - cc.riskTolerance) > c.credit + 10);
|
|
||||||
|
|
||||||
INSERT INTO tmp.sale_problems(ticketFk, hasTicketRequest)
|
|
||||||
SELECT DISTINCT tl.ticketFk, TRUE
|
|
||||||
FROM tmp.ticket_list tl
|
|
||||||
JOIN vn.ticketRequest tr ON tr.ticketFk = tl.ticketFk
|
|
||||||
WHERE tr.isOK IS NULL
|
|
||||||
ON DUPLICATE KEY UPDATE
|
|
||||||
hasTicketRequest = TRUE;
|
|
||||||
|
|
||||||
OPEN vCursor;
|
|
||||||
|
|
||||||
WHILE NOT vDone
|
|
||||||
DO
|
|
||||||
FETCH vCursor INTO vWarehouse, vDate;
|
|
||||||
|
|
||||||
CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouse, vDate);
|
|
||||||
|
|
||||||
INSERT INTO tmp.sale_problems(ticketFk, isAvailable, saleFk)
|
|
||||||
SELECT tl.ticketFk, FALSE, s.id
|
|
||||||
FROM tmp.ticket_list tl
|
|
||||||
JOIN vn.ticket t ON t.id = tl.ticketFk
|
|
||||||
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 it.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 = FALSE, saleFk = VALUES(saleFk);
|
|
||||||
|
|
||||||
INSERT INTO tmp.sale_problems(ticketFk, itemShortage, saleFk)
|
|
||||||
SELECT ticketFk, problem, saleFk
|
|
||||||
FROM (
|
|
||||||
SELECT tl.ticketFk, CONCAT('F: ',GROUP_CONCAT(i.id, ' ', i.longName, ' ')) problem, s.id AS saleFk
|
|
||||||
FROM tmp.ticket_list tl
|
|
||||||
JOIN vn.ticket t ON t.id = tl.ticketFk
|
|
||||||
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 vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk
|
|
||||||
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(issw.visible, 0)
|
|
||||||
AND s.quantity > 0
|
|
||||||
AND s.isPicked = FALSE
|
|
||||||
AND s.reserved = FALSE
|
|
||||||
AND it.categoryFk != 6
|
|
||||||
AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate)
|
|
||||||
AND NOT i.generic
|
|
||||||
AND CURDATE() = vDate
|
|
||||||
AND t.warehouseFk = vWarehouse
|
|
||||||
GROUP BY tl.ticketFk LIMIT 1) sub
|
|
||||||
ON DUPLICATE KEY UPDATE
|
|
||||||
itemShortage = sub.problem, saleFk = sub.saleFk;
|
|
||||||
|
|
||||||
INSERT INTO tmp.sale_problems(ticketFk, itemDelay, saleFk)
|
|
||||||
SELECT ticketFk, problem, saleFk
|
|
||||||
FROM (
|
|
||||||
SELECT tl.ticketFk, GROUP_CONCAT('I: ',i.id, ' ', i.longName, ' ') problem, s.id AS saleFk
|
|
||||||
FROM tmp.ticket_list tl
|
|
||||||
JOIN vn.ticket t ON t.id = tl.ticketFk
|
|
||||||
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 vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk
|
|
||||||
WHERE s.quantity > IFNULL(issw.visible, 0)
|
|
||||||
AND s.quantity > 0
|
|
||||||
AND s.isPicked = FALSE
|
|
||||||
AND s.reserved = FALSE
|
|
||||||
AND it.categoryFk != 6
|
|
||||||
AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate)
|
|
||||||
AND NOT i.generic
|
|
||||||
AND CURDATE() = vDate
|
|
||||||
AND t.warehouseFk = vWarehouse
|
|
||||||
GROUP BY tl.ticketFk LIMIT 1) sub
|
|
||||||
ON DUPLICATE KEY UPDATE
|
|
||||||
itemDelay = sub.problem, saleFk = sub.saleFk;
|
|
||||||
END WHILE;
|
|
||||||
|
|
||||||
CLOSE vCursor;
|
|
||||||
|
|
||||||
INSERT INTO tmp.sale_problems(ticketFk, isTaxDataChecked)
|
|
||||||
SELECT DISTINCT tl.ticketFk, FALSE
|
|
||||||
FROM tmp.ticket_list tl
|
|
||||||
JOIN vn.client c ON c.id = tl.clientFk
|
|
||||||
WHERE c.isTaxDataChecked = FALSE
|
|
||||||
ON DUPLICATE KEY UPDATE
|
|
||||||
isTaxDataChecked = FALSE;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE
|
|
||||||
tmp.clientGetDebt,
|
|
||||||
tmp.ticket_list;
|
|
||||||
END;;$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,48 +0,0 @@
|
||||||
drop procedure `vn`.`ticket_getProblems`;
|
|
||||||
|
|
||||||
DELIMITER $$
|
|
||||||
$$
|
|
||||||
create
|
|
||||||
definer = root@`%` procedure `vn`.`ticket_getProblems`(IN vIsTodayRelative tinyint(1))
|
|
||||||
BEGIN
|
|
||||||
/**
|
|
||||||
* Calcula los problemas para un conjunto de tickets.
|
|
||||||
* Agrupados por ticket
|
|
||||||
*
|
|
||||||
* @table tmp.sale_getProblems(ticketFk, clientFk, warehouseFk, shipped) Identificadores de los tickets a calcular
|
|
||||||
* @return tmp.ticket_problems
|
|
||||||
*/
|
|
||||||
CALL sale_getProblems(vIsTodayRelative);
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticket_problems;
|
|
||||||
CREATE TEMPORARY TABLE tmp.ticket_problems
|
|
||||||
(INDEX (ticketFk))
|
|
||||||
ENGINE = MEMORY
|
|
||||||
SELECT
|
|
||||||
ticketFk,
|
|
||||||
MAX(p.isFreezed) AS isFreezed,
|
|
||||||
MAX(p.risk) AS risk,
|
|
||||||
MAX(p.hasHighRisk) AS hasHighRisk,
|
|
||||||
MAX(p.hasTicketRequest) AS hasTicketRequest,
|
|
||||||
MIN(p.isAvailable) AS isAvailable,
|
|
||||||
MAX(p.itemShortage) AS itemShortage,
|
|
||||||
MIN(p.isTaxDataChecked) AS isTaxDataChecked,
|
|
||||||
MAX(p.hasComponentLack) AS hasComponentLack,
|
|
||||||
0 AS totalProblems
|
|
||||||
FROM tmp.sale_problems p
|
|
||||||
GROUP BY ticketFk;
|
|
||||||
|
|
||||||
UPDATE tmp.ticket_problems tp
|
|
||||||
SET tp.totalProblems = (
|
|
||||||
(tp.isFreezed) +
|
|
||||||
IF(tp.risk, TRUE, FALSE) +
|
|
||||||
(tp.hasTicketRequest) +
|
|
||||||
(tp.isAvailable = 0) +
|
|
||||||
(tp.isTaxDataChecked = 0) +
|
|
||||||
(tp.hasComponentLack)
|
|
||||||
);
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE
|
|
||||||
tmp.sale_problems;
|
|
||||||
END;;$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1 +0,0 @@
|
||||||
alter table `vn`.`travelThermograph` modify `temperature` enum('COOL', 'WARM') null;
|
|
|
@ -1 +0,0 @@
|
||||||
UPDATE salix.ACL t SET t.principalId = 'employee' WHERE t.id = 269;
|
|
|
@ -1,3 +0,0 @@
|
||||||
ALTER TABLE vn.accountingType ADD maxAmount INT DEFAULT NULL NULL;
|
|
||||||
|
|
||||||
UPDATE vn.accountingType SET maxAmount = 1000 WHERE code = 'cash';
|
|
|
@ -1,4 +0,0 @@
|
||||||
ALTER TABLE vn.payMethod CHANGE ibanRequired ibanRequiredForClients tinyint(3) DEFAULT 0 NULL;
|
|
||||||
ALTER TABLE vn.payMethod ADD ibanRequiredForSuppliers tinyint(3) DEFAULT 0 NULL;
|
|
||||||
ALTER TABLE vn.payMethod CHANGE ibanRequiredForSuppliers ibanRequiredForSuppliers tinyint(3) DEFAULT 0 NULL AFTER ibanRequiredForClients;
|
|
||||||
UPDATE vn.payMethod SET ibanRequiredForSuppliers = 1 WHERE code = 'wireTransfer';
|
|
|
@ -1,2 +0,0 @@
|
||||||
ALTER TABLE vn.silexACL MODIFY module VARCHAR(50) NOT NULL;
|
|
||||||
ALTER TABLE vn.silexACL MODIFY method VARCHAR(50) NOT NULL;
|
|
|
@ -1,48 +0,0 @@
|
||||||
drop procedure `vn`.`ticket_getProblems`;
|
|
||||||
|
|
||||||
DELIMITER $$
|
|
||||||
$$
|
|
||||||
create
|
|
||||||
definer = root@`%` procedure `vn`.`ticket_getProblems`(IN vIsTodayRelative tinyint(1))
|
|
||||||
BEGIN
|
|
||||||
/**
|
|
||||||
* Calcula los problemas para un conjunto de tickets.
|
|
||||||
* Agrupados por ticket
|
|
||||||
*
|
|
||||||
* @table tmp.sale_getProblems(ticketFk, clientFk, warehouseFk, shipped) Identificadores de los tickets a calcular
|
|
||||||
* @return tmp.ticket_problems
|
|
||||||
*/
|
|
||||||
CALL sale_getProblems(vIsTodayRelative);
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticket_problems;
|
|
||||||
CREATE TEMPORARY TABLE tmp.ticket_problems
|
|
||||||
(PRIMARY KEY (ticketFk))
|
|
||||||
ENGINE = MEMORY
|
|
||||||
SELECT
|
|
||||||
ticketFk,
|
|
||||||
MAX(p.isFreezed) AS isFreezed,
|
|
||||||
MAX(p.risk) AS risk,
|
|
||||||
MAX(p.hasHighRisk) AS hasHighRisk,
|
|
||||||
MAX(p.hasTicketRequest) AS hasTicketRequest,
|
|
||||||
MIN(p.isAvailable) AS isAvailable,
|
|
||||||
MAX(p.itemShortage) AS itemShortage,
|
|
||||||
MIN(p.isTaxDataChecked) AS isTaxDataChecked,
|
|
||||||
MAX(p.hasComponentLack) AS hasComponentLack,
|
|
||||||
0 AS totalProblems
|
|
||||||
FROM tmp.sale_problems p
|
|
||||||
GROUP BY ticketFk;
|
|
||||||
|
|
||||||
UPDATE tmp.ticket_problems tp
|
|
||||||
SET tp.totalProblems = (
|
|
||||||
(tp.isFreezed) +
|
|
||||||
IF(tp.risk, TRUE, FALSE) +
|
|
||||||
(tp.hasTicketRequest) +
|
|
||||||
(tp.isAvailable = 0) +
|
|
||||||
(tp.isTaxDataChecked = 0) +
|
|
||||||
(tp.hasComponentLack)
|
|
||||||
);
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE
|
|
||||||
tmp.sale_problems;
|
|
||||||
END;;$$
|
|
||||||
DELIMITER ;
|
|
|
@ -1,14 +0,0 @@
|
||||||
CREATE TABLE `salix`.`defaultViewConfig`
|
|
||||||
(
|
|
||||||
tableCode VARCHAR(25) not null,
|
|
||||||
columns JSON not null
|
|
||||||
)
|
|
||||||
comment 'The default configuration of columns for views';
|
|
||||||
|
|
||||||
INSERT INTO `salix`.`defaultViewConfig` (tableCode, columns)
|
|
||||||
VALUES
|
|
||||||
('itemsIndex', '{"intrastat":false,"stemMultiplier":false,"landed":false}'),
|
|
||||||
('latestBuys', '{"intrastat":false,"description":false,"density":false,"isActive":false,"freightValue":false,"packageValue":false,"isIgnored":false,"price2":false,"minPrice":true,"ektFk":false,"weight":false,"id":true,"packing":true,"grouping":true,"quantity":true,"size":false,"name":true,"code":true,"origin":true,"family":true,"entryFk":true,"buyingValue":true,"comissionValue":false,"price3":true,"packageFk":true,"packingOut":true}'),
|
|
||||||
('ticketsMonitor', '{"id":false}');
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
|
||||||
|
VALUES ('Sale','payBack','WRITE','ALLOW','ROLE','employee');
|
|
@ -0,0 +1,90 @@
|
||||||
|
DROP PROCEDURE IF EXISTS `vn`.`ticket_doRefund`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
$$
|
||||||
|
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_doRefund`(IN vOriginTicket INT, OUT vNewTicket INT)
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
DECLARE vDone BIT DEFAULT 0;
|
||||||
|
DECLARE vCustomer MEDIUMINT;
|
||||||
|
DECLARE vWarehouse TINYINT;
|
||||||
|
DECLARE vCompany MEDIUMINT;
|
||||||
|
DECLARE vAddress MEDIUMINT;
|
||||||
|
DECLARE vRefundAgencyMode INT;
|
||||||
|
DECLARE vItemFk INT;
|
||||||
|
DECLARE vQuantity DECIMAL (10,2);
|
||||||
|
DECLARE vConcept VARCHAR(50);
|
||||||
|
DECLARE vPrice DECIMAL (10,2);
|
||||||
|
DECLARE vDiscount TINYINT;
|
||||||
|
DECLARE vSaleNew INT;
|
||||||
|
DECLARE vSaleMain INT;
|
||||||
|
DECLARE vZoneFk INT;
|
||||||
|
|
||||||
|
DECLARE vRsMainTicket CURSOR FOR
|
||||||
|
SELECT *
|
||||||
|
FROM tmp.sale;
|
||||||
|
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1;
|
||||||
|
|
||||||
|
SELECT id INTO vRefundAgencyMode
|
||||||
|
FROM agencyMode WHERE `name` = 'ABONO';
|
||||||
|
|
||||||
|
SELECT clientFk, warehouseFk, companyFk, addressFk
|
||||||
|
INTO vCustomer, vWarehouse, vCompany, vAddress
|
||||||
|
FROM ticket
|
||||||
|
WHERE id = vOriginTicket;
|
||||||
|
|
||||||
|
SELECT id INTO vZoneFk
|
||||||
|
FROM zone WHERE agencyModeFk = vRefundAgencyMode
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
INSERT INTO vn.ticket (
|
||||||
|
clientFk,
|
||||||
|
shipped,
|
||||||
|
addressFk,
|
||||||
|
agencyModeFk,
|
||||||
|
nickname,
|
||||||
|
warehouseFk,
|
||||||
|
companyFk,
|
||||||
|
landed,
|
||||||
|
zoneFk
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
vCustomer,
|
||||||
|
CURDATE(),
|
||||||
|
vAddress,
|
||||||
|
vRefundAgencyMode,
|
||||||
|
a.nickname,
|
||||||
|
vWarehouse,
|
||||||
|
vCompany,
|
||||||
|
CURDATE(),
|
||||||
|
vZoneFk
|
||||||
|
FROM address a
|
||||||
|
WHERE a.id = vAddress;
|
||||||
|
|
||||||
|
SET vNewTicket = LAST_INSERT_ID();
|
||||||
|
|
||||||
|
SET vDone := 0;
|
||||||
|
OPEN vRsMainTicket ;
|
||||||
|
FETCH vRsMainTicket INTO vSaleMain, vItemFk, vQuantity, vConcept, vPrice, vDiscount;
|
||||||
|
|
||||||
|
WHILE NOT vDone DO
|
||||||
|
|
||||||
|
INSERT INTO vn.sale(ticketFk, itemFk, quantity, concept, price, discount)
|
||||||
|
VALUES( vNewTicket, vItemFk, vQuantity, vConcept, vPrice, vDiscount );
|
||||||
|
|
||||||
|
SET vSaleNew = LAST_INSERT_ID();
|
||||||
|
|
||||||
|
INSERT INTO vn.saleComponent(saleFk,componentFk,`value`)
|
||||||
|
SELECT vSaleNew,componentFk,`value`
|
||||||
|
FROM vn.saleComponent
|
||||||
|
WHERE saleFk = vSaleMain;
|
||||||
|
|
||||||
|
FETCH vRsMainTicket INTO vSaleMain, vItemFk, vQuantity, vConcept, vPrice, vDiscount;
|
||||||
|
|
||||||
|
END WHILE;
|
||||||
|
CLOSE vRsMainTicket;
|
||||||
|
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,2 @@
|
||||||
|
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
||||||
|
VALUES('InvoiceInDueDay', '*', '*', 'ALLOW', 'ROLE', 'administrative');
|
|
@ -0,0 +1,248 @@
|
||||||
|
DROP PROCEDURE IF EXISTS vn.invoiceInBookingMain;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
$$
|
||||||
|
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`invoiceInBookingMain`(vInvoiceInId INT)
|
||||||
|
BEGIN
|
||||||
|
DECLARE vTotalAmount,vTotalAmountDivisa DECIMAL(10,2);
|
||||||
|
DECLARE vBookNumber,vSerialNumber INT;
|
||||||
|
DECLARE vRate DECIMAL(10,4);
|
||||||
|
|
||||||
|
CALL invoiceInBookingCommon(vInvoiceInId,vSerialNumber);
|
||||||
|
|
||||||
|
SELECT SUM(iit.taxableBase * IF( i.serial= 'R' AND ti.Iva <> 'HP DEVENGADO 21 ISP', 1 +(ti.PorcentajeIva/100),1)),
|
||||||
|
SUM(iit.foreignValue * IF( i.serial= 'R', 1 + (ti.PorcentajeIva/100),1)),
|
||||||
|
iit.taxableBase/iit.foreignValue
|
||||||
|
INTO vTotalAmount, vTotalAmountDivisa, vRate
|
||||||
|
FROM newInvoiceIn i
|
||||||
|
JOIN invoiceInTax iit ON iit.invoiceInFk = i.id
|
||||||
|
LEFT JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk;
|
||||||
|
|
||||||
|
CALL vn.ledger_next(vBookNumber);
|
||||||
|
|
||||||
|
-- Apunte del proveedor
|
||||||
|
|
||||||
|
INSERT INTO XDiario(ASIEN,
|
||||||
|
FECHA,
|
||||||
|
SUBCTA,
|
||||||
|
EUROHABER,
|
||||||
|
CONCEPTO,
|
||||||
|
CAMBIO,
|
||||||
|
HABERME,
|
||||||
|
NFACTICK,
|
||||||
|
CLAVE,
|
||||||
|
empresa_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
vBookNumber,
|
||||||
|
n.bookEntried,
|
||||||
|
s.supplierAccount,
|
||||||
|
vTotalAmount EUROHABER,
|
||||||
|
n.conceptWithSupplier,
|
||||||
|
vRate,
|
||||||
|
vTotalAmountDivisa,
|
||||||
|
n.invoicesCount,
|
||||||
|
vInvoiceInId,
|
||||||
|
n.companyFk
|
||||||
|
FROM newInvoiceIn n
|
||||||
|
JOIN newSupplier s;
|
||||||
|
|
||||||
|
-- Línea de Gastos
|
||||||
|
INSERT INTO XDiario ( ASIEN,
|
||||||
|
FECHA,
|
||||||
|
SUBCTA,
|
||||||
|
CONTRA,
|
||||||
|
EURODEBE,
|
||||||
|
EUROHABER,
|
||||||
|
CONCEPTO,
|
||||||
|
CAMBIO,
|
||||||
|
DEBEME,
|
||||||
|
HABERME,
|
||||||
|
NFACTICK,
|
||||||
|
empresa_id
|
||||||
|
)
|
||||||
|
SELECT vBookNumber ASIEN,
|
||||||
|
n.bookEntried FECHA,
|
||||||
|
IF(e.isWithheld , LPAD(RIGHT(s.supplierAccount,5),10,iit.expenceFk),iit.expenceFk) SUBCTA,
|
||||||
|
s.supplierAccount CONTRA,
|
||||||
|
IF(e.isWithheld AND iit.taxableBase < 0, NULL, ROUND(SUM(iit.taxableBase),2)) EURODEBE,
|
||||||
|
IF(e.isWithheld AND iit.taxableBase < 0,ROUND(SUM(-iit.taxableBase),2),NULL) EUROHABER,
|
||||||
|
n.conceptWithSupplier CONCEPTO,
|
||||||
|
vRate,
|
||||||
|
IF(e.isWithheld,NULL,ABS(ROUND(SUM(iit.foreignValue),2))) DEBEME,
|
||||||
|
IF(e.isWithheld,ABS(ROUND(SUM(iit.foreignValue),2)),NULL) HABERME,
|
||||||
|
n.invoicesCount NFACTICK,
|
||||||
|
n.companyFk empresa_id
|
||||||
|
FROM newInvoiceIn n
|
||||||
|
JOIN newSupplier s
|
||||||
|
JOIN invoiceInTax iit ON iit.invoiceInFk = n.id
|
||||||
|
JOIN (SELECT * FROM expence e GROUP BY e.id)e ON e.id = iit.expenceFk
|
||||||
|
WHERE e.name != 'Suplidos Transitarios nacionales'
|
||||||
|
GROUP BY iit.expenceFk;
|
||||||
|
|
||||||
|
-- Líneas de IVA
|
||||||
|
|
||||||
|
INSERT INTO XDiario( ASIEN,
|
||||||
|
FECHA,
|
||||||
|
SUBCTA,
|
||||||
|
CONTRA,
|
||||||
|
EURODEBE,
|
||||||
|
BASEEURO,
|
||||||
|
CONCEPTO,
|
||||||
|
FACTURA,
|
||||||
|
IVA,
|
||||||
|
AUXILIAR,
|
||||||
|
SERIE,
|
||||||
|
TIPOOPE,
|
||||||
|
FECHA_EX,
|
||||||
|
FECHA_OP,
|
||||||
|
NFACTICK,
|
||||||
|
FACTURAEX,
|
||||||
|
L340,
|
||||||
|
LRECT349,
|
||||||
|
TIPOCLAVE,
|
||||||
|
TIPOEXENCI,
|
||||||
|
TIPONOSUJE,
|
||||||
|
TIPOFACT,
|
||||||
|
TIPORECTIF,
|
||||||
|
TERIDNIF,
|
||||||
|
TERNIF,
|
||||||
|
TERNOM,
|
||||||
|
FECREGCON,
|
||||||
|
empresa_id
|
||||||
|
)
|
||||||
|
SELECT vBookNumber ASIEN,
|
||||||
|
n.bookEntried FECHA,
|
||||||
|
IF(n.expenceFkDeductible>0, n.expenceFkDeductible, ti.CuentaIvaSoportado) SUBCTA,
|
||||||
|
s.supplierAccount CONTRA,
|
||||||
|
SUM(ROUND(ti.PorcentajeIva * it.taxableBase / 100 /* + 0.0001*/ , 2)) EURODEBE,
|
||||||
|
SUM(it.taxableBase) BASEEURO,
|
||||||
|
GROUP_CONCAT(DISTINCT e.`name` SEPARATOR ', ') CONCEPTO,
|
||||||
|
vSerialNumber FACTURA,
|
||||||
|
ti.PorcentajeIva IVA,
|
||||||
|
IF(isUeeMember AND eWithheld.id IS NULL,'','*') AUXILIAR,
|
||||||
|
n.serial SERIE,
|
||||||
|
ttr.ClaveOperacionDefecto,
|
||||||
|
n.issued FECHA_EX,
|
||||||
|
n.operated FECHA_OP,
|
||||||
|
n.invoicesCount NFACTICK,
|
||||||
|
n.supplierRef FACTURAEX,
|
||||||
|
TRUE L340,
|
||||||
|
(isSameCountry OR NOT isUeeMember) LRECT349,
|
||||||
|
n.cplusTrascendency472Fk TIPOCLAVE,
|
||||||
|
n.cplusTaxBreakFk TIPOEXENCI,
|
||||||
|
n.cplusSubjectOpFk TIPONOSUJE,
|
||||||
|
n.cplusInvoiceType472Fk TIPOFACT,
|
||||||
|
n.cplusRectificationTypeFk TIPORECTIF,
|
||||||
|
iis.cplusTerIdNifFk TERIDNIF,
|
||||||
|
s.nif AS TERNIF,
|
||||||
|
s.name AS TERNOM,
|
||||||
|
n.booked FECREGCON,
|
||||||
|
n.companyFk
|
||||||
|
FROM newInvoiceIn n
|
||||||
|
JOIN newSupplier s
|
||||||
|
JOIN invoiceInTax it ON n.id = it.invoiceInFk
|
||||||
|
JOIN sage.TiposIva ti ON ti.CodigoIva = it.taxTypeSageFk
|
||||||
|
JOIN sage.TiposTransacciones ttr ON ttr.CodigoTransaccion = it.transactionTypeSageFk
|
||||||
|
JOIN invoiceInSerial iis ON iis.code = n.serial
|
||||||
|
JOIN (SELECT * FROM expence e GROUP BY e.id)e ON e.id = it.expenceFk
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT eWithheld.id
|
||||||
|
FROM invoiceInTax hold
|
||||||
|
JOIN expence eWithheld ON eWithheld.id = hold.expenceFk AND eWithheld.isWithheld
|
||||||
|
WHERE hold.invoiceInFk = vInvoiceInId LIMIT 1
|
||||||
|
) eWithheld ON TRUE
|
||||||
|
WHERE it.taxTypeSageFk IS NOT NULL
|
||||||
|
AND it.taxTypeSageFk NOT IN (22, 90)
|
||||||
|
GROUP BY ti.PorcentajeIva, e.id;
|
||||||
|
|
||||||
|
-- Línea iva inversor sujeto pasivo
|
||||||
|
|
||||||
|
INSERT INTO XDiario( ASIEN,
|
||||||
|
FECHA,
|
||||||
|
SUBCTA,
|
||||||
|
CONTRA,
|
||||||
|
EUROHABER,
|
||||||
|
BASEEURO,
|
||||||
|
CONCEPTO,
|
||||||
|
FACTURA,
|
||||||
|
IVA,
|
||||||
|
AUXILIAR,
|
||||||
|
SERIE,
|
||||||
|
TIPOOPE,
|
||||||
|
FECHA_EX,
|
||||||
|
FECHA_OP,
|
||||||
|
NFACTICK,
|
||||||
|
FACTURAEX,
|
||||||
|
L340,
|
||||||
|
LRECT349,
|
||||||
|
TIPOCLAVE,
|
||||||
|
TIPOEXENCI,
|
||||||
|
TIPONOSUJE,
|
||||||
|
TIPOFACT,
|
||||||
|
TIPORECTIF,
|
||||||
|
TERIDNIF,
|
||||||
|
TERNIF,
|
||||||
|
TERNOM,
|
||||||
|
empresa_id
|
||||||
|
)
|
||||||
|
SELECT vBookNumber ASIEN,
|
||||||
|
n.bookEntried FECHA,
|
||||||
|
ti.CuentaIvaRepercutido SUBCTA,
|
||||||
|
s.supplierAccount CONTRA,
|
||||||
|
SUM(ROUND(ti.PorcentajeIva * it.taxableBase / 100,2)) EUROHABER,
|
||||||
|
ROUND(SUM(it.taxableBase),2) BASEEURO,
|
||||||
|
GROUP_CONCAT(DISTINCT e.`name` SEPARATOR ', ') CONCEPTO,
|
||||||
|
vSerialNumber FACTURA,
|
||||||
|
ti.PorcentajeIva IVA,
|
||||||
|
'*' AUXILIAR,
|
||||||
|
n.serial SERIE,
|
||||||
|
ttr.ClaveOperacionDefecto,
|
||||||
|
n.issued FECHA_EX,
|
||||||
|
n.operated FECHA_OP,
|
||||||
|
n.invoicesCount NFACTICK,
|
||||||
|
n.supplierRef FACTURAEX,
|
||||||
|
FALSE L340,
|
||||||
|
(isSameCountry OR NOT isUeeMember) LRECT349,
|
||||||
|
1 TIPOCLAVE,
|
||||||
|
n.cplusTaxBreakFk TIPOEXENCI,
|
||||||
|
n.cplusSubjectOpFk TIPONOSUJE,
|
||||||
|
n.cplusInvoiceType472Fk TIPOFACT,
|
||||||
|
n.cplusRectificationTypeFk TIPORECTIF,
|
||||||
|
iis.cplusTerIdNifFk TERIDNIF,
|
||||||
|
s.nif AS TERNIF,
|
||||||
|
s.name AS TERNOM,
|
||||||
|
n.companyFk
|
||||||
|
FROM newInvoiceIn n
|
||||||
|
JOIN newSupplier s
|
||||||
|
JOIN invoiceInTax it ON n.id = it.invoiceInFk
|
||||||
|
JOIN sage.TiposIva ti ON ti.CodigoIva = it.taxTypeSageFk
|
||||||
|
JOIN sage.TiposTransacciones ttr ON ttr.CodigoTransaccion = it.transactionTypeSageFk
|
||||||
|
JOIN invoiceInSerial iis ON iis.code = n.serial
|
||||||
|
JOIN (SELECT * FROM expence e GROUP BY e.id)e ON e.id = it.expenceFk
|
||||||
|
WHERE ti.Iva = 'HP DEVENGADO 21 ISP' OR MID(s.account, 4, 1) = '1'
|
||||||
|
GROUP BY ti.PorcentajeIva, e.id;
|
||||||
|
|
||||||
|
-- Actualización del registro original
|
||||||
|
UPDATE invoiceIn ii
|
||||||
|
JOIN newInvoiceIn ni ON ii.id = ni.id
|
||||||
|
SET ii.serialNumber = vSerialNumber,
|
||||||
|
ii.isBooked = TRUE;
|
||||||
|
|
||||||
|
-- Problemas derivados de la precisión en los decimales al calcular los impuestos
|
||||||
|
UPDATE XDiario
|
||||||
|
SET EURODEBE = EURODEBE -
|
||||||
|
(SELECT IF(ABS(sub.difference) = 0.01, sub.difference, 0)
|
||||||
|
FROM(
|
||||||
|
SELECT SUM(IFNULL(ROUND(EURODEBE, 2),0)) - SUM(IFNULL(ROUND(EUROHABER, 2), 0)) difference
|
||||||
|
FROM XDiario
|
||||||
|
WHERE ASIEN = vBookNumber
|
||||||
|
)sub
|
||||||
|
)
|
||||||
|
WHERE ASIEN = vBookNumber
|
||||||
|
AND EURODEBE <> 0
|
||||||
|
ORDER BY id DESC
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,38 @@
|
||||||
|
USE vn;
|
||||||
|
DELIMITER $$
|
||||||
|
$$
|
||||||
|
CREATE OR REPLACE
|
||||||
|
ALGORITHM = UNDEFINED VIEW `vn`.`saleVolume` AS
|
||||||
|
select
|
||||||
|
`s`.`ticketFk` AS `ticketFk`,
|
||||||
|
`s`.`id` AS `saleFk`,
|
||||||
|
round(`ic`.`cm3delivery` * `s`.`quantity` / 1000, 0) AS `litros`,
|
||||||
|
`t`.`routeFk` AS `routeFk`,
|
||||||
|
`t`.`shipped` AS `shipped`,
|
||||||
|
`t`.`landed` AS `landed`,
|
||||||
|
`s`.`quantity` * `ic`.`cm3delivery` / 1000000 AS `volume`,
|
||||||
|
`s`.`quantity` * `ic`.`grams` / 1000 AS `physicalWeight`,
|
||||||
|
`s`.`quantity` * `ic`.`cm3delivery` * greatest(`i`.`density`, 167) / 1000000 AS `weight`,
|
||||||
|
`s`.`quantity` * `ic`.`cm3delivery` / 1000000 AS `physicalVolume`,
|
||||||
|
`s`.`quantity` * `ic`.`cm3delivery` * ifnull(`t`.`zonePrice`, `z`.`price`) / (`vc`.`standardFlowerBox` * 1000) AS `freight`,
|
||||||
|
`t`.`zoneFk` AS `zoneFk`,
|
||||||
|
`t`.`clientFk` AS `clientFk`,
|
||||||
|
`s`.`isPicked` AS `isPicked`,
|
||||||
|
`s`.`quantity` * `s`.`price` * (100 - `s`.`discount`) / 100 AS `eurosValue`,
|
||||||
|
`i`.`itemPackingTypeFk` AS `itemPackingTypeFk`
|
||||||
|
from
|
||||||
|
(((((`sale` `s`
|
||||||
|
join `item` `i` on
|
||||||
|
(`i`.`id` = `s`.`itemFk`))
|
||||||
|
join `ticket` `t` on
|
||||||
|
(`t`.`id` = `s`.`ticketFk`))
|
||||||
|
join `zone` `z` on
|
||||||
|
(`z`.`id` = `t`.`zoneFk`))
|
||||||
|
join `volumeConfig` `vc`)
|
||||||
|
join `itemCost` `ic` on
|
||||||
|
(`ic`.`itemFk` = `s`.`itemFk`
|
||||||
|
and `ic`.`warehouseFk` = `t`.`warehouseFk`))
|
||||||
|
where
|
||||||
|
`s`.`quantity` > 0;
|
||||||
|
$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE `vn`.`smsConfig` ADD apiKey varchar(50) NULL;
|
||||||
|
ALTER TABLE `vn`.`smsConfig` CHANGE `user` user__ varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;
|
||||||
|
ALTER TABLE `vn`.`smsConfig` CHANGE password password__ varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;
|
||||||
|
ALTER TABLE `vn`.`sms` MODIFY COLUMN statusCode smallint(9) DEFAULT 0 NULL;
|
||||||
|
ALTER TABLE `vn`.`sms` MODIFY COLUMN status varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT 'OK' NULL;
|
|
@ -0,0 +1,25 @@
|
||||||
|
ALTER TABLE `postgresql`.`business` ADD payedHolidays INT NULL;
|
||||||
|
ALTER TABLE `postgresql`.`business` CHANGE payedHolidays payedHolidays INT NULL AFTER reasonEndFk;
|
||||||
|
|
||||||
|
CREATE OR REPLACE
|
||||||
|
ALGORITHM = UNDEFINED VIEW `vn`.`workerLabour` AS
|
||||||
|
select
|
||||||
|
`b`.`business_id` AS `businessFk`,
|
||||||
|
`p`.`id_trabajador` AS `workerFk`,
|
||||||
|
`bl`.`workcenter_id` AS `workCenterFk`,
|
||||||
|
`b`.`date_start` AS `started`,
|
||||||
|
`b`.`date_end` AS `ended`,
|
||||||
|
`d`.`id` AS `departmentFk`,
|
||||||
|
`b`.`payedHolidays` AS `payedHolidays`
|
||||||
|
from
|
||||||
|
((((`postgresql`.`person` `p`
|
||||||
|
join `postgresql`.`profile` `pr` on
|
||||||
|
((`pr`.`person_id` = `p`.`person_id`)))
|
||||||
|
join `postgresql`.`business` `b` on
|
||||||
|
((`b`.`client_id` = `pr`.`profile_id`)))
|
||||||
|
join `postgresql`.`business_labour` `bl` on
|
||||||
|
((`b`.`business_id` = `bl`.`business_id`)))
|
||||||
|
join `vn`.`department` `d` on
|
||||||
|
((`d`.`id` = `bl`.`department_id`)))
|
||||||
|
order by
|
||||||
|
`b`.`date_start` desc
|
|
@ -0,0 +1,7 @@
|
||||||
|
UPDATE `vn`.`smsConfig`
|
||||||
|
SET `uri` = 'https://api.gateway360.com/api/3.0/sms/send'
|
||||||
|
WHERE `id` = 1;
|
||||||
|
|
||||||
|
UPDATE `vn`.`smsConfig`
|
||||||
|
SET `apiKey` = '5715476da95b46d686a5a255e6459523'
|
||||||
|
WHERE `id` = 1;
|
File diff suppressed because one or more lines are too long
|
@ -8,7 +8,7 @@ ALTER TABLE `vn`.`ticket` AUTO_INCREMENT = 1;
|
||||||
|
|
||||||
INSERT INTO `salix`.`AccessToken` (`id`, `ttl`, `created`, `userId`)
|
INSERT INTO `salix`.`AccessToken` (`id`, `ttl`, `created`, `userId`)
|
||||||
VALUES
|
VALUES
|
||||||
('TOTALLY_SECURE_TOKEN', '1209600', CURDATE(), 66);
|
('DEFAULT_TOKEN', '1209600', CURDATE(), 66);
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO `vn`.`ticketConfig` (`id`, `scopeDays`)
|
INSERT INTO `vn`.`ticketConfig` (`id`, `scopeDays`)
|
||||||
|
@ -104,17 +104,17 @@ INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
|
||||||
(3, 'GBP', 'Libra', 1),
|
(3, 'GBP', 'Libra', 1),
|
||||||
(4, 'JPY', 'Yen Japones', 1);
|
(4, 'JPY', 'Yen Japones', 1);
|
||||||
|
|
||||||
INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`, `continentFk`)
|
INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`, `continentFk`, `hasDailyInvoice`, `CEE`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'España', 1, 'ES', 1, 24, 4),
|
(1, 'España', 1, 'ES', 1, 24, 4, 0, 1),
|
||||||
(2, 'Italia', 1, 'IT', 1, 27, 4),
|
(2, 'Italia', 1, 'IT', 1, 27, 4, 0, 1),
|
||||||
(3, 'Alemania', 1, 'DE', 1, 22, 4),
|
(3, 'Alemania', 1, 'DE', 1, 22, 4, 0, 1),
|
||||||
(4, 'Rumania', 1, 'RO', 1, 24, 4),
|
(4, 'Rumania', 1, 'RO', 1, 24, 4, 0, 1),
|
||||||
(5, 'Holanda', 1, 'NL', 1, 18, 4),
|
(5, 'Holanda', 1, 'NL', 1, 18, 4, 0, 1),
|
||||||
(8, 'Portugal', 1, 'PT', 1, 27, 4),
|
(8, 'Portugal', 1, 'PT', 1, 27, 4, 0, 1),
|
||||||
(13,'Ecuador', 0, 'EC', 1, 24, 2),
|
(13,'Ecuador', 0, 'EC', 1, 24, 2, 1, 2),
|
||||||
(19,'Francia', 1, 'FR', 1, 27, 4),
|
(19,'Francia', 1, 'FR', 1, 27, 4, 0, 1),
|
||||||
(30,'Canarias', 1, 'IC', 1, 24, 4);
|
(30,'Canarias', 1, 'IC', 1, 24, 4, 1, 2);
|
||||||
|
|
||||||
INSERT INTO `hedera`.`language` (`code`, `name`, `orgName`, `isActive`)
|
INSERT INTO `hedera`.`language` (`code`, `name`, `orgName`, `isActive`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -243,7 +243,7 @@ INSERT INTO `vn`.`province`(`id`, `name`, `countryFk`, `autonomyFk`, `warehouseF
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'Province one', 1, 1, NULL),
|
(1, 'Province one', 1, 1, NULL),
|
||||||
(2, 'Province two', 1, 1, NULL),
|
(2, 'Province two', 1, 1, NULL),
|
||||||
(3, 'Province three', 1, 2, NULL),
|
(3, 'Province three', 30, 2, NULL),
|
||||||
(4, 'Province four', 2, 3, NULL),
|
(4, 'Province four', 2, 3, NULL),
|
||||||
(5, 'Province five', 13, 4, NULL);
|
(5, 'Province five', 13, 4, NULL);
|
||||||
|
|
||||||
|
@ -455,7 +455,8 @@ INSERT INTO `vn`.`creditInsurance`(`id`, `creditClassification`, `credit`, `crea
|
||||||
|
|
||||||
INSERT INTO `vn`.`companyGroup`(`id`, `code`)
|
INSERT INTO `vn`.`companyGroup`(`id`, `code`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'Wayne Industries');
|
(1, 'wayneIndustries'),
|
||||||
|
(2, 'Verdnatura');
|
||||||
|
|
||||||
INSERT INTO `vn`.`bankEntity`(`id`, `countryFk`, `name`, `bic`)
|
INSERT INTO `vn`.`bankEntity`(`id`, `countryFk`, `name`, `bic`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -466,13 +467,13 @@ INSERT INTO `vn`.`supplierAccount`(`id`, `supplierFk`, `iban`, `bankEntityFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(241, 442, 'ES111122333344111122221111', 128);
|
(241, 442, 'ES111122333344111122221111', 128);
|
||||||
|
|
||||||
INSERT INTO `vn`.`company`(`id`, `code`, `supplierAccountFk`, `workerManagerFk`, `companyCode`, `sage200Company`, `expired`, `phytosanitary`)
|
INSERT INTO `vn`.`company`(`id`, `code`, `supplierAccountFk`, `workerManagerFk`, `companyCode`, `sage200Company`, `expired`, `companyGroupFk`, `phytosanitary`)
|
||||||
VALUES
|
VALUES
|
||||||
(69 , 'CCs', NULL, 30, NULL, 0, NULL, NULL),
|
(69 , 'CCs', NULL, 30, NULL, 0, NULL, 1, NULL),
|
||||||
(442 , 'VNL', 241, 30, 2 , 1, NULL, 'VNL Company - Plant passport'),
|
(442 , 'VNL', 241, 30, 2 , 1, NULL, 2, 'VNL Company - Plant passport'),
|
||||||
(567 , 'VNH', NULL, 30, NULL, 4, NULL, 'VNH Company - Plant passport'),
|
(567 , 'VNH', NULL, 30, NULL, 4, NULL, 1, 'VNH Company - Plant passport'),
|
||||||
(791 , 'FTH', NULL, 30, NULL, 3, '2015-11-30', NULL),
|
(791 , 'FTH', NULL, 30, NULL, 3, '2015-11-30', 1, NULL),
|
||||||
(1381, 'ORN', NULL, 30, NULL, 7, NULL, 'ORN Company - Plant passport');
|
(1381, 'ORN', NULL, 30, NULL, 7, NULL, 1, 'ORN Company - Plant passport');
|
||||||
|
|
||||||
INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion`)
|
INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -486,7 +487,9 @@ INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaF
|
||||||
('A', 'Global nacional', 1, 'NATIONAL', 0),
|
('A', 'Global nacional', 1, 'NATIONAL', 0),
|
||||||
('T', 'Española rapida', 1, 'NATIONAL', 0),
|
('T', 'Española rapida', 1, 'NATIONAL', 0),
|
||||||
('V', 'Intracomunitaria global', 0, 'CEE', 1),
|
('V', 'Intracomunitaria global', 0, 'CEE', 1),
|
||||||
('M', 'Múltiple nacional', 1, 'NATIONAL', 0);
|
('M', 'Múltiple nacional', 1, 'NATIONAL', 0),
|
||||||
|
('E', 'Exportación rápida', 0, 'WORLD', 0);
|
||||||
|
;
|
||||||
|
|
||||||
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`)
|
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -606,7 +609,7 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF
|
||||||
(9 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1104, 'Stark tower', 124, NULL, 0, 3, 5, 1, CURDATE()),
|
(9 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1104, 'Stark tower', 124, NULL, 0, 3, 5, 1, CURDATE()),
|
||||||
(10, 1, 1, 5, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1102, 'Ingram Street', 2, NULL, 0, 1, 5, 1, CURDATE()),
|
(10, 1, 1, 5, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1102, 'Ingram Street', 2, NULL, 0, 1, 5, 1, CURDATE()),
|
||||||
(11, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1102, 'NY roofs', 122, NULL, 0, 3, 5, 1, CURDATE()),
|
(11, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1102, 'NY roofs', 122, NULL, 0, 3, 5, 1, CURDATE()),
|
||||||
(12, 1, 1, 1, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, CURDATE()),
|
(12, 1, 8, 1, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, CURDATE()),
|
||||||
(13, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1103, 'Phone Box', 123, NULL, 0, 3, 5, 1, CURDATE()),
|
(13, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1103, 'Phone Box', 123, NULL, 0, 3, 5, 1, CURDATE()),
|
||||||
(14, 1, 2, 1, NULL, CURDATE(), CURDATE(), 1104, 'Malibu Point', 4, NULL, 0, 9, 5, 1, CURDATE()),
|
(14, 1, 2, 1, NULL, CURDATE(), CURDATE(), 1104, 'Malibu Point', 4, NULL, 0, 9, 5, 1, CURDATE()),
|
||||||
(15, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1105, 'An incredibly long alias for testing purposes', 125, NULL, 0, 3, 5, 1, CURDATE()),
|
(15, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1105, 'An incredibly long alias for testing purposes', 125, NULL, 0, 3, 5, 1, CURDATE()),
|
||||||
|
@ -800,25 +803,25 @@ INSERT INTO `vn`.`itemFamily`(`code`, `description`)
|
||||||
('VT', 'Sales');
|
('VT', 'Sales');
|
||||||
|
|
||||||
INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`,
|
INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`,
|
||||||
`comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`, `isFloramondo`, `genericFk`)
|
`comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`, `isFloramondo`, `genericFk`, `itemPackingTypeFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT', 0, NULL),
|
(1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT', 0, NULL, 'V'),
|
||||||
(2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT', 0, NULL),
|
(2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT', 0, NULL, 'H'),
|
||||||
(3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT', 0, NULL),
|
(3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT', 0, NULL, NULL),
|
||||||
(4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT', 0, NULL),
|
(4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT', 0, NULL, NULL),
|
||||||
(5, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 3, 'VT', 0, NULL),
|
(5, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 3, 'VT', 0, NULL, NULL),
|
||||||
(6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT', 0, NULL),
|
(6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT', 0, NULL, NULL),
|
||||||
(7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT', 0, NULL),
|
(7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT', 0, NULL, NULL),
|
||||||
(8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT', 0, NULL),
|
(8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT', 0, NULL, NULL),
|
||||||
(9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 1, NULL),
|
(9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 1, NULL, NULL),
|
||||||
(10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT', 0, NULL),
|
(10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT', 0, NULL, NULL),
|
||||||
(11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT', 0, NULL),
|
(11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT', 0, NULL, NULL),
|
||||||
(12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT', 0, NULL),
|
(12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT', 0, NULL, NULL),
|
||||||
(13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 0, 2, 'VT', 1, NULL),
|
(13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 0, 2, 'VT', 1, NULL, NULL),
|
||||||
(14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT', 1, NULL),
|
(14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT', 1, NULL, NULL),
|
||||||
(15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0, NULL),
|
(15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0, NULL, NULL),
|
||||||
(16, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0, NULL),
|
(16, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0, NULL, NULL),
|
||||||
(71, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT', 0, NULL);
|
(71, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT', 0, NULL, NULL);
|
||||||
|
|
||||||
-- Update the taxClass after insert of the items
|
-- Update the taxClass after insert of the items
|
||||||
UPDATE `vn`.`itemTaxCountry` SET `taxClassFk` = 2
|
UPDATE `vn`.`itemTaxCountry` SET `taxClassFk` = 2
|
||||||
|
@ -1078,11 +1081,15 @@ INSERT INTO `vn`.`itemPlacement`(`id`, `itemFk`, `warehouseFk`, `code`)
|
||||||
(3, 1, 3, 'A33'),
|
(3, 1, 3, 'A33'),
|
||||||
(4, 2, 1, 'A44');
|
(4, 2, 1, 'A44');
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`train`(`id`, `name`)
|
||||||
INSERT INTO `vn`.`collection`(`id`, `workerFk`, `stateFk`, `created`)
|
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1106, 5, DATE_ADD(CURDATE(),INTERVAL +1 DAY)),
|
(1, 'Train1'),
|
||||||
(2, 1106, 14, CURDATE());
|
(2, 'Train2');
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`collection`(`id`, `workerFk`, `stateFk`, `created`, `trainFk`)
|
||||||
|
VALUES
|
||||||
|
(1, 1106, 5, DATE_ADD(CURDATE(),INTERVAL +1 DAY), 1),
|
||||||
|
(2, 1106, 14, CURDATE(), 1);
|
||||||
|
|
||||||
INSERT INTO `vn`.`ticketCollection`(`id`, `ticketFk`, `collectionFk`)
|
INSERT INTO `vn`.`ticketCollection`(`id`, `ticketFk`, `collectionFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1290,11 +1297,11 @@ INSERT INTO `vn`.`supplierAddress`(`id`, `supplierFk`, `nickname`, `street`, `pr
|
||||||
(5, 442, 'GCR building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222'),
|
(5, 442, 'GCR building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222'),
|
||||||
(6, 442, 'The Gotham Tonight building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222');
|
(6, 442, 'The Gotham Tonight building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222');
|
||||||
|
|
||||||
INSERT INTO `vn`.`supplier`(`id`, `name`, `nickname`,`account`,`countryFk`,`nif`,`isFarmer`,`commission`, `created`, `isActive`, `street`, `city`, `provinceFk`, `postCode`, `payMethodFk`, `payDemFk`, `payDay`, `taxTypeSageFk`, `withholdingSageFk`, `transactionTypeSageFk`, `workerFk`, `supplierActivityFk`, `isPayMethodChecked`)
|
INSERT INTO `vn`.`supplier`(`id`, `name`, `nickname`,`account`,`countryFk`,`nif`, `commission`, `created`, `isActive`, `street`, `city`, `provinceFk`, `postCode`, `payMethodFk`, `payDemFk`, `payDay`, `taxTypeSageFk`, `withholdingSageFk`, `transactionTypeSageFk`, `workerFk`, `supplierActivityFk`, `isPayMethodChecked`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'Plants SL', 'Plants nick', 4100000001, 1, '06089160W', 0, 0, CURDATE(), 1, 'supplier address 1', 'PONTEVEDRA', 1, 15214, 1, 1, 15, 4, 1, 1, 18, 'flowerPlants', 1),
|
(1, 'Plants SL', 'Plants nick', 4100000001, 1, '06089160W', 0, CURDATE(), 1, 'supplier address 1', 'PONTEVEDRA', 1, 15214, 1, 1, 15, 4, 1, 1, 18, 'flowerPlants', 1),
|
||||||
(2, 'Farmer King', 'The farmer', 4000020002, 1, '87945234L', 1, 0, CURDATE(), 1, 'supplier address 2', 'SILLA', 2, 43022, 1, 2, 10, 93, 2, 8, 18, 'animals', 1),
|
(2, 'Farmer King', 'The farmer', 4000020002, 1, '87945234L', 0, CURDATE(), 1, 'supplier address 2', 'SILLA', 2, 43022, 1, 2, 10, 93, 2, 8, 18, 'animals', 1),
|
||||||
(442, 'Verdnatura Levante SL', 'Verdnatura', 5115000442, 1, '06815934E', 0, 0, CURDATE(), 1, 'supplier address 3', 'SILLA', 1, 43022, 1, 2, 15, 6, 9, 3, 18, 'flowerPlants', 1);
|
(442, 'Verdnatura Levante SL', 'Verdnatura', 5115000442, 1, '06815934E', 0, CURDATE(), 1, 'supplier address 3', 'SILLA', 1, 43022, 1, 2, 15, 6, 9, 3, 18, 'flowerPlants', 1);
|
||||||
|
|
||||||
INSERT INTO `vn`.`supplierContact`(`id`, `supplierFk`, `phone`, `mobile`, `email`, `observation`, `name`)
|
INSERT INTO `vn`.`supplierContact`(`id`, `supplierFk`, `phone`, `mobile`, `email`, `observation`, `name`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1904,9 +1911,9 @@ INSERT INTO `postgresql`.`calendar_employee` (`business_id`, `calendar_state_id`
|
||||||
(1107, 1, IF(MONTH(CURDATE()) >= 1 AND DAY(CURDATE()) > 20, DATE_ADD(CURDATE(), INTERVAL -14 DAY), DATE_ADD(CURDATE(), INTERVAL 9 DAY))),
|
(1107, 1, IF(MONTH(CURDATE()) >= 1 AND DAY(CURDATE()) > 20, DATE_ADD(CURDATE(), INTERVAL -14 DAY), DATE_ADD(CURDATE(), INTERVAL 9 DAY))),
|
||||||
(1107, 2, IF(MONTH(CURDATE()) >= 1 AND DAY(CURDATE()) > 20, DATE_ADD(CURDATE(), INTERVAL -15 DAY), DATE_ADD(CURDATE(), INTERVAL 7 DAY)));
|
(1107, 2, IF(MONTH(CURDATE()) >= 1 AND DAY(CURDATE()) > 20, DATE_ADD(CURDATE(), INTERVAL -15 DAY), DATE_ADD(CURDATE(), INTERVAL 7 DAY)));
|
||||||
|
|
||||||
INSERT INTO `vn`.`smsConfig` (`id`, `uri`, `title`)
|
INSERT INTO `vn`.`smsConfig` (`id`, `uri`, `title`, `apiKey`)
|
||||||
VALUES
|
VALUES
|
||||||
('1', 'https://websms.xtratelecom.es/api_php/server.wsdl', 'Verdnatura');
|
('1', 'https://api.gateway360.com/api/3.0/sms/send', 'Verdnatura', '5715476da95b46d686a5a255e6459523');
|
||||||
|
|
||||||
INSERT INTO `vn`.`sharingClient`(`id`, `workerFk`, `started`, `ended`, `clientFk`)
|
INSERT INTO `vn`.`sharingClient`(`id`, `workerFk`, `started`, `ended`, `clientFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -2348,7 +2355,7 @@ REPLACE INTO `vn`.`invoiceIn`(`id`, `serialNumber`,`serial`, `supplierFk`, `issu
|
||||||
|
|
||||||
INSERT INTO `vn`.`invoiceInDueDay`(`invoiceInFk`, `dueDated`, `bankFk`, `amount`)
|
INSERT INTO `vn`.`invoiceInDueDay`(`invoiceInFk`, `dueDated`, `bankFk`, `amount`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, CURDATE(), 1, 237),
|
(1, CURDATE(), 1, 336.99),
|
||||||
(1, CURDATE(), 1, 15.25),
|
(1, CURDATE(), 1, 15.25),
|
||||||
(2, CURDATE(), 1, 168),
|
(2, CURDATE(), 1, 168),
|
||||||
(2, CURDATE(), 1, 55.17),
|
(2, CURDATE(), 1, 55.17),
|
||||||
|
|
12040
db/dump/structure.sql
12040
db/dump/structure.sql
File diff suppressed because it is too large
Load Diff
|
@ -458,7 +458,8 @@ export default {
|
||||||
firstSaleQuantity: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5)',
|
firstSaleQuantity: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(5)',
|
||||||
firstSaleDiscount: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(8)',
|
firstSaleDiscount: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(8)',
|
||||||
invoiceOutRef: 'vn-ticket-summary > vn-card > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(7) > section > span',
|
invoiceOutRef: 'vn-ticket-summary > vn-card > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(7) > section > span',
|
||||||
setOk: 'vn-ticket-summary vn-button[label="SET OK"] > button',
|
stateButton: 'vn-ticket-summary vn-button-menu > button ',
|
||||||
|
stateAutocomplete: 'div.filter.ng-scope > vn-textfield > div.container > div.infix > div.control',
|
||||||
descriptorTicketId: 'vn-ticket-descriptor > vn-descriptor-content > div > div.body > div.top > div'
|
descriptorTicketId: 'vn-ticket-descriptor > vn-descriptor-content > div > div.body > div.top > div'
|
||||||
},
|
},
|
||||||
ticketsIndex: {
|
ticketsIndex: {
|
||||||
|
@ -559,6 +560,7 @@ export default {
|
||||||
moreMenuUnmarkReseved: 'vn-item[name="unreserve"]',
|
moreMenuUnmarkReseved: 'vn-item[name="unreserve"]',
|
||||||
moreMenuUpdateDiscount: 'vn-item[name="discount"]',
|
moreMenuUpdateDiscount: 'vn-item[name="discount"]',
|
||||||
moreMenuRecalculatePrice: 'vn-item[name="calculatePrice"]',
|
moreMenuRecalculatePrice: 'vn-item[name="calculatePrice"]',
|
||||||
|
moreMenuPayBack: 'vn-item[name="payBack"]',
|
||||||
moreMenuUpdateDiscountInput: 'vn-input-number[ng-model="$ctrl.edit.discount"] input',
|
moreMenuUpdateDiscountInput: 'vn-input-number[ng-model="$ctrl.edit.discount"] input',
|
||||||
transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text',
|
transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text',
|
||||||
transferQuantityCell: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable',
|
transferQuantityCell: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable',
|
||||||
|
|
|
@ -206,7 +206,22 @@ describe('Ticket Edit sale path', () => {
|
||||||
expect(message.text).toContain('Data saved!');
|
expect(message.text).toContain('Data saved!');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should log in as salesAssistant and navigate to ticket sales', async() => {
|
||||||
|
await page.loginAndModule('salesAssistant', 'ticket');
|
||||||
|
await page.accessToSearchResult('16');
|
||||||
|
await page.accessToSection('ticket.card.sale');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select the third sale and create a pay back', async() => {
|
||||||
|
await page.waitToClick(selectors.ticketSales.firstSaleCheckbox);
|
||||||
|
await page.waitToClick(selectors.ticketSales.moreMenu);
|
||||||
|
await page.waitToClick(selectors.ticketSales.moreMenuPayBack);
|
||||||
|
await page.waitForState('ticket.card.sale');
|
||||||
|
});
|
||||||
|
|
||||||
it('should select the third sale and create a claim of it', async() => {
|
it('should select the third sale and create a claim of it', async() => {
|
||||||
|
await page.accessToSearchResult('16');
|
||||||
|
await page.accessToSection('ticket.card.sale');
|
||||||
await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox);
|
await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox);
|
||||||
await page.waitToClick(selectors.ticketSales.moreMenu);
|
await page.waitToClick(selectors.ticketSales.moreMenu);
|
||||||
await page.waitToClick(selectors.ticketSales.moreMenuCreateClaim);
|
await page.waitToClick(selectors.ticketSales.moreMenuCreateClaim);
|
||||||
|
|
|
@ -76,8 +76,24 @@ describe('Ticket Summary path', () => {
|
||||||
await page.waitForState('ticket.card.summary');
|
await page.waitForState('ticket.card.summary');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click on the SET OK button', async() => {
|
it('should set the ticket state to OK using the top right button', async() => {
|
||||||
await page.waitToClick(selectors.ticketSummary.setOk);
|
const searchValue = 'OK';
|
||||||
|
await page.waitToClick(selectors.ticketSummary.stateButton);
|
||||||
|
await page.write(selectors.ticketSummary.stateAutocomplete, searchValue);
|
||||||
|
try {
|
||||||
|
await page.waitForFunction(text => {
|
||||||
|
const element = document.querySelector('li.active');
|
||||||
|
if (element)
|
||||||
|
return element.innerText.toLowerCase().includes(text.toLowerCase());
|
||||||
|
}, {}, searchValue);
|
||||||
|
} catch (error) {
|
||||||
|
const state = await page.evaluate(() => {
|
||||||
|
const stateSelector = 'vn-ticket-summary vn-label-value:nth-child(1) > section > span';
|
||||||
|
return document.querySelector(stateSelector).value;
|
||||||
|
});
|
||||||
|
throw new Error(`${stateSelector} innerText is ${state}! ${error}`);
|
||||||
|
}
|
||||||
|
await page.keyboard.press('Enter');
|
||||||
const message = await page.waitForSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
expect(message.text).toContain('Data saved!');
|
||||||
|
|
|
@ -43,4 +43,10 @@
|
||||||
&.disabled.checked > .btn {
|
&.disabled.checked > .btn {
|
||||||
background-color: $color-font-secondary;
|
background-color: $color-font-secondary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[triple-state]:not(.indeterminate):not(.checked) {
|
||||||
|
.btn {
|
||||||
|
background-color: lighten($color-alert, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,9 +171,10 @@ export default class SmartTable extends Component {
|
||||||
if (field.length === 2)
|
if (field.length === 2)
|
||||||
sortType = field[1];
|
sortType = field[1];
|
||||||
|
|
||||||
|
const priority = this.sortCriteria.length + 1;
|
||||||
const column = this.columns.find(column => column.field == fieldName);
|
const column = this.columns.find(column => column.field == fieldName);
|
||||||
if (column) {
|
if (column) {
|
||||||
this.sortCriteria.push({field: fieldName, sortType: sortType});
|
this.sortCriteria.push({field: fieldName, sortType: sortType, priority: priority});
|
||||||
|
|
||||||
const isASC = sortType == 'ASC';
|
const isASC = sortType == 'ASC';
|
||||||
const isDESC = sortType == 'DESC';
|
const isDESC = sortType == 'DESC';
|
||||||
|
@ -187,6 +188,8 @@ export default class SmartTable extends Component {
|
||||||
column.element.classList.remove('desc');
|
column.element.classList.remove('desc');
|
||||||
column.element.classList.add('asc');
|
column.element.classList.add('asc');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setPriority(column.element, priority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,9 +244,13 @@ export default class SmartTable extends Component {
|
||||||
const isDESC = existingCriteria && existingCriteria.sortType == 'DESC';
|
const isDESC = existingCriteria && existingCriteria.sortType == 'DESC';
|
||||||
|
|
||||||
if (!existingCriteria) {
|
if (!existingCriteria) {
|
||||||
this.sortCriteria.push({field: field, sortType: 'ASC'});
|
const priority = this.sortCriteria.length + 1;
|
||||||
|
|
||||||
|
this.sortCriteria.push({field: field, sortType: 'ASC', priority: priority});
|
||||||
element.classList.remove('desc');
|
element.classList.remove('desc');
|
||||||
element.classList.add('asc');
|
element.classList.add('asc');
|
||||||
|
|
||||||
|
this.setPriority(element, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDESC) {
|
if (isDESC) {
|
||||||
|
@ -252,6 +259,8 @@ export default class SmartTable extends Component {
|
||||||
}), 1);
|
}), 1);
|
||||||
element.classList.remove('desc');
|
element.classList.remove('desc');
|
||||||
element.classList.remove('asc');
|
element.classList.remove('asc');
|
||||||
|
|
||||||
|
element.querySelector('sort-priority').remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isASC) {
|
if (isASC) {
|
||||||
|
@ -260,9 +269,29 @@ export default class SmartTable extends Component {
|
||||||
element.classList.add('desc');
|
element.classList.add('desc');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let priority = 0;
|
||||||
|
for (const criteria of this.sortCriteria) {
|
||||||
|
const column = this.columns.find(column => column.field == criteria.field);
|
||||||
|
if (column) {
|
||||||
|
criteria.priority = priority;
|
||||||
|
priority++;
|
||||||
|
|
||||||
|
column.element.querySelector('sort-priority').remove();
|
||||||
|
|
||||||
|
this.setPriority(column.element, priority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.applySort();
|
this.applySort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPriority(column, priority) {
|
||||||
|
const sortPriority = document.createElement('sort-priority');
|
||||||
|
sortPriority.setAttribute('class', 'sort-priority');
|
||||||
|
sortPriority.innerHTML = priority;
|
||||||
|
column.appendChild(sortPriority);
|
||||||
|
}
|
||||||
|
|
||||||
displaySearch() {
|
displaySearch() {
|
||||||
const header = this.element.querySelector('thead > tr');
|
const header = this.element.querySelector('thead > tr');
|
||||||
if (!header) return;
|
if (!header) return;
|
||||||
|
|
|
@ -96,9 +96,10 @@ describe('Component smartTable', () => {
|
||||||
|
|
||||||
expect(firstSortCriteria.field).toEqual('id');
|
expect(firstSortCriteria.field).toEqual('id');
|
||||||
expect(firstSortCriteria.sortType).toEqual('ASC');
|
expect(firstSortCriteria.sortType).toEqual('ASC');
|
||||||
|
expect(firstSortCriteria.priority).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should insert two new objects to the controller sortCriteria with a sortType values of "ASC" and "DESC"', () => {
|
it('should add new entries to the controller sortCriteria with a sortType values of "ASC" and "DESC"', () => {
|
||||||
const element = document.createElement('div');
|
const element = document.createElement('div');
|
||||||
controller.model = {order: 'test1, id DESC'};
|
controller.model = {order: 'test1, id DESC'};
|
||||||
controller.columns = [
|
controller.columns = [
|
||||||
|
@ -114,8 +115,11 @@ describe('Component smartTable', () => {
|
||||||
|
|
||||||
expect(firstSortCriteria.field).toEqual('test1');
|
expect(firstSortCriteria.field).toEqual('test1');
|
||||||
expect(firstSortCriteria.sortType).toEqual('ASC');
|
expect(firstSortCriteria.sortType).toEqual('ASC');
|
||||||
|
expect(firstSortCriteria.priority).toEqual(1);
|
||||||
|
|
||||||
expect(secondSortCriteria.field).toEqual('id');
|
expect(secondSortCriteria.field).toEqual('id');
|
||||||
expect(secondSortCriteria.sortType).toEqual('DESC');
|
expect(secondSortCriteria.sortType).toEqual('DESC');
|
||||||
|
expect(secondSortCriteria.priority).toEqual(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ smart-table {
|
||||||
|
|
||||||
}
|
}
|
||||||
th[field][number] {
|
th[field][number] {
|
||||||
& > :before {
|
& > span:before {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
font-family: 'Material Icons';
|
font-family: 'Material Icons';
|
||||||
content: 'arrow_downward';
|
content: 'arrow_downward';
|
||||||
|
@ -19,26 +19,26 @@ smart-table {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.asc > :before, &.desc > :before {
|
&.asc > span:before, &.desc > span:before {
|
||||||
color: $color-font;
|
color: $color-font;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.asc > :before {
|
&.asc > span:before {
|
||||||
content: 'arrow_upward';
|
content: 'arrow_upward';
|
||||||
}
|
}
|
||||||
|
|
||||||
&.desc > :before {
|
&.desc > span:before {
|
||||||
content: 'arrow_downward';
|
content: 'arrow_downward';
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover > :before {
|
&:hover > span:before {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
th[field]:not([number]) {
|
th[field]:not([number]) {
|
||||||
& > :after {
|
& > span:after {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
font-family: 'Material Icons';
|
font-family: 'Material Icons';
|
||||||
content: 'arrow_downward';
|
content: 'arrow_downward';
|
||||||
|
@ -48,20 +48,20 @@ smart-table {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.asc > :after, &.desc > :after {
|
&.asc > span:after, &.desc > span:after {
|
||||||
color: $color-font;
|
color: $color-font;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.asc > :after {
|
&.asc > span:after {
|
||||||
content: 'arrow_upward';
|
content: 'arrow_upward';
|
||||||
}
|
}
|
||||||
|
|
||||||
&.desc > :after {
|
&.desc > span:after {
|
||||||
content: 'arrow_downward';
|
content: 'arrow_downward';
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover > :after {
|
&:hover > span:after {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,4 +143,16 @@ smart-table {
|
||||||
flex: initial;
|
flex: initial;
|
||||||
width: 33%
|
width: 33%
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
.sort-priority {
|
||||||
|
background-color: $color-font-bg-marginal;
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: 2px 5px;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
width: 7px;
|
||||||
|
height: 13px;
|
||||||
|
|
||||||
|
font-size: 10px;
|
||||||
|
color: $color-font-bg
|
||||||
}
|
}
|
|
@ -23,371 +23,398 @@
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-100:before {
|
.icon-isTooLittle:before {
|
||||||
content: "\e976";
|
|
||||||
}
|
|
||||||
.icon-account:before {
|
|
||||||
content: "\e900";
|
|
||||||
}
|
|
||||||
.icon-actions:before {
|
|
||||||
content: "\e901";
|
|
||||||
}
|
|
||||||
.icon-addperson:before {
|
|
||||||
content: "\e902";
|
|
||||||
}
|
|
||||||
.icon-agency:before {
|
|
||||||
content: "\e903";
|
|
||||||
}
|
|
||||||
.icon-albaran:before {
|
|
||||||
content: "\e904";
|
|
||||||
}
|
|
||||||
.icon-anonymous:before {
|
|
||||||
content: "\e905";
|
|
||||||
}
|
|
||||||
.icon-apps:before {
|
|
||||||
content: "\e906";
|
|
||||||
}
|
|
||||||
.icon-artificial:before {
|
|
||||||
content: "\e907";
|
|
||||||
}
|
|
||||||
.icon-attach:before {
|
|
||||||
content: "\e908";
|
|
||||||
}
|
|
||||||
.icon-barcode:before {
|
|
||||||
content: "\e909";
|
|
||||||
}
|
|
||||||
.icon-basket:before {
|
|
||||||
content: "\e90a";
|
|
||||||
}
|
|
||||||
.icon-basketadd:before {
|
|
||||||
content: "\e90b";
|
|
||||||
}
|
|
||||||
.icon-bin:before {
|
|
||||||
content: "\e90c";
|
|
||||||
}
|
|
||||||
.icon-botanical:before {
|
|
||||||
content: "\e90d";
|
|
||||||
}
|
|
||||||
.icon-bucket:before {
|
|
||||||
content: "\e90e";
|
|
||||||
}
|
|
||||||
.icon-buscaman:before {
|
|
||||||
content: "\e90f";
|
|
||||||
}
|
|
||||||
.icon-buyrequest:before {
|
|
||||||
content: "\e910";
|
|
||||||
}
|
|
||||||
.icon-calc_volum .path1:before {
|
|
||||||
content: "\e911";
|
|
||||||
color: rgb(0, 0, 0);
|
|
||||||
}
|
|
||||||
.icon-calc_volum .path2:before {
|
|
||||||
content: "\e912";
|
|
||||||
margin-left: -1em;
|
|
||||||
color: rgb(0, 0, 0);
|
|
||||||
}
|
|
||||||
.icon-calc_volum .path3:before {
|
|
||||||
content: "\e913";
|
|
||||||
margin-left: -1em;
|
|
||||||
color: rgb(0, 0, 0);
|
|
||||||
}
|
|
||||||
.icon-calc_volum .path4:before {
|
|
||||||
content: "\e914";
|
|
||||||
margin-left: -1em;
|
|
||||||
color: rgb(0, 0, 0);
|
|
||||||
}
|
|
||||||
.icon-calc_volum .path5:before {
|
|
||||||
content: "\e915";
|
|
||||||
margin-left: -1em;
|
|
||||||
color: rgb(0, 0, 0);
|
|
||||||
}
|
|
||||||
.icon-calc_volum .path6:before {
|
|
||||||
content: "\e916";
|
|
||||||
margin-left: -1em;
|
|
||||||
color: rgb(255, 255, 255);
|
|
||||||
}
|
|
||||||
.icon-calendar:before {
|
|
||||||
content: "\e917";
|
|
||||||
}
|
|
||||||
.icon-catalog:before {
|
|
||||||
content: "\e918";
|
|
||||||
}
|
|
||||||
.icon-claims:before {
|
|
||||||
content: "\e919";
|
|
||||||
}
|
|
||||||
.icon-client:before {
|
|
||||||
content: "\e91a";
|
|
||||||
}
|
|
||||||
.icon-clone:before {
|
|
||||||
content: "\e91b";
|
content: "\e91b";
|
||||||
}
|
}
|
||||||
.icon-columnadd:before {
|
|
||||||
content: "\e91c";
|
|
||||||
}
|
|
||||||
.icon-columndelete:before {
|
|
||||||
content: "\e91d";
|
|
||||||
}
|
|
||||||
.icon-accessory:before {
|
|
||||||
content: "\e91e";
|
|
||||||
}
|
|
||||||
.icon-components:before {
|
|
||||||
content: "\e91f";
|
|
||||||
}
|
|
||||||
.icon-handmade:before {
|
|
||||||
content: "\e920";
|
|
||||||
}
|
|
||||||
.icon-consignatarios:before {
|
|
||||||
content: "\e921";
|
|
||||||
}
|
|
||||||
.icon-control:before {
|
|
||||||
content: "\e922";
|
|
||||||
}
|
|
||||||
.icon-credit:before {
|
|
||||||
content: "\e923";
|
|
||||||
}
|
|
||||||
.icon-deletedTicketCross:before {
|
|
||||||
content: "\e924";
|
|
||||||
}
|
|
||||||
.icon-deleteline:before {
|
|
||||||
content: "\e925";
|
|
||||||
}
|
|
||||||
.icon-delivery:before {
|
|
||||||
content: "\e926";
|
|
||||||
}
|
|
||||||
.icon-deliveryprices:before {
|
|
||||||
content: "\e927";
|
|
||||||
}
|
|
||||||
.icon-details:before {
|
|
||||||
content: "\e928";
|
|
||||||
}
|
|
||||||
.icon-dfiscales:before {
|
|
||||||
content: "\e929";
|
|
||||||
}
|
|
||||||
.icon-doc:before {
|
|
||||||
content: "\e92a";
|
|
||||||
}
|
|
||||||
.icon-entry:before {
|
|
||||||
content: "\e92b";
|
|
||||||
}
|
|
||||||
.icon-exit:before {
|
|
||||||
content: "\e92c";
|
|
||||||
}
|
|
||||||
.icon-eye:before {
|
|
||||||
content: "\e92d";
|
|
||||||
}
|
|
||||||
.icon-fixedPrice:before {
|
|
||||||
content: "\e92e";
|
|
||||||
}
|
|
||||||
.icon-flower:before {
|
|
||||||
content: "\e92f";
|
|
||||||
}
|
|
||||||
.icon-frozen:before {
|
.icon-frozen:before {
|
||||||
content: "\e930";
|
content: "\e900";
|
||||||
}
|
|
||||||
.icon-fruit:before {
|
|
||||||
content: "\e931";
|
|
||||||
}
|
|
||||||
.icon-funeral:before {
|
|
||||||
content: "\e932";
|
|
||||||
}
|
|
||||||
.icon-greuge:before {
|
|
||||||
content: "\e933";
|
|
||||||
}
|
|
||||||
.icon-grid:before {
|
|
||||||
content: "\e934";
|
|
||||||
}
|
|
||||||
.icon-handmadeArtificial:before {
|
|
||||||
content: "\e935";
|
|
||||||
}
|
|
||||||
.icon-headercol:before {
|
|
||||||
content: "\e936";
|
|
||||||
}
|
|
||||||
.icon-history:before {
|
|
||||||
content: "\e937";
|
|
||||||
}
|
|
||||||
.icon-disabled:before {
|
|
||||||
content: "\e938";
|
|
||||||
}
|
|
||||||
.icon-info:before {
|
|
||||||
content: "\e939";
|
|
||||||
}
|
|
||||||
.icon-inventory:before {
|
|
||||||
content: "\e93a";
|
|
||||||
}
|
|
||||||
.icon-invoice:before {
|
|
||||||
content: "\e93b";
|
|
||||||
}
|
|
||||||
.icon-invoice-in:before {
|
|
||||||
content: "\e93c";
|
|
||||||
}
|
|
||||||
.icon-invoice-in-create:before {
|
|
||||||
content: "\e93d";
|
|
||||||
}
|
|
||||||
.icon-invoice-out:before {
|
|
||||||
content: "\e93e";
|
|
||||||
}
|
|
||||||
.icon-item:before {
|
|
||||||
content: "\e93f";
|
|
||||||
}
|
|
||||||
.icon-languaje:before {
|
|
||||||
content: "\e940";
|
|
||||||
}
|
|
||||||
.icon-lines:before {
|
|
||||||
content: "\e941";
|
|
||||||
}
|
|
||||||
.icon-linesprepaired:before {
|
|
||||||
content: "\e942";
|
|
||||||
}
|
|
||||||
.icon-logout:before {
|
|
||||||
content: "\e943";
|
|
||||||
}
|
|
||||||
.icon-mana:before {
|
|
||||||
content: "\e944";
|
|
||||||
}
|
|
||||||
.icon-mandatory:before {
|
|
||||||
content: "\e945";
|
|
||||||
}
|
|
||||||
.icon-net:before {
|
|
||||||
content: "\e946";
|
|
||||||
}
|
|
||||||
.icon-niche:before {
|
|
||||||
content: "\e947";
|
|
||||||
}
|
|
||||||
.icon-no036:before {
|
|
||||||
content: "\e948";
|
|
||||||
}
|
|
||||||
.icon-notes:before {
|
|
||||||
content: "\e949";
|
|
||||||
}
|
|
||||||
.icon-noweb:before {
|
|
||||||
content: "\e94a";
|
|
||||||
}
|
|
||||||
.icon-onlinepayment:before {
|
|
||||||
content: "\e94b";
|
|
||||||
}
|
|
||||||
.icon-package:before {
|
|
||||||
content: "\e94c";
|
|
||||||
}
|
|
||||||
.icon-payment:before {
|
|
||||||
content: "\e94d";
|
|
||||||
}
|
|
||||||
.icon-pbx:before {
|
|
||||||
content: "\e94e";
|
|
||||||
}
|
}
|
||||||
.icon-Person:before {
|
.icon-Person:before {
|
||||||
content: "\e94f";
|
content: "\e901";
|
||||||
}
|
}
|
||||||
.icon-pets:before {
|
.icon-handmadeArtificial:before {
|
||||||
content: "\e950";
|
content: "\e902";
|
||||||
}
|
}
|
||||||
.icon-photo:before {
|
.icon-fruit:before {
|
||||||
content: "\e951";
|
content: "\e903";
|
||||||
}
|
}
|
||||||
.icon-plant:before {
|
.icon-funeral:before {
|
||||||
content: "\e952";
|
content: "\e904";
|
||||||
}
|
|
||||||
.icon-stowaway:before {
|
|
||||||
content: "\e953";
|
|
||||||
}
|
|
||||||
.icon-preserved:before {
|
|
||||||
content: "\e954";
|
|
||||||
}
|
|
||||||
.icon-recovery:before {
|
|
||||||
content: "\e955";
|
|
||||||
}
|
|
||||||
.icon-regentry:before {
|
|
||||||
content: "\e956";
|
|
||||||
}
|
|
||||||
.icon-reserve:before {
|
|
||||||
content: "\e957";
|
|
||||||
}
|
|
||||||
.icon-revision:before {
|
|
||||||
content: "\e958";
|
|
||||||
}
|
|
||||||
.icon-risk:before {
|
|
||||||
content: "\e959";
|
|
||||||
}
|
|
||||||
.icon-services:before {
|
|
||||||
content: "\e95a";
|
|
||||||
}
|
|
||||||
.icon-settings:before {
|
|
||||||
content: "\e95b";
|
|
||||||
}
|
|
||||||
.icon-shipment-01 .path1:before {
|
|
||||||
content: "\e95c";
|
|
||||||
color: rgb(225, 225, 225);
|
|
||||||
}
|
|
||||||
.icon-shipment-01 .path2:before {
|
|
||||||
content: "\e95d";
|
|
||||||
margin-left: -1em;
|
|
||||||
color: rgb(0, 0, 0);
|
|
||||||
}
|
|
||||||
.icon-sign:before {
|
|
||||||
content: "\e95e";
|
|
||||||
}
|
|
||||||
.icon-sms:before {
|
|
||||||
content: "\e95f";
|
|
||||||
}
|
|
||||||
.icon-solclaim:before {
|
|
||||||
content: "\e960";
|
|
||||||
}
|
|
||||||
.icon-solunion:before {
|
|
||||||
content: "\e961";
|
|
||||||
}
|
|
||||||
.icon-splitline:before {
|
|
||||||
content: "\e962";
|
|
||||||
}
|
|
||||||
.icon-splur:before {
|
|
||||||
content: "\e963";
|
|
||||||
}
|
|
||||||
.icon-supplier:before {
|
|
||||||
content: "\e965";
|
|
||||||
}
|
|
||||||
.icon-supplierfalse:before {
|
|
||||||
content: "\e966";
|
|
||||||
}
|
|
||||||
.icon-tags:before {
|
|
||||||
content: "\e967";
|
|
||||||
}
|
|
||||||
.icon-tax:before {
|
|
||||||
content: "\e968";
|
|
||||||
}
|
|
||||||
.icon-thermometer:before {
|
|
||||||
content: "\e969";
|
|
||||||
}
|
|
||||||
.icon-ticket:before {
|
|
||||||
content: "\e96a";
|
|
||||||
}
|
|
||||||
.icon-traceability:before {
|
|
||||||
content: "\e96b";
|
|
||||||
}
|
|
||||||
.icon-transaction:before {
|
|
||||||
content: "\e96c";
|
|
||||||
}
|
}
|
||||||
.icon-treatments:before {
|
.icon-treatments:before {
|
||||||
content: "\e96d";
|
content: "\e905";
|
||||||
}
|
}
|
||||||
.icon-unavailable:before {
|
.icon-preserved:before {
|
||||||
content: "\e96e";
|
content: "\e906";
|
||||||
}
|
}
|
||||||
.icon-greenery:before {
|
.icon-greenery:before {
|
||||||
content: "\e96f";
|
content: "\e907";
|
||||||
}
|
}
|
||||||
.icon-volume:before {
|
.icon-plant:before {
|
||||||
content: "\e970";
|
content: "\e908";
|
||||||
}
|
}
|
||||||
.icon-wand:before {
|
.icon-handmade:before {
|
||||||
content: "\e971";
|
content: "\e909";
|
||||||
}
|
}
|
||||||
.icon-web:before {
|
.icon-accessory:before {
|
||||||
content: "\e972";
|
content: "\e90a";
|
||||||
}
|
}
|
||||||
.icon-wiki:before {
|
.icon-artificial:before {
|
||||||
content: "\e973";
|
content: "\e90b";
|
||||||
}
|
}
|
||||||
.icon-worker:before {
|
.icon-flower:before {
|
||||||
content: "\e974";
|
content: "\e90c";
|
||||||
|
}
|
||||||
|
.icon-fixedPrice:before {
|
||||||
|
content: "\e90d";
|
||||||
|
}
|
||||||
|
.icon-addperson:before {
|
||||||
|
content: "\e90e";
|
||||||
|
}
|
||||||
|
.icon-supplierfalse:before {
|
||||||
|
content: "\e90f";
|
||||||
|
}
|
||||||
|
.icon-invoice-out:before {
|
||||||
|
content: "\e910";
|
||||||
|
}
|
||||||
|
.icon-invoice-in:before {
|
||||||
|
content: "\e911";
|
||||||
|
}
|
||||||
|
.icon-invoice-in-create:before {
|
||||||
|
content: "\e912";
|
||||||
|
}
|
||||||
|
.icon-basketadd:before {
|
||||||
|
content: "\e913";
|
||||||
|
}
|
||||||
|
.icon-basket:before {
|
||||||
|
content: "\e914";
|
||||||
|
}
|
||||||
|
.icon-calc_volum .path1:before {
|
||||||
|
content: "\e915";
|
||||||
|
}
|
||||||
|
.icon-calc_volum .path2:before {
|
||||||
|
content: "\e916";
|
||||||
|
margin-left: -1em;
|
||||||
|
}
|
||||||
|
.icon-calc_volum .path3:before {
|
||||||
|
content: "\e917";
|
||||||
|
margin-left: -1em;
|
||||||
|
}
|
||||||
|
.icon-calc_volum .path4:before {
|
||||||
|
content: "\e918";
|
||||||
|
margin-left: -1em;
|
||||||
|
}
|
||||||
|
.icon-calc_volum .path5:before {
|
||||||
|
content: "\e919";
|
||||||
|
margin-left: -1em;
|
||||||
|
}
|
||||||
|
.icon-calc_volum .path6:before {
|
||||||
|
content: "\e91a";
|
||||||
|
margin-left: -1em;
|
||||||
|
}
|
||||||
|
.icon-deliveryprices:before {
|
||||||
|
content: "\e91c";
|
||||||
|
}
|
||||||
|
.icon-onlinepayment:before {
|
||||||
|
content: "\e91d";
|
||||||
|
}
|
||||||
|
.icon-risk:before {
|
||||||
|
content: "\e91e";
|
||||||
|
}
|
||||||
|
.icon-noweb:before {
|
||||||
|
content: "\e91f";
|
||||||
|
}
|
||||||
|
.icon-no036:before {
|
||||||
|
content: "\e920";
|
||||||
|
}
|
||||||
|
.icon-inactive:before {
|
||||||
|
content: "\e921";
|
||||||
|
}
|
||||||
|
.icon-unavailable:before {
|
||||||
|
content: "\e922";
|
||||||
|
}
|
||||||
|
.icon-invoice-01:before {
|
||||||
|
content: "\e923";
|
||||||
|
}
|
||||||
|
.icon-invoice:before {
|
||||||
|
content: "\e924";
|
||||||
|
}
|
||||||
|
.icon-supplier:before {
|
||||||
|
content: "\e925";
|
||||||
|
}
|
||||||
|
.icon-client2:before {
|
||||||
|
content: "\e926";
|
||||||
|
}
|
||||||
|
.icon-supplier2:before {
|
||||||
|
content: "\e927";
|
||||||
|
}
|
||||||
|
.icon-client:before {
|
||||||
|
content: "\e928";
|
||||||
|
}
|
||||||
|
.icon-shipment-01:before {
|
||||||
|
content: "\e929";
|
||||||
|
}
|
||||||
|
.icon-inventory:before {
|
||||||
|
content: "\e92b";
|
||||||
}
|
}
|
||||||
.icon-zone:before {
|
.icon-zone:before {
|
||||||
|
content: "\e92c";
|
||||||
|
}
|
||||||
|
.icon-wiki:before {
|
||||||
|
content: "\e92d";
|
||||||
|
}
|
||||||
|
.icon-attach:before {
|
||||||
|
content: "\e92e";
|
||||||
|
}
|
||||||
|
.icon-zone2:before {
|
||||||
|
content: "\e92f";
|
||||||
|
}
|
||||||
|
.icon-anonymous:before {
|
||||||
|
content: "\e930";
|
||||||
|
}
|
||||||
|
.icon-net:before {
|
||||||
|
content: "\e931";
|
||||||
|
}
|
||||||
|
.icon-buyrequest:before {
|
||||||
|
content: "\e932";
|
||||||
|
}
|
||||||
|
.icon-thermometer:before {
|
||||||
|
content: "\e933";
|
||||||
|
}
|
||||||
|
.icon-entry:before {
|
||||||
|
content: "\e934";
|
||||||
|
}
|
||||||
|
.icon-deletedTicket:before {
|
||||||
|
content: "\e935";
|
||||||
|
}
|
||||||
|
.icon-deliveryprices-01:before {
|
||||||
|
content: "\e936";
|
||||||
|
}
|
||||||
|
.icon-catalog:before {
|
||||||
|
content: "\e937";
|
||||||
|
}
|
||||||
|
.icon-agency:before {
|
||||||
|
content: "\e938";
|
||||||
|
}
|
||||||
|
.icon-delivery:before {
|
||||||
|
content: "\e939";
|
||||||
|
}
|
||||||
|
.icon-wand:before {
|
||||||
|
content: "\e93a";
|
||||||
|
}
|
||||||
|
.icon-buscaman:before {
|
||||||
|
content: "\e93b";
|
||||||
|
}
|
||||||
|
.icon-pbx:before {
|
||||||
|
content: "\e93c";
|
||||||
|
}
|
||||||
|
.icon-calendar:before {
|
||||||
|
content: "\e93d";
|
||||||
|
}
|
||||||
|
.icon-splitline:before {
|
||||||
|
content: "\e93e";
|
||||||
|
}
|
||||||
|
.icon-consignatarios:before {
|
||||||
|
content: "\e93f";
|
||||||
|
}
|
||||||
|
.icon-tax:before {
|
||||||
|
content: "\e940";
|
||||||
|
}
|
||||||
|
.icon-notes:before {
|
||||||
|
content: "\e941";
|
||||||
|
}
|
||||||
|
.icon-lines:before {
|
||||||
|
content: "\e942";
|
||||||
|
}
|
||||||
|
.icon-languaje:before {
|
||||||
|
content: "\e943";
|
||||||
|
}
|
||||||
|
.icon-greuge:before {
|
||||||
|
content: "\e944";
|
||||||
|
}
|
||||||
|
.icon-credit:before {
|
||||||
|
content: "\e945";
|
||||||
|
}
|
||||||
|
.icon-components:before {
|
||||||
|
content: "\e946";
|
||||||
|
}
|
||||||
|
.icon-pets:before {
|
||||||
|
content: "\e947";
|
||||||
|
}
|
||||||
|
.icon-linesprepaired:before {
|
||||||
|
content: "\e948";
|
||||||
|
}
|
||||||
|
.icon-control:before {
|
||||||
|
content: "\e949";
|
||||||
|
}
|
||||||
|
.icon-revision:before {
|
||||||
|
content: "\e94a";
|
||||||
|
}
|
||||||
|
.icon-newinvoices:before {
|
||||||
|
content: "\e94b";
|
||||||
|
}
|
||||||
|
.icon-services:before {
|
||||||
|
content: "\e94c";
|
||||||
|
}
|
||||||
|
.icon-newalbaran:before {
|
||||||
|
content: "\e94d";
|
||||||
|
}
|
||||||
|
.icon-solunion:before {
|
||||||
|
content: "\e94e";
|
||||||
|
}
|
||||||
|
.icon-stowaway:before {
|
||||||
|
content: "\e94f";
|
||||||
|
}
|
||||||
|
.icon-exit:before {
|
||||||
|
content: "\e950";
|
||||||
|
}
|
||||||
|
.icon-apps:before {
|
||||||
|
content: "\e951";
|
||||||
|
}
|
||||||
|
.icon-info:before {
|
||||||
|
content: "\e952";
|
||||||
|
}
|
||||||
|
.icon-columndelete:before {
|
||||||
|
content: "\e953";
|
||||||
|
}
|
||||||
|
.icon-columnadd:before {
|
||||||
|
content: "\e954";
|
||||||
|
}
|
||||||
|
.icon-deleteline:before {
|
||||||
|
content: "\e955";
|
||||||
|
}
|
||||||
|
.icon-item:before {
|
||||||
|
content: "\e956";
|
||||||
|
}
|
||||||
|
.icon-worker:before {
|
||||||
|
content: "\e957";
|
||||||
|
}
|
||||||
|
.icon-headercol:before {
|
||||||
|
content: "\e958";
|
||||||
|
}
|
||||||
|
.icon-reserva:before {
|
||||||
|
content: "\e959";
|
||||||
|
}
|
||||||
|
.icon-100:before {
|
||||||
|
content: "\e95a";
|
||||||
|
}
|
||||||
|
.icon-noweb1:before {
|
||||||
|
content: "\e95b";
|
||||||
|
}
|
||||||
|
.icon-settings1:before {
|
||||||
|
content: "\e95c";
|
||||||
|
}
|
||||||
|
.icon-sign:before {
|
||||||
|
content: "\e95d";
|
||||||
|
}
|
||||||
|
.icon-polizon:before {
|
||||||
|
content: "\e95e";
|
||||||
|
}
|
||||||
|
.icon-solclaim:before {
|
||||||
|
content: "\e95f";
|
||||||
|
}
|
||||||
|
.icon-actions:before {
|
||||||
|
content: "\e960";
|
||||||
|
}
|
||||||
|
.icon-details:before {
|
||||||
|
content: "\e961";
|
||||||
|
}
|
||||||
|
.icon-traceability:before {
|
||||||
|
content: "\e962";
|
||||||
|
}
|
||||||
|
.icon-claims:before {
|
||||||
|
content: "\e963";
|
||||||
|
}
|
||||||
|
.icon-regentry:before {
|
||||||
|
content: "\e964";
|
||||||
|
}
|
||||||
|
.icon-regentry-1:before {
|
||||||
|
content: "\e965";
|
||||||
|
}
|
||||||
|
.icon-transaction:before {
|
||||||
|
content: "\e966";
|
||||||
|
}
|
||||||
|
.icon-history:before {
|
||||||
|
content: "\e968";
|
||||||
|
}
|
||||||
|
.icon-entry:before {
|
||||||
|
content: "\e969";
|
||||||
|
}
|
||||||
|
.icon-mana:before {
|
||||||
|
content: "\e96a";
|
||||||
|
}
|
||||||
|
.icon-ticket:before {
|
||||||
|
content: "\e96b";
|
||||||
|
}
|
||||||
|
.icon-niche:before {
|
||||||
|
content: "\e96c";
|
||||||
|
}
|
||||||
|
.icon-tags:before {
|
||||||
|
content: "\e96d";
|
||||||
|
}
|
||||||
|
.icon-volume:before {
|
||||||
|
content: "\e96e";
|
||||||
|
}
|
||||||
|
.icon-bin:before {
|
||||||
|
content: "\e96f";
|
||||||
|
}
|
||||||
|
.icon-splur:before {
|
||||||
|
content: "\e970";
|
||||||
|
}
|
||||||
|
.icon-barcode:before {
|
||||||
|
content: "\e971";
|
||||||
|
}
|
||||||
|
.icon-botanical:before {
|
||||||
|
content: "\e972";
|
||||||
|
}
|
||||||
|
.icon-clone:before {
|
||||||
|
content: "\e973";
|
||||||
|
}
|
||||||
|
.icon-photo:before {
|
||||||
|
content: "\e974";
|
||||||
|
}
|
||||||
|
.icon-sms:before {
|
||||||
content: "\e975";
|
content: "\e975";
|
||||||
}
|
}
|
||||||
|
.icon-eye:before {
|
||||||
|
content: "\e976";
|
||||||
|
}
|
||||||
|
.icon-doc:before {
|
||||||
|
content: "\e977";
|
||||||
|
}
|
||||||
|
.icon-package:before {
|
||||||
|
content: "\e978";
|
||||||
|
}
|
||||||
|
.icon-settings:before {
|
||||||
|
content: "\e979";
|
||||||
|
}
|
||||||
|
.icon-bucket:before {
|
||||||
|
content: "\e97a";
|
||||||
|
}
|
||||||
|
.icon-mandatory:before {
|
||||||
|
content: "\e97b";
|
||||||
|
}
|
||||||
|
.icon-recovery:before {
|
||||||
|
content: "\e97c";
|
||||||
|
}
|
||||||
|
.icon-payment:before {
|
||||||
|
content: "\e97e";
|
||||||
|
}
|
||||||
|
.icon-invoices:before {
|
||||||
|
content: "\e97f";
|
||||||
|
}
|
||||||
|
.icon-grid:before {
|
||||||
|
content: "\e980";
|
||||||
|
}
|
||||||
|
.icon-logout:before {
|
||||||
|
content: "\e981";
|
||||||
|
}
|
||||||
|
.icon-web:before {
|
||||||
|
content: "\e982";
|
||||||
|
}
|
||||||
|
.icon-albaran:before {
|
||||||
|
content: "\e983";
|
||||||
|
}
|
||||||
|
.icon-dfiscales:before {
|
||||||
|
content: "\e984";
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 162 KiB |
Binary file not shown.
Binary file not shown.
|
@ -51,7 +51,7 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
color: $color-main;
|
color: $color-main;
|
||||||
}
|
}
|
||||||
.text-secondary {
|
.text-secondary {
|
||||||
color: $color-font-secondary;
|
color: $color-font-light;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helpers */
|
/* Helpers */
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
{
|
||||||
|
"name": "salix-front",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@uirouter/angularjs": {
|
||||||
|
"version": "1.0.29",
|
||||||
|
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.29.tgz",
|
||||||
|
"integrity": "sha512-RImWnBarNixkMto0o8stEaGwZmvhv5cnuOLXyMU2pY8MP2rgEF74ZNJTLeJCW14LR7XDUxVH8Mk8bPI6lxedmQ==",
|
||||||
|
"requires": {
|
||||||
|
"@uirouter/core": "6.0.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@uirouter/core": {
|
||||||
|
"version": "6.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.7.tgz",
|
||||||
|
"integrity": "sha512-KUTJxL+6q0PiBnFx4/Z+Hsyg0pSGiaW5yZQeJmUxknecjpTbnXkLU8H2EqRn9N2B+qDRa7Jg8RcgeNDPY72O1w=="
|
||||||
|
},
|
||||||
|
"angular": {
|
||||||
|
"version": "1.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.2.tgz",
|
||||||
|
"integrity": "sha512-IauMOej2xEe7/7Ennahkbb5qd/HFADiNuLSESz9Q27inmi32zB0lnAsFeLEWcox3Gd1F6YhNd1CP7/9IukJ0Gw=="
|
||||||
|
},
|
||||||
|
"angular-animate": {
|
||||||
|
"version": "1.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.8.2.tgz",
|
||||||
|
"integrity": "sha512-Jbr9+grNMs9Kj57xuBU3Ju3NOPAjS1+g2UAwwDv7su1lt0/PLDy+9zEwDiu8C8xJceoTbmBNKiWGPJGBdCQLlA=="
|
||||||
|
},
|
||||||
|
"angular-moment": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/angular-moment/-/angular-moment-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-KG8rvO9MoaBLwtGnxTeUveSyNtrL+RNgGl1zqWN36+HDCCVGk2DGWOzqKWB6o+eTTbO3Opn4hupWKIElc8XETA==",
|
||||||
|
"requires": {
|
||||||
|
"moment": ">=2.8.0 <3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"angular-translate": {
|
||||||
|
"version": "2.18.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.4.tgz",
|
||||||
|
"integrity": "sha512-KohNrkH6J9PK+VW0L/nsRTcg5Fw70Ajwwe3Jbfm54Pf9u9Fd+wuingoKv+h45mKf38eT+Ouu51FPua8VmZNoCw==",
|
||||||
|
"requires": {
|
||||||
|
"angular": "^1.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"angular-translate-loader-partial": {
|
||||||
|
"version": "2.18.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.18.4.tgz",
|
||||||
|
"integrity": "sha512-bsjR+FbB0sdA2528E/ugwKdlPPQhA1looxLxI3otayBTFXBpED33besfSZhYAISLgNMSL038vSssfRUen9qD8w==",
|
||||||
|
"requires": {
|
||||||
|
"angular-translate": "~2.18.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"argparse": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||||
|
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||||
|
"requires": {
|
||||||
|
"sprintf-js": "~1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"croppie": {
|
||||||
|
"version": "2.6.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/croppie/-/croppie-2.6.5.tgz",
|
||||||
|
"integrity": "sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ=="
|
||||||
|
},
|
||||||
|
"esprima": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||||
|
},
|
||||||
|
"js-yaml": {
|
||||||
|
"version": "3.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||||
|
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||||
|
"requires": {
|
||||||
|
"argparse": "^1.0.7",
|
||||||
|
"esprima": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mg-crud": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/mg-crud/-/mg-crud-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-p6AWGzWSPK7/8ZpIBpS2V1vDggw=",
|
||||||
|
"requires": {
|
||||||
|
"angular": "^1.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"moment": {
|
||||||
|
"version": "2.29.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||||
|
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
||||||
|
},
|
||||||
|
"oclazyload": {
|
||||||
|
"version": "0.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/oclazyload/-/oclazyload-0.6.3.tgz",
|
||||||
|
"integrity": "sha1-Kjirv/QJDAihEBZxkZRbWfLoJ5w="
|
||||||
|
},
|
||||||
|
"require-yaml": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/require-yaml/-/require-yaml-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-LhsY2RPDuqcqWk03O28Tjd0sMr0=",
|
||||||
|
"requires": {
|
||||||
|
"js-yaml": "^4.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
|
},
|
||||||
|
"js-yaml": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||||
|
"requires": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sprintf-js": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||||
|
},
|
||||||
|
"validator": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/validator/-/validator-6.3.0.tgz",
|
||||||
|
"integrity": "sha1-R84j7Y1Ord+p1LjvAHG2zxB418g="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -120,5 +120,6 @@
|
||||||
"This item is not available": "This item is not available",
|
"This item is not available": "This item is not available",
|
||||||
"Deny buy request": "Purchase request for ticket id [{{ticketId}}]({{{url}}}) has been rejected. Reason: {{observation}}",
|
"Deny buy request": "Purchase request for ticket id [{{ticketId}}]({{{url}}}) has been rejected. Reason: {{observation}}",
|
||||||
"The type of business must be filled in basic data": "The type of business must be filled in basic data",
|
"The type of business must be filled in basic data": "The type of business must be filled in basic data",
|
||||||
"isWithoutNegatives": "isWithoutNegatives"
|
"isWithoutNegatives": "isWithoutNegatives",
|
||||||
alexm marked this conversation as resolved
|
|||||||
|
"The worker has hours recorded that day": "The worker has hours recorded that day"
|
||||||
}
|
}
|
|
@ -96,13 +96,13 @@
|
||||||
"This postcode already exists": "Este código postal ya existe",
|
"This postcode already exists": "Este código postal ya existe",
|
||||||
"Concept cannot be blank": "El concepto no puede quedar en blanco",
|
"Concept cannot be blank": "El concepto no puede quedar en blanco",
|
||||||
"File doesn't exists": "El archivo no existe",
|
"File doesn't exists": "El archivo no existe",
|
||||||
"You don't have privileges to change the zone": "No tienes permisos para cambiar la zona",
|
"You don't have privileges to change the zone or for these parameters there are more than one shipping options, talk to agencies": "No tienes permisos para cambiar la zona o para esos parámetros hay más de una opción de envío, hable con las agencias",
|
||||||
"This ticket is already on weekly tickets": "Este ticket ya está en tickets programados",
|
"This ticket is already on weekly tickets": "Este ticket ya está en tickets programados",
|
||||||
"Ticket id cannot be blank": "El id de ticket no puede quedar en blanco",
|
"Ticket id cannot be blank": "El id de ticket no puede quedar en blanco",
|
||||||
"Weekday cannot be blank": "El día de la semana no puede quedar en blanco",
|
"Weekday cannot be blank": "El día de la semana no puede quedar en blanco",
|
||||||
"You can't delete a confirmed order": "No puedes borrar un pedido confirmado",
|
"You can't delete a confirmed order": "No puedes borrar un pedido confirmado",
|
||||||
"Can't create stowaway for this ticket": "No se puede crear un polizon para este ticket",
|
"Can't create stowaway for this ticket": "No se puede crear un polizon para este ticket",
|
||||||
"The socialName has an invalid format": "El nombre fiscal tiene un formato incorrecto",
|
"The social name has an invalid format": "El nombre fiscal tiene un formato incorrecto",
|
||||||
"Invalid quantity": "Cantidad invalida",
|
"Invalid quantity": "Cantidad invalida",
|
||||||
"This postal code is not valid": "This postal code is not valid",
|
"This postal code is not valid": "This postal code is not valid",
|
||||||
"is invalid": "is invalid",
|
"is invalid": "is invalid",
|
||||||
|
@ -210,11 +210,14 @@
|
||||||
"Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio",
|
"Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio",
|
||||||
"You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito",
|
"You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito",
|
||||||
"You can't change the credit set to zero from a manager": "No puedes cambiar el cŕedito establecido a cero por un gerente",
|
"You can't change the credit set to zero from a manager": "No puedes cambiar el cŕedito establecido a cero por un gerente",
|
||||||
|
"Amounts do not match": "Las cantidades no coinciden",
|
||||||
"The PDF document does not exists": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'",
|
"The PDF document does not exists": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'",
|
||||||
"The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos",
|
"The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos",
|
||||||
"You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días",
|
"You can't create a claim from a ticket delivered more than seven days ago": "No puedes crear una reclamación de un ticket entregado hace más de siete días",
|
||||||
"The worker has hours recorded that day": "El trabajador tiene horas fichadas ese día",
|
"The worker has hours recorded that day": "El trabajador tiene horas fichadas ese día",
|
||||||
"The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día",
|
"The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día",
|
||||||
"isWithoutNegatives": "Tiene Negativos",
|
"isWithoutNegatives": "Tiene Negativos",
|
||||||
"You can not modify is pay method checked": "No se puede modificar el campo método de pago validado"
|
"You can not modify is pay method checked": "No se puede modificar el campo método de pago validado",
|
||||||
|
"Can't transfer claimed sales": "No puedes transferir lineas reclamadas",
|
||||||
|
"You don't have privileges to create pay back": "No tienes permisos para crear un abono"
|
||||||
alexm marked this conversation as resolved
Outdated
joan
commented
this should be translated or removed? this should be translated or removed?
|
|||||||
}
|
}
|
|
@ -59,11 +59,12 @@ module.exports = Self => {
|
||||||
|
|
||||||
const landedPlusWeek = new Date(ticket.landed);
|
const landedPlusWeek = new Date(ticket.landed);
|
||||||
landedPlusWeek.setDate(landedPlusWeek.getDate() + 7);
|
landedPlusWeek.setDate(landedPlusWeek.getDate() + 7);
|
||||||
|
const hasClaimManagerRole = await models.Account.hasRole(userId, 'claimManager', myOptions);
|
||||||
const isClaimable = landedPlusWeek >= new Date();
|
const isClaimable = landedPlusWeek >= new Date();
|
||||||
|
|
||||||
if (ticket.isDeleted)
|
if (ticket.isDeleted)
|
||||||
throw new UserError(`You can't create a claim for a removed ticket`);
|
throw new UserError(`You can't create a claim for a removed ticket`);
|
||||||
if (!isClaimable)
|
if (!isClaimable && !hasClaimManagerRole)
|
||||||
throw new UserError(`You can't create a claim from a ticket delivered more than seven days ago`);
|
throw new UserError(`You can't create a claim from a ticket delivered more than seven days ago`);
|
||||||
|
|
||||||
const newClaim = await Self.create({
|
const newClaim = await Self.create({
|
||||||
|
|
|
@ -46,9 +46,40 @@ describe('Claim createFromSales()', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to create a claim for a ticket delivered more than seven days ago as claimManager', async() => {
|
||||||
|
const tx = await models.Claim.beginTransaction({});
|
||||||
|
const claimManagerId = 72;
|
||||||
|
activeCtx.accessToken.userId = claimManagerId;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const todayMinusEightDays = new Date();
|
||||||
|
todayMinusEightDays.setDate(todayMinusEightDays.getDate() - 8);
|
||||||
|
|
||||||
|
const ticket = await models.Ticket.findById(ticketId, options);
|
||||||
|
await ticket.updateAttribute('landed', todayMinusEightDays, options);
|
||||||
|
|
||||||
|
const claim = await models.Claim.createFromSales(ctx, ticketId, newSale, options);
|
||||||
|
|
||||||
|
expect(claim.ticketFk).toEqual(ticketId);
|
||||||
|
|
||||||
|
const claimBeginning = await models.ClaimBeginning.findOne({where: {claimFk: claim.id}}, options);
|
||||||
|
|
||||||
|
expect(claimBeginning.saleFk).toEqual(newSale[0].id);
|
||||||
|
expect(claimBeginning.quantity).toEqual(newSale[0].quantity);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it('should not be able to create a claim for a ticket delivered more than seven days ago', async() => {
|
it('should not be able to create a claim for a ticket delivered more than seven days ago', async() => {
|
||||||
const tx = await models.Claim.beginTransaction({});
|
const tx = await models.Claim.beginTransaction({});
|
||||||
|
|
||||||
|
activeCtx.accessToken.userId = 1;
|
||||||
let error;
|
let error;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
const soap = require('soap');
|
const got = require('got');
|
||||||
const xmlParser = require('xml2js').parseString;
|
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
|
@ -35,57 +34,49 @@ module.exports = Self => {
|
||||||
Self.send = async(ctx, destinationFk, destination, message) => {
|
Self.send = async(ctx, destinationFk, destination, message) => {
|
||||||
const userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
const smsConfig = await Self.app.models.SmsConfig.findOne();
|
const smsConfig = await Self.app.models.SmsConfig.findOne();
|
||||||
const soapClient = await soap.createClientAsync(smsConfig.uri);
|
|
||||||
|
if (destination.length == 9) {
|
||||||
|
const spainPrefix = '0034';
|
||||||
|
destination = spainPrefix + destination;
|
||||||
|
}
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
user: smsConfig.user,
|
api_key: smsConfig.apiKey,
|
||||||
pass: smsConfig.password,
|
messages: [{
|
||||||
src: smsConfig.title,
|
from: smsConfig.title,
|
||||||
dst: destination,
|
to: destination,
|
||||||
msg: message
|
text: message
|
||||||
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
let xmlResponse;
|
let response;
|
||||||
let xmlResult;
|
|
||||||
let xmlParsed;
|
|
||||||
let status;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production')
|
||||||
status = {
|
response = {result: [{status: 'ok'}]};
|
||||||
codigo: [200],
|
else {
|
||||||
descripcion: ['Fake response']
|
const jsonTest = {
|
||||||
|
json: params
|
||||||
};
|
};
|
||||||
} else {
|
response = await got.post(smsConfig.uri, jsonTest).json();
|
||||||
[xmlResponse] = await soapClient.sendSMSAsync(params);
|
|
||||||
xmlResult = xmlResponse.result.$value;
|
|
||||||
xmlParsed = await new Promise((resolve, reject) => {
|
|
||||||
xmlParser(xmlResult, (err, result) => {
|
|
||||||
if (err)
|
|
||||||
reject(err);
|
|
||||||
resolve(result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
[status] = xmlParsed['xtratelecom-sms-response'].sms;
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
const statusCode = status.codigo[0];
|
const [result] = response.result;
|
||||||
const statusDescription = status.descripcion[0];
|
const error = result.error_id;
|
||||||
|
|
||||||
const newSms = {
|
const newSms = {
|
||||||
senderFk: userId,
|
senderFk: userId,
|
||||||
destinationFk: destinationFk || null,
|
destinationFk: destinationFk || null,
|
||||||
destination: destination,
|
destination: destination,
|
||||||
message: message,
|
message: message,
|
||||||
statusCode: statusCode,
|
status: error
|
||||||
status: statusDescription
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const sms = await Self.create(newSms);
|
const sms = await Self.create(newSms);
|
||||||
|
|
||||||
if (statusCode != 200)
|
if (error)
|
||||||
throw new UserError(`We weren't able to send this SMS`);
|
throw new UserError(`We weren't able to send this SMS`);
|
||||||
|
|
||||||
return sms;
|
return sms;
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const app = require('vn-loopback/server/server');
|
||||||
const soap = require('soap');
|
|
||||||
|
|
||||||
describe('sms send()', () => {
|
describe('sms send()', () => {
|
||||||
it('should return the expected message and status code', async() => {
|
it('should not return status error', async() => {
|
||||||
const code = 200;
|
const ctx = {req: {accessToken: {userId: 1}}};
|
||||||
spyOn(soap, 'createClientAsync').and.returnValue('a so fake client');
|
const result = await app.models.Sms.send(ctx, 1105, '123456789', 'My SMS Body');
|
||||||
let ctx = {req: {accessToken: {userId: 1}}};
|
|
||||||
let result = await app.models.Sms.send(ctx, 1105, 'destination', 'My SMS Body');
|
|
||||||
|
|
||||||
expect(result.statusCode).toEqual(code);
|
expect(result.status).toBeUndefined();
|
||||||
expect(result.status).toContain('Fake response');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -55,15 +55,6 @@ module.exports = Self => {
|
||||||
with: /^[\w|.|-]+@[\w|-]+(\.[\w|-]+)*(,[\w|.|-]+@[\w|-]+(\.[\w|-]+)*)*$/
|
with: /^[\w|.|-]+@[\w|-]+(\.[\w|-]+)*(,[\w|.|-]+@[\w|-]+(\.[\w|-]+)*)*$/
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.validate('businessTypeFk', hasBusinessType, {
|
|
||||||
message: `The type of business must be filled in basic data`
|
|
||||||
});
|
|
||||||
|
|
||||||
function hasBusinessType(err) {
|
|
||||||
if (!this.businessTypeFk)
|
|
||||||
err();
|
|
||||||
}
|
|
||||||
|
|
||||||
Self.validatesLengthOf('postcode', {
|
Self.validatesLengthOf('postcode', {
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
allowBlank: true,
|
allowBlank: true,
|
||||||
|
@ -189,6 +180,32 @@ module.exports = Self => {
|
||||||
return regexp.test(value);
|
return regexp.test(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Self.observe('before save', async ctx => {
|
||||||
|
const changes = ctx.data || ctx.instance;
|
||||||
|
const orgData = ctx.currentInstance;
|
||||||
|
|
||||||
|
const businessTypeFk = changes && changes.businessTypeFk || orgData && orgData.businessTypeFk;
|
||||||
|
const isTaxDataChecked = changes && changes.isTaxDataChecked || orgData && orgData.isTaxDataChecked;
|
||||||
|
|
||||||
|
let invalidBusinessType = false;
|
||||||
|
if (!ctx.isNewInstance) {
|
||||||
|
const isWorker = await Self.app.models.UserAccount.findById(orgData.id);
|
||||||
|
const changedFields = Object.keys(changes);
|
||||||
|
const hasChangedOtherFields = changedFields.some(key => key !== 'businessTypeFk');
|
||||||
|
|
||||||
|
if (!businessTypeFk && !isTaxDataChecked && !isWorker && !hasChangedOtherFields)
|
||||||
|
invalidBusinessType = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.isNewInstance) {
|
||||||
|
if (!businessTypeFk && !isTaxDataChecked)
|
||||||
|
invalidBusinessType = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invalidBusinessType)
|
||||||
|
throw new UserError(`The type of business must be filled in basic data`);
|
||||||
|
});
|
||||||
|
|
||||||
Self.observe('before save', async function(ctx) {
|
Self.observe('before save', async function(ctx) {
|
||||||
const changes = ctx.data || ctx.instance;
|
const changes = ctx.data || ctx.instance;
|
||||||
const orgData = ctx.currentInstance;
|
const orgData = ctx.currentInstance;
|
||||||
|
@ -206,7 +223,7 @@ module.exports = Self => {
|
||||||
&& orgData.isTaxDataChecked != isTaxDataChecked;
|
&& orgData.isTaxDataChecked != isTaxDataChecked;
|
||||||
|
|
||||||
if ((socialNameChanged || dataCheckedChanged) && !isAlpha(socialName))
|
if ((socialNameChanged || dataCheckedChanged) && !isAlpha(socialName))
|
||||||
throw new UserError('The socialName has an invalid format');
|
throw new UserError(`The social name has an invalid format`);
|
||||||
|
|
||||||
if (changes.salesPerson === null) {
|
if (changes.salesPerson === null) {
|
||||||
changes.credit = 0;
|
changes.credit = 0;
|
||||||
|
@ -267,7 +284,7 @@ module.exports = Self => {
|
||||||
replyTo: worker.email
|
replyTo: worker.email
|
||||||
};
|
};
|
||||||
await got.get(`${origin}/api/email/payment-update`, {
|
await got.get(`${origin}/api/email/payment-update`, {
|
||||||
query: params
|
searchParams: params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,7 @@
|
||||||
"uri": {
|
"uri": {
|
||||||
"type": "String"
|
"type": "String"
|
||||||
},
|
},
|
||||||
"user": {
|
"apiKey": {
|
||||||
"type": "String"
|
|
||||||
},
|
|
||||||
"password": {
|
|
||||||
"type": "String"
|
"type": "String"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
|
|
|
@ -26,8 +26,7 @@
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
"statusCode": {
|
"statusCode": {
|
||||||
"type": "Number",
|
"type": "Number"
|
||||||
"required": true
|
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"type": "String"
|
"type": "String"
|
||||||
|
|
|
@ -82,7 +82,7 @@ class Controller extends Dialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
set amountToReturn(value) {
|
set amountToReturn(value) {
|
||||||
if (!value) return;
|
if (isNaN(value)) return;
|
||||||
|
|
||||||
value = value.toFixed(2);
|
value = value.toFixed(2);
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,13 @@
|
||||||
{{::agencyModeName}} - {{::warehouseInName}} ({{::shipped | date: 'dd/MM/yyyy'}}) →
|
{{::agencyModeName}} - {{::warehouseInName}} ({{::shipped | date: 'dd/MM/yyyy'}}) →
|
||||||
{{::warehouseOutName}} ({{::landed | date: 'dd/MM/yyyy'}})
|
{{::warehouseOutName}} ({{::landed | date: 'dd/MM/yyyy'}})
|
||||||
</tpl-item>
|
</tpl-item>
|
||||||
|
<append>
|
||||||
|
<vn-icon-button
|
||||||
|
icon="filter_alt"
|
||||||
|
vn-click-stop="$ctrl.showFilterDialog($ctrl.entry.travelFk)"
|
||||||
|
vn-tooltip="Filter...">
|
||||||
|
</vn-icon-button>
|
||||||
|
</append>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
|
@ -121,4 +128,94 @@
|
||||||
ng-click="watcher.loadOriginalData()">
|
ng-click="watcher.loadOriginalData()">
|
||||||
</vn-button>
|
</vn-button>
|
||||||
</vn-button-bar>
|
</vn-button-bar>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<!-- Filter travel dialog -->
|
||||||
|
<vn-dialog
|
||||||
|
vn-id="filterDialog"
|
||||||
|
message="Filter travel">
|
||||||
|
<tpl-body class="travelFilter">
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete
|
||||||
|
label="Agency"
|
||||||
|
ng-model="$ctrl.travelFilterParams.agencyFk"
|
||||||
|
url="AgencyModes"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-autocomplete
|
||||||
|
label="Warehouse Out"
|
||||||
|
ng-model="$ctrl.travelFilterParams.warehouseOutFk"
|
||||||
|
url="Warehouses"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-autocomplete
|
||||||
|
label="Warehouse In"
|
||||||
|
ng-model="$ctrl.travelFilterParams.warehouseInFk"
|
||||||
|
url="Warehouses"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-date-picker
|
||||||
|
label="Shipped"
|
||||||
|
ng-model="$ctrl.travelFilterParams.shipped">
|
||||||
|
</vn-date-picker>
|
||||||
|
<vn-date-picker
|
||||||
|
label="Landed"
|
||||||
|
ng-model="$ctrl.travelFilterParams.landed">
|
||||||
|
</vn-date-picker>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal class="vn-mb-md">
|
||||||
|
<vn-button vn-none
|
||||||
|
label="Search"
|
||||||
|
ng-click="$ctrl.filter()">
|
||||||
|
</vn-button>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-crud-model
|
||||||
|
vn-id="travelsModel"
|
||||||
|
url="Travels"
|
||||||
|
filter="$ctrl.travelFilter"
|
||||||
|
data="travels"
|
||||||
|
limit="10">
|
||||||
|
</vn-crud-model>
|
||||||
|
<vn-data-viewer
|
||||||
|
model="travelsModel"
|
||||||
|
class="vn-w-lg">
|
||||||
|
<vn-table class="scrollable">
|
||||||
|
<vn-thead>
|
||||||
|
<vn-tr>
|
||||||
|
<vn-th shrink>ID</vn-th>
|
||||||
|
<vn-th expand>Agency</vn-th>
|
||||||
|
<vn-th expand>Warehouse Out</vn-th>
|
||||||
|
<vn-th expand>Warehouse In</vn-th>
|
||||||
|
<vn-th expand>Shipped</vn-th>
|
||||||
|
<vn-th expand>Landed</vn-th>
|
||||||
|
</vn-tr>
|
||||||
|
</vn-thead>
|
||||||
|
<vn-tbody>
|
||||||
|
<a ng-repeat="travel in travels"
|
||||||
|
class="clickable vn-tr search-result"
|
||||||
|
ng-click="$ctrl.selectTravel(travel.id)">
|
||||||
|
<vn-td shrink>
|
||||||
|
<span
|
||||||
|
vn-click-stop="travelDescriptor.show($event, travel.id)"
|
||||||
|
class="link">
|
||||||
|
{{::travel.id}}
|
||||||
|
</span>
|
||||||
|
</vn-td>
|
||||||
|
<vn-td expand>{{::travel.agency.name}}</vn-td>
|
||||||
|
<vn-td expand>{{::travel.warehouseOut.name}}</vn-td>
|
||||||
|
<vn-td expand>{{::travel.warehouseIn.name}}</vn-td>
|
||||||
|
<vn-td expand>{{::travel.shipped | date: 'dd/MM/yyyy'}}</vn-td>
|
||||||
|
<vn-td expand>{{::travel.landed | date: 'dd/MM/yyyy'}}</vn-td>
|
||||||
|
</a>
|
||||||
|
</vn-tbody>
|
||||||
|
</vn-table>
|
||||||
|
</vn-data-viewer>
|
||||||
|
<vn-travel-descriptor-popover
|
||||||
|
vn-id="travel-descriptor"
|
||||||
|
warehouse-fk="$ctrl.vnConfig.warehouseFk">
|
||||||
|
</vn-travel-descriptor-popover>
|
||||||
|
</tpl-body>
|
||||||
|
</vn-dialog>
|
|
@ -1,10 +1,68 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
import Section from 'salix/components/section';
|
import Section from 'salix/components/section';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
class Controller extends Section {
|
||||||
|
showFilterDialog(travel) {
|
||||||
|
this.activeTravel = travel;
|
||||||
|
this.travelFilterParams = {};
|
||||||
|
this.travelFilter = {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'agency',
|
||||||
|
scope: {
|
||||||
|
fields: ['name']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relation: 'warehouseIn',
|
||||||
|
scope: {
|
||||||
|
fields: ['name']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relation: 'warehouseOut',
|
||||||
|
scope: {
|
||||||
|
fields: ['name']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$.filterDialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
selectTravel(id) {
|
||||||
|
this.entry.travelFk = id;
|
||||||
|
this.$.filterDialog.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
filter() {
|
||||||
|
const filter = this.travelFilter;
|
||||||
|
const params = this.travelFilterParams;
|
||||||
|
const where = {};
|
||||||
|
for (let key in params) {
|
||||||
|
const value = params[key];
|
||||||
|
if (!value) continue;
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case 'agencyFk':
|
||||||
|
case 'warehouseInFk':
|
||||||
|
case 'warehouseOutFk':
|
||||||
|
case 'shipped':
|
||||||
|
case 'landed':
|
||||||
|
where[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filter.where = where;
|
||||||
|
this.$.travelsModel.applyFilter(filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
ngModule.vnComponent('vnEntryBasicData', {
|
ngModule.vnComponent('vnEntryBasicData', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: Section,
|
|
||||||
bindings: {
|
bindings: {
|
||||||
entry: '<'
|
entry: '<'
|
||||||
}
|
},
|
||||||
|
controller: Controller
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
.travelFilter{
|
||||||
|
width: 950px;
|
||||||
|
}
|
|
@ -179,7 +179,7 @@
|
||||||
ng-click="$ctrl.selectItem(item.id)">
|
ng-click="$ctrl.selectItem(item.id)">
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
<span
|
<span
|
||||||
ng-click="itemDescriptor.show($event, item.id)"
|
vn-click-stop="itemDescriptor.show($event, item.id)"
|
||||||
class="link">
|
class="link">
|
||||||
{{::item.id}}
|
{{::item.id}}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('getTotals', {
|
||||||
|
description: 'Return totals for an invoiceIn',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: {
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'invoiceIn id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: '/:id/getTotals',
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.getTotals = async(id, options) => {
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
const [result] = await Self.rawSql(`
|
||||||
|
SELECT iit.*,
|
||||||
|
SUM(iidd.amount) totalDueDay
|
||||||
|
FROM vn.invoiceIn ii
|
||||||
|
LEFT JOIN (SELECT SUM(iit.taxableBase) totalTaxableBase,
|
||||||
|
SUM(iit.taxableBase * (1 + (ti.PorcentajeIva / 100))) totalVat
|
||||||
|
FROM vn.invoiceInTax iit
|
||||||
|
LEFT JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk
|
||||||
|
WHERE iit.invoiceInFk = ?) iit ON TRUE
|
||||||
|
LEFT JOIN vn.invoiceInDueDay iidd ON iidd.invoiceInFk = ii.id
|
||||||
|
WHERE
|
||||||
|
ii.id = ?`, [id, id]);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,21 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
|
describe('invoiceIn getTotals()', () => {
|
||||||
|
it('should check that returns invoiceIn totals', async() => {
|
||||||
|
const invoiceInId = 1;
|
||||||
|
const tx = await models.InvoiceIn.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const invoiceIntotals = await models.InvoiceIn.getTotals(invoiceInId, options);
|
||||||
|
|
||||||
|
expect(typeof invoiceIntotals.totalTaxableBase).toBe('number');
|
||||||
|
expect(invoiceIntotals.totalTaxableBase).toEqual(invoiceIntotals.totalDueDay);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,34 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
|
describe('invoiceIn toBook()', () => {
|
||||||
|
it('should check that invoiceIn is booked', async() => {
|
||||||
|
const userId = 1;
|
||||||
|
const ctx = {
|
||||||
|
req: {
|
||||||
|
|
||||||
|
accessToken: {userId: userId},
|
||||||
|
headers: {origin: 'http://localhost:5000'},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const invoiceInId = 1;
|
||||||
|
const tx = await models.InvoiceIn.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const invoiceInBefore = await models.InvoiceIn.findById(invoiceInId, null, options);
|
||||||
|
|
||||||
|
expect(invoiceInBefore.isBooked).toEqual(false);
|
||||||
|
|
||||||
|
await models.InvoiceIn.toBook(ctx, invoiceInId, options);
|
||||||
|
|
||||||
|
const invoiceIn = await models.InvoiceIn.findById(invoiceInId, null, options);
|
||||||
|
|
||||||
|
expect(invoiceIn.isBooked).toEqual(true);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -20,6 +20,7 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.summary = async(id, options) => {
|
Self.summary = async(id, options) => {
|
||||||
|
const models = Self.app.models;
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
|
@ -85,25 +86,9 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
let summaryObj = await models.InvoiceIn.findById(id, filter, myOptions);
|
||||||
|
|
||||||
let summaryObj = await Self.app.models.InvoiceIn.findById(id, filter, myOptions);
|
summaryObj.totals = await models.InvoiceIn.getTotals(id, myOptions);
|
||||||
|
|
||||||
summaryObj.totals = await getTotals(id);
|
|
||||||
return summaryObj;
|
return summaryObj;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getTotals(invoiceInFk) {
|
|
||||||
return (await Self.rawSql(`
|
|
||||||
SELECT iit.*,
|
|
||||||
SUM(iidd.amount) totalDueDay
|
|
||||||
FROM vn.invoiceIn ii
|
|
||||||
LEFT JOIN (SELECT SUM(iit.taxableBase) totalTaxableBase,
|
|
||||||
SUM(iit.taxableBase * (1 + (ti.PorcentajeIva / 100))) totalVat
|
|
||||||
FROM vn.invoiceInTax iit
|
|
||||||
LEFT JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk
|
|
||||||
WHERE iit.invoiceInFk = ?) iit ON TRUE
|
|
||||||
LEFT JOIN vn.invoiceInDueDay iidd ON iidd.invoiceInFk = ii.id
|
|
||||||
WHERE
|
|
||||||
ii.id = ?`, [invoiceInFk, invoiceInFk]))[0];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('toBook', {
|
||||||
|
description: 'To book the invoiceIn',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: {
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The invoiceIn id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: '/:id/toBook',
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.toBook = async(ctx, id, options) => {
|
||||||
|
let tx;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Self.rawSql(`CALL vn.invoiceInBookingMain(?)`, [id], myOptions);
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -2,4 +2,6 @@ module.exports = Self => {
|
||||||
require('../methods/invoice-in/filter')(Self);
|
require('../methods/invoice-in/filter')(Self);
|
||||||
require('../methods/invoice-in/summary')(Self);
|
require('../methods/invoice-in/summary')(Self);
|
||||||
require('../methods/invoice-in/clone')(Self);
|
require('../methods/invoice-in/clone')(Self);
|
||||||
|
require('../methods/invoice-in/toBook')(Self);
|
||||||
|
require('../methods/invoice-in/getTotals')(Self);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
<vn-descriptor-content module="invoiceIn" description="$ctrl.invoiceIn.supplierRef">
|
<vn-descriptor-content module="invoiceIn" description="$ctrl.invoiceIn.supplierRef">
|
||||||
<slot-menu>
|
<slot-menu>
|
||||||
|
<vn-item
|
||||||
|
ng-click="$ctrl.checkToBook()"
|
||||||
|
vn-acl="administrative"
|
||||||
|
ng-hide="$ctrl.invoiceIn.isBooked == true"
|
||||||
|
translate>
|
||||||
|
To book
|
||||||
|
</vn-item>
|
||||||
|
|
||||||
<vn-item
|
<vn-item
|
||||||
ng-click="deleteConfirmation.show()"
|
ng-click="deleteConfirmation.show()"
|
||||||
vn-acl="invoicing"
|
vn-acl="administrative"
|
||||||
vn-acl-action="remove"
|
vn-acl-action="remove"
|
||||||
name="deleteInvoice"
|
name="deleteInvoice"
|
||||||
translate>
|
translate>
|
||||||
|
@ -10,7 +18,7 @@
|
||||||
</vn-item>
|
</vn-item>
|
||||||
<vn-item
|
<vn-item
|
||||||
ng-click="cloneConfirmation.show()"
|
ng-click="cloneConfirmation.show()"
|
||||||
vn-acl="invoicing"
|
vn-acl="administrative"
|
||||||
name="cloneInvoice"
|
name="cloneInvoice"
|
||||||
translate>
|
translate>
|
||||||
Clone Invoice
|
Clone Invoice
|
||||||
|
@ -26,7 +34,7 @@
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value label="Supplier">
|
<vn-label-value label="Supplier">
|
||||||
<span ng-click="supplierDescriptor.show($event, $ctrl.invoiceIn.supplier.id)" class="link">
|
<span ng-click="supplierDescriptor.show($event, $ctrl.invoiceIn.supplier.id)" class="link">
|
||||||
{{$ctrl.invoiceIn.supplier.nickname}}
|
{{$ctrl.invoiceIn.supplier.nickname}}
|
||||||
</span>
|
</span>
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
</div>
|
</div>
|
||||||
|
@ -46,7 +54,9 @@
|
||||||
icon="icon-invoice-in">
|
icon="icon-invoice-in">
|
||||||
</vn-quick-link>
|
</vn-quick-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</slot-body>
|
</slot-body>
|
||||||
</vn-descriptor-content>
|
</vn-descriptor-content>
|
||||||
<vn-confirm
|
<vn-confirm
|
||||||
|
@ -62,3 +72,8 @@
|
||||||
<vn-supplier-descriptor-popover
|
<vn-supplier-descriptor-popover
|
||||||
vn-id="supplierDescriptor">
|
vn-id="supplierDescriptor">
|
||||||
</vn-supplier-descriptor-popover>
|
</vn-supplier-descriptor-popover>
|
||||||
|
<vn-confirm
|
||||||
|
vn-id="confirm-toBookAnyway"
|
||||||
|
message="Are you sure you want to book this invoice?"
|
||||||
|
on-accept="$ctrl.onAcceptToBook()">
|
||||||
|
</vn-confirm>
|
|
@ -51,6 +51,43 @@ class Controller extends Descriptor {
|
||||||
return this.getData(`InvoiceIns/${this.id}`, {filter})
|
return this.getData(`InvoiceIns/${this.id}`, {filter})
|
||||||
.then(res => this.entity = res.data);
|
.then(res => this.entity = res.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkToBook() {
|
||||||
|
let message = '';
|
||||||
|
const id = this.invoiceIn.id;
|
||||||
|
this.$q.all([
|
||||||
|
this.$http.get(`InvoiceIns/${this.id}/getTotals`)
|
||||||
|
.then(res => {
|
||||||
|
const taxableBaseNotEqualDueDay = res.data.totalDueDay != res.data.totalTaxableBase;
|
||||||
|
const vatNotEqualDueDay = res.data.totalDueDay != res.data.totalVat;
|
||||||
|
if (taxableBaseNotEqualDueDay && vatNotEqualDueDay)
|
||||||
|
message += 'amountsDoNotMatch';
|
||||||
|
}),
|
||||||
|
this.$http.get('InvoiceInDueDays/count', {
|
||||||
|
filter: {
|
||||||
|
where: {
|
||||||
|
invoiceInFk: id,
|
||||||
|
dueDated: {gte: new Date()}
|
||||||
|
}
|
||||||
|
}})
|
||||||
|
.then(res => {
|
||||||
|
if (res.data)
|
||||||
|
message += 'future payments';
|
||||||
|
})
|
||||||
|
|
||||||
|
]).finally(() => {
|
||||||
|
if (message.length)
|
||||||
|
this.$.confirmToBookAnyway.show();
|
||||||
|
else
|
||||||
|
this.onAcceptToBook();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onAcceptToBook() {
|
||||||
|
this.$http.post(`InvoiceIns/${this.id}/toBook`)
|
||||||
|
.then(() => this.$state.reload())
|
||||||
|
.then(() => this.vnApp.showSuccess(this.$t('InvoiceIn booked')));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnInvoiceInDescriptor', {
|
ngModule.vnComponent('vnInvoiceInDescriptor', {
|
||||||
|
|
|
@ -8,19 +8,70 @@ describe('vnInvoiceInDescriptor', () => {
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||||
$httpBackend = _$httpBackend_;
|
$httpBackend = _$httpBackend_;
|
||||||
controller = $componentController('vnInvoiceInDescriptor', {$element: null});
|
const $element = angular.element('<vn-invoice-in-descriptor></vn-invoice-in-descriptor>');
|
||||||
|
|
||||||
|
controller = $componentController('vnInvoiceInDescriptor', {$element});
|
||||||
|
controller.invoiceIn = {id: 1};
|
||||||
|
$httpBackend.when('GET', `InvoiceIns/${controller.invoiceIn.id}`).respond({id: 1});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('loadData()', () => {
|
describe('loadData()', () => {
|
||||||
it(`should perform a get query to store the invoice in data into the controller`, () => {
|
it(`should perform a get query to store the invoice in data into the controller`, () => {
|
||||||
const id = 1;
|
expect(controller.invoiceIn).toEqual({id: 1});
|
||||||
const response = {id: 1};
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$httpBackend.expectGET(`InvoiceIns/${id}`).respond(response);
|
describe('onAcceptToBook()', () => {
|
||||||
controller.id = id;
|
it(`should perform a post query to book the invoice`, () => {
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
controller.$state.reload = jest.fn();
|
||||||
|
|
||||||
|
const id = 1;
|
||||||
|
|
||||||
|
$httpBackend.expectPOST(`InvoiceIns/${id}/toBook`).respond();
|
||||||
|
controller.onAcceptToBook();
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
|
|
||||||
expect(controller.invoiceIn).toEqual(response);
|
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('InvoiceIn booked');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('checkToBook()', () => {
|
||||||
|
it(`should show a warning before book`, () => {
|
||||||
|
controller.$.confirmToBookAnyway = {show: () => {}};
|
||||||
|
jest.spyOn(controller.$.confirmToBookAnyway, 'show');
|
||||||
|
|
||||||
|
const invoceInId = 1;
|
||||||
|
const data = {
|
||||||
|
totalDueDay: 'an amount',
|
||||||
|
totalTaxableBase: 'distinct amount'
|
||||||
|
};
|
||||||
|
|
||||||
|
$httpBackend.expectGET(`InvoiceIns/${invoceInId}/getTotals`).respond(data);
|
||||||
|
$httpBackend.expectGET(`InvoiceInDueDays/count`).respond();
|
||||||
|
|
||||||
|
controller.checkToBook();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.$.confirmToBookAnyway.show).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should call onAcceptToBook`, () => {
|
||||||
|
controller.onAcceptToBook = jest.fn();
|
||||||
|
|
||||||
|
const invoceInId = 1;
|
||||||
|
const data = {
|
||||||
|
totalDueDay: 'same amount',
|
||||||
|
totalTaxableBase: 'same amount'
|
||||||
|
};
|
||||||
|
|
||||||
|
$httpBackend.expectGET(`InvoiceIns/${invoceInId}/getTotals`).respond(data);
|
||||||
|
$httpBackend.expectGET(`InvoiceInDueDays/count`).respond();
|
||||||
|
|
||||||
|
controller.checkToBook();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.onAcceptToBook).toHaveBeenCalledWith();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
InvoiceIn: Facturas recibidas
|
|
||||||
Search invoices in by reference: Buscar facturas recibidas por referencia
|
|
||||||
Entries list: Listado de entradas
|
|
||||||
InvoiceIn deleted: Factura eliminada
|
|
||||||
Remove tax: Quitar iva
|
|
||||||
Add tax: Añadir iva
|
Add tax: Añadir iva
|
||||||
|
Amounts do not match: La BI no coincide con el vencimiento ni con el total
|
||||||
|
Due day: Vencimiento
|
||||||
|
Entries list: Listado de entradas
|
||||||
|
Foreign value: Divisa
|
||||||
|
InvoiceIn: Facturas recibidas
|
||||||
|
InvoiceIn cloned: Factura clonada
|
||||||
|
InvoiceIn deleted: Factura eliminada
|
||||||
|
Invoice list: Listado de facturas recibidas
|
||||||
|
InvoiceIn booked: Factura contabilizada
|
||||||
|
Remove tax: Quitar iva
|
||||||
Sage tax: Sage iva
|
Sage tax: Sage iva
|
||||||
Sage transaction: Sage transaccion
|
Sage transaction: Sage transaccion
|
||||||
Foreign value: Divisa
|
Search invoices in by reference: Buscar facturas recibidas por referencia
|
||||||
Due day: Vencimiento
|
To book: Contabilizar
|
||||||
Invoice list: Listado de facturas recibidas
|
|
||||||
InvoiceIn cloned: Factura clonada
|
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,20 @@
|
||||||
ng-model="filter.fi">
|
ng-model="filter.fi">
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one ng-model="filter.supplierFk"
|
||||||
|
url="Suppliers"
|
||||||
|
show-field="nickname"
|
||||||
|
search-function="{or: [{id: $search}, {nickname: {like: '%'+ $search +'%'}}]}"
|
||||||
|
value-field="id"
|
||||||
|
order="nickname"
|
||||||
|
label="Supplier">
|
||||||
|
<tpl-item>
|
||||||
|
{{::id}} - {{::nickname}}
|
||||||
|
</tpl-item>
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
vn-one
|
vn-one
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const got = require('got');
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethodCtx('createPdf', {
|
Self.remoteMethodCtx('createPdf', {
|
||||||
|
@ -57,39 +57,37 @@ module.exports = Self => {
|
||||||
hasPdf: true
|
hasPdf: true
|
||||||
}, myOptions);
|
}, myOptions);
|
||||||
|
|
||||||
const response = got.stream(`${origin}/api/report/invoice`, {
|
return axios.get(`${origin}/api/report/invoice`, {
|
||||||
query: {
|
responseType: 'stream',
|
||||||
|
params: {
|
||||||
authorization: auth.id,
|
authorization: auth.id,
|
||||||
invoiceId: id
|
invoiceId: id
|
||||||
}
|
}
|
||||||
});
|
}).then(async response => {
|
||||||
|
const issued = invoiceOut.issued;
|
||||||
|
const year = issued.getFullYear().toString();
|
||||||
|
const month = (issued.getMonth() + 1).toString();
|
||||||
|
const day = issued.getDate().toString();
|
||||||
|
|
||||||
const issued = invoiceOut.issued;
|
const container = await models.InvoiceContainer.container(year);
|
||||||
const year = issued.getFullYear().toString();
|
const rootPath = container.client.root;
|
||||||
const month = (issued.getMonth() + 1).toString();
|
const fileName = `${year}${invoiceOut.ref}.pdf`;
|
||||||
const day = issued.getDate().toString();
|
const src = path.join(rootPath, year, month, day);
|
||||||
|
fileSrc = path.join(src, fileName);
|
||||||
|
|
||||||
const container = await models.InvoiceContainer.container(year);
|
await fs.mkdir(src, {recursive: true});
|
||||||
const rootPath = container.client.root;
|
|
||||||
const fileName = `${year}${invoiceOut.ref}.pdf`;
|
|
||||||
const src = path.join(rootPath, year, month, day);
|
|
||||||
fileSrc = path.join(src, fileName);
|
|
||||||
|
|
||||||
await fs.mkdir(src, {recursive: true});
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
if (tx) await tx.commit();
|
response.data.pipe(fs.createWriteStream(fileSrc));
|
||||||
|
}).catch(async e => {
|
||||||
|
if (fs.existsSync(fileSrc))
|
||||||
|
await fs.unlink(fileSrc);
|
||||||
|
|
||||||
const writeStream = fs.createWriteStream(fileSrc);
|
throw e;
|
||||||
writeStream.on('open', () => response.pipe(writeStream));
|
|
||||||
writeStream.on('finish', () => writeStream.end());
|
|
||||||
|
|
||||||
return new Promise(resolve => {
|
|
||||||
writeStream.on('close', () => resolve(invoiceOut));
|
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (tx) await tx.rollback();
|
if (tx) await tx.rollback();
|
||||||
if (fs.existsSync(fileSrc))
|
|
||||||
await fs.unlink(fileSrc);
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,24 +1,28 @@
|
||||||
const models = require('vn-loopback/server/server').models;
|
const models = require('vn-loopback/server/server').models;
|
||||||
const got = require('got');
|
const LoopBackContext = require('loopback-context');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
describe('InvoiceOut createPdf()', () => {
|
describe('InvoiceOut createPdf()', () => {
|
||||||
const userId = 1;
|
const userId = 1;
|
||||||
const ctx = {
|
const activeCtx = {
|
||||||
req: {
|
accessToken: {userId: userId, id: 'DEFAULT_TOKEN'},
|
||||||
|
headers: {origin: 'http://localhost:5000'}
|
||||||
accessToken: {userId: userId},
|
|
||||||
headers: {origin: 'http://localhost:5000'},
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
const ctx = {req: activeCtx};
|
||||||
|
|
||||||
it('should create a new PDF file and set true the hasPdf property', async() => {
|
it('should create a new PDF file and set true the hasPdf property', async() => {
|
||||||
const invoiceId = 1;
|
const invoiceId = 1;
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
const response = {
|
const response = {
|
||||||
pipe: () => {},
|
data: {
|
||||||
on: () => {},
|
pipe: () => {},
|
||||||
|
on: () => {},
|
||||||
|
}
|
||||||
};
|
};
|
||||||
spyOn(got, 'stream').and.returnValue(response);
|
spyOn(axios, 'get').and.returnValue(new Promise(resolve => resolve(response)));
|
||||||
spyOn(models.InvoiceContainer, 'container').and.returnValue({
|
spyOn(models.InvoiceContainer, 'container').and.returnValue({
|
||||||
client: {root: '/path'}
|
client: {root: '/path'}
|
||||||
});
|
});
|
||||||
|
@ -32,9 +36,10 @@ describe('InvoiceOut createPdf()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await models.InvoiceOut.createPdf(ctx, invoiceId, options);
|
await models.InvoiceOut.createPdf(ctx, invoiceId, options);
|
||||||
|
const invoiceOut = await models.InvoiceOut.findById(invoiceId, null, options);
|
||||||
|
|
||||||
expect(result.hasPdf).toBe(true);
|
expect(invoiceOut.hasPdf).toBe(true);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -23,6 +23,6 @@ describe('InvoiceOut download()', () => {
|
||||||
const result = await models.InvoiceOut.download(ctx, invoiceId);
|
const result = await models.InvoiceOut.download(ctx, invoiceId);
|
||||||
|
|
||||||
expect(result[1]).toEqual('application/pdf');
|
expect(result[1]).toEqual('application/pdf');
|
||||||
expect(result[2]).toEqual('filename="2021T1111111.pdf"');
|
expect(result[2]).toMatch(/filename="\d{4}T1111111.pdf"/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,6 +19,10 @@ class Controller extends Section {
|
||||||
this.id = value.id;
|
this.id = value.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get hasInvoicing() {
|
||||||
|
return this.aclService.hasAny(['invoicing']);
|
||||||
|
}
|
||||||
|
|
||||||
loadData() {
|
loadData() {
|
||||||
const filter = {
|
const filter = {
|
||||||
include: [
|
include: [
|
||||||
|
@ -51,8 +55,13 @@ class Controller extends Section {
|
||||||
|
|
||||||
deleteInvoiceOut() {
|
deleteInvoiceOut() {
|
||||||
return this.$http.post(`InvoiceOuts/${this.invoiceOut.id}/delete`)
|
return this.$http.post(`InvoiceOuts/${this.invoiceOut.id}/delete`)
|
||||||
.then(() => this.$state.go('invoiceOut.index'))
|
.then(() => {
|
||||||
.then(() => this.$state.reload())
|
const isInsideInvoiceOut = this.$state.current.name.startsWith('invoiceOut');
|
||||||
|
if (isInsideInvoiceOut)
|
||||||
|
this.$state.go('invoiceOut.index');
|
||||||
|
else
|
||||||
|
this.$state.reload();
|
||||||
|
})
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('InvoiceOut deleted')));
|
.then(() => this.vnApp.showSuccess(this.$t('InvoiceOut deleted')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,35 @@ describe('vnInvoiceOutDescriptorMenu', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('deleteInvoiceOut()', () => {
|
||||||
|
it(`should make a query and call showSuccess()`, () => {
|
||||||
|
controller.invoiceOut = invoiceOut;
|
||||||
|
controller.$state.reload = jest.fn();
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
|
||||||
|
$httpBackend.expectPOST(`InvoiceOuts/${invoiceOut.id}/delete`).respond();
|
||||||
|
controller.deleteInvoiceOut();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.$state.reload).toHaveBeenCalled();
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should make a query and call showSuccess() after state.go if the state wasn't in invoiceOut module`, () => {
|
||||||
|
controller.invoiceOut = invoiceOut;
|
||||||
|
jest.spyOn(controller.$state, 'go').mockReturnValue('ok');
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
controller.$state.current.name = 'invoiceOut.card.something';
|
||||||
|
|
||||||
|
$httpBackend.expectPOST(`InvoiceOuts/${invoiceOut.id}/delete`).respond();
|
||||||
|
controller.deleteInvoiceOut();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.$state.go).toHaveBeenCalledWith('invoiceOut.index');
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('sendPdfInvoice()', () => {
|
describe('sendPdfInvoice()', () => {
|
||||||
it('should make a query to the email invoice endpoint and show a message snackbar', () => {
|
it('should make a query to the email invoice endpoint and show a message snackbar', () => {
|
||||||
jest.spyOn(controller.vnApp, 'showMessage');
|
jest.spyOn(controller.vnApp, 'showMessage');
|
||||||
|
|
|
@ -14,4 +14,4 @@ InvoiceOut booked: Factura asentada
|
||||||
Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura?
|
Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura?
|
||||||
Regenerate PDF invoice: Regenerar PDF factura
|
Regenerate PDF invoice: Regenerar PDF factura
|
||||||
The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado
|
The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado
|
||||||
The email can't be empty: El correo no puede estar vacío
|
The email can't be empty: El correo no puede estar vacío
|
||||||
|
|
|
@ -112,7 +112,10 @@ module.exports = Self => {
|
||||||
case 'search':
|
case 'search':
|
||||||
return /^\d+$/.test(value)
|
return /^\d+$/.test(value)
|
||||||
? {or: [{'i.id': value}, codeWhere]}
|
? {or: [{'i.id': value}, codeWhere]}
|
||||||
: {or: [{'i.name': {like: `%${value}%`}}, codeWhere]};
|
: {or: [
|
||||||
|
{'i.name': {like: `%${value}%`}},
|
||||||
|
{'i.longName': {like: `%${value}%`}},
|
||||||
|
codeWhere]};
|
||||||
case 'id':
|
case 'id':
|
||||||
case 'isActive':
|
case 'isActive':
|
||||||
case 'typeFk':
|
case 'typeFk':
|
||||||
|
|
|
@ -296,7 +296,7 @@
|
||||||
ng-click="$ctrl.selectItem(item.id)">
|
ng-click="$ctrl.selectItem(item.id)">
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
<span
|
<span
|
||||||
ng-click="itemDescriptor.show($event, item.id)"
|
vn-click-stop="itemDescriptor.show($event, item.id)"
|
||||||
class="link">
|
class="link">
|
||||||
{{::item.id}}
|
{{::item.id}}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -5,6 +5,7 @@ Search tickets: Buscar tickets
|
||||||
Delete selected elements: Eliminar los elementos seleccionados
|
Delete selected elements: Eliminar los elementos seleccionados
|
||||||
All the selected elements will be deleted. Are you sure you want to continue?: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar?
|
All the selected elements will be deleted. Are you sure you want to continue?: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar?
|
||||||
Component lack: Faltan componentes
|
Component lack: Faltan componentes
|
||||||
|
Ticket too little: Ticket demasiado pequeño
|
||||||
Minimize/Maximize: Minimizar/Maximizar
|
Minimize/Maximize: Minimizar/Maximizar
|
||||||
Problems: Problemas
|
Problems: Problemas
|
||||||
Theoretical: Teórica
|
Theoretical: Teórica
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="SalesMonitors/salesFilter"
|
url="SalesMonitors/salesFilter"
|
||||||
limit="20"
|
auto-load="false"
|
||||||
order="shipped DESC, theoreticalHour, id">
|
limit="20">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-portal slot="topbar">
|
<vn-portal slot="topbar">
|
||||||
<vn-searchbar
|
<vn-searchbar
|
||||||
|
@ -122,6 +122,12 @@
|
||||||
class="bright"
|
class="bright"
|
||||||
icon="icon-components">
|
icon="icon-components">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
|
<vn-icon
|
||||||
|
ng-show="::ticket.isTooLittle"
|
||||||
|
translate-attr="{title: 'Ticket too little'}"
|
||||||
|
class="bright"
|
||||||
|
icon="icon-isTooLittle">
|
||||||
|
</vn-icon>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span
|
<span
|
||||||
|
|
|
@ -10,7 +10,12 @@
|
||||||
],
|
],
|
||||||
"card": []
|
"card": []
|
||||||
},
|
},
|
||||||
"keybindings": [],
|
"keybindings": [
|
||||||
|
{
|
||||||
|
"key": "m",
|
||||||
|
"state": "monitor.index"
|
||||||
|
}
|
||||||
|
],
|
||||||
"routes": [
|
"routes": [
|
||||||
{
|
{
|
||||||
"url": "/monitor",
|
"url": "/monitor",
|
||||||
|
|
|
@ -15,6 +15,12 @@
|
||||||
{"state": "order.card.line", "icon": "icon-lines"}
|
{"state": "order.card.line", "icon": "icon-lines"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"keybindings": [
|
||||||
|
{
|
||||||
|
"key": "o",
|
||||||
|
"state": "order.index"
|
||||||
|
}
|
||||||
|
],
|
||||||
"routes": [
|
"routes": [
|
||||||
{
|
{
|
||||||
"url": "/order",
|
"url": "/order",
|
||||||
|
|
|
@ -38,7 +38,6 @@ module.exports = Self => {
|
||||||
'payDemFk',
|
'payDemFk',
|
||||||
'payDay',
|
'payDay',
|
||||||
'account',
|
'account',
|
||||||
'isFarmer',
|
|
||||||
'sageTaxTypeFk',
|
'sageTaxTypeFk',
|
||||||
'sageTransactionTypeFk',
|
'sageTransactionTypeFk',
|
||||||
'sageWithholdingFk',
|
'sageWithholdingFk',
|
||||||
|
@ -102,6 +101,11 @@ module.exports = Self => {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
let supplier = await Self.app.models.Supplier.findOne(filter);
|
let supplier = await Self.app.models.Supplier.findOne(filter);
|
||||||
|
|
||||||
|
const farmerCode = 2;
|
||||||
|
if (supplier.sageWithholdingFk == farmerCode)
|
||||||
|
supplier.isFarmer = true;
|
||||||
|
|
||||||
return supplier;
|
return supplier;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,4 +25,12 @@ describe('Supplier getSummary()', () => {
|
||||||
|
|
||||||
expect(payMethod.name).toEqual('PayMethod one');
|
expect(payMethod.name).toEqual('PayMethod one');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it(`should get if supplier is farmer by sageWithholdingFk`, async() => {
|
||||||
|
const supplier = await app.models.Supplier.findById(2);
|
||||||
|
const supplierSummary = await app.models.Supplier.getSummary(2);
|
||||||
|
|
||||||
|
expect(supplier.isFarmer).toBeUndefined();
|
||||||
|
expect(supplierSummary.isFarmer).toEqual(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,12 +7,14 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
async function ibanValidation(err, done) {
|
async function ibanValidation(err, done) {
|
||||||
let filter = {
|
const supplier = await Self.app.models.Supplier.findById(this.supplierFk);
|
||||||
|
const filter = {
|
||||||
fields: ['code'],
|
fields: ['code'],
|
||||||
where: {id: this.countryFk}
|
where: {id: supplier.countryFk}
|
||||||
};
|
};
|
||||||
let country = await Self.app.models.Country.findOne(filter);
|
|
||||||
let code = country ? country.code.toLowerCase() : null;
|
const country = await Self.app.models.Country.findOne(filter);
|
||||||
|
const code = country ? country.code.toLowerCase() : null;
|
||||||
if (code != 'es')
|
if (code != 'es')
|
||||||
return done();
|
return done();
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,6 @@ module.exports = Self => {
|
||||||
&& orgData.socialName != socialName;
|
&& orgData.socialName != socialName;
|
||||||
|
|
||||||
if ((socialNameChanged) && !isAlpha(socialName))
|
if ((socialNameChanged) && !isAlpha(socialName))
|
||||||
throw new UserError('The socialName has an invalid format');
|
throw new UserError('The social name has an invalid format');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,9 +27,6 @@
|
||||||
"nif": {
|
"nif": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"isFarmer": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"phone": {
|
"phone": {
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('payBack', {
|
||||||
|
description: 'Create ticket with the selected lines changing the sign to the quantites',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'sales',
|
||||||
|
description: 'The sales',
|
||||||
|
type: ['object'],
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'ticketId',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The ticket id'
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: 'number',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/payBack`,
|
||||||
|
verb: 'post'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.payBack = async(ctx, sales, ticketId, options) => {
|
||||||
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const salesIds = [];
|
||||||
|
const params = [];
|
||||||
|
const userId = ctx.req.accessToken.userId;
|
||||||
|
|
||||||
|
const isClaimManager = await Self.app.models.Account.hasRole(userId, 'claimManager');
|
||||||
|
const isSalesAssistant = await Self.app.models.Account.hasRole(userId, 'salesAssistant');
|
||||||
|
const hasValidRole = isClaimManager || isSalesAssistant;
|
||||||
|
|
||||||
|
if (!hasValidRole)
|
||||||
|
throw new UserError(`You don't have privileges to create pay back`);
|
||||||
|
|
||||||
|
sales.forEach(sale => {
|
||||||
|
salesIds.push(sale.id);
|
||||||
|
params.push('?');
|
||||||
|
});
|
||||||
|
|
||||||
|
const paramsString = params.join();
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
DROP TEMPORARY TABLE IF EXISTS tmp.sale;
|
||||||
|
CREATE TEMPORARY TABLE tmp.sale
|
||||||
|
SELECT s.id, s.itemFk, - s.quantity, s.concept, s.price, s.discount
|
||||||
|
FROM sale s
|
||||||
|
WHERE s.id IN (${paramsString});
|
||||||
|
CALL vn.ticket_doRefund(${ticketId}, @newTicket);
|
||||||
|
DROP TEMPORARY TABLE tmp.sale;`;
|
||||||
|
|
||||||
|
await Self.rawSql(query, salesIds, myOptions);
|
||||||
|
const [newTicket] = await Self.rawSql('SELECT @newTicket id', null, myOptions);
|
||||||
|
ticketId = newTicket.id;
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return ticketId;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,54 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
|
describe('sale payBack()', () => {
|
||||||
|
it('should create ticket with the selected lines changing the sign to the quantites', async() => {
|
||||||
|
const tx = await models.Sale.beginTransaction({});
|
||||||
|
const ctx = {req: {accessToken: {userId: 9}}};
|
||||||
|
|
||||||
|
const ticketId = 11;
|
||||||
|
const sales = [
|
||||||
|
{id: 7, ticketFk: 11},
|
||||||
|
{id: 8, ticketFk: 11}
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const response = await models.Sale.payBack(ctx, sales, ticketId, options);
|
||||||
|
const [newTicketId] = await models.Sale.rawSql('SELECT MAX(t.id) id FROM vn.ticket t;', null, options);
|
||||||
|
|
||||||
|
expect(response).toEqual(newTicketId.id);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should throw an error if the user doesn't have privileges to create a pay back`, async() => {
|
||||||
|
const tx = await models.Sale.beginTransaction({});
|
||||||
|
const ctx = {req: {accessToken: {userId: 1}}};
|
||||||
|
|
||||||
|
const ticketId = 11;
|
||||||
|
const sales = [
|
||||||
|
{id: 7, ticketFk: 11}
|
||||||
|
];
|
||||||
|
|
||||||
|
let error;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
await models.Sale.payBack(ctx, sales, ticketId, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toBeDefined();
|
||||||
|
expect(error.message).toEqual(`You don't have privileges to create pay back`);
|
||||||
|
});
|
||||||
|
});
|
|
@ -118,10 +118,19 @@ module.exports = Self => {
|
||||||
|
|
||||||
const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss', myOptions);
|
const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss', myOptions);
|
||||||
if (!isProductionBoss) {
|
if (!isProductionBoss) {
|
||||||
const zoneShipped = await models.Agency.getShipped(args.landed, args.addressFk, args.agencyModeFk, args.warehouseFk, myOptions);
|
const zoneShipped = await models.Agency.getShipped(
|
||||||
|
args.landed,
|
||||||
|
args.addressFk,
|
||||||
|
args.agencyModeFk,
|
||||||
|
args.warehouseFk,
|
||||||
|
myOptions);
|
||||||
|
|
||||||
if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk)
|
if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk) {
|
||||||
throw new UserError(`You don't have privileges to change the zone`);
|
const error = `You don't have privileges to change the zone or
|
||||||
|
for these parameters there are more than one shipping options, talk to agencies`;
|
||||||
|
|
||||||
|
throw new UserError(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (args.isWithoutNegatives) {
|
if (args.isWithoutNegatives) {
|
||||||
const query = `CALL ticket_getVisibleAvailable(?,?)`;
|
const query = `CALL ticket_getVisibleAvailable(?,?)`;
|
||||||
|
|
|
@ -9,10 +9,14 @@ module.exports = Self => {
|
||||||
description: 'ticket id',
|
description: 'ticket id',
|
||||||
http: {source: 'path'}
|
http: {source: 'path'}
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: [{
|
||||||
type: ['Object'],
|
arg: 'saleVolume',
|
||||||
root: true
|
type: ['object']
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
arg: 'packingTypeVolume',
|
||||||
|
type: ['object']
|
||||||
|
}],
|
||||||
http: {
|
http: {
|
||||||
path: `/:id/getVolume`,
|
path: `/:id/getVolume`,
|
||||||
verb: 'GET'
|
verb: 'GET'
|
||||||
|
@ -25,7 +29,21 @@ module.exports = Self => {
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
return Self.rawSql(`SELECT * FROM vn.saleVolume
|
const saleVolume = await Self.rawSql(`
|
||||||
WHERE ticketFk = ?`, [ticketFk], myOptions);
|
SELECT saleFk, volume
|
||||||
|
FROM vn.saleVolume
|
||||||
|
WHERE ticketFk = ?`, [ticketFk], myOptions);
|
||||||
|
|
||||||
|
const packingTypeVolume = await Self.rawSql(`
|
||||||
|
SELECT s.itemPackingTypeFk code,
|
||||||
|
i.description,
|
||||||
|
SUM(s.volume) volume
|
||||||
|
FROM vn.saleVolume s
|
||||||
|
LEFT JOIN vn.itemPackingType i
|
||||||
|
ON i.code = s.itemPackingTypeFk
|
||||||
|
WHERE s.ticketFk = ?
|
||||||
|
GROUP BY s.itemPackingTypeFk`, [ticketFk], myOptions);
|
||||||
|
|
||||||
|
return [saleVolume, packingTypeVolume];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -87,8 +87,12 @@ module.exports = Self => {
|
||||||
args.warehouseId,
|
args.warehouseId,
|
||||||
myOptions);
|
myOptions);
|
||||||
|
|
||||||
if (!zoneShipped || zoneShipped.zoneFk != args.zoneId)
|
if (!zoneShipped || zoneShipped.zoneFk != args.zoneId) {
|
||||||
throw new UserError(`You don't have privileges to change the zone`);
|
const error = `You don't have privileges to change the zone or
|
||||||
|
for these parameters there are more than one shipping options, talk to agencies`;
|
||||||
|
|
||||||
|
throw new UserError(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const items = await models.Sale.find({
|
const items = await models.Sale.find({
|
||||||
|
|
|
@ -8,9 +8,15 @@ describe('ticket getVolume()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const ticketId = 1;
|
const ticketId = 1;
|
||||||
const result = await models.Ticket.getVolume(ticketId, options);
|
const expectedSaleVolume = 1.09;
|
||||||
|
const expectedPackingTypeVolume = 0.028;
|
||||||
|
|
||||||
expect(result[0].volume).toEqual(1.09);
|
const result = await models.Ticket.getVolume(ticketId, options);
|
||||||
|
const [saleVolume] = result[0];
|
||||||
|
const [packingTypeVolume] = result[1];
|
||||||
|
|
||||||
|
expect(saleVolume.volume).toEqual(expectedSaleVolume);
|
||||||
|
expect(packingTypeVolume.volume).toEqual(expectedPackingTypeVolume);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -58,13 +58,63 @@ describe('sale transferSales()', () => {
|
||||||
expect(error.message).toEqual(`The sales of the receiver ticket can't be modified`);
|
expect(error.message).toEqual(`The sales of the receiver ticket can't be modified`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should transfer the sales from one ticket to a new one then send them back and delete the created ticket', async() => {
|
it('should throw an error if any of the sales has a claim', async() => {
|
||||||
|
const tx = await models.Ticket.beginTransaction({});
|
||||||
|
|
||||||
|
let error;
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const ticketId = 11;
|
||||||
|
const receiverTicketId = null;
|
||||||
|
const sales = await models.Ticket.getSales(ticketId, options);
|
||||||
|
|
||||||
|
await models.Ticket.transferSales(ctx, ticketId, receiverTicketId, sales, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error.message).toEqual(`Can't transfer claimed sales`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to transfer claimed sales if the role is claimManager', async() => {
|
||||||
|
const tx = await models.Ticket.beginTransaction({});
|
||||||
|
|
||||||
|
let error;
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const claimManagerId = 72;
|
||||||
|
const myActiveCtx = {
|
||||||
|
accessToken: {userId: claimManagerId},
|
||||||
|
};
|
||||||
|
const myCtx = {req: myActiveCtx};
|
||||||
|
|
||||||
|
const ticketId = 11;
|
||||||
|
const receiverTicketId = null;
|
||||||
|
const sales = await models.Ticket.getSales(ticketId, options);
|
||||||
|
|
||||||
|
await models.Ticket.transferSales(myCtx, ticketId, receiverTicketId, sales, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should transfer the sales from a ticket to a new one', async() => {
|
||||||
const tx = await models.Ticket.beginTransaction({});
|
const tx = await models.Ticket.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const formerTicketId = 11;
|
const formerTicketId = 22;
|
||||||
let createdTicketId = undefined;
|
let createdTicketId = undefined;
|
||||||
|
|
||||||
let formerTicketSales = await models.Ticket.getSales(formerTicketId, options);
|
let formerTicketSales = await models.Ticket.getSales(formerTicketId, options);
|
||||||
|
@ -77,23 +127,11 @@ describe('sale transferSales()', () => {
|
||||||
createdTicketId = createdTicket.id;
|
createdTicketId = createdTicket.id;
|
||||||
|
|
||||||
formerTicketSales = await models.Ticket.getSales(formerTicketId, options);
|
formerTicketSales = await models.Ticket.getSales(formerTicketId, options);
|
||||||
createdTicketSales = await models.Ticket.getSales(createdTicketId, options);
|
let createdTicketSales = await models.Ticket.getSales(createdTicketId, options);
|
||||||
|
|
||||||
expect(formerTicketSales.length).toEqual(0);
|
expect(formerTicketSales.length).toEqual(0);
|
||||||
expect(createdTicketSales.length).toEqual(2);
|
expect(createdTicketSales.length).toEqual(2);
|
||||||
|
|
||||||
await models.Ticket.transferSales(
|
|
||||||
ctx, createdTicketId, formerTicketId, createdTicketSales, options);
|
|
||||||
|
|
||||||
formerTicketSales = await models.Ticket.getSales(formerTicketId, options);
|
|
||||||
createdTicketSales = await models.Ticket.getSales(createdTicketId, options);
|
|
||||||
|
|
||||||
createdTicket = await models.Ticket.findById(createdTicketId, null, options);
|
|
||||||
|
|
||||||
expect(createdTicket.isDeleted).toBeTruthy();
|
|
||||||
expect(formerTicketSales.length).toEqual(2);
|
|
||||||
expect(createdTicketSales.length).toEqual(0);
|
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
|
@ -109,10 +147,9 @@ describe('sale transferSales()', () => {
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const currentTicket = await models.Ticket.findById(11, null, options);
|
const currentTicketId = 22;
|
||||||
const currentTicketSales = await models.Ticket.getSales(currentTicket.id, options);
|
const currentTicketSales = await models.Ticket.getSales(currentTicketId, options);
|
||||||
|
|
||||||
const currentTicketId = currentTicket.id;
|
|
||||||
const receiverTicketId = undefined;
|
const receiverTicketId = undefined;
|
||||||
|
|
||||||
currentTicketSales[0].quantity = 99;
|
currentTicketSales[0].quantity = 99;
|
||||||
|
@ -135,7 +172,7 @@ describe('sale transferSales()', () => {
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const formerTicketId = 11;
|
const formerTicketId = 22;
|
||||||
let createdTicketId = undefined;
|
let createdTicketId = undefined;
|
||||||
|
|
||||||
let formerTicketSales = await models.Ticket.getSales(formerTicketId, options);
|
let formerTicketSales = await models.Ticket.getSales(formerTicketId, options);
|
||||||
|
@ -143,7 +180,7 @@ describe('sale transferSales()', () => {
|
||||||
const completeSaleId = formerTicketSales[1].id;
|
const completeSaleId = formerTicketSales[1].id;
|
||||||
let partialSaleTotalQuantity = formerTicketSales[0].quantity;
|
let partialSaleTotalQuantity = formerTicketSales[0].quantity;
|
||||||
|
|
||||||
expect(partialSaleTotalQuantity).toEqual(15);
|
expect(partialSaleTotalQuantity).toEqual(30);
|
||||||
|
|
||||||
formerTicketSales[0].quantity = 1;
|
formerTicketSales[0].quantity = 1;
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,13 @@ module.exports = Self => {
|
||||||
for (const sale of originalSales)
|
for (const sale of originalSales)
|
||||||
map.set(sale.id, sale);
|
map.set(sale.id, sale);
|
||||||
|
|
||||||
|
const saleIds = sales.map(sale => sale.id);
|
||||||
|
|
||||||
|
const isClaimManager = await models.Account.hasRole(userId, 'claimManager');
|
||||||
|
const hasClaimedSales = await models.ClaimBeginning.findOne({where: {saleFk: {inq: saleIds}}});
|
||||||
|
if (hasClaimedSales && !isClaimManager)
|
||||||
|
throw new UserError(`Can't transfer claimed sales`);
|
||||||
|
|
||||||
for (const sale of sales) {
|
for (const sale of sales) {
|
||||||
const originalSale = map.get(sale.id);
|
const originalSale = map.get(sale.id);
|
||||||
const originalSaleData = { // <-- Loopback modifies original instance on save
|
const originalSaleData = { // <-- Loopback modifies original instance on save
|
||||||
|
|
|
@ -6,6 +6,7 @@ module.exports = Self => {
|
||||||
require('../methods/sale/updateQuantity')(Self);
|
require('../methods/sale/updateQuantity')(Self);
|
||||||
require('../methods/sale/updateConcept')(Self);
|
require('../methods/sale/updateConcept')(Self);
|
||||||
require('../methods/sale/recalculatePrice')(Self);
|
require('../methods/sale/recalculatePrice')(Self);
|
||||||
|
require('../methods/sale/payBack')(Self);
|
||||||
require('../methods/sale/canEdit')(Self);
|
require('../methods/sale/canEdit')(Self);
|
||||||
|
|
||||||
Self.validatesPresenceOf('concept', {
|
Self.validatesPresenceOf('concept', {
|
||||||
|
|
|
@ -149,7 +149,10 @@ class Controller extends Section {
|
||||||
return this.$http.post(`Tickets/${this.id}/setDeleted`)
|
return this.$http.post(`Tickets/${this.id}/setDeleted`)
|
||||||
.then(() => this.reload())
|
.then(() => this.reload())
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$state.go('ticket.index');
|
const isInsideTicket = this.$state.current.name.startsWith('ticket');
|
||||||
|
if (isInsideTicket)
|
||||||
|
this.$state.go('ticket.index');
|
||||||
|
|
||||||
this.vnApp.showSuccess(this.$t('Ticket deleted. You can undo this action within the first hour'));
|
this.vnApp.showSuccess(this.$t('Ticket deleted. You can undo this action within the first hour'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,9 +78,22 @@ describe('Ticket Component vnTicketDescriptorMenu', () => {
|
||||||
|
|
||||||
describe('deleteTicket()', () => {
|
describe('deleteTicket()', () => {
|
||||||
it('should make a query and call vnApp.showSuccess()', () => {
|
it('should make a query and call vnApp.showSuccess()', () => {
|
||||||
|
jest.spyOn(controller, 'reload').mockReturnThis();
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
|
||||||
|
$httpBackend.expectPOST(`Tickets/${ticket.id}/setDeleted`).respond();
|
||||||
|
controller.deleteTicket();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.reload).toHaveBeenCalled();
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should make a query and call showSuccess() after state.go if the state wasn't inside ticket module`, () => {
|
||||||
jest.spyOn(controller, 'reload').mockReturnThis();
|
jest.spyOn(controller, 'reload').mockReturnThis();
|
||||||
jest.spyOn(controller.$state, 'go').mockReturnValue('ok');
|
jest.spyOn(controller.$state, 'go').mockReturnValue('ok');
|
||||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
controller.$state.current.name = 'ticket.card.something';
|
||||||
|
|
||||||
$httpBackend.expectPOST(`Tickets/${ticket.id}/setDeleted`).respond();
|
$httpBackend.expectPOST(`Tickets/${ticket.id}/setDeleted`).respond();
|
||||||
controller.deleteTicket();
|
controller.deleteTicket();
|
||||||
|
|
|
@ -37,6 +37,7 @@ Observation type: Tipo de observación
|
||||||
Original: Original
|
Original: Original
|
||||||
Package size: Bultos
|
Package size: Bultos
|
||||||
Package type: Tipo de porte
|
Package type: Tipo de porte
|
||||||
|
Packing type: Encajado
|
||||||
Phone: Teléfono
|
Phone: Teléfono
|
||||||
PPU: Ud.
|
PPU: Ud.
|
||||||
Price: Precio
|
Price: Precio
|
||||||
|
|
|
@ -490,4 +490,11 @@
|
||||||
ng-if="$ctrl.isEditable && $ctrl.hasReserves()">
|
ng-if="$ctrl.isEditable && $ctrl.hasReserves()">
|
||||||
Unmark as reserved
|
Unmark as reserved
|
||||||
</vn-item>
|
</vn-item>
|
||||||
|
<vn-item translate
|
||||||
|
name="payBack"
|
||||||
|
ng-click="$ctrl.createPayBack()"
|
||||||
|
vn-acl="claimManager, salesAssistant"
|
||||||
|
vn-acl-action="remove">
|
||||||
|
Pay Back
|
||||||
|
</vn-item>
|
||||||
</vn-menu>
|
</vn-menu>
|
|
@ -40,7 +40,9 @@ class Controller extends Section {
|
||||||
const landedPlusWeek = new Date(this.ticket.landed);
|
const landedPlusWeek = new Date(this.ticket.landed);
|
||||||
landedPlusWeek.setDate(landedPlusWeek.getDate() + 7);
|
landedPlusWeek.setDate(landedPlusWeek.getDate() + 7);
|
||||||
|
|
||||||
return landedPlusWeek >= new Date();
|
const hasClaimManagerRole = this.aclService.hasAny(['claimManager']);
|
||||||
|
|
||||||
|
return landedPlusWeek >= new Date() || hasClaimManagerRole;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -460,6 +462,18 @@ class Controller extends Section {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createPayBack() {
|
||||||
|
const sales = this.selectedValidSales();
|
||||||
|
if (!sales) return;
|
||||||
|
|
||||||
|
const params = {sales: sales, ticketId: this.ticket.id};
|
||||||
|
const query = `Sales/payBack`;
|
||||||
|
this.resetChanges();
|
||||||
|
this.$http.post(query, params).then(res => {
|
||||||
|
this.$state.go('ticket.card.sale', {id: res.data});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
itemSearchFunc($search) {
|
itemSearchFunc($search) {
|
||||||
return /^\d+$/.test($search)
|
return /^\d+$/.test($search)
|
||||||
? {id: $search}
|
? {id: $search}
|
||||||
|
|
|
@ -701,6 +701,22 @@ describe('Ticket', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('createPayBack()', () => {
|
||||||
|
it('should make an HTTP POST query and then call to the $state go() method', () => {
|
||||||
|
jest.spyOn(controller, 'selectedValidSales').mockReturnValue(controller.sales);
|
||||||
|
jest.spyOn(controller, 'resetChanges');
|
||||||
|
jest.spyOn(controller.$state, 'go');
|
||||||
|
|
||||||
|
const expectedId = 9999;
|
||||||
|
$httpBackend.expect('POST', `Sales/payBack`).respond(200, expectedId);
|
||||||
|
controller.createPayBack();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.resetChanges).toHaveBeenCalledWith();
|
||||||
|
expect(controller.$state.go).toHaveBeenCalledWith('ticket.card.sale', {id: expectedId});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('itemSearchFunc()', () => {
|
describe('itemSearchFunc()', () => {
|
||||||
it('should return the filter by id property for an input of a number', () => {
|
it('should return the filter by id property for an input of a number', () => {
|
||||||
const itemId = 1;
|
const itemId = 1;
|
||||||
|
|
|
@ -35,4 +35,5 @@ Address: Dirección
|
||||||
Warehouse: Almacen
|
Warehouse: Almacen
|
||||||
Agency: Agencia
|
Agency: Agencia
|
||||||
Shipped: F. envio
|
Shipped: F. envio
|
||||||
Packaging: Encajado
|
Packaging: Encajado
|
||||||
|
Pay Back: Abono
|
|
@ -11,14 +11,14 @@
|
||||||
Ticket #{{$ctrl.summary.id}} - {{$ctrl.summary.client.name}}
|
Ticket #{{$ctrl.summary.id}} - {{$ctrl.summary.client.name}}
|
||||||
({{$ctrl.summary.client.id}}) - {{$ctrl.summary.nickname}}
|
({{$ctrl.summary.client.id}}) - {{$ctrl.summary.nickname}}
|
||||||
</span>
|
</span>
|
||||||
<vn-button
|
<vn-button-menu
|
||||||
disabled="!$ctrl.isEditable"
|
disabled="!$ctrl.isEditable"
|
||||||
class="flat"
|
class="message"
|
||||||
style="color: inherit;"
|
label="Change state"
|
||||||
label="SET OK"
|
value-field="code"
|
||||||
ng-click="$ctrl.setOkState()"
|
url="States/editableStates"
|
||||||
vn-tooltip="Change ticket state to 'Ok'">
|
on-change="$ctrl.changeState(value)">
|
||||||
</vn-button>
|
</vn-button-menu>
|
||||||
<vn-ticket-descriptor-menu
|
<vn-ticket-descriptor-menu
|
||||||
ng-if="!$ctrl.isTicketModule"
|
ng-if="!$ctrl.isTicketModule"
|
||||||
ticket-id="$ctrl.summary.id"
|
ticket-id="$ctrl.summary.id"
|
||||||
|
|
|
@ -59,10 +59,11 @@ class Controller extends Summary {
|
||||||
this.$.invoiceOutDescriptor.show(event.target, this.summary.invoiceOut.id);
|
this.$.invoiceOutDescriptor.show(event.target, this.summary.invoiceOut.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
setOkState() {
|
changeState(value) {
|
||||||
const params = {ticketFk: 'id' in this.ticket ? this.ticket.id : this.$params.id};
|
const params = {
|
||||||
|
ticketFk: 'id' in this.ticket ? this.ticket.id : this.$params.id,
|
||||||
params.code = 'OK';
|
code: value
|
||||||
|
};
|
||||||
|
|
||||||
this.$http.post(`TicketTrackings/changeState`, params)
|
this.$http.post(`TicketTrackings/changeState`, params)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
|
@ -42,5 +42,20 @@ describe('Ticket', () => {
|
||||||
expect(controller.formattedAddress).toEqual('1007 Mountain Drive - 46060 - Gotham (Gotham)');
|
expect(controller.formattedAddress).toEqual('1007 Mountain Drive - 46060 - Gotham (Gotham)');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('changeState()', () => {
|
||||||
|
it('should change the state', () => {
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
const value = 'myTicketState';
|
||||||
|
|
||||||
|
let res = {id: 1, nickname: 'myNickname'};
|
||||||
|
$httpBackend.when('GET', `Tickets/1/summary`).respond(200, res);
|
||||||
|
$httpBackend.expectPOST(`TicketTrackings/changeState`).respond(200, 'ok');
|
||||||
|
controller.changeState(value);
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,4 +2,5 @@ Address phone: Tel. consignatario
|
||||||
Address mobile: Móv. consignatario
|
Address mobile: Móv. consignatario
|
||||||
Client phone: Tel. cliente
|
Client phone: Tel. cliente
|
||||||
Client mobile: Móv. cliente
|
Client mobile: Móv. cliente
|
||||||
Go to the ticket: Ir al ticket
|
Go to the ticket: Ir al ticket
|
||||||
|
Change state: Cambiar estado
|
|
@ -6,22 +6,17 @@
|
||||||
data="$ctrl.sales"
|
data="$ctrl.sales"
|
||||||
limit="20">
|
limit="20">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-crud-model auto-load="true"
|
|
||||||
url="tickets/{{$ctrl.$params.id}}/getVolume"
|
|
||||||
data="$ctrl.volumes">
|
|
||||||
</vn-crud-model>
|
|
||||||
<mg-ajax path="tickets/{{$ctrl.$params.id}}/getTotalVolume" options="mgEdit"></mg-ajax>
|
|
||||||
<vn-vertical>
|
<vn-vertical>
|
||||||
<vn-card class="vn-pa-lg">
|
<vn-card class="vn-pa-lg">
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<div class="totalBox">
|
<div class="totalBox" ng-repeat="packingType in $ctrl.packingTypeVolume">
|
||||||
<vn-label-value label="Total"
|
<vn-label-value label="Tipo"
|
||||||
value="{{::edit.model.totalVolume}}">
|
value="{{::packingType.description}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value label="Cajas"
|
<vn-label-value label="Volumen"
|
||||||
value="{{::edit.model.totalBoxes}}">
|
value="{{::packingType.volume}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
</div>
|
</div>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-vertical>
|
<vn-vertical>
|
||||||
<vn-table model="model">
|
<vn-table model="model">
|
||||||
|
@ -29,6 +24,7 @@
|
||||||
<vn-tr>
|
<vn-tr>
|
||||||
<vn-th field="itemFk" number>Item</vn-th>
|
<vn-th field="itemFk" number>Item</vn-th>
|
||||||
<vn-th field="concept" default-order="ASC">Description</vn-th>
|
<vn-th field="concept" default-order="ASC">Description</vn-th>
|
||||||
|
<vn-th field="itemPackingTypeFk" number>Packing type</vn-th>
|
||||||
<vn-th field="quantity" number>Quantity</vn-th>
|
<vn-th field="quantity" number>Quantity</vn-th>
|
||||||
<vn-th number>m³ per quantity</vn-th>
|
<vn-th number>m³ per quantity</vn-th>
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
|
@ -55,6 +51,7 @@
|
||||||
tabindex="-1">
|
tabindex="-1">
|
||||||
</vn-fetched-tags>
|
</vn-fetched-tags>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
|
<vn-td number>{{::sale.item.itemPackingTypeFk}}</vn-td>
|
||||||
<vn-td number>{{::sale.quantity}}</vn-td>
|
<vn-td number>{{::sale.quantity}}</vn-td>
|
||||||
<vn-td number>{{::sale.saleVolume.volume | number:3}}</vn-td>
|
<vn-td number>{{::sale.saleVolume.volume | number:3}}</vn-td>
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
|
|
|
@ -23,24 +23,19 @@ class Controller extends Section {
|
||||||
if (value) this.applyVolumes();
|
if (value) this.applyVolumes();
|
||||||
}
|
}
|
||||||
|
|
||||||
get volumes() {
|
|
||||||
return this._volumes;
|
|
||||||
}
|
|
||||||
|
|
||||||
set volumes(value) {
|
|
||||||
this._volumes = value;
|
|
||||||
|
|
||||||
if (value) this.applyVolumes();
|
|
||||||
}
|
|
||||||
|
|
||||||
applyVolumes() {
|
applyVolumes() {
|
||||||
if (!this.sales || !this.volumes) return;
|
const ticket = this.sales[0].ticketFk;
|
||||||
|
this.$http.get(`Tickets/${ticket}/getVolume`).then(res => {
|
||||||
|
const saleVolume = res.data.saleVolume;
|
||||||
|
|
||||||
this.sales.forEach(sale => {
|
const volumes = new Map();
|
||||||
this.volumes.forEach(volume => {
|
for (const volume of saleVolume)
|
||||||
if (sale.id === volume.saleFk)
|
volumes.set(volume.saleFk, volume);
|
||||||
sale.saleVolume = volume;
|
|
||||||
});
|
for (const sale of this.sales)
|
||||||
|
sale.saleVolume = volumes.get(sale.id);
|
||||||
|
|
||||||
|
this.packingTypeVolume = res.data.packingTypeVolume;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
this should be translated or removed?