diff --git a/db/changes/10360-september/00-ACL.sql b/db/changes/10360-september/00-ACL.sql deleted file mode 100644 index 6a3fcf708..000000000 --- a/db/changes/10360-september/00-ACL.sql +++ /dev/null @@ -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; \ No newline at end of file diff --git a/db/changes/10360-september/00-sale_problems.sql b/db/changes/10360-september/00-sale_problems.sql deleted file mode 100644 index 2702b524c..000000000 --- a/db/changes/10360-september/00-sale_problems.sql +++ /dev/null @@ -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 ; diff --git a/db/changes/10360-september/00-ticket_getProblems.sql b/db/changes/10360-september/00-ticket_getProblems.sql deleted file mode 100644 index dacba7e09..000000000 --- a/db/changes/10360-september/00-ticket_getProblems.sql +++ /dev/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 - (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 ; diff --git a/db/changes/10360-september/01-travelThermograph.sql b/db/changes/10360-september/01-travelThermograph.sql deleted file mode 100644 index dec86d102..000000000 --- a/db/changes/10360-september/01-travelThermograph.sql +++ /dev/null @@ -1 +0,0 @@ -alter table `vn`.`travelThermograph` modify `temperature` enum('COOL', 'WARM') null; \ No newline at end of file diff --git a/db/changes/10370-pickles/00-ACL.sql b/db/changes/10370-pickles/00-ACL.sql deleted file mode 100644 index c5e10dec5..000000000 --- a/db/changes/10370-pickles/00-ACL.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE salix.ACL t SET t.principalId = 'employee' WHERE t.id = 269; diff --git a/db/changes/10370-pickles/00-accountingType.sql b/db/changes/10370-pickles/00-accountingType.sql deleted file mode 100644 index 1313e8223..000000000 --- a/db/changes/10370-pickles/00-accountingType.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE vn.accountingType ADD maxAmount INT DEFAULT NULL NULL; - -UPDATE vn.accountingType SET maxAmount = 1000 WHERE code = 'cash'; diff --git a/db/changes/10370-pickles/00-payMethod.sql b/db/changes/10370-pickles/00-payMethod.sql deleted file mode 100644 index ac6429b99..000000000 --- a/db/changes/10370-pickles/00-payMethod.sql +++ /dev/null @@ -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'; \ No newline at end of file diff --git a/db/changes/10370-pickles/00-silexACL.sql b/db/changes/10370-pickles/00-silexACL.sql deleted file mode 100644 index 82623baf0..000000000 --- a/db/changes/10370-pickles/00-silexACL.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE vn.silexACL MODIFY module VARCHAR(50) NOT NULL; -ALTER TABLE vn.silexACL MODIFY method VARCHAR(50) NOT NULL; \ No newline at end of file diff --git a/db/changes/10370-pickles/00-ticket_getProblems.sql b/db/changes/10370-pickles/00-ticket_getProblems.sql deleted file mode 100644 index 2ee057cd2..000000000 --- a/db/changes/10370-pickles/00-ticket_getProblems.sql +++ /dev/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 ; \ No newline at end of file diff --git a/db/changes/10380-allsaints/00-defaultViewConfig.sql b/db/changes/10380-allsaints/00-defaultViewConfig.sql deleted file mode 100644 index e4b2f6c3d..000000000 --- a/db/changes/10380-allsaints/00-defaultViewConfig.sql +++ /dev/null @@ -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}'); - - \ No newline at end of file diff --git a/db/changes/10410-noname/00-smsConfig.sql b/db/changes/10410-noname/00-smsConfig.sql deleted file mode 100644 index b3f1610d4..000000000 --- a/db/changes/10410-noname/00-smsConfig.sql +++ /dev/null @@ -1,5 +0,0 @@ -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; diff --git a/db/changes/10410-noname/01-smsConfig_update.sql b/db/changes/10410-noname/01-smsConfig_update.sql deleted file mode 100644 index c4b4c895e..000000000 --- a/db/changes/10410-noname/01-smsConfig_update.sql +++ /dev/null @@ -1,7 +0,0 @@ -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; \ No newline at end of file diff --git a/db/changes/10411-january/00-acl.sql b/db/changes/10411-january/00-acl.sql new file mode 100644 index 000000000..fad50d15d --- /dev/null +++ b/db/changes/10411-january/00-acl.sql @@ -0,0 +1,2 @@ +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES('InvoiceInDueDay', '*', '*', 'ALLOW', 'ROLE', 'administrative'); \ No newline at end of file diff --git a/db/changes/10411-january/00-booking.sql b/db/changes/10411-january/00-booking.sql new file mode 100644 index 000000000..b89234139 --- /dev/null +++ b/db/changes/10411-january/00-booking.sql @@ -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 ; diff --git a/db/changes/10411-january/00-companyGroup.sql b/db/changes/10411-january/00-companyGroup.sql new file mode 100644 index 000000000..2c5477e63 --- /dev/null +++ b/db/changes/10411-january/00-companyGroup.sql @@ -0,0 +1,12 @@ +UPDATE `vn`.`companyGroup` + SET `code`='verdnatura' + WHERE `id`=1; +UPDATE `vn`.`companyGroup` + SET `code`='ornamental' + WHERE `id`=2; +UPDATE `vn`.`companyGroup` + SET `code`='other' + WHERE `id`=3; +UPDATE `vn`.`companyGroup` + SET `code`='provisional' + WHERE `id`=4; diff --git a/db/changes/10411-january/00-saleVolume.sql b/db/changes/10411-january/00-saleVolume.sql new file mode 100644 index 000000000..e8a5e3433 --- /dev/null +++ b/db/changes/10411-january/00-saleVolume.sql @@ -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 ; diff --git a/db/changes/10411-january/00-ticket_getMovable.sql b/db/changes/10411-january/00-ticket_getMovable.sql new file mode 100644 index 000000000..5f5b0a93a --- /dev/null +++ b/db/changes/10411-january/00-ticket_getMovable.sql @@ -0,0 +1,43 @@ +DROP PROCEDURE IF EXISTS `vn`.`ticket_getMovable`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_getMovable`(vTicketFk INT, vDatedNew DATETIME, vWarehouseFk INT) +BEGIN +/** + * Cálcula el stock movible para los artículos de un ticket + * + * @param vTicketFk -> Ticket + * @param vDatedNew -> Nueva fecha + * @return Sales con Movible +*/ + DECLARE vDatedOld DATETIME; + + SELECT t.shipped INTO vDatedOld + FROM ticket t + WHERE t.id = vTicketFk; + + CALL itemStock(vWarehouseFk, DATE_SUB(vDatedNew, INTERVAL 1 DAY), NULL); + CALL item_getMinacum(vWarehouseFk, vDatedNew, DATEDIFF(vDatedOld, vDatedNew), NULL); + + SELECT s.id, + s.itemFk, + s.quantity, + s.concept, + s.price, + s.reserved, + s.discount, + i.image, + i.subName, + il.stock + IFNULL(im.amount, 0) AS movable + FROM ticket t + JOIN sale s ON s.ticketFk = t.id + JOIN item i ON i.id = s.itemFk + LEFT JOIN tmp.itemMinacum im ON im.itemFk = s.itemFk AND im.warehouseFk = vWarehouseFk + LEFT JOIN tmp.itemList il ON il.itemFk = s.itemFk + WHERE t.id = vTicketFk; + + DROP TEMPORARY TABLE IF EXISTS tmp.itemList; + DROP TEMPORARY TABLE IF EXISTS tmp.itemMinacum; +END$$ +DELIMITER ; diff --git a/db/changes/10411-january/00-workerLabour.sql b/db/changes/10411-january/00-workerLabour.sql new file mode 100644 index 000000000..8630eee22 --- /dev/null +++ b/db/changes/10411-january/00-workerLabour.sql @@ -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 \ No newline at end of file diff --git a/db/docker.js b/db/docker.js index c9a0b88a2..ea9fe8ed1 100644 --- a/db/docker.js +++ b/db/docker.js @@ -137,7 +137,8 @@ module.exports = class Docker { user: this.dbConf.username, password: this.dbConf.password, host: this.dbConf.host, - port: this.dbConf.port + port: this.dbConf.port, + connectTimeout: maxInterval }; log('Waiting for MySQL init process...'); diff --git a/db/dump/dumpedFixtures.sql b/db/dump/dumpedFixtures.sql index f9f381bec..e11cf44d5 100644 --- a/db/dump/dumpedFixtures.sql +++ b/db/dump/dumpedFixtures.sql @@ -34,7 +34,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2022-01-03 7:27:20 +-- Dump completed on 2022-01-13 7:50:24 USE `account`; -- MariaDB dump 10.19 Distrib 10.5.12-MariaDB, for debian-linux-gnu (x86_64) -- @@ -120,7 +120,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2022-01-03 7:27:21 +-- Dump completed on 2022-01-13 7:50:25 USE `salix`; -- MariaDB dump 10.19 Distrib 10.5.12-MariaDB, for debian-linux-gnu (x86_64) -- @@ -144,7 +144,7 @@ USE `salix`; LOCK TABLES `ACL` WRITE; /*!40000 ALTER TABLE `ACL` DISABLE KEYS */; -INSERT INTO `ACL` VALUES (1,'Account','*','*','ALLOW','ROLE','employee'),(3,'Address','*','*','ALLOW','ROLE','employee'),(5,'AgencyService','*','READ','ALLOW','ROLE','employee'),(7,'Client','*','*','ALLOW','ROLE','employee'),(9,'ClientObservation','*','*','ALLOW','ROLE','employee'),(11,'ContactChannel','*','READ','ALLOW','ROLE','trainee'),(13,'Employee','*','READ','ALLOW','ROLE','employee'),(14,'PayMethod','*','READ','ALLOW','ROLE','trainee'),(16,'FakeProduction','*','READ','ALLOW','ROLE','employee'),(17,'Warehouse','* ','READ','ALLOW','ROLE','trainee'),(18,'State','*','READ','ALLOW','ROLE','employee'),(20,'TicketState','*','*','ALLOW','ROLE','employee'),(24,'Delivery','*','READ','ALLOW','ROLE','employee'),(25,'Zone','*','READ','ALLOW','ROLE','employee'),(26,'ClientCredit','*','*','ALLOW','ROLE','employee'),(27,'ClientCreditLimit','*','READ','ALLOW','ROLE','trainee'),(30,'GreugeType','*','READ','ALLOW','ROLE','trainee'),(31,'Mandate','*','READ','ALLOW','ROLE','trainee'),(32,'MandateType','*','READ','ALLOW','ROLE','trainee'),(33,'Company','*','READ','ALLOW','ROLE','trainee'),(34,'Greuge','*','READ','ALLOW','ROLE','trainee'),(35,'AddressObservation','*','*','ALLOW','ROLE','employee'),(36,'ObservationType','*','*','ALLOW','ROLE','employee'),(37,'Greuge','*','WRITE','ALLOW','ROLE','employee'),(38,'AgencyMode','*','READ','ALLOW','ROLE','employee'),(39,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(40,'ItemBotanical','*','WRITE','ALLOW','ROLE','buyer'),(41,'ItemBotanical','*','READ','ALLOW','ROLE','employee'),(42,'ItemPlacement','*','WRITE','ALLOW','ROLE','buyer'),(43,'ItemPlacement','*','WRITE','ALLOW','ROLE','replenisher'),(44,'ItemPlacement','*','READ','ALLOW','ROLE','employee'),(45,'ItemBarcode','*','READ','ALLOW','ROLE','employee'),(46,'ItemBarcode','*','WRITE','ALLOW','ROLE','buyer'),(47,'ItemBarcode','*','WRITE','ALLOW','ROLE','replenisher'),(51,'ItemTag','*','READ','ALLOW','ROLE','employee'),(53,'Item','*','READ','ALLOW','ROLE','employee'),(54,'Item','*','WRITE','ALLOW','ROLE','buyer'),(55,'Recovery','*','READ','ALLOW','ROLE','trainee'),(56,'Recovery','*','WRITE','ALLOW','ROLE','administrative'),(58,'CreditClassification','*','*','ALLOW','ROLE','insurance'),(60,'CreditInsurance','*','*','ALLOW','ROLE','insurance'),(61,'InvoiceOut','*','READ','ALLOW','ROLE','employee'),(62,'Ticket','*','*','ALLOW','ROLE','employee'),(63,'TicketObservation','*','*','ALLOW','ROLE','employee'),(64,'Route','*','READ','ALLOW','ROLE','employee'),(65,'Sale','*','READ','ALLOW','ROLE','employee'),(66,'TicketTracking','*','READ','ALLOW','ROLE','employee'),(68,'TicketPackaging','*','*','ALLOW','ROLE','employee'),(69,'Packaging','*','READ','ALLOW','ROLE','employee'),(70,'Packaging','*','WRITE','ALLOW','ROLE','logistic'),(71,'SaleChecked','*','READ','ALLOW','ROLE','employee'),(72,'SaleComponent','*','READ','ALLOW','ROLE','employee'),(73,'Expedition','*','READ','ALLOW','ROLE','employee'),(74,'Expedition','*','WRITE','ALLOW','ROLE','deliveryBoss'),(75,'Expedition','*','WRITE','ALLOW','ROLE','production'),(76,'AnnualAverageInvoiced','*','READ','ALLOW','ROLE','employee'),(77,'WorkerMana','*','READ','ALLOW','ROLE','employee'),(78,'TicketTracking','*','WRITE','ALLOW','ROLE','production'),(79,'TicketTracking','changeState','*','ALLOW','ROLE','employee'),(80,'Sale','deleteSales','*','ALLOW','ROLE','employee'),(81,'Sale','moveToTicket','*','ALLOW','ROLE','employee'),(82,'Sale','updateQuantity','*','ALLOW','ROLE','employee'),(83,'Sale','updatePrice','*','ALLOW','ROLE','employee'),(84,'Sale','updateDiscount','*','ALLOW','ROLE','employee'),(85,'SaleTracking','*','READ','ALLOW','ROLE','employee'),(86,'Order','*','*','ALLOW','ROLE','employee'),(87,'OrderRow','*','*','ALLOW','ROLE','employee'),(88,'ClientContact','*','*','ALLOW','ROLE','employee'),(89,'Sale','moveToNewTicket','*','ALLOW','ROLE','employee'),(90,'Sale','reserve','*','ALLOW','ROLE','employee'),(91,'TicketWeekly','*','READ','ALLOW','ROLE','employee'),(94,'Agency','landsThatDay','*','ALLOW','ROLE','employee'),(96,'ClaimEnd','*','READ','ALLOW','ROLE','employee'),(97,'ClaimEnd','*','WRITE','ALLOW','ROLE','claimManager'),(98,'ClaimBeginning','*','*','ALLOW','ROLE','employee'),(99,'ClaimDevelopment','*','READ','ALLOW','ROLE','employee'),(100,'ClaimDevelopment','*','WRITE','ALLOW','ROLE','claimManager'),(101,'Claim','*','*','ALLOW','ROLE','employee'),(102,'Claim','createFromSales','*','ALLOW','ROLE','employee'),(103,'ClaimEnd','importTicketSales','WRITE','ALLOW','ROLE','claimManager'),(104,'Item','*','WRITE','ALLOW','ROLE','marketingBoss'),(105,'ItemBarcode','*','WRITE','ALLOW','ROLE','marketingBoss'),(106,'ItemBotanical','*','WRITE','ALLOW','ROLE','marketingBoss'),(108,'ItemPlacement','*','WRITE','ALLOW','ROLE','marketingBoss'),(109,'UserConfig','*','*','ALLOW','ROLE','employee'),(110,'Bank','*','READ','ALLOW','ROLE','trainee'),(111,'ClientLog','*','READ','ALLOW','ROLE','trainee'),(112,'Defaulter','*','READ','ALLOW','ROLE','employee'),(113,'ClientRisk','*','READ','ALLOW','ROLE','trainee'),(114,'Receipt','*','READ','ALLOW','ROLE','trainee'),(115,'Receipt','*','WRITE','ALLOW','ROLE','administrative'),(116,'BankEntity','*','*','ALLOW','ROLE','employee'),(117,'ClientSample','*','*','ALLOW','ROLE','employee'),(118,'WorkerTeam','*','*','ALLOW','ROLE','salesPerson'),(119,'Travel','*','READ','ALLOW','ROLE','employee'),(120,'Travel','*','WRITE','ALLOW','ROLE','buyer'),(121,'Item','regularize','*','ALLOW','ROLE','employee'),(122,'TicketRequest','*','*','ALLOW','ROLE','employee'),(123,'Worker','*','*','ALLOW','ROLE','employee'),(124,'Client','confirmTransaction','WRITE','ALLOW','ROLE','administrative'),(125,'Agency','getAgenciesWithWarehouse','*','ALLOW','ROLE','employee'),(126,'Client','activeWorkersWithRole','*','ALLOW','ROLE','employee'),(127,'TicketLog','*','READ','ALLOW','ROLE','employee'),(129,'TicketService','*','*','ALLOW','ROLE','employee'),(130,'Expedition','*','WRITE','ALLOW','ROLE','packager'),(131,'CreditInsurance','*','READ','ALLOW','ROLE','trainee'),(132,'CreditClassification','*','READ','ALLOW','ROLE','trainee'),(133,'ItemTag','*','WRITE','ALLOW','ROLE','marketingBoss'),(135,'ZoneGeo','*','READ','ALLOW','ROLE','employee'),(136,'ZoneCalendar','*','READ','ALLOW','ROLE','employee'),(137,'ZoneIncluded','*','READ','ALLOW','ROLE','employee'),(138,'LabourHoliday','*','READ','ALLOW','ROLE','employee'),(139,'LabourHolidayLegend','*','READ','ALLOW','ROLE','employee'),(140,'LabourHolidayType','*','READ','ALLOW','ROLE','employee'),(141,'Zone','*','*','ALLOW','ROLE','deliveryBoss'),(142,'ZoneCalendar','*','WRITE','ALLOW','ROLE','deliveryBoss'),(143,'ZoneIncluded','*','*','ALLOW','ROLE','deliveryBoss'),(144,'Stowaway','*','*','ALLOW','ROLE','employee'),(145,'Ticket','getPossibleStowaways','READ','ALLOW','ROLE','employee'),(147,'UserConfigView','*','*','ALLOW','ROLE','employee'),(148,'UserConfigView','*','*','ALLOW','ROLE','employee'),(149,'Sip','*','READ','ALLOW','ROLE','employee'),(150,'Sip','*','WRITE','ALLOW','ROLE','hr'),(151,'Department','*','READ','ALLOW','ROLE','employee'),(152,'Department','*','WRITE','ALLOW','ROLE','hr'),(153,'Route','*','READ','ALLOW','ROLE','employee'),(154,'Route','*','WRITE','ALLOW','ROLE','delivery'),(155,'Calendar','*','READ','ALLOW','ROLE','hr'),(156,'WorkerLabour','*','READ','ALLOW','ROLE','hr'),(157,'Calendar','absences','READ','ALLOW','ROLE','employee'),(158,'ItemTag','*','WRITE','ALLOW','ROLE','accessory'),(160,'TicketServiceType','*','READ','ALLOW','ROLE','employee'),(161,'TicketConfig','*','READ','ALLOW','ROLE','employee'),(162,'InvoiceOut','delete','WRITE','ALLOW','ROLE','invoicing'),(163,'InvoiceOut','book','WRITE','ALLOW','ROLE','invoicing'),(165,'TicketDms','*','*','ALLOW','ROLE','employee'),(167,'Worker','isSubordinate','READ','ALLOW','ROLE','employee'),(168,'Worker','mySubordinates','READ','ALLOW','ROLE','employee'),(169,'WorkerTimeControl','filter','READ','ALLOW','ROLE','employee'),(170,'WorkerTimeControl','addTime','WRITE','ALLOW','ROLE','employee'),(171,'TicketServiceType','*','WRITE','ALLOW','ROLE','administrative'),(172,'Sms','*','READ','ALLOW','ROLE','employee'),(173,'Sms','send','WRITE','ALLOW','ROLE','employee'),(174,'Agency','getLanded','READ','ALLOW','ROLE','employee'),(175,'Agency','getShipped','READ','ALLOW','ROLE','employee'),(176,'Device','*','*','ALLOW','ROLE','employee'),(177,'Device','*','*','ALLOW','ROLE','employee'),(178,'WorkerTimeControl','*','*','ALLOW','ROLE','employee'),(179,'ItemLog','*','READ','ALLOW','ROLE','employee'),(180,'RouteLog','*','READ','ALLOW','ROLE','employee'),(181,'Dms','removeFile','WRITE','ALLOW','ROLE','employee'),(182,'Dms','uploadFile','WRITE','ALLOW','ROLE','employee'),(183,'Dms','downloadFile','READ','ALLOW','ROLE','employee'),(184,'Client','uploadFile','WRITE','ALLOW','ROLE','employee'),(185,'ClientDms','removeFile','WRITE','ALLOW','ROLE','employee'),(186,'ClientDms','*','READ','ALLOW','ROLE','trainee'),(187,'Ticket','uploadFile','WRITE','ALLOW','ROLE','employee'),(190,'Route','updateVolume','WRITE','ALLOW','ROLE','deliveryBoss'),(191,'Agency','getLanded','READ','ALLOW','ROLE','employee'),(192,'Agency','getShipped','READ','ALLOW','ROLE','employee'),(194,'Postcode','*','WRITE','ALLOW','ROLE','deliveryBoss'),(195,'Ticket','addSale','WRITE','ALLOW','ROLE','employee'),(196,'Dms','updateFile','WRITE','ALLOW','ROLE','employee'),(197,'Dms','*','READ','ALLOW','ROLE','trainee'),(198,'ClaimDms','removeFile','WRITE','ALLOW','ROLE','employee'),(199,'ClaimDms','*','READ','ALLOW','ROLE','employee'),(200,'Claim','uploadFile','WRITE','ALLOW','ROLE','employee'),(201,'Sale','updateConcept','WRITE','ALLOW','ROLE','employee'),(202,'Claim','updateClaimAction','WRITE','ALLOW','ROLE','claimManager'),(203,'UserPhone','*','*','ALLOW','ROLE','employee'),(204,'WorkerDms','removeFile','WRITE','ALLOW','ROLE','hr'),(205,'WorkerDms','*','READ','ALLOW','ROLE','hr'),(206,'Chat','*','*','ALLOW','ROLE','employee'),(207,'Chat','sendMessage','*','ALLOW','ROLE','employee'),(208,'Sale','recalculatePrice','WRITE','ALLOW','ROLE','employee'),(209,'Ticket','recalculateComponents','WRITE','ALLOW','ROLE','employee'),(211,'TravelLog','*','READ','ALLOW','ROLE','buyer'),(212,'Thermograph','*','*','ALLOW','ROLE','buyer'),(213,'TravelThermograph','*','WRITE','ALLOW','ROLE','buyer'),(214,'Entry','*','*','ALLOW','ROLE','buyer'),(215,'TicketWeekly','*','WRITE','ALLOW','ROLE','buyer'),(216,'TravelThermograph','*','READ','ALLOW','ROLE','employee'),(218,'Intrastat','*','*','ALLOW','ROLE','buyer'),(219,'Account','acl','READ','ALLOW','ROLE','account'),(220,'Account','getCurrentUserData','READ','ALLOW','ROLE','account'),(221,'UserConfig','getUserConfig','READ','ALLOW','ROLE','account'),(222,'Client','*','READ','ALLOW','ROLE','trainee'),(226,'ClientObservation','*','READ','ALLOW','ROLE','trainee'),(227,'Address','*','READ','ALLOW','ROLE','trainee'),(228,'AddressObservation','*','READ','ALLOW','ROLE','trainee'),(230,'ClientCredit','*','READ','ALLOW','ROLE','trainee'),(231,'ClientContact','*','READ','ALLOW','ROLE','trainee'),(232,'ClientSample','*','READ','ALLOW','ROLE','trainee'),(233,'EntryLog','*','READ','ALLOW','ROLE','buyer'),(234,'WorkerLog','*','READ','ALLOW','ROLE','salesAssistant'),(235,'CustomsAgent','*','*','ALLOW','ROLE','employee'),(236,'Buy','*','*','ALLOW','ROLE','buyer'),(237,'WorkerDms','filter','*','ALLOW','ROLE','employee'),(238,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(239,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(240,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(241,'SupplierContact','*','WRITE','ALLOW','ROLE','administrative'),(242,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(244,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(246,'Account','changePassword','*','ALLOW','ROLE','account'),(247,'UserAccount','exists','*','ALLOW','ROLE','account'),(248,'RoleMapping','*','READ','ALLOW','ROLE','account'),(249,'UserPassword','*','READ','ALLOW','ROLE','account'),(250,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(251,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(252,'Supplier','*','READ','ALLOW','ROLE','employee'),(253,'Supplier','*','WRITE','ALLOW','ROLE','administrative'),(254,'SupplierLog','*','READ','ALLOW','ROLE','employee'),(256,'Image','*','WRITE','ALLOW','ROLE','employee'),(257,'FixedPrice','*','*','ALLOW','ROLE','buyer'),(258,'PayDem','*','READ','ALLOW','ROLE','employee'),(259,'Client','createReceipt','*','ALLOW','ROLE','salesAssistant'),(260,'PrintServerQueue','*','WRITE','ALLOW','ROLE','employee'),(261,'SupplierAccount','*','*','ALLOW','ROLE','administrative'),(262,'Entry','*','*','ALLOW','ROLE','administrative'),(263,'InvoiceIn','*','*','ALLOW','ROLE','administrative'),(264,'StarredModule','*','*','ALLOW','ROLE','employee'),(265,'ItemBotanical','*','WRITE','ALLOW','ROLE','logisticBoss'),(266,'ZoneLog','*','READ','ALLOW','ROLE','employee'),(267,'Genus','*','WRITE','ALLOW','ROLE','logisticBoss'),(268,'Specie','*','WRITE','ALLOW','ROLE','logisticBoss'),(269,'InvoiceOut','createPdf','WRITE','ALLOW','ROLE','employee'),(270,'SupplierAddress','*','*','ALLOW','ROLE','employee'),(271,'SalesMonitor','*','*','ALLOW','ROLE','employee'),(272,'InvoiceInLog','*','*','ALLOW','ROLE','employee'),(273,'InvoiceInTax','*','*','ALLOW','ROLE','administrative'),(274,'InvoiceInLog','*','READ','ALLOW','ROLE','administrative'),(275,'InvoiceOut','createManualInvoice','WRITE','ALLOW','ROLE','invoicing'),(276,'InvoiceOut','globalInvoicing','WRITE','ALLOW','ROLE','invoicing'),(277,'Role','*','*','ALLOW','ROLE','it'),(278,'RoleInherit','*','WRITE','ALLOW','ROLE','grant'),(279,'MailAlias','*','*','ALLOW','ROLE','marketing'),(282,'UserAccount','*','WRITE','ALLOW','ROLE','it'),(283,'EntryObservation','*','*','ALLOW','ROLE','buyer'),(284,'LdapConfig','*','*','ALLOW','ROLE','sysadmin'),(285,'SambaConfig','*','*','ALLOW','ROLE','sysadmin'),(286,'ACL','*','*','ALLOW','ROLE','developer'),(287,'AccessToken','*','*','ALLOW','ROLE','developer'),(288,'MailAliasAccount','*','*','ALLOW','ROLE','marketing'),(289,'MailAliasAccount','*','*','ALLOW','ROLE','hr'),(290,'MailAlias','*','*','ALLOW','ROLE','hr'),(291,'MailForward','*','*','ALLOW','ROLE','marketing'),(292,'MailForward','*','*','ALLOW','ROLE','hr'),(293,'RoleInherit','*','*','ALLOW','ROLE','it'),(294,'RoleRole','*','*','ALLOW','ROLE','it'),(295,'AccountConfig','*','*','ALLOW','ROLE','sysadmin'); +INSERT INTO `ACL` VALUES (1,'Account','*','*','ALLOW','ROLE','employee'),(3,'Address','*','*','ALLOW','ROLE','employee'),(5,'AgencyService','*','READ','ALLOW','ROLE','employee'),(7,'Client','*','*','ALLOW','ROLE','employee'),(9,'ClientObservation','*','*','ALLOW','ROLE','employee'),(11,'ContactChannel','*','READ','ALLOW','ROLE','trainee'),(13,'Employee','*','READ','ALLOW','ROLE','employee'),(14,'PayMethod','*','READ','ALLOW','ROLE','trainee'),(16,'FakeProduction','*','READ','ALLOW','ROLE','employee'),(17,'Warehouse','* ','READ','ALLOW','ROLE','trainee'),(18,'State','*','READ','ALLOW','ROLE','employee'),(20,'TicketState','*','*','ALLOW','ROLE','employee'),(24,'Delivery','*','READ','ALLOW','ROLE','employee'),(25,'Zone','*','READ','ALLOW','ROLE','employee'),(26,'ClientCredit','*','*','ALLOW','ROLE','employee'),(27,'ClientCreditLimit','*','READ','ALLOW','ROLE','trainee'),(30,'GreugeType','*','READ','ALLOW','ROLE','trainee'),(31,'Mandate','*','READ','ALLOW','ROLE','trainee'),(32,'MandateType','*','READ','ALLOW','ROLE','trainee'),(33,'Company','*','READ','ALLOW','ROLE','trainee'),(34,'Greuge','*','READ','ALLOW','ROLE','trainee'),(35,'AddressObservation','*','*','ALLOW','ROLE','employee'),(36,'ObservationType','*','*','ALLOW','ROLE','employee'),(37,'Greuge','*','WRITE','ALLOW','ROLE','employee'),(38,'AgencyMode','*','READ','ALLOW','ROLE','employee'),(39,'ItemTag','*','WRITE','ALLOW','ROLE','buyer'),(40,'ItemBotanical','*','WRITE','ALLOW','ROLE','buyer'),(41,'ItemBotanical','*','READ','ALLOW','ROLE','employee'),(42,'ItemPlacement','*','WRITE','ALLOW','ROLE','buyer'),(43,'ItemPlacement','*','WRITE','ALLOW','ROLE','replenisher'),(44,'ItemPlacement','*','READ','ALLOW','ROLE','employee'),(45,'ItemBarcode','*','READ','ALLOW','ROLE','employee'),(46,'ItemBarcode','*','WRITE','ALLOW','ROLE','buyer'),(47,'ItemBarcode','*','WRITE','ALLOW','ROLE','replenisher'),(51,'ItemTag','*','READ','ALLOW','ROLE','employee'),(53,'Item','*','READ','ALLOW','ROLE','employee'),(54,'Item','*','WRITE','ALLOW','ROLE','buyer'),(55,'Recovery','*','READ','ALLOW','ROLE','trainee'),(56,'Recovery','*','WRITE','ALLOW','ROLE','administrative'),(58,'CreditClassification','*','*','ALLOW','ROLE','insurance'),(60,'CreditInsurance','*','*','ALLOW','ROLE','insurance'),(61,'InvoiceOut','*','READ','ALLOW','ROLE','employee'),(62,'Ticket','*','*','ALLOW','ROLE','employee'),(63,'TicketObservation','*','*','ALLOW','ROLE','employee'),(64,'Route','*','READ','ALLOW','ROLE','employee'),(65,'Sale','*','READ','ALLOW','ROLE','employee'),(66,'TicketTracking','*','READ','ALLOW','ROLE','employee'),(68,'TicketPackaging','*','*','ALLOW','ROLE','employee'),(69,'Packaging','*','READ','ALLOW','ROLE','employee'),(70,'Packaging','*','WRITE','ALLOW','ROLE','logistic'),(71,'SaleChecked','*','READ','ALLOW','ROLE','employee'),(72,'SaleComponent','*','READ','ALLOW','ROLE','employee'),(73,'Expedition','*','READ','ALLOW','ROLE','employee'),(74,'Expedition','*','WRITE','ALLOW','ROLE','deliveryBoss'),(75,'Expedition','*','WRITE','ALLOW','ROLE','production'),(76,'AnnualAverageInvoiced','*','READ','ALLOW','ROLE','employee'),(77,'WorkerMana','*','READ','ALLOW','ROLE','employee'),(78,'TicketTracking','*','WRITE','ALLOW','ROLE','production'),(79,'TicketTracking','changeState','*','ALLOW','ROLE','employee'),(80,'Sale','deleteSales','*','ALLOW','ROLE','employee'),(81,'Sale','moveToTicket','*','ALLOW','ROLE','employee'),(82,'Sale','updateQuantity','*','ALLOW','ROLE','employee'),(83,'Sale','updatePrice','*','ALLOW','ROLE','employee'),(84,'Sale','updateDiscount','*','ALLOW','ROLE','employee'),(85,'SaleTracking','*','READ','ALLOW','ROLE','employee'),(86,'Order','*','*','ALLOW','ROLE','employee'),(87,'OrderRow','*','*','ALLOW','ROLE','employee'),(88,'ClientContact','*','*','ALLOW','ROLE','employee'),(89,'Sale','moveToNewTicket','*','ALLOW','ROLE','employee'),(90,'Sale','reserve','*','ALLOW','ROLE','employee'),(91,'TicketWeekly','*','READ','ALLOW','ROLE','employee'),(94,'Agency','landsThatDay','*','ALLOW','ROLE','employee'),(96,'ClaimEnd','*','READ','ALLOW','ROLE','employee'),(97,'ClaimEnd','*','WRITE','ALLOW','ROLE','claimManager'),(98,'ClaimBeginning','*','*','ALLOW','ROLE','employee'),(99,'ClaimDevelopment','*','READ','ALLOW','ROLE','employee'),(100,'ClaimDevelopment','*','WRITE','ALLOW','ROLE','claimManager'),(101,'Claim','*','*','ALLOW','ROLE','employee'),(102,'Claim','createFromSales','*','ALLOW','ROLE','employee'),(103,'ClaimEnd','importTicketSales','WRITE','ALLOW','ROLE','claimManager'),(104,'Item','*','WRITE','ALLOW','ROLE','marketingBoss'),(105,'ItemBarcode','*','WRITE','ALLOW','ROLE','marketingBoss'),(106,'ItemBotanical','*','WRITE','ALLOW','ROLE','marketingBoss'),(108,'ItemPlacement','*','WRITE','ALLOW','ROLE','marketingBoss'),(109,'UserConfig','*','*','ALLOW','ROLE','employee'),(110,'Bank','*','READ','ALLOW','ROLE','trainee'),(111,'ClientLog','*','READ','ALLOW','ROLE','trainee'),(112,'Defaulter','*','READ','ALLOW','ROLE','employee'),(113,'ClientRisk','*','READ','ALLOW','ROLE','trainee'),(114,'Receipt','*','READ','ALLOW','ROLE','trainee'),(115,'Receipt','*','WRITE','ALLOW','ROLE','administrative'),(116,'BankEntity','*','*','ALLOW','ROLE','employee'),(117,'ClientSample','*','*','ALLOW','ROLE','employee'),(118,'WorkerTeam','*','*','ALLOW','ROLE','salesPerson'),(119,'Travel','*','READ','ALLOW','ROLE','employee'),(120,'Travel','*','WRITE','ALLOW','ROLE','buyer'),(121,'Item','regularize','*','ALLOW','ROLE','employee'),(122,'TicketRequest','*','*','ALLOW','ROLE','employee'),(123,'Worker','*','*','ALLOW','ROLE','employee'),(124,'Client','confirmTransaction','WRITE','ALLOW','ROLE','administrative'),(125,'Agency','getAgenciesWithWarehouse','*','ALLOW','ROLE','employee'),(126,'Client','activeWorkersWithRole','*','ALLOW','ROLE','employee'),(127,'TicketLog','*','READ','ALLOW','ROLE','employee'),(129,'TicketService','*','*','ALLOW','ROLE','employee'),(130,'Expedition','*','WRITE','ALLOW','ROLE','packager'),(131,'CreditInsurance','*','READ','ALLOW','ROLE','trainee'),(132,'CreditClassification','*','READ','ALLOW','ROLE','trainee'),(133,'ItemTag','*','WRITE','ALLOW','ROLE','marketingBoss'),(135,'ZoneGeo','*','READ','ALLOW','ROLE','employee'),(136,'ZoneCalendar','*','READ','ALLOW','ROLE','employee'),(137,'ZoneIncluded','*','READ','ALLOW','ROLE','employee'),(138,'LabourHoliday','*','READ','ALLOW','ROLE','employee'),(139,'LabourHolidayLegend','*','READ','ALLOW','ROLE','employee'),(140,'LabourHolidayType','*','READ','ALLOW','ROLE','employee'),(141,'Zone','*','*','ALLOW','ROLE','deliveryBoss'),(142,'ZoneCalendar','*','WRITE','ALLOW','ROLE','deliveryBoss'),(143,'ZoneIncluded','*','*','ALLOW','ROLE','deliveryBoss'),(144,'Stowaway','*','*','ALLOW','ROLE','employee'),(145,'Ticket','getPossibleStowaways','READ','ALLOW','ROLE','employee'),(147,'UserConfigView','*','*','ALLOW','ROLE','employee'),(148,'UserConfigView','*','*','ALLOW','ROLE','employee'),(149,'Sip','*','READ','ALLOW','ROLE','employee'),(150,'Sip','*','WRITE','ALLOW','ROLE','hr'),(151,'Department','*','READ','ALLOW','ROLE','employee'),(152,'Department','*','WRITE','ALLOW','ROLE','hr'),(153,'Route','*','READ','ALLOW','ROLE','employee'),(154,'Route','*','WRITE','ALLOW','ROLE','delivery'),(155,'Calendar','*','READ','ALLOW','ROLE','hr'),(156,'WorkerLabour','*','READ','ALLOW','ROLE','hr'),(157,'Calendar','absences','READ','ALLOW','ROLE','employee'),(158,'ItemTag','*','WRITE','ALLOW','ROLE','accessory'),(160,'TicketServiceType','*','READ','ALLOW','ROLE','employee'),(161,'TicketConfig','*','READ','ALLOW','ROLE','employee'),(162,'InvoiceOut','delete','WRITE','ALLOW','ROLE','invoicing'),(163,'InvoiceOut','book','WRITE','ALLOW','ROLE','invoicing'),(165,'TicketDms','*','*','ALLOW','ROLE','employee'),(167,'Worker','isSubordinate','READ','ALLOW','ROLE','employee'),(168,'Worker','mySubordinates','READ','ALLOW','ROLE','employee'),(169,'WorkerTimeControl','filter','READ','ALLOW','ROLE','employee'),(170,'WorkerTimeControl','addTime','WRITE','ALLOW','ROLE','employee'),(171,'TicketServiceType','*','WRITE','ALLOW','ROLE','administrative'),(172,'Sms','*','READ','ALLOW','ROLE','employee'),(173,'Sms','send','WRITE','ALLOW','ROLE','employee'),(174,'Agency','getLanded','READ','ALLOW','ROLE','employee'),(175,'Agency','getShipped','READ','ALLOW','ROLE','employee'),(176,'Device','*','*','ALLOW','ROLE','employee'),(177,'Device','*','*','ALLOW','ROLE','employee'),(178,'WorkerTimeControl','*','*','ALLOW','ROLE','employee'),(179,'ItemLog','*','READ','ALLOW','ROLE','employee'),(180,'RouteLog','*','READ','ALLOW','ROLE','employee'),(181,'Dms','removeFile','WRITE','ALLOW','ROLE','employee'),(182,'Dms','uploadFile','WRITE','ALLOW','ROLE','employee'),(183,'Dms','downloadFile','READ','ALLOW','ROLE','employee'),(184,'Client','uploadFile','WRITE','ALLOW','ROLE','employee'),(185,'ClientDms','removeFile','WRITE','ALLOW','ROLE','employee'),(186,'ClientDms','*','READ','ALLOW','ROLE','trainee'),(187,'Ticket','uploadFile','WRITE','ALLOW','ROLE','employee'),(190,'Route','updateVolume','WRITE','ALLOW','ROLE','deliveryBoss'),(191,'Agency','getLanded','READ','ALLOW','ROLE','employee'),(192,'Agency','getShipped','READ','ALLOW','ROLE','employee'),(194,'Postcode','*','WRITE','ALLOW','ROLE','deliveryBoss'),(195,'Ticket','addSale','WRITE','ALLOW','ROLE','employee'),(196,'Dms','updateFile','WRITE','ALLOW','ROLE','employee'),(197,'Dms','*','READ','ALLOW','ROLE','trainee'),(198,'ClaimDms','removeFile','WRITE','ALLOW','ROLE','employee'),(199,'ClaimDms','*','READ','ALLOW','ROLE','employee'),(200,'Claim','uploadFile','WRITE','ALLOW','ROLE','employee'),(201,'Sale','updateConcept','WRITE','ALLOW','ROLE','employee'),(202,'Claim','updateClaimAction','WRITE','ALLOW','ROLE','claimManager'),(203,'UserPhone','*','*','ALLOW','ROLE','employee'),(204,'WorkerDms','removeFile','WRITE','ALLOW','ROLE','hr'),(205,'WorkerDms','*','READ','ALLOW','ROLE','hr'),(206,'Chat','*','*','ALLOW','ROLE','employee'),(207,'Chat','sendMessage','*','ALLOW','ROLE','employee'),(208,'Sale','recalculatePrice','WRITE','ALLOW','ROLE','employee'),(209,'Ticket','recalculateComponents','WRITE','ALLOW','ROLE','employee'),(211,'TravelLog','*','READ','ALLOW','ROLE','buyer'),(212,'Thermograph','*','*','ALLOW','ROLE','buyer'),(213,'TravelThermograph','*','WRITE','ALLOW','ROLE','buyer'),(214,'Entry','*','*','ALLOW','ROLE','buyer'),(215,'TicketWeekly','*','WRITE','ALLOW','ROLE','buyer'),(216,'TravelThermograph','*','READ','ALLOW','ROLE','employee'),(218,'Intrastat','*','*','ALLOW','ROLE','buyer'),(219,'Account','acl','READ','ALLOW','ROLE','account'),(220,'Account','getCurrentUserData','READ','ALLOW','ROLE','account'),(221,'UserConfig','getUserConfig','READ','ALLOW','ROLE','account'),(222,'Client','*','READ','ALLOW','ROLE','trainee'),(226,'ClientObservation','*','READ','ALLOW','ROLE','trainee'),(227,'Address','*','READ','ALLOW','ROLE','trainee'),(228,'AddressObservation','*','READ','ALLOW','ROLE','trainee'),(230,'ClientCredit','*','READ','ALLOW','ROLE','trainee'),(231,'ClientContact','*','READ','ALLOW','ROLE','trainee'),(232,'ClientSample','*','READ','ALLOW','ROLE','trainee'),(233,'EntryLog','*','READ','ALLOW','ROLE','buyer'),(234,'WorkerLog','*','READ','ALLOW','ROLE','salesAssistant'),(235,'CustomsAgent','*','*','ALLOW','ROLE','employee'),(236,'Buy','*','*','ALLOW','ROLE','buyer'),(237,'WorkerDms','filter','*','ALLOW','ROLE','employee'),(238,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(239,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(240,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(241,'SupplierContact','*','WRITE','ALLOW','ROLE','administrative'),(242,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(244,'supplier','*','WRITE','ALLOW','ROLE','administrative'),(246,'Account','changePassword','*','ALLOW','ROLE','account'),(247,'UserAccount','exists','*','ALLOW','ROLE','account'),(248,'RoleMapping','*','READ','ALLOW','ROLE','account'),(249,'UserPassword','*','READ','ALLOW','ROLE','account'),(250,'Town','*','WRITE','ALLOW','ROLE','deliveryBoss'),(251,'Province','*','WRITE','ALLOW','ROLE','deliveryBoss'),(252,'Supplier','*','READ','ALLOW','ROLE','employee'),(253,'Supplier','*','WRITE','ALLOW','ROLE','administrative'),(254,'SupplierLog','*','READ','ALLOW','ROLE','employee'),(256,'Image','*','WRITE','ALLOW','ROLE','employee'),(257,'FixedPrice','*','*','ALLOW','ROLE','buyer'),(258,'PayDem','*','READ','ALLOW','ROLE','employee'),(259,'Client','createReceipt','*','ALLOW','ROLE','salesAssistant'),(260,'PrintServerQueue','*','WRITE','ALLOW','ROLE','employee'),(261,'SupplierAccount','*','*','ALLOW','ROLE','administrative'),(262,'Entry','*','*','ALLOW','ROLE','administrative'),(263,'InvoiceIn','*','*','ALLOW','ROLE','administrative'),(264,'StarredModule','*','*','ALLOW','ROLE','employee'),(265,'ItemBotanical','*','WRITE','ALLOW','ROLE','logisticBoss'),(266,'ZoneLog','*','READ','ALLOW','ROLE','employee'),(267,'Genus','*','WRITE','ALLOW','ROLE','logisticBoss'),(268,'Specie','*','WRITE','ALLOW','ROLE','logisticBoss'),(269,'InvoiceOut','createPdf','WRITE','ALLOW','ROLE','employee'),(270,'SupplierAddress','*','*','ALLOW','ROLE','employee'),(271,'SalesMonitor','*','*','ALLOW','ROLE','employee'),(272,'InvoiceInLog','*','*','ALLOW','ROLE','employee'),(273,'InvoiceInTax','*','*','ALLOW','ROLE','administrative'),(274,'InvoiceInLog','*','READ','ALLOW','ROLE','administrative'),(275,'InvoiceOut','createManualInvoice','WRITE','ALLOW','ROLE','invoicing'),(276,'InvoiceOut','globalInvoicing','WRITE','ALLOW','ROLE','invoicing'),(277,'Role','*','*','ALLOW','ROLE','it'),(278,'RoleInherit','*','WRITE','ALLOW','ROLE','grant'),(279,'MailAlias','*','*','ALLOW','ROLE','marketing'),(282,'UserAccount','*','WRITE','ALLOW','ROLE','it'),(283,'EntryObservation','*','*','ALLOW','ROLE','buyer'),(284,'LdapConfig','*','*','ALLOW','ROLE','sysadmin'),(285,'SambaConfig','*','*','ALLOW','ROLE','sysadmin'),(286,'ACL','*','*','ALLOW','ROLE','developer'),(287,'AccessToken','*','*','ALLOW','ROLE','developer'),(288,'MailAliasAccount','*','*','ALLOW','ROLE','marketing'),(289,'MailAliasAccount','*','*','ALLOW','ROLE','hr'),(290,'MailAlias','*','*','ALLOW','ROLE','hr'),(291,'MailForward','*','*','ALLOW','ROLE','marketing'),(292,'MailForward','*','*','ALLOW','ROLE','hr'),(293,'RoleInherit','*','*','ALLOW','ROLE','it'),(294,'RoleRole','*','*','ALLOW','ROLE','it'),(295,'AccountConfig','*','*','ALLOW','ROLE','sysadmin'),(296,'Collection','*','READ','ALLOW','ROLE','employee'); /*!40000 ALTER TABLE `ACL` ENABLE KEYS */; UNLOCK TABLES; @@ -186,7 +186,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2022-01-03 7:27:22 +-- Dump completed on 2022-01-13 7:50:26 USE `vn`; -- MariaDB dump 10.19 Distrib 10.5.12-MariaDB, for debian-linux-gnu (x86_64) -- @@ -410,7 +410,7 @@ UNLOCK TABLES; LOCK TABLES `state` WRITE; /*!40000 ALTER TABLE `state` DISABLE KEYS */; -INSERT INTO `state` VALUES (1,'Arreglar',2,0,'FIXING',NULL,1,0,0,0,0,0,0,4,1),(2,'Libre',2,0,'FREE',NULL,2,1,0,0,0,1,0,4,1),(3,'OK',3,0,'OK',3,28,1,0,0,0,1,1,3,0),(4,'Impreso',4,0,'PRINTED',2,29,1,0,1,0,0,1,2,0),(5,'Preparación',6,1,'ON_PREPARATION',7,5,0,0,0,2,0,0,2,0),(6,'En Revisión',7,1,'ON_CHECKING',NULL,6,0,1,0,3,0,0,1,0),(7,'Sin Acabar',1,0,'NOT_READY',NULL,7,0,0,0,0,0,0,4,1),(8,'Revisado',8,1,'CHECKED',NULL,8,0,1,0,3,0,0,1,0),(9,'Encajando',9,2,'PACKING',NULL,9,0,1,0,0,0,0,1,0),(10,'Encajado',10,2,'PACKED',NULL,10,0,1,0,0,0,0,0,0),(11,'Facturado',0,3,'INVOICED',NULL,11,0,1,0,0,0,0,0,0),(12,'Bloqueado',0,0,'BLOCKED',NULL,12,0,0,0,0,0,0,4,1),(13,'En Reparto',11,3,'ON_DELIVERY',NULL,13,0,1,0,0,0,0,0,0),(14,'Preparado',6,1,'PREPARED',NULL,14,0,1,0,2,0,0,1,0),(15,'Pte Recogida',12,3,'WAITING_FOR_PICKUP',NULL,15,0,1,0,0,0,0,0,0),(16,'Entregado',13,3,'DELIVERED',NULL,16,0,1,0,0,0,0,0,0),(20,'Asignado',4,0,'PICKER_DESIGNED',NULL,20,1,0,0,0,0,0,2,0),(21,'Retornado',4,1,'PRINTED_BACK',6,21,0,0,0,0,0,0,2,0),(22,'¿Fecha?',2,0,'WRONG_DATE',NULL,22,0,0,0,0,0,0,4,1),(23,'URGENTE',5,1,'LAST_CALL',NULL,23,1,0,1,0,0,0,4,1),(24,'Encadenado',4,0,'CHAINED',4,24,0,0,0,0,0,0,3,1),(25,'Embarcando',3,0,'BOARDING',5,25,1,0,0,0,0,0,3,0),(26,'Prep Previa',5,1,'PREVIOUS_PREPARATION',1,26,0,0,0,1,0,0,2,0),(27,'Prep Asistida',5,1,'ASSISTED_PREPARATION',7,27,0,0,0,0,0,0,2,0),(28,'Previa OK',3,1,'OK PREVIOUS',3,28,0,0,0,1,1,1,3,0),(29,'Previa Impreso',4,1,'PRINTED PREVIOUS',2,29,0,0,1,1,0,1,3,0),(30,'Embarcado',4,1,'BOARD',5,30,0,0,0,2,0,0,3,0),(31,'Polizon Impreso',4,1,'PRINTED STOWAWAY',2,29,1,0,1,0,0,1,3,0),(32,'Polizon OK',3,1,'OK STOWAWAY',3,31,1,0,0,1,1,1,3,0),(33,'Auto_Impreso',4,0,'PRINTED_AUTO',2,29,1,0,1,0,0,1,2,0),(34,'Pte Pago',3,0,'WAITING_FOR_PAYMENT',NULL,34,0,0,0,0,0,0,4,1),(35,'Semi-Encajado',9,2,'HALF_PACKED',NULL,10,0,1,0,0,0,0,1,0),(36,'Control Previa',3,1,'PREVIOUS_CONTROL',1,36,0,1,0,1,0,1,3,0); +INSERT INTO `state` VALUES (1,'Arreglar',2,0,'FIXING',NULL,1,0,0,0,0,0,0,4,1),(2,'Libre',2,0,'FREE',NULL,2,1,0,0,0,1,0,4,1),(3,'OK',3,0,'OK',3,28,1,0,0,0,1,1,3,0),(4,'Impreso',4,0,'PRINTED',2,29,1,0,1,0,0,1,2,0),(5,'Preparación',6,1,'ON_PREPARATION',7,5,0,0,0,2,0,0,2,0),(6,'En Revisión',7,1,'ON_CHECKING',NULL,6,0,1,0,3,0,0,1,0),(7,'Sin Acabar',1,0,'NOT_READY',NULL,7,0,0,0,0,0,0,4,1),(8,'Revisado',8,1,'CHECKED',NULL,8,0,1,0,3,0,0,1,0),(9,'Encajando',9,2,'PACKING',NULL,9,0,1,0,0,0,0,1,0),(10,'Encajado',10,2,'PACKED',NULL,10,0,1,0,0,0,0,0,0),(11,'Facturado',0,3,'INVOICED',NULL,11,0,1,0,0,0,0,0,0),(12,'Bloqueado',0,0,'BLOCKED',NULL,12,0,0,0,0,0,0,4,1),(13,'En Reparto',11,3,'ON_DELIVERY',NULL,13,0,1,0,0,0,0,0,0),(14,'Preparado',6,1,'PREPARED',NULL,14,0,1,0,2,0,0,1,0),(15,'Pte Recogida',12,3,'WAITING_FOR_PICKUP',NULL,15,0,1,0,0,0,0,0,0),(16,'Entregado',13,3,'DELIVERED',NULL,16,0,1,0,0,0,0,0,0),(20,'Asignado',4,0,'PICKER_DESIGNED',NULL,20,1,0,0,0,0,0,2,0),(21,'Retornado',4,1,'PRINTED_BACK',6,21,0,0,0,0,0,0,2,0),(22,'¿Fecha?',2,0,'WRONG_DATE',NULL,22,0,0,0,0,0,0,4,1),(23,'URGENTE',5,1,'LAST_CALL',NULL,23,1,0,1,0,0,0,4,1),(24,'Encadenado',4,0,'CHAINED',4,24,0,0,0,0,0,0,3,1),(25,'Embarcando',3,0,'BOARDING',5,25,1,0,0,0,0,0,3,0),(26,'Prep Previa',5,1,'PREVIOUS_PREPARATION',1,26,0,0,0,1,0,0,2,0),(27,'Prep Asistida',5,1,'ASSISTED_PREPARATION',7,27,0,0,0,0,0,0,2,0),(28,'Previa OK',3,1,'OK PREVIOUS',3,28,0,0,0,1,1,1,3,0),(29,'Previa Impreso',4,1,'PRINTED PREVIOUS',2,29,0,0,1,1,0,1,3,0),(30,'Embarcado',4,1,'BOARD',5,30,0,0,0,2,0,0,3,0),(31,'Polizon Impreso',4,1,'PRINTED STOWAWAY',2,29,1,0,1,0,0,1,3,0),(32,'Polizon OK',3,1,'OK STOWAWAY',3,31,1,0,0,1,1,1,3,0),(33,'Auto_Impreso',4,0,'PRINTED_AUTO',2,29,1,0,1,0,0,1,2,0),(34,'Pte Pago',3,0,'WAITING_FOR_PAYMENT',NULL,34,0,0,0,0,0,0,4,1),(35,'Semi-Encajado',9,2,'HALF_PACKED',NULL,10,0,1,0,0,0,0,1,0),(36,'Control Previa',3,1,'PREVIOUS_CONTROL',1,36,0,1,0,4,0,1,3,0); /*!40000 ALTER TABLE `state` ENABLE KEYS */; UNLOCK TABLES; @@ -452,7 +452,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2022-01-03 7:27:26 +-- Dump completed on 2022-01-13 7:50:30 USE `cache`; -- MariaDB dump 10.19 Distrib 10.5.12-MariaDB, for debian-linux-gnu (x86_64) -- @@ -488,7 +488,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2022-01-03 7:27:26 +-- Dump completed on 2022-01-13 7:50:31 USE `hedera`; -- MariaDB dump 10.19 Distrib 10.5.12-MariaDB, for debian-linux-gnu (x86_64) -- @@ -554,7 +554,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2022-01-03 7:27:28 +-- Dump completed on 2022-01-13 7:50:32 USE `postgresql`; -- MariaDB dump 10.19 Distrib 10.5.12-MariaDB, for debian-linux-gnu (x86_64) -- @@ -640,7 +640,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2022-01-03 7:27:29 +-- Dump completed on 2022-01-13 7:50:33 USE `sage`; -- MariaDB dump 10.19 Distrib 10.5.12-MariaDB, for debian-linux-gnu (x86_64) -- @@ -696,4 +696,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2022-01-03 7:27:29 +-- Dump completed on 2022-01-13 7:50:33 diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 5bfc76560..07eaf23fd 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -8,7 +8,7 @@ ALTER TABLE `vn`.`ticket` AUTO_INCREMENT = 1; INSERT INTO `salix`.`AccessToken` (`id`, `ttl`, `created`, `userId`) VALUES - ('TOTALLY_SECURE_TOKEN', '1209600', CURDATE(), 66); + ('DEFAULT_TOKEN', '1209600', CURDATE(), 66); INSERT INTO `vn`.`ticketConfig` (`id`, `scopeDays`) @@ -104,17 +104,17 @@ INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`) (3, 'GBP', 'Libra', 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 - (1, 'España', 1, 'ES', 1, 24, 4), - (2, 'Italia', 1, 'IT', 1, 27, 4), - (3, 'Alemania', 1, 'DE', 1, 22, 4), - (4, 'Rumania', 1, 'RO', 1, 24, 4), - (5, 'Holanda', 1, 'NL', 1, 18, 4), - (8, 'Portugal', 1, 'PT', 1, 27, 4), - (13,'Ecuador', 0, 'EC', 1, 24, 2), - (19,'Francia', 1, 'FR', 1, 27, 4), - (30,'Canarias', 1, 'IC', 1, 24, 4); + (1, 'España', 1, 'ES', 1, 24, 4, 0, 1), + (2, 'Italia', 1, 'IT', 1, 27, 4, 0, 1), + (3, 'Alemania', 1, 'DE', 1, 22, 4, 0, 1), + (4, 'Rumania', 1, 'RO', 1, 24, 4, 0, 1), + (5, 'Holanda', 1, 'NL', 1, 18, 4, 0, 1), + (8, 'Portugal', 1, 'PT', 1, 27, 4, 0, 1), + (13,'Ecuador', 0, 'EC', 1, 24, 2, 1, 2), + (19,'Francia', 1, 'FR', 1, 27, 4, 0, 1), + (30,'Canarias', 1, 'IC', 1, 24, 4, 1, 2); INSERT INTO `hedera`.`language` (`code`, `name`, `orgName`, `isActive`) VALUES @@ -243,7 +243,7 @@ INSERT INTO `vn`.`province`(`id`, `name`, `countryFk`, `autonomyFk`, `warehouseF VALUES (1, 'Province one', 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), (5, 'Province five', 13, 4, NULL); @@ -455,7 +455,8 @@ INSERT INTO `vn`.`creditInsurance`(`id`, `creditClassification`, `credit`, `crea INSERT INTO `vn`.`companyGroup`(`id`, `code`) VALUES - (1, 'Wayne Industries'); + (1, 'wayneIndustries'), + (2, 'verdnatura'); INSERT INTO `vn`.`bankEntity`(`id`, `countryFk`, `name`, `bic`) VALUES @@ -466,13 +467,13 @@ INSERT INTO `vn`.`supplierAccount`(`id`, `supplierFk`, `iban`, `bankEntityFk`) VALUES (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 - (69 , 'CCs', NULL, 30, NULL, 0, NULL, NULL), - (442 , 'VNL', 241, 30, 2 , 1, NULL, 'VNL Company - Plant passport'), - (567 , 'VNH', NULL, 30, NULL, 4, NULL, 'VNH Company - Plant passport'), - (791 , 'FTH', NULL, 30, NULL, 3, '2015-11-30', NULL), - (1381, 'ORN', NULL, 30, NULL, 7, NULL, 'ORN Company - Plant passport'); + (69 , 'CCs', NULL, 30, NULL, 0, NULL, 1, NULL), + (442 , 'VNL', 241, 30, 2 , 1, NULL, 2, 'VNL Company - Plant passport'), + (567 , 'VNH', NULL, 30, NULL, 4, NULL, 1, 'VNH Company - Plant passport'), + (791 , 'FTH', NULL, 30, NULL, 3, '2015-11-30', 1, NULL), + (1381, 'ORN', NULL, 30, NULL, 7, NULL, 1, 'ORN Company - Plant passport'); INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion`) VALUES @@ -486,7 +487,9 @@ INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaF ('A', 'Global nacional', 1, 'NATIONAL', 0), ('T', 'Española rapida', 1, 'NATIONAL', 0), ('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`) VALUES @@ -622,6 +625,7 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF (25 ,NULL, 8, 1, NULL, CURDATE(), CURDATE(), 1101, 'Bruce Wayne', 1, NULL, 0, 1, 5, 1, CURDATE()), (26 ,NULL, 8, 1, NULL, CURDATE(), CURDATE(), 1101, 'An incredibly long alias for testing purposes', 1, NULL, 0, 1, 5, 1, CURDATE()), (27 ,NULL, 8, 1, NULL, CURDATE(), CURDATE(), 1101, 'Wolverine', 1, NULL, 0, 1, 5, 1, CURDATE()); + INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`) VALUES (1, 11, 1, 'ready'), @@ -799,25 +803,25 @@ INSERT INTO `vn`.`itemFamily`(`code`, `description`) ('VT', 'Sales'); 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 - (1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT', 0, NULL), - (2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT', 0, NULL), - (3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT', 0, NULL), - (4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', 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), - (6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', 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), - (8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT', 0, NULL), - (9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 1, NULL), - (10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', 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), - (12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT', 0, NULL), - (13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 0, 2, 'VT', 1, NULL), - (14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT', 1, NULL), - (15, 4, 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), - (71, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, '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, 'H'), + (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, 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, 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, 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, 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, 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, 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, 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 `vn`.`itemTaxCountry` SET `taxClassFk` = 2 @@ -896,7 +900,8 @@ INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `pric (29, 4, 17, 'Melee weapon heavy shield 1x0.5m', 20, 1.72, 0, 0, 0, CURDATE()), (30, 4, 18, 'Melee weapon heavy shield 1x0.5m', 20, 1.72, 0, 0, 0, CURDATE()), (31, 2, 23, 'Melee weapon combat fist 15cm', -5, 7.08, 0, 0, 0, CURDATE()), - (32, 1, 24, 'Ranged weapon longbow 2m', -1, 8.07, 0, 0, 0, CURDATE()); + (32, 1, 24, 'Ranged weapon longbow 2m', -1, 8.07, 0, 0, 0, CURDATE()), + (33, 5, 14, 'Ranged weapon pistol 9mm', 50, 1.79, 0, 0, 0, CURDATE()); INSERT INTO `vn`.`saleChecked`(`saleFk`, `isChecked`) VALUES @@ -2350,7 +2355,7 @@ REPLACE INTO `vn`.`invoiceIn`(`id`, `serialNumber`,`serial`, `supplierFk`, `issu INSERT INTO `vn`.`invoiceInDueDay`(`invoiceInFk`, `dueDated`, `bankFk`, `amount`) VALUES - (1, CURDATE(), 1, 237), + (1, CURDATE(), 1, 336.99), (1, CURDATE(), 1, 15.25), (2, CURDATE(), 1, 168), (2, CURDATE(), 1, 55.17), @@ -2429,4 +2434,12 @@ INSERT INTO `vn`.`expeditionScan` (`id`, `expeditionFk`, `scanned`, `palletFk`) CALL `cache`.`last_buy_refresh`(FALSE); UPDATE `vn`.`item` SET `genericFk` = 9 - WHERE `id` = 2; \ No newline at end of file + WHERE `id` = 2; + +INSERT INTO `bs`.`defaulter` (`clientFk`, `amount`, `created`, `defaulterSinced`) + VALUES + (1101, 500, CURDATE(), CURDATE()), + (1102, 500, CURDATE(), CURDATE()), + (1103, 500, CURDATE(), CURDATE()), + (1107, 500, CURDATE(), CURDATE()), + (1109, 500, CURDATE(), CURDATE()); diff --git a/db/dump/structure.sql b/db/dump/structure.sql index 1d862bdf3..5b463d420 100644 --- a/db/dump/structure.sql +++ b/db/dump/structure.sql @@ -5885,212 +5885,6 @@ BEGIN SET s.amountNewBorn = n.amount WHERE n.dated >= vDatedFrom; -END ;; -DELIMITER ; -/*!50003 SET sql_mode = @saved_sql_mode */ ; -/*!50003 SET character_set_client = @saved_cs_client */ ; -/*!50003 SET character_set_results = @saved_cs_results */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `salesMonthlyCopy` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_general_ci */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `salesMonthlyCopy`() -BEGIN - DECLARE vPlusNewClient INT DEFAULT 100; - DECLARE vScoreNewClient INT DEFAULT 100; - DECLARE vRowCount INT DEFAULT 1; - DECLARE vMaxRow INT; - - -- COMERCIAL Y EQUIPO - DROP TEMPORARY TABLE IF EXISTS tmp.salesPersons; - CREATE TEMPORARY TABLE tmp.salesPersons - ENGINE = MEMORY - SELECT u.id workerFk, - u.name salesPerson, - d.name team, - u2.name bossFk - FROM vn.department d - JOIN vn.workerDepartment wd ON wd.departmentFk = d.id - JOIN account.user u ON u.id = wd.workerFk - JOIN vn.worker w ON w.id = u.id - JOIN account.user u2 ON u2.id = w.bossFk - WHERE d.name LIKE '%EQUIPO%'; - - -- VENTA, COMISIÓN - DROP TEMPORARY TABLE IF EXISTS tmp.sale; - CREATE TEMPORARY TABLE tmp.sale - ENGINE = MEMORY - SELECT YEAR(s.dated) year, - MONTH(s.dated) month, - u.name, - SUM(s.amount) currentSale, - SUM(s.amount)*cc.rate commissionSale, - s.salesPersonFk workerFk, - cc.minimumSalesByQuarter/3 minimumSalesByMonth - FROM - bs.salesByclientSalesPerson s - JOIN vn.client c ON c.id = s.salesPersonFk - JOIN account.user u ON u.id = s.salesPersonFk - JOIN vn.commissionConfig cc - WHERE dated BETWEEN util.firstDayOfMonth(CURDATE()) AND LAST_DAY(CURDATE()) - GROUP BY year, month, workerFk; - - -- OBJETIVO EVALUABLE (GRUPO) Y OBJETIVO INCENTIVO (INDIVIDUAL) - DROP TEMPORARY TABLE IF EXISTS tmp.objectives; - CREATE TEMPORARY TABLE tmp.objectives - ENGINE = MEMORY - SELECT sg.rank, - sg.goal goalGroup, - sg2.goal goalIncentive, - sub.walletWeigth, - sub.walletWeigth*sg2.goal/100 AS incentiveObjective, - sub.walletWeigth*sg.goal/100 AS evaluableObjective, - sub.workerFk, - rb.bonus - FROM ( - SELECT - CASE - WHEN portfolioWeight >= sg1.walletWeightFrom - AND portfolioWeight <= sg1.walletWeightTo THEN 1 - WHEN portfolioWeight >= sg2.walletWeightFrom - AND portfolioWeight <= sg2.walletWeightTo THEN 2 - WHEN portfolioWeight >= sg3.walletWeightFrom - AND portfolioWeight <= sg3.walletWeightTo THEN 3 - WHEN portfolioWeight >= sg4.walletWeightFrom - AND portfolioWeight <= sg4.walletWeightTo THEN 4 - WHEN portfolioWeight >= sg5.walletWeightFrom - AND portfolioWeight <= sg5.walletWeightTo THEN 5 - END rank, - u.id workerFk, - IFNULL(v.portfolioWeight,0) AS walletWeigth - FROM bs.vendedores v - JOIN account.`user` u ON u.id = v.Id_Trabajador - JOIN vn.saleGoal sg1 ON sg1.`rank` = 1 AND sg1.`year` = YEAR(CURDATE()) AND sg1.`month` = MONTH(CURDATE()) - JOIN vn.saleGoal sg2 ON sg2.`rank` = 2 AND sg2.`year` = YEAR(CURDATE()) AND sg2.`month` = MONTH(CURDATE()) - JOIN vn.saleGoal sg3 ON sg3.`rank` = 3 AND sg3.`year` = YEAR(CURDATE()) AND sg3.`month` = MONTH(CURDATE()) - JOIN vn.saleGoal sg4 ON sg4.`rank` = 4 AND sg4.`year` = YEAR(CURDATE()) AND sg4.`month` = MONTH(CURDATE()) - JOIN vn.saleGoal sg5 ON sg5.`rank` = 5 AND sg5.`year` = YEAR(CURDATE()) AND sg5.`month` = MONTH(CURDATE()) - WHERE v.año = YEAR(CURDATE())-1 AND v.mes = MONTH(CURDATE()) - GROUP BY u.id - ) sub - JOIN vn.saleGoal sg ON sg.`rank` = sub.rank AND sg.goalType = 'grupo' AND sg.`year` = YEAR(CURDATE()) AND sg.`month` = MONTH(CURDATE()) - JOIN vn.saleGoal sg2 ON sg2.`rank` = sub.rank AND sg2.goalType = 'individual' AND sg2.`year` = YEAR(CURDATE()) AND sg2.`month` = MONTH(CURDATE()) - JOIN vn.rankBonus rb ON rb.`rank` = sub.`rank`; - - -- PUNTUACIÓN EQUIPO, PLUS OBJETIVO EQUIPO Y PLUS VARIABLE JEFE DE EQUIPO - DROP TEMPORARY TABLE IF EXISTS tmp.scoreTeam; - CREATE TEMPORARY TABLE tmp.scoreTeam - ENGINE = MEMORY - SELECT *, - IF(sub1.scoreTeam >= sub1.minScoreForPlusTeam, sub1.plusTeamValue, 0) plusTeam, - IF(sub1.scoreTeam >= sub1.minScoreForPlusBoss, countSalesPerson * sub1.plusBoss, 0) plusBossTeam - FROM ( - SELECT *, - (100/sub.countSalesPerson)*countGroupAchieved scoreTeam - FROM ( - SELECT COUNT(u.id) countSalesPerson, - u.id workerFk, - u.name salesPerson, - d.name team, - cc.minScoreForPlusTeam, - cc.minScoreForPlusBoss, - cc.plusTeam plusTeamValue, - cc.plusBoss, - s.minimumSalesByMonth, - s.currentSale, - SUM(IF(s.currentSale > r.evaluableObjective, 1, 0)) countGroupAchieved - FROM vn.department d - JOIN vn.workerDepartment wd ON wd.departmentFk = d.id - JOIN account.user u ON u.id = wd.workerFk - JOIN tmp.sale s ON s.workerFk = wd.workerFk - JOIN tmp.objectives r ON r.workerFk = wd.workerFk - JOIN vn.commissionConfig cc - WHERE d.name LIKE '%EQUIPO%' - GROUP BY d.name - ) sub - ) sub1; - - -- PLUS CLIENTES NUEVOS - DROP TEMPORARY TABLE IF EXISTS tmp.newClients; - CREATE TEMPORARY TABLE tmp.newClients ( - id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, - workerFk INTEGER(11), - name VARCHAR(30), - total DECIMAL(10,3), - plusNewClient INTEGER(11), - scoreNewClient INTEGER(11) - ); - - INSERT INTO tmp.newClients (workerFk, total, name, plusNewClient) - SELECT u.id workerFk, u.name, SUM(v.importe) total, vPlusNewClient - FROM bs.clientNewBorn cn - JOIN bs.ventas v ON DATE_ADD(cn.firstShipped, INTERVAL 1 YEAR) > v.fecha AND v.Id_Cliente = cn.clientFk - JOIN vn.client c ON c.id = v.Id_Cliente - JOIN account.user u ON u.id = c.salesPersonFk - JOIN vn.workerDepartment wd ON wd.workerFk = u.id - JOIN vn.department d On d.id = wd.departmentFk - WHERE v.fecha >= util.firstDayOfMonth(CURDATE()) - AND cn.firstShipped >= util.firstDayOfMonth(DATE_ADD(CURDATE(), INTERVAL -1 year)) - AND d.name LIKE 'EQUIPO%' - GROUP BY u.id - ORDER BY total DESC; - - SET vMaxRow = ROW_COUNT(); - - my_loop: LOOP - UPDATE tmp.newClients SET plusNewClient = vPlusNewClient WHERE id = vRowCount; - UPDATE tmp.newClients SET scoreNewClient = vScoreNewClient WHERE id = vRowCount; - - IF (vRowCount <= 20) THEN - SET vPlusNewClient = vPlusNewClient - 5; - ELSE - SET vPlusNewClient = 0; - END IF; - - SET vScoreNewClient = vScoreNewClient - 1; - SET vRowCount = vRowCount + 1; - - IF vRowCount > vMaxRow THEN - LEAVE my_loop; - END IF; - END LOOP my_loop; - - SELECT * - FROM ( - SELECT sp.salesPerson, - sp.team, - s.`year`, - s.`month`, - s.currentSale, - s.commissionSale, - IF(s.currentSale > s.minimumSalesByMonth AND s.currentSale > r.incentiveObjective, r.bonus, 0) plusIndividual, - IF(s.currentSale > s.minimumSalesByMonth, st.plusTeam, 0) plusTeam, - nc.plusNewClient, - IF(sp.bossFk = 'ricar', st.plusBossTeam, 0) plusBossTeam, - st.scoreTeam, - nc.scoreNewClient - FROM tmp.salesPersons sp - LEFT JOIN tmp.sale s ON s.workerFk = sp.workerFk - LEFT JOIN tmp.objectives r ON r.workerFk = sp.workerFk - LEFT JOIN tmp.scoreTeam st ON st.team = sp.team - LEFT JOIN tmp.newClients nc ON nc.workerFk = sp.workerFk - ) sub - ORDER BY salesPerson; - - DROP TEMPORARY TABLE - tmp.salesPersons, - tmp.sale, - tmp.objectives, - tmp.scoreTeam, - tmp.newClients; - END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -6114,22 +5908,19 @@ BEGIN DECLARE vRowCount INT DEFAULT 1; DECLARE vMaxRow INT; - IF(DAY(CURDATE()) = 5) THEN + IF(DAY(CURDATE()) = 5) THEN -- COMERCIAL Y EQUIPO DROP TEMPORARY TABLE IF EXISTS tmp.salesPersons; CREATE TEMPORARY TABLE tmp.salesPersons ENGINE = MEMORY SELECT u.id workerFk, u.name salesPersonName, - d.name teamName, - u2.name bossFk + d.name teamName FROM vn.department d JOIN vn.workerDepartment wd ON wd.departmentFk = d.id JOIN account.user u ON u.id = wd.workerFk - JOIN vn.worker w ON w.id = u.id - JOIN account.user u2 ON u2.id = w.bossFk WHERE d.name LIKE '%EQUIPO%'; - + -- VENTA, COMISIÓN DROP TEMPORARY TABLE IF EXISTS tmp.sale; CREATE TEMPORARY TABLE tmp.sale @@ -6148,7 +5939,7 @@ BEGIN JOIN vn.commissionConfig cc WHERE dated BETWEEN util.firstDayOfMonth(DATE_SUB(CURDATE(), INTERVAL 1 MONTH)) AND LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 1 MONTH)) GROUP BY year, month, workerFk; - + -- OBJETIVO EVALUABLE (GRUPO) Y OBJETIVO INCENTIVO (INDIVIDUAL) DROP TEMPORARY TABLE IF EXISTS tmp.objectives; CREATE TEMPORARY TABLE tmp.objectives @@ -6190,19 +5981,19 @@ BEGIN JOIN vn.saleGoal sg ON sg.`rank` = sub.rank AND sg.goalType = 'grupo' AND sg.`year` = YEAR(DATE_SUB(CURDATE(), INTERVAL 1 MONTH)) AND sg.`month` = MONTH(DATE_SUB(CURDATE(), INTERVAL 1 MONTH)) JOIN vn.saleGoal sg2 ON sg2.`rank` = sub.rank AND sg2.goalType = 'individual' AND sg2.`year` = YEAR(DATE_SUB(CURDATE(), INTERVAL 1 MONTH)) AND sg2.`month` = MONTH(DATE_SUB(CURDATE(), INTERVAL 1 MONTH)) JOIN vn.rankBonus rb ON rb.`rank` = sub.`rank`; - + -- PUNTUACIÓN EQUIPO, PLUS OBJETIVO EQUIPO Y PLUS VARIABLE JEFE DE EQUIPO - DROP TEMPORARY TABLE IF EXISTS tmp.teamScore; - CREATE TEMPORARY TABLE tmp.teamScore + DROP TEMPORARY TABLE IF EXISTS tmp.scoreTeam; + CREATE TEMPORARY TABLE tmp.scoreTeam ENGINE = MEMORY SELECT *, IF(sub1.teamScore >= sub1.minScoreForPlusTeam, sub1.plusTeamValue, 0) teamPlus, - IF(sub1.teamScore >= sub1.minScoreForPlusBoss, IF(sub1.teamName = 'EQUIPO MIRIAM MAR', (sub1.countSalesPerson-2)*sub1.plusBoss, (sub1.countSalesPerson-1)*sub1.plusBoss), 0) teamBossPlus -- se resta 1 pq el jefe de equipo no cuenta + IF(sub1.teamScore >= sub1.minScoreForPlusBoss, countSalesPerson * sub1.plusBoss, 0) teamBossPlus FROM ( SELECT *, (100/sub.countSalesPerson)*countGroupAchieved teamScore FROM ( - SELECT COUNT(u.id) countSalesPerson, + SELECT COUNT(u.id) countSalesPerson, u.id workerFk, u.name salesPersonName, d.name teamName, @@ -6210,8 +6001,6 @@ BEGIN cc.minScoreForPlusBoss, cc.plusTeam plusTeamValue, cc.plusBoss, - s.minimumSalesByMonth, - s.currentSale, SUM(IF(s.currentSale > r.evaluableObjective, 1, 0)) countGroupAchieved FROM vn.department d JOIN vn.workerDepartment wd ON wd.departmentFk = d.id @@ -6223,7 +6012,7 @@ BEGIN GROUP BY d.name ) sub ) sub1; - + -- PLUS CLIENTES NUEVOS DROP TEMPORARY TABLE IF EXISTS tmp.newClients; CREATE TEMPORARY TABLE tmp.newClients ( @@ -6269,26 +6058,26 @@ BEGIN END IF; END LOOP my_loop; - INSERT INTO bs.salesMonthlySnapshot - SELECT * - FROM ( - SELECT sp.salesPersonName, - sp.teamName, - s.`year`, - s.`month`, - s.currentSale, - s.commissionSale, - IF(s.currentSale > s.minimumSalesByMonth AND s.currentSale > r.incentiveObjective, r.bonus, 0) individualPlus, - IF(s.currentSale > s.minimumSalesByMonth, st.teamPlus, 0) teamPlus, - st.teamScore, - nc.newClientPlus, - nc.newClientScore, - IF(sp.bossFk = 'ricar' OR sp.bossFk = 'miriam', IF(sp.salesPersonName = 'miriam' OR sp.salesPersonName = 'mmar', st.teamBossPlus/2, st.teamBossPlus), 0) teamBossPlus -- para que solo tengan teamBossPlus los jefes/ como hay 2 jefes de equipo, el plus se divide - FROM tmp.salesPersons sp - LEFT JOIN tmp.sale s ON s.workerFk = sp.workerFk - LEFT JOIN tmp.objectives r ON r.workerFk = sp.workerFk - LEFT JOIN tmp.teamScore st ON st.teamName = sp.teamName - LEFT JOIN tmp.newClients nc ON nc.workerFk = sp.workerFk + INSERT INTO bs.salesMonthlySnapshot + SELECT * + FROM ( + SELECT sp.salesPersonName, + sp.teamName, + s.`year`, + s.`month`, + s.currentSale, + s.commissionSale, + IF(s.currentSale > s.minimumSalesByMonth AND s.currentSale > r.incentiveObjective, r.bonus, 0) individualPlus, + np.teamPlus, + np.teamScore, + nc.newClientPlus, + nc.newClientScore, + np.teamBossPlus + FROM tmp.salesPersons sp + LEFT JOIN tmp.sale s ON s.workerFk = sp.workerFk + LEFT JOIN tmp.objectives r ON r.workerFk = sp.workerFk + LEFT JOIN tmp.scoreTeam np ON np.teamName = sp.teamName + LEFT JOIN tmp.newClients nc ON nc.workerFk = sp.workerFk ) sub ORDER BY salesPersonName; @@ -6296,9 +6085,10 @@ BEGIN tmp.salesPersons, tmp.sale, tmp.objectives, - tmp.teamScore, + tmp.scoreTeam, tmp.newClients; - END IF; + END IF; + END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -10145,7 +9935,7 @@ CREATE TABLE `supplyResponseLog` ( PRIMARY KEY (`id`), KEY `supplyResponseLog_FK` (`supplyResponseFk`), CONSTRAINT `supplyResponseLog_FK` FOREIGN KEY (`supplyResponseFk`) REFERENCES `supplyResponse` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDBDEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +) ENGINE=InnoDBDEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Esta tabla la utiliza la empresa LOGIFLORA. No kkear.'; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -10973,9 +10763,9 @@ DELIMITER ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; @@ -10987,10 +10777,10 @@ proc: BEGIN DECLARE vFreeId INT; DECLARE vSupplyResponseFk INT; DECLARE vLastInserted DATETIME; - DECLARE vIsAuctionDay BOOLEAN; - DECLARE vMaxNewItems INT DEFAULT 10000; + DECLARE vIsAuctionDay BOOLEAN; + DECLARE vMaxNewItems INT DEFAULT 10000; DECLARE vStartingTime DATETIME; - DECLARE vAalsmeerMarketPlaceID VARCHAR(13) DEFAULT '8713783439043'; + DECLARE vAalsmeerMarketPlaceID VARCHAR(13) DEFAULT '8713783439043'; DECLARE cur1 CURSOR FOR SELECT id @@ -11041,21 +10831,13 @@ proc: BEGIN DROP TEMPORARY TABLE IF EXISTS tmp; CREATE TEMPORARY TABLE tmp (INDEX (`Item_ArticleCode`)) ENGINE = MEMORY - SELECT t.*, - IFNULL(idt.itemTypeFk, igo.itemTypeFk) itemTypeFk, - igo.expenseFk , - igo.intrastatFk , - igo.originFk + SELECT t.* FROM ( SELECT * FROM edi.supplyOffer ORDER BY (MarketPlaceID = vAalsmeerMarketPlaceID) DESC, NumberOfUnits DESC) t - JOIN edi.item_groupToOffer igo ON igo.group_code = t.group_id - LEFT JOIN edi.item_defaultType idt ON idt.item_id = t.Item_ArticleCode GROUP BY t.srId ; - - -- select now(),'Antes de crear edi.offer'; DROP TEMPORARY TABLE IF EXISTS edi.offer; CREATE TEMPORARY TABLE edi.offer (INDEX (`srID`), INDEX (`EmbalageCode`), @@ -11470,9 +11252,9 @@ DELIMITER ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; @@ -11484,10 +11266,10 @@ proc: BEGIN DECLARE vFreeId INT; DECLARE vSupplyResponseFk INT; DECLARE vLastInserted DATETIME; - DECLARE vIsAuctionDay BOOLEAN; - DECLARE vMaxNewItems INT DEFAULT 10000; + DECLARE vIsAuctionDay BOOLEAN; + DECLARE vMaxNewItems INT DEFAULT 10000; DECLARE vStartingTime DATETIME; - DECLARE vAalsmeerMarketPlaceID VARCHAR(13) DEFAULT '8713783439043'; + DECLARE vAalsmeerMarketPlaceID VARCHAR(13) DEFAULT '8713783439043'; DECLARE cur1 CURSOR FOR SELECT id @@ -11538,21 +11320,12 @@ proc: BEGIN DROP TEMPORARY TABLE IF EXISTS tmp; CREATE TEMPORARY TABLE tmp (INDEX (`Item_ArticleCode`)) ENGINE = MEMORY - SELECT t.*, - IFNULL(idt.itemTypeFk, igo.itemTypeFk) itemTypeFk, - igo.expenseFk , - igo.intrastatFk , - igo.originFk + SELECT t.* FROM ( SELECT * FROM edi.supplyOffer ORDER BY (MarketPlaceID = vAalsmeerMarketPlaceID) DESC, NumberOfUnits DESC) t - JOIN edi.item_groupToOffer igo ON igo.group_code = t.group_id - LEFT JOIN edi.item_defaultType idt ON idt.item_id = t.Item_ArticleCode - GROUP BY t.srId - ; - - -- select now(),'Antes de crear edi.offer'; + GROUP BY t.srId; DROP TEMPORARY TABLE IF EXISTS edi.offer; CREATE TEMPORARY TABLE edi.offer (INDEX (`srID`), INDEX (`EmbalageCode`), @@ -11613,8 +11386,6 @@ proc: BEGIN START TRANSACTION; - CALL util.debugAdd('edi.floramondo_offerRefresh_BETA',CONCAT('offerItems:' ,(SELECT COUNT(*) FROM edi.offer))); - -- Actualizamos el campo supplyResponseFk para aquellos articulos que ya estan creados y reutilizamos UPDATE IGNORE edi.offer o JOIN vn.item i @@ -11848,10 +11619,7 @@ proc: BEGIN UPDATE edi.warehouseFloramondo SET entryFk = vn.floramondo_getEntry(TIMESTAMPADD(DAY,travellingDays,vLanded), warehouseFk); - CALL util.debugAdd('edi.floramondo_offerRefresh_BETA',CONCAT('offerItems:' ,(SELECT COUNT(*) FROM edi.offer))); - - CALL util.debugAdd('edi.floramondo_offerRefresh_BETA',CONCAT('vLanded:' ,vLanded)); - + IF vLanded IS NOT NULL THEN -- actualiza la oferta existente UPDATE vn.buy b @@ -11862,7 +11630,6 @@ proc: BEGIN b.buyingValue = o.price WHERE (b.quantity <> o.NumberOfUnits * o.NumberOfItemsPerCask OR b.buyingValue <> o.price); - -- Se eliminan las ofertas ya incluidas en las entradas DELETE o FROM edi.offer o @@ -11919,6 +11686,7 @@ proc: BEGIN JOIN edi.warehouseFloramondo wf ON wf.entryFk = b.entryFk JOIN vn.warehouse w ON w.id = wf.warehouseFk WHERE w.name = 'VNH' + AND b.quantity > 0 GROUP BY sr.vmpID) sub ON o.supplier = sub.name SET o.vnh = sub.total; @@ -11931,18 +11699,17 @@ proc: BEGIN JOIN edi.warehouseFloramondo wf ON wf.entryFk = b.entryFk JOIN vn.warehouse w ON w.id = wf.warehouseFk WHERE w.name = 'ALGEMESI' + AND b.quantity > 0 GROUP BY sr.vmpID) sub ON o.supplier = sub.name SET o.algemesi = sub.total; - CALL util.debugAdd('edi.floramondo_offerRefresh_BETA',CONCAT('offerItems:' ,(SELECT COUNT(*) FROM edi.offer))); - END IF; - /* + DROP TEMPORARY TABLE edi.offer, itemToInsert; - */ + DROP TABLE tmp.item; COMMIT; @@ -11961,7 +11728,496 @@ proc: BEGIN INSERT INTO edi.log(tableName, fieldName,fieldValue) VALUES('floramondo_offerRefresh','Tiempo de proceso',TIMEDIFF(NOW(),vStartingTime)); - SELECT * FROM util.debug WHERE variable = 'edi.floramondo_offerRefresh_BETA' ORDER BY id desc; + + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `floramondo_offerRefresh_beta2` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `floramondo_offerRefresh_beta2`() +proc: BEGIN + + DECLARE vLanded DATETIME; + DECLARE done INT DEFAULT FALSE; + DECLARE vFreeId INT; + DECLARE vSupplyResponseFk INT; + DECLARE vLastInserted DATETIME; + DECLARE vIsAuctionDay BOOLEAN; + DECLARE vMaxNewItems INT DEFAULT 10000; + DECLARE vStartingTime DATETIME; + DECLARE vAalsmeerMarketPlaceID VARCHAR(13) DEFAULT '8713783439043'; + + DECLARE cur1 CURSOR FOR + SELECT id + FROM edi.item_free; + + DECLARE cur2 CURSOR FOR + SELECT srId + FROM itemToInsert; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + DECLARE EXIT HANDLER FOR SQLSTATE '45000' + BEGIN + ROLLBACK; + RESIGNAL; + END; + + SET vStartingTime = NOW(); + + TRUNCATE edi.offerList ; + + INSERT INTO edi.offerList(supplier, total) + SELECT v.name, COUNT(DISTINCT sr.ID) total + FROM edi.supplyResponse sr + JOIN edi.VMPSettings v ON v.VMPID = sr.vmpID + WHERE sr.NumberOfUnits > 0 + AND sr.EmbalageCode != 999 + GROUP BY sr.vmpID; + + UPDATE edi.offerList o + JOIN (SELECT v.name, COUNT(*) total + FROM edi.supplyOffer sr + JOIN edi.VMPSettings v ON v.VMPID = sr.vmpID + GROUP BY sr.vmpID) sub ON o.supplier = sub.name + SET o.`filter` = sub.total; + + -- Refresca las fotos de los items existentes, con prioridad baja (0.7 seg) + INSERT IGNORE INTO vn.itemImageQueue(itemFk, url,priority) + SELECT i.id, sr.PictureReference , 100 + FROM edi.supplyResponse sr + JOIN vn.item i ON i.supplyResponseFk = sr.ID + WHERE i.image != edi.imageName(sr.PictureReference) + AND sr.NumberOfUnits > 0; + + -- Elimina de la lista de items libres aquellos que ya existen + DELETE itf.* + FROM edi.item_free itf + JOIN vn.item i ON i.id = itf.id; + + DROP TEMPORARY TABLE IF EXISTS tmp; + CREATE TEMPORARY TABLE tmp (INDEX (`Item_ArticleCode`)) ENGINE = MEMORY + SELECT t.* + FROM ( + SELECT * + FROM edi.supplyOffer + ORDER BY (MarketPlaceID = vAalsmeerMarketPlaceID) DESC, NumberOfUnits DESC) t + GROUP BY t.srId + ; + + DROP TEMPORARY TABLE IF EXISTS edi.offer; + CREATE TEMPORARY TABLE edi.offer (INDEX (`srID`), INDEX (`EmbalageCode`), + INDEX (`ef1`), INDEX (`ef2`), INDEX (`ef3`), INDEX (`ef4`),INDEX (`ef5`), INDEX (`ef6`), + INDEX (`s1Value`), INDEX (`s2Value`), INDEX (`s3Value`), INDEX (`s4Value`),INDEX (`s5Value`), INDEX (`s6Value`)) + ENGINE = MEMORY + SELECT so.*, + ev1.type_description s1Value, + ev2.type_description s2Value, + ev3.type_description s3Value, + ev4.type_description s4Value, + ev5.type_description s5Value, + ev6.type_description s6Value, + eif1.feature ef1, + eif2.feature ef2, + eif3.feature ef3, + eif4.feature ef4, + eif5.feature ef5, + eif6.feature ef6 + FROM tmp so + LEFT JOIN edi.item_feature eif1 ON eif1.item_id = so.Item_ArticleCode + AND eif1.presentation_order = 1 AND eif1.expiry_date IS NULL + LEFT JOIN edi.item_feature eif2 ON eif2.item_id = so.Item_ArticleCode + AND eif2.presentation_order = 2 AND eif2.expiry_date IS NULL + LEFT JOIN edi.item_feature eif3 ON eif3.item_id = so.Item_ArticleCode + AND eif3.presentation_order = 3 AND eif3.expiry_date IS NULL + LEFT JOIN edi.item_feature eif4 ON eif4.item_id = so.Item_ArticleCode + AND eif4.presentation_order = 4 AND eif4.expiry_date IS NULL + LEFT JOIN edi.item_feature eif5 ON eif5.item_id = so.Item_ArticleCode + AND eif5.presentation_order = 5 AND eif5.expiry_date IS NULL + LEFT JOIN edi.item_feature eif6 ON eif6.item_id = so.Item_ArticleCode + AND eif6.presentation_order = 6 AND eif6.expiry_date IS NULL + LEFT JOIN edi.`value` ev1 ON ev1.type_id = eif1.feature AND so.s1 = ev1.type_value + LEFT JOIN edi.`value` ev2 ON ev2.type_id = eif2.feature AND so.s2 = ev2.type_value + LEFT JOIN edi.`value` ev3 ON ev3.type_id = eif3.feature AND so.s3 = ev3.type_value + LEFT JOIN edi.`value` ev4 ON ev4.type_id = eif4.feature AND so.s4 = ev4.type_value + LEFT JOIN edi.`value` ev5 ON ev5.type_id = eif5.feature AND so.s5 = ev5.type_value + LEFT JOIN edi.`value` ev6 ON ev6.type_id = eif6.feature AND so.s6 = ev6.type_value + ORDER BY Price; + + DROP TEMPORARY TABLE tmp; + + DELETE o + FROM edi.offer o + LEFT JOIN vn.tag t1 ON t1.ediTypeFk = o.ef1 AND t1.overwrite = 'size' + LEFT JOIN vn.tag t2 ON t2.ediTypeFk = o.ef2 AND t2.overwrite = 'size' + LEFT JOIN vn.tag t3 ON t3.ediTypeFk = o.ef3 AND t3.overwrite = 'size' + LEFT JOIN vn.tag t4 ON t4.ediTypeFk = o.ef4 AND t4.overwrite = 'size' + LEFT JOIN vn.tag t5 ON t5.ediTypeFk = o.ef5 AND t5.overwrite = 'size' + LEFT JOIN vn.tag t6 ON t6.ediTypeFk = o.ef6 AND t6.overwrite = 'size' + JOIN vn.floramondoConfig fc ON TRUE + WHERE (t1.id IS NOT NULL AND CONVERT(s1Value, UNSIGNED) > fc.itemMaxSize) + OR(t2.id IS NOT NULL AND CONVERT(s2Value, UNSIGNED) > fc.itemMaxSize) + OR(t3.id IS NOT NULL AND CONVERT(s3Value, UNSIGNED) > fc.itemMaxSize) + OR(t4.id IS NOT NULL AND CONVERT(s4Value, UNSIGNED) > fc.itemMaxSize) + OR(t5.id IS NOT NULL AND CONVERT(s5Value, UNSIGNED) > fc.itemMaxSize) + OR(t6.id IS NOT NULL AND CONVERT(s6Value, UNSIGNED) > fc.itemMaxSize); + + START TRANSACTION; + + -- Actualizamos el campo supplyResponseFk para aquellos articulos que ya estan creados y reutilizamos + UPDATE IGNORE edi.offer o + JOIN vn.item i + ON i.name = o.product_name + AND i.subname <=> o.company_name + AND i.value5 <=> o.s1Value + AND i.value6 <=> o.s2Value + AND i.value7 <=> o.s3Value + AND i.value8 <=> o.s4Value + AND i.value9 <=> o.s5Value + AND i.value10 <=> o.s6Value + AND i.NumberOfItemsPerCask <=> o.NumberOfItemsPerCask + AND i.EmbalageCode <=> o.EmbalageCode + AND i.quality <=> o.Quality + JOIN vn.itemType it ON it.id = i.typeFk + LEFT JOIN vn.sale s ON s.itemFk = i.id + LEFT JOIN vn.ticket t ON t.id = s.ticketFk AND t.shipped > TIMESTAMPADD(WEEK, -1, CURDATE()) + LEFT JOIN edi.supplyResponse sr ON sr.ID = i.supplyResponseFk + LEFT JOIN edi.deliveryInformation di ON di.supplyResponseID = sr.ID + LEFT JOIN edi.putOrder po ON po.supplyResponseID = i.supplyResponseFk AND po.OrderTradeLineDateTime > TIMESTAMPADD(WEEK, -1, CURDATE()) + SET i.supplyResponseFk = o.srID + WHERE ( sr.ID IS NULL + OR sr.NumberOfUnits = 0 + OR di.LatestOrderDateTime < NOW() + OR di.ID IS NULL) + AND it.isInventory + AND t.id IS NULL + AND po.id IS NULL; + -- select now(),'Antes de crear ITO'; + DROP TEMPORARY TABLE IF EXISTS itemToInsert; + CREATE TEMPORARY TABLE itemToInsert ENGINE = MEMORY + SELECT o.*, CAST(NULL AS DECIMAL(6,0)) as itemFk + FROM edi.offer o + LEFT JOIN vn.item i ON i.supplyResponseFk = o.srId + WHERE i.id IS NULL + LIMIT vMaxNewItems; + + -- Reciclado de nº de item + OPEN cur1; + OPEN cur2; + + read_loop: LOOP + + FETCH cur2 INTO vSupplyResponseFk; + FETCH cur1 INTO vFreeId; + + IF done THEN + LEAVE read_loop; + END IF; + + UPDATE itemToInsert + SET itemFk = vFreeId + WHERE srId = vSupplyResponseFk; + + END LOOP; + + CLOSE cur1; + CLOSE cur2; + + -- Insertamos todos los items en Articles de la oferta + INSERT INTO vn.item( id, + `name`, + longName, + subName, + expenceFk, + typeFk, + intrastatFk, + originFk, + supplyResponseFk, + numberOfItemsPerCask, + embalageCode, + quality, + isFloramondo) + SELECT iti.itemFk, + iti.product_name, + iti.product_name, + iti.company_name, + iti.expenseFk, + iti.itemTypeFk, + iti.intrastatFk, + iti.originFk, + iti.`srId`, + iti.NumberOfItemsPerCask, + iti.EmbalageCode, + iti.Quality, + TRUE + FROM itemToInsert iti; + + INSERT IGNORE INTO vn.itemImageQueue(itemFk, url) + SELECT i.id, PictureReference + FROM itemToInsert ii + JOIN vn.item i ON i.supplyResponseFk = ii.srId + WHERE PictureReference IS NOT NULL; + + INSERT INTO edi.log(tableName, fieldName,fieldValue) + SELECT 'itemImageQueue','NumImagenesPtes', COUNT(*) + FROM vn.itemImageQueue + WHERE attempts = 0; + + -- Inserta si se añadiesen tags nuevos + INSERT IGNORE INTO vn.tag (name, ediTypeFk) + SELECT description, type_id FROM edi.type; + + -- Inserta los tags sólo en los articulos nuevos + + -- desabilita el trigger para recalcular los tags al final + SET @isTriggerDisabled = TRUE; + + INSERT INTO vn.itemTag(itemFk, tagFk, value, priority) + SELECT i.id, t.id , ii.product_name, 1 + FROM itemToInsert ii + JOIN vn.tag t ON t.`name` = 'Producto' + JOIN vn.item i ON i.supplyResponseFk = ii.`srId`; + + INSERT INTO vn.itemTag(itemFk, tagFk, value, priority) + SELECT i.id, t.id , ii.Quality, 3 + FROM itemToInsert ii + JOIN vn.tag t ON t.`name` = 'Calidad' + JOIN vn.item i ON i.supplyResponseFk = ii.`srId`; + + INSERT INTO vn.itemTag(itemFk, tagFk, value, priority) + SELECT i.id, t.id , ii.company_name, 4 + FROM itemToInsert ii + JOIN vn.tag t ON t.`name` = 'Productor' + JOIN vn.item i ON i.supplyResponseFk = ii.`srId`; + + INSERT INTO vn.itemTag(itemFk, tagFk, value, priority) + SELECT i.id, t.id , s1Value, 5 + FROM itemToInsert ii + JOIN vn.tag t ON t.ediTypeFk = ii.ef1 + JOIN vn.item i ON i.supplyResponseFk = ii.`srId` + WHERE NOT ISNULL(s1Value); + + INSERT INTO vn.itemTag(itemFk, tagFk, value, priority) + SELECT i.id, t.id , s2Value, 6 + FROM itemToInsert ii + JOIN vn.tag t ON t.ediTypeFk = ii.ef2 + JOIN vn.item i ON i.supplyResponseFk = ii.`srId` + WHERE NOT ISNULL(s2Value); + + INSERT INTO vn.itemTag(itemFk, tagFk, value, priority) + SELECT i.id, t.id , s3Value, 7 + FROM itemToInsert ii + JOIN vn.tag t ON t.ediTypeFk = ii.ef3 + JOIN vn.item i ON i.supplyResponseFk = ii.`srId` + WHERE NOT ISNULL(s3Value); + + INSERT INTO vn.itemTag(itemFk, tagFk, value, priority) + SELECT i.id, t.id , s4Value, 8 + FROM itemToInsert ii + JOIN vn.tag t ON t.ediTypeFk = ii.ef4 + JOIN vn.item i ON i.supplyResponseFk = ii.`srId` + WHERE NOT ISNULL(s4Value); + + INSERT INTO vn.itemTag(itemFk, tagFk, value, priority) + SELECT i.id, t.id , s5Value, 9 + FROM itemToInsert ii + JOIN vn.tag t ON t.ediTypeFk = ii.ef5 + JOIN vn.item i ON i.supplyResponseFk = ii.`srId` + WHERE NOT ISNULL(s5Value); + + INSERT INTO vn.itemTag(itemFk, tagFk, value, priority) + SELECT i.id, t.id , s6Value, 10 + FROM itemToInsert ii + JOIN vn.tag t ON t.ediTypeFk = ii.ef6 + JOIN vn.item i ON i.supplyResponseFk = ii.`srId` + WHERE NOT ISNULL(s6Value); + + INSERT IGNORE INTO vn.itemTag(itemFk, tagFk, value, priority) + SELECT i.id, t.id, IFNULL(ink.name, ik.color), 11 + FROM itemToInsert ii + JOIN vn.item i ON i.supplyResponseFk = ii.`srId` + JOIN vn.tag t ON t.`name` = 'Color' + LEFT JOIN edi.feature f ON f.item_id = ii.Item_ArticleCode + LEFT JOIN edi.`type` tp ON tp.type_id = f.feature_type_id AND tp.`description` = 'Hoofdkleur 1' + LEFT JOIN vn.ink ON ink.dutchCode = f.feature_value + LEFT JOIN vn.itemInk ik ON ik.longName = i.longName + WHERE ink.name IS NOT NULL + OR ik.color IS NOT NULL; + + UPDATE vn.item i + JOIN itemToInsert ii ON i.supplyResponseFk = ii.`srId` + JOIN vn.packaging p ON p.id LIKE ii.EmbalageCode AND hasCompressionVariations + JOIN vn.itemTag diameter ON diameter.itemFk = i.id + JOIN vn.tag tDiameter ON tDiameter.overwrite = 'diameter' AND tDiameter.id = diameter.tagFk + JOIN vn.itemTag size ON size.itemFk = i.id + JOIN vn.tag tSize ON tSize.overwrite = 'size' AND tSize.id = size.tagFk + SET i.`compression` = + (PI() * POW(diameter.`value`/ 2, 2) * size.`value`) + / + ((p.width * p.depth * p.height) / ii.NumberOfItemsPerCask); + + DROP TABLE IF EXISTS tmp.item; + CREATE TABLE tmp.item + (PRIMARY KEY (id)) + SELECT i.id FROM vn.item i + JOIN itemToInsert ii ON i.supplyResponseFk = ii.`srId`; + + CALL vn.item_refreshTags(); + + SET @isTriggerDisabled = FALSE; + + SELECT MIN(LatestDeliveryDateTime) INTO vLanded + FROM edi.supplyResponse sr + JOIN edi.deliveryInformation di ON di.supplyResponseID = sr.ID + JOIN edi.marketPlace mp ON mp.id = sr.MarketPlaceID + JOIN vn.floramondoConfig fc + WHERE mp.isLatestOrderDateTimeRelevant + AND di.LatestOrderDateTime > IF(fc.MaxLatestOrderHour > HOUR(NOW()), CURDATE(), TIMESTAMPADD(DAY,1,CURDATE())); + + UPDATE vn.floramondoConfig + SET nextLanded = vLanded + WHERE vLanded IS NOT NULL; + + -- Elimina la oferta obsoleta + UPDATE vn.buy b + JOIN vn.entry e ON e.id = b.entryFk + JOIN vn.travel tr ON tr.id = e.travelFk + JOIN vn.agencyMode am ON am.id = tr.agencyFk + JOIN vn.item i ON i.id = b.itemFk + LEFT JOIN edi.supplyResponse sr ON i.supplyResponseFk = sr.ID + LEFT JOIN edi.deliveryInformation di ON di.ID = b.deliveryFk + SET b.quantity = 0 + WHERE (IFNULL(di.LatestOrderDateTime,NOW()) <= NOW() + OR i.supplyResponseFk IS NULL + OR sr.NumberOfUnits = 0) + AND am.name = 'LOGIFLORA' + AND e.isRaid; + + -- Localiza las entradas de cada almacen + UPDATE edi.warehouseFloramondo + SET entryFk = vn.floramondo_getEntry(TIMESTAMPADD(DAY,travellingDays,vLanded), warehouseFk); + + + IF vLanded IS NOT NULL THEN + -- actualiza la oferta existente + UPDATE vn.buy b + JOIN edi.warehouseFloramondo wf ON wf.entryFk = b.entryFk + JOIN vn.item i ON i.id = b.itemFk + JOIN edi.offer o ON i.supplyResponseFk = o.`srId` + SET b.quantity = o.NumberOfUnits * o.NumberOfItemsPerCask, + b.buyingValue = o.price + WHERE (b.quantity <> o.NumberOfUnits * o.NumberOfItemsPerCask OR b.buyingValue <> o.price); + + -- Se eliminan las ofertas ya incluidas en las entradas + DELETE o + FROM edi.offer o + JOIN vn.item i ON i.supplyResponseFk = o.srId + JOIN vn.buy b ON i.id = b.itemFk + JOIN edi.warehouseFloramondo wf ON wf.entryFk = b.entryFk; + + -- Se inserta el resto + SET vLastInserted := NOW(); + + -- Inserta la oferta + INSERT INTO vn.buy(entryFk, + itemFk, + quantity, + buyingValue, + stickers, + packing, + `grouping`, + groupingMode, + packageFk, + deliveryFk) + + SELECT wf.entryFk, + i.id, + o.NumberOfUnits * o.NumberOfItemsPerCask as quantity, + o.Price, + o.NumberOfUnits as etiquetas, + o.NumberOfItemsPerCask as packing, + GREATEST(1, IFNULL(o.MinimumQuantity,0)) * o.NumberOfItemsPerCask as `grouping`, + 2, -- Obliga al Packing + o.embalageCode, + o.diId + FROM edi.offer o + JOIN vn.item i ON i.supplyResponseFk = o.srId + JOIN edi.warehouseFloramondo wf + JOIN vn.packaging p ON p.id LIKE o.embalageCode; -- llevar esta linea i mirar de crear els packages a temps real + + DROP TEMPORARY TABLE IF EXISTS tmp.buyRecalc; + + CREATE TEMPORARY TABLE tmp.buyRecalc + SELECT b.id + FROM vn.buy b + JOIN edi.warehouseFloramondo wf ON wf.entryFk = b.entryFk + WHERE b.created >= vLastInserted; + + CALL vn.buy_recalcPrices(); + + UPDATE edi.offerList o + JOIN (SELECT v.name, COUNT(DISTINCT b.itemFk) total + FROM vn.buy b + JOIN vn.item i ON i.id = b.itemFk + JOIN edi.supplyResponse sr ON sr.ID = i.supplyResponseFk + JOIN edi.VMPSettings v ON v.VMPID = sr.vmpID + JOIN edi.warehouseFloramondo wf ON wf.entryFk = b.entryFk + JOIN vn.warehouse w ON w.id = wf.warehouseFk + WHERE w.name = 'VNH' + AND b.quantity > 0 + GROUP BY sr.vmpID) sub ON o.supplier = sub.name + SET o.vnh = sub.total; + + UPDATE edi.offerList o + JOIN (SELECT v.name, COUNT(DISTINCT b.itemFk) total + FROM vn.buy b + JOIN vn.item i ON i.id = b.itemFk + JOIN edi.supplyResponse sr ON sr.ID = i.supplyResponseFk + JOIN edi.VMPSettings v ON v.VMPID = sr.vmpID + JOIN edi.warehouseFloramondo wf ON wf.entryFk = b.entryFk + JOIN vn.warehouse w ON w.id = wf.warehouseFk + WHERE w.name = 'ALGEMESI' + AND b.quantity > 0 + GROUP BY sr.vmpID) sub ON o.supplier = sub.name + SET o.algemesi = sub.total; + + + END IF; + + DROP TEMPORARY TABLE + edi.offer, + itemToInsert; + + DROP TABLE tmp.item; + + COMMIT; + + -- Esto habria que pasarlo a procesos programados o trabajar con tags y dejar las familias + UPDATE vn.item i + SET typeFk = 121 + WHERE i.longName LIKE 'Rosa Garden %' + AND typeFk = 17; + + UPDATE vn.item i + SET typeFk = 156 + WHERE i.longName LIKE 'Rosa ec %' + AND typeFk = 17; + + INSERT INTO edi.log(tableName, fieldName,fieldValue) + VALUES('floramondo_offerRefresh','Tiempo de proceso',TIMEDIFF(NOW(),vStartingTime)); + + END ;; DELIMITER ; @@ -12468,17 +12724,17 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `orderLog` */; +/*!50003 DROP PROCEDURE IF EXISTS `orderLog__` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8 */ ; -/*!50003 SET character_set_results = utf8 */ ; -/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `orderLog`(vItemFk INT) +CREATE DEFINER=`root`@`%` PROCEDURE `orderLog__`(vItemFk INT) BEGIN DECLARE vSupplyResponseFk INT; @@ -18492,6 +18748,36 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `sip_getExtension` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `sip_getExtension`(vUserId INT(10)) +BEGIN + + /* + * Devuelve la extensión pbx del usuario + * + * @param vUserId Id del usuario + * + */ + + SELECT extension + FROM sip s + WHERE s.user_id = vUserId; + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 DROP PROCEDURE IF EXISTS `sip_isValid` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -19487,13 +19773,13 @@ CREATE TABLE `TiposTransacciones` ( /*!40101 SET character_set_client = @saved_cs_client */; -- --- Table structure for table `XDiario_movConta_IVA` +-- Table structure for table `XDiario_movConta_IVA__` -- -DROP TABLE IF EXISTS `XDiario_movConta_IVA`; +DROP TABLE IF EXISTS `XDiario_movConta_IVA__`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; -CREATE TABLE `XDiario_movConta_IVA` ( +CREATE TABLE `XDiario_movConta_IVA__` ( `id` int(11) NOT NULL, `CodigoDivisa` varchar(3) COLLATE utf8_unicode_ci NOT NULL, `BaseIva1` double DEFAULT NULL, @@ -19920,7 +20206,8 @@ BEGIN * @vYear Año contable del que se quiere trasladar la información * @vCompanyFk Empresa de la que se quiere trasladar datos */ - DECLARE vDated DATE; + DECLARE vDatedFrom DATETIME; + DECLARE vDatedTo DATETIME; DECLARE vDuaTransactionFk INT; DECLARE vTaxImportFk INT; DECLARE vTaxImportReducedFk INT; @@ -19929,6 +20216,7 @@ BEGIN DECLARE vSerialDua VARCHAR(1) DEFAULT 'D'; DECLARE vInvoiceTypeInformativeCode VARCHAR(1); DECLARE vCountryCanariasCode, vCountryCeutaMelillaCode VARCHAR(2) ; + DECLARE vBookEntries TEXT; SELECT SiglaNacion INTO vCountryCanariasCode FROM Naciones @@ -19961,7 +20249,8 @@ BEGIN SELECT codeSage INTO vInvoiceTypeInformativeCode FROM invoiceType WHERE code ='informative'; - SELECT CAST(CONCAT(vYear, '-01-01') AS DATE) INTO vDated; + SELECT CAST(CONCAT(vYear, '-01-01') AS DATETIME), util.dayEnd(CAST(CONCAT(vYear, '-12-31') AS DATE)) + INTO vDatedFrom, vDatedTo; TRUNCATE movContaIVA; @@ -20164,7 +20453,7 @@ BEGIN )sub3 ON sub3.account = x.SUBCTA WHERE x.enlazadoSage = FALSE AND x.empresa_id = vCompanyFk - AND x.FECHA >= vDated; + AND x.FECHA BETWEEN vDatedFrom AND vDatedTo; -- Metálicos UPDATE movConta m @@ -20287,13 +20576,50 @@ BEGIN AND importeDivisa > 0 AND ImporteAsiento < 0; + -- Comprobación que los importes e ivas sean correctos, avisa vía CAU + SELECT GROUP_CONCAT(Asiento ORDER BY Asiento ASC SEPARATOR ' \n\r') INTO vBookEntries + FROM(SELECT sub.Asiento + FROM (SELECT mc.Asiento, SUM(mc.ImporteAsiento) amount + FROM movConta mc + WHERE mc.enlazadoSage = FALSE + GROUP BY mc.Asiento)sub + JOIN (SELECT x.ASIEN, SUM(IFNULL(x.EURODEBE,0) + IFNULL(x.EUROHABER,0)) amount + FROM vn.XDiario x + WHERE x.enlazadoSage = FALSE + GROUP BY ASIEN)sub2 ON sub2.ASIEN = sub.Asiento + WHERE sub.amount <> sub2.amount + UNION ALL + SELECT sub.Asiento + FROM (SELECT Asiento, SUM(BaseIva1 + BaseIva2 + BaseIva3 + BaseIva4) amountTaxableBase + FROM movConta + WHERE TipoFactura <> 'I' + AND enlazadoSage = FALSE + GROUP BY Asiento) sub + JOIN (SELECT ASIEN, SUM(BASEEURO) amountTaxableBase + FROM (SELECT ASIEN, SUM(BASEEURO) BASEEURO + FROM vn.XDiario + WHERE FACTURA + AND auxiliar <> '*' + AND enlazadoSage = FALSE + GROUP BY FACTURA, ASIEN)sub3 + GROUP BY ASIEN) sub2 ON sub2.ASIEN = sub.Asiento + WHERE sub.amountTaxableBase<>sub2.amountTaxableBase + AND sub.amountTaxableBase/2 <> sub2.amountTaxableBase) sub; + + IF vBookEntries IS NOT NULL THEN + CALL vn.mail_insert('cau@verdnatura.es, administracion@verdnatura.es', + 'noreply@verdnatura.es', + CONCAT('Asientos contables importados incorrectamente'), + CONCAT('

Existen asientos que difieren entre la info. de XDiario y la que se ha importado a Sage.

+ Asientos nº ', vBookEntries, '
')); + END IF; END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `clientesProveedoresAdd` */; +/*!50003 DROP PROCEDURE IF EXISTS `clientesProveedoresAdd__` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -20303,7 +20629,7 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `clientesProveedoresAdd`() +CREATE DEFINER=`root`@`%` PROCEDURE `clientesProveedoresAdd__`() BEGIN TRUNCATE TABLE clientesProveedores; INSERT INTO clientesProveedores @@ -20443,6 +20769,146 @@ BEGIN TRUNCATE TABLE clientesProveedores; + INSERT INTO clientesProveedores + (CodigoEmpresa, + ClienteOProveedor, + CodigoClienteProveedor, + RazonSocial, + Nombre, + Domicilio, + CodigoCuenta, + CifDni, + CifEuropeo, + CodigoPostal, + Municipio, + CodigoProvincia, + Provincia, + CodigoNacion, + SiglaNacion, + PersonaFisicaJuridica, + TipoDocumentoPersona, + CodigoIva, + Nacion, + Telefono, + Telefono2, + CodigoTransaccion, + CodigoRetencion, + Email1, + iban) + SELECT + IF (@@hostname = 'db', co.companyCode, co.companyCodeTest), + 'C', + c.id, + c.socialName, + c.socialName, + IFNULL(c.street, ''), + c.accountingAccount, + TRIM(IF(cu.code = LEFT(c.fi, 2), MID(c.fi, 3, LENGTH(c.fi)-1), c.fi)), + IF(n.NacionCEE,TRIM(IF(cu.code = LEFT(c.fi, 2), c.fi, CONCAT(cu.code,c.fi))) , ''), + IFNULL(c.postcode, ''), + IFNULL(c.city, ''), + IFNULL(pr.CodigoProvincia, ''), + IFNULL(p.name, ''), + IF(n.SiglaNacion = vCountryCanariasCode COLLATE utf8_general_ci, IF(@isCeutaMelilla := IF(pr.Provincia IN ('CEUTA', 'MELILLA'), TRUE, FALSE), vCountryCeutaMelillaFk, IF (@isCanarias, vCountryCanariasCode, n.CodigoNacion)), n.CodigoNacion), + IF(n.SiglaNacion = vCountryCanariasCode COLLATE utf8_general_ci, IF(@isCeutaMelilla, vCountryCeutaMelillaCode, IF (@isCanarias, vCountryCanariasCode, n.SiglaNacion)), n.SiglaNacion), + IF((c.fi REGEXP '^([[:blank:]]|[[:digit:]])'), 'J','F'), + IF(cu.code IN('ES','EX'), + 1, + IF((cu.isUeeMember AND c.isVies), 2, 4)), + IFNULL(c.taxTypeSageFk,0), + IF(n.SiglaNacion = vCountryCanariasCode COLLATE utf8_general_ci, + IF(@isCeutaMelilla, 'CEUTA Y MELILLA', IF (@isCanarias, 'ISLAS CANARIAS', n.Nacion)), + n.Nacion), + IFNULL(c.phone, ''), + IFNULL(c.mobile, ''), + IFNULL(c.transactionTypeSageFk, 0), + '0', + IFNULL(SUBSTR(c.email, 1, LOCATE(',', CONCAT(c.email, ','))-1), ''), + IFNULL(c.iban, '') + FROM vn.`client` c + JOIN clientLastTwoMonths clm ON clm.clientFk = c.id + JOIN vn.company co ON co.id = clm.companyFk + LEFT JOIN vn.country cu ON cu.id = c.countryFk + LEFT JOIN Naciones n ON n.countryFk = cu.id + LEFT JOIN vn.province p ON p.id = c.provinceFk + LEFT JOIN Provincias pr ON pr.provinceFk = p.id + WHERE c.isRelevant + AND co.id = vCompanyFk + UNION ALL + SELECT IF (@@hostname = 'db', c.companyCode, companyCodeTest), + 'P', + s.id, + s.name, + s.name, + IFNULL(s.street, ''), + s.account, + TRIM(IF(co.code = LEFT(s.nif, 2), MID(s.nif, 3, LENGTH(s.nif) - 1), s.nif)), + IF(n.NacionCEE, TRIM(CONCAT(co.code, IF(co.code = LEFT(s.nif, 2), MID(s.nif, 3, LENGTH(s.nif) - 1), s.nif))), ''), + IFNULL(s.postCode,''), + IFNULL(s.city, ''), + IFNULL(pr.CodigoProvincia, ''), + IFNULL(p.name, ''), + n.CodigoNacion, + n.SiglaNacion COLLATE utf8_general_ci, + IF((s.nif REGEXP '^([[:blank:]]|[[:digit:]])'),'J','F'), + IF(co.country IN ('España', 'España exento'), 1,IF(co.isUeeMember = 1, 2, 4)), + IFNULL(s.taxTypeSageFk, 0), + n.Nacion, + IFNULL(con.Telefono, ''), + IFNULL(con.Movil, ''), + IFNULL(s.transactionTypeSageFk, 0), + IFNULL(s.withholdingSageFk, '0'), + IFNULL(SUBSTR(con.email, 1, (COALESCE(NULLIF(LOCATE(',', con.email), 0), 99) - 1)), ''), + IFNULL(iban, '') + FROM vn.supplier s + JOIN providerLastThreeMonths pl ON pl.supplierFk = s.id + LEFT JOIN vn.country co ON co.id = s.countryFk + LEFT JOIN Naciones n ON n.countryFk = co.id + LEFT JOIN vn.province p ON p.id = s.provinceFk + LEFT JOIN Provincias pr ON pr.provinceFk = p.id + LEFT JOIN vn2008.Relaciones r ON r.Id_Proveedor = s.id + LEFT JOIN vn.supplierAccount sa ON sa.supplierFk = s.id + LEFT JOIN vn2008.Contactos con ON con.Id_Contacto = r.Id_Contacto + JOIN vn.company c ON c.id = pl.companyFk + WHERE c.id = vCompanyFk AND + s.isActive AND + s.nif <> '' + GROUP BY pl.supplierFk, pl.companyFk; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `clientSupplier_add__` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `clientSupplier_add__`(vCompanyFk INT) +BEGIN +/** + * Prepara los datos de clientes y proveedores para exportarlos a Sage + * @vCompanyFk Empresa dela que se quiere trasladar datos + */ + DECLARE vCountryCeutaMelillaFk INT; + DECLARE vCountryCanariasCode, vCountryCeutaMelillaCode VARCHAR(2); + + SELECT SiglaNacion INTO vCountryCanariasCode + FROM Naciones + WHERE Nacion ='ISLAS CANARIAS'; + + SELECT CodigoNacion, SiglaNacion INTO vCountryCeutaMelillaFk, vCountryCeutaMelillaCode + FROM Naciones + WHERE Nacion ='CEUTA Y MELILLA'; + + TRUNCATE TABLE clientesProveedores; + INSERT INTO clientesProveedores (CodigoEmpresa, ClienteOProveedor, @@ -20774,7 +21240,8 @@ BEGIN DECLARE vDone BOOL DEFAULT FALSE; DECLARE vInvoiceFk INT; DECLARE vXDiarioFk INT; - DECLARE vDated DATE; + DECLARE vDatedFrom DATETIME; + DECLARE vDatedTo DATETIME; DECLARE vSerialDua VARCHAR(1) DEFAULT 'D'; DECLARE vAccountVNL VARCHAR(10); DECLARE vAccountTaxOutstanding VARCHAR(10); @@ -20789,13 +21256,15 @@ BEGIN LEFT JOIN vn.invoiceInTax it ON it.invoiceInFk = ii.id WHERE(it.taxTypeSageFk IS NOT NULL OR x.SERIE = vSerialDua COLLATE utf8_general_ci) AND x.enlazadoSage = FALSE - AND x.FECHA >= vDated + AND x.FECHA BETWEEN vDatedFrom AND vDatedTo AND x.empresa_id = vCompanyFk ) sub ON sub.ASIEN = x.ASIEN WHERE x.CLAVE IS NOT NULL; DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; - SELECT CAST(CONCAT(vYear, '-01-01') AS DATE) INTO vDated; + + SELECT CAST(CONCAT(vYear, '-01-01') AS DATETIME), util.dayEnd(CAST(CONCAT(vYear, '-12-31') AS DATE)) + INTO vDatedFrom, vDatedTo; SELECT accountingAccount INTO vAccountVNL FROM vn.`client` @@ -20817,7 +21286,7 @@ BEGIN FROM vn.XDiario x WHERE x.enlazadoSage = FALSE AND x.SUBCTA = vAccountTaxOutstanding COLLATE utf8_general_ci - AND x.FECHA >= vDated + AND x.FECHA BETWEEN vDatedFrom AND vDatedTo )sub ON sub.ASIEN = x.ASIEN WHERE NOT x.CONTRA <=> vAccountVNL; @@ -20833,7 +21302,7 @@ BEGIN IF(c.code = 'EUR', '',c.`code`) currencyFk FROM vn.invoiceIn i JOIN vn.currency c ON c.id = i.currencyFk - WHERE i.bookEntried >= vDated + WHERE i.bookEntried BETWEEN vDatedFrom AND vDatedTo UNION ALL SELECT d.id, d.code, @@ -20946,7 +21415,7 @@ BEGIN WHERE SUBCTA LIKE '472%' AND x.enlazadoSage = FALSE AND x.empresa_id = vCompanyFk - AND x.FECHA >= vDated + AND x.FECHA BETWEEN vDatedFrom AND vDatedTo ) sub ON sub.ASIEN = x.ASIEN WHERE x.SUBCTA LIKE '477%' )sub2 ON sub2.ASIEN = x.ASIEN @@ -21257,7 +21726,8 @@ BEGIN DECLARE vDone BOOL DEFAULT FALSE; DECLARE vInvoiceFk INT; DECLARE vXDiarioFk INT; - DECLARE vDated DATE; + DECLARE vDatedFrom DATETIME; + DECLARE vDatedTo DATETIME; DECLARE vCursor CURSOR FOR SELECT i.id, @@ -21270,15 +21740,16 @@ BEGIN WHERE x.enlazadoSage = FALSE AND x.FACTURA AND x.empresa_id = vCompanyFk - AND x.FECHA >= vDated + AND x.FECHA BETWEEN vDatedFrom AND vDatedTo GROUP BY refFk ) sub ON sub.ASIEN = x.ASIEN GROUP BY refFk )sub2 ON sub2.refFk = i.ref; DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; - - SELECT CAST(CONCAT(vYear, '-01-01') AS DATE) INTO vDated; + + SELECT CAST(CONCAT(vYear, '-01-01') AS DATETIME), util.dayEnd(CAST(CONCAT(vYear, '-12-31') AS DATE)) + INTO vDatedFrom, vDatedTo; OPEN vCursor; @@ -21301,7 +21772,7 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `movContaAdd` */; +/*!50003 DROP PROCEDURE IF EXISTS `movContaAdd__` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -21311,12 +21782,13 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `movContaAdd`() +CREATE DEFINER=`root`@`%` PROCEDURE `movContaAdd__`() BEGIN /* Copia en movConta los asientos de XDiario para que luego los importe el proceso automático que hay en SQL Server */ DECLARE vDated DATE; SELECT CONCAT(YEAR(CURDATE()), "-01-01") INTO vDated; +SELECT "2021-01-01" INTO vDated; TRUNCATE XDiario_movConta_IVA; DELETE FROM movConta WHERE enlazadoSage = FALSE AND Asiento <> 1 ; CALL clientesProveedoresAdd; @@ -21503,7 +21975,7 @@ BEGIN JOIN vn.company c ON c.id = x.empresa_id LEFT JOIN XDiario_movConta_IVA xmi ON xmi.id = x.id AND xmi.moveData > 0 LEFT JOIN (SELECT ASIEN, FECREGCON, FECHA_EX - FROM (SELECT ASIEN, FECREGCON, FECHA_EX + FROM (SELECT DISTINCT ASIEN, FECREGCON, FECHA_EX FROM vn2008.XDiario ORDER BY ASIEN, FECREGCON DESC, FECHA_EX DESC ) sub GROUP BY ASIEN @@ -21855,491 +22327,6 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `movContaAdd__` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_general_ci */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `movContaAdd__`() -BEGIN - - /* Copia en movConta los asientos de XDiario para que luego los importe el proceso automático que hay en SQL Server - * - */ - - DECLARE vMaxAsiento INT; - - SELECT GREATEST(810000,IFNULL(MAX(Asiento),0)) INTO vMaxAsiento - FROM movConta; - - TRUNCATE XDiario_movConta_IVA; - DELETE FROM movConta WHERE enlazadoSage = FALSE ; - - CALL clientesProveedoresAdd; - CALL planCuentasPgcAdd; - CALL XDiario_movConta_IVA_InvoiceOutAdd_Manager; - CALL XDiario_movConta_IVA_InvoiceInAdd_Manager; - INSERT INTO movConta( - TipoEntrada, -- VARCHAR(2) - Ejercicio, -- Año - CodigoEmpresa, -- ENT(2) - Asiento, -- LONG(4), nº ASIENTO - CargoAbono, -- VARCHAR(1) "D" debe ó "H" haber - CodigoCuenta, -- VARCHAR(15) partida contable - Contrapartida, -- VARCHAR(15) partida contable - FechaAsiento, -- FECHA(8) - Comentario, -- VARCHAR(40) - ImporteAsiento, -- DOBLE(19) - NumeroPeriodo, -- ENT(2) "-1" Al informar este valor se calcula automát. A partir de la fecha de asiento - FechaGrabacion, -- FECHA(8) - CodigoDivisa, -- VARCHAR(3) - ImporteCambio, -- DOBLE(19) - ImporteDivisa, -- DOBLE(19) - FactorCambio, -- DOBLE(19) - IdProcesoIME, -- GUID(16) - TipoCarteraIME, -- ENT(2) "0" para que no genere cartera - TipoAnaliticaIME, -- ENT(2) - StatusTraspasadoIME, -- BYTE "0" para dejar como no importado aún - TipoImportacionIME, -- BYTE "0" Alta "1" Baja - Metalico347, -- ENT(2) - /* ESTOS CAMPOS SOLO SE INFORMAN EN EL CASO DE SER FACTURA */ - BaseIva1, -- DOBLE(19) - PorBaseCorrectora1, -- DOBLE(19) - PorIva1, -- DOBLE(19) - CuotaIva1, -- DOBLE(19) - PorRecargoEquivalencia1,-- DOBLE(19) - RecargoEquivalencia1, -- DOBLE(19) - CodigoTransaccion1, -- BYTE "0" Nacional "1" Intracomunitario "2" Extracomunitario - BaseIva2, - PorBaseCorrectora2, - PorIva2, - CuotaIva2, - PorRecargoEquivalencia2, - RecargoEquivalencia2, - CodigoTransaccion2, - BaseIva3, - PorBaseCorrectora3, - PorIva3, - CuotaIva3, - PorRecargoEquivalencia3, - RecargoEquivalencia3, - CodigoTransaccion3, - BaseIva4, - PorBaseCorrectora4, - PorIva4, - CuotaIva4, - PorRecargoEquivalencia4, - RecargoEquivalencia4, - CodigoTransaccion4, - Año, -- ENT(2) - Serie, -- VARCHAR(10) - Factura, -- LONG(4) - SuFacturaNo, -- VARCHAR(40) - FechaFactura, -- FECHA(8) - ImporteFactura, -- DOBLE(19) - TipoFactura, -- VARCHAR(1) "E" / "R" / "I" - CodigoCuentaFactura, -- VARCHAR(15) cuenta del cliente/proveedor - CifDni, -- VARCHAR(13) - Nombre, -- VARCHAR(35) - CodigoRetencion, -- ENT(2) - BaseRetencion, -- DOBLE(19) - PorRetencion, -- DOBLE(19) - ImporteRetencion, -- DOBLE(19) - SiglaNacion, -- VARCHAR(2) "ES" por defecto - EjercicioFactura, -- ENT(2) - FechaOperacion, -- FECHA(8) - Exclusion347, -- ENT(2) - MantenerAsiento, -- BYTE "-1" mantener "0" Sage asigna nuevo - ClaveOperacionFactura_, -- VARCHAR(1) P(4721000011,4721000021)-I(4721000015-4720000005-4720000006)-D (Rectificativas) - TipoRectificativa, -- ENT(2) - FechaFacturaOriginal, -- FECHA(8) - BaseImponibleOriginal, -- DOBLE(19) - CuotaIvaOriginal, -- DOBLE(19) - ClaseAbonoRectificativas,-- ENT(2) - RecargoEquivalenciaOriginal, -- DOBLE(19) */ - LibreA1, - CodigoIva1, -- ENT(6) - CodigoIva2, -- ENT(6) - CodigoIva3, -- ENT(6) - CodigoIva4, -- ENT(6) - Intracomunitaria -- INT(2) - ) - SELECT 'EN' as TipoEntrada, - YEAR(x.FECHA) AS Ejercicio, - IF (@@hostname = 'db', c.companyCode, companyCodeTest) AS CodigoEmpresa, -- ENT(2) c.companyCode AS CodigoEmpresa, - x.ASIEN AS Asiento, -- LONG(4), nº ASIENTO - IF(x.EURODEBE,"D","H") AS CargoAbono, -- VARCHAR(1) "D" debe ó "H" haber - x.SUBCTA AS CodigoCuenta, -- VARCHAR(15) partida contable - x.CONTRA AS Contrapartida, -- VARCHAR(15) partida contable - x.FECHA AS FechaAsiento, -- FECHA(8) - SUBSTRING(x.CONCEPTO, 1, 40) AS Comentario, -- VARCHAR(40) - IF(x.EURODEBE,x.EURODEBE,x.EUROHABER) AS ImporteAsiento, -- DOBLE(19) - MONTH(x.FECHA) AS NumeroPeriodo, -- ENT(2) "-1" Al informar este valor se calcula automát. A partir de la fecha de asiento - IF( sub2.FECREGCON IS NULL, sub2.FECHA_EX, sub2.FECREGCON) FechaGrabacion, -- FECHA(8) - 'EUR' AS CodigoDivisa, -- VARCHAR(3) - x.CAMBIO AS ImporteCambio, -- DOBLE(19) - IFNULL(x.EURODEBE,x.EUROHABER) AS ImporteDivisa, -- DOBLE(19) - IF(x.CAMBIO,1,0) AS FactorCambio, -- DOBLE(19) - NULL AS IdProcesoIME, -- GUID(16) - 0 AS TipoCarteraIME, -- ENT(2) "0" para que no genere cartera - 0 AS TipoAnaliticaIME, -- ENT(2) - 0 AS StatusTraspasadoIME, -- BYTE "0" para dejar como no importado aún - 0 AS TipoImportacionIME, -- BYTE "0" Alta "1" Baja - x.METAL as Metalico347, - /* ESTOS CAMPOS SOLO SE INFORMAN EN EL CASO DE SER FACTURA */ - xmi.BaseIva1, -- DOBLE(19) - xmi.PorBaseCorrectora1, -- DOBLE(19) - xmi.PorIva1, -- DOBLE(19) - xmi.CuotaIva1, -- DOBLE(19) - xmi.PorRecargoEquivalencia1,-- DOBLE(19) - xmi.RecargoEquivalencia1, -- DOBLE(19) - xmi.CodigoTransaccion1, -- BYTE "0" Nacional "1" Intracomunitario "2" Extracomunitario - xmi.BaseIva2, - xmi.PorBaseCorrectora2, - xmi.PorIva2, - xmi.CuotaIva2, - xmi.PorRecargoEquivalencia2, - xmi.RecargoEquivalencia2, - xmi.CodigoTransaccion2, - xmi.BaseIva3, - xmi.PorBaseCorrectora3, - xmi.PorIva3, - xmi.CuotaIva3, - xmi.PorRecargoEquivalencia3, - xmi.RecargoEquivalencia3, - xmi.CodigoTransaccion3, - xmi.BaseIva4, - xmi.PorBaseCorrectora4, - xmi.PorIva4, - xmi.CuotaIva4, - xmi.PorRecargoEquivalencia4, - xmi.RecargoEquivalencia4, - xmi.CodigoTransaccion4, - xmi.Año, -- ENT(2) - xmi.Serie, -- VARCHAR(10) - xmi.Factura, -- LONG(4) - xmi.SuFacturaNo, -- VARCHAR(40) - xmi.FechaFactura, -- FECHA(8) - xmi.ImporteFactura, -- DOBLE(19) - xmi.TipoFactura, -- VARCHAR(1) "E" / "R" - xmi.CodigoCuentaFactura, -- VARCHAR(15) cuenta del cliente/proveedor - xmi.CifDni, -- VARCHAR(13) - xmi.Nombre, -- VARCHAR(35) - xmi.CodigoRetencion, -- ENT(2) - xmi.BaseRetencion, -- DOBLE(19) - xmi.PorRetencion, -- DOBLE(19) - xmi.ImporteRetencion, -- DOBLE(19) - xmi.SiglaNacion, -- VARCHAR(2) "ES" por defecto - xmi.EjercicioFactura, -- ENT(2) - xmi.FechaOperacion, -- FECHA(8) - xmi.Exclusion347, -- ENT(2) - 1, -- xmi.MantenerAsiento BYTE "-1" mantener "0" Sage asigna nuevo - xmi.ClaveOperacionFactura, -- VARCHAR(1) - xmi.TipoRectificativa, -- ENT(2) - xmi.FechaFacturaOriginal, -- FECHA(8) - xmi.BaseImponibleOriginal, -- DOBLE(19) - xmi.CuotaIvaOriginal, -- DOBLE(19) - xmi.ClaseAbonoRectificativas,-- ENT(2) - xmi.RecargoEquivalenciaOriginal,-- DOBLE(19) */ - xmi.LibreA1, - xmi.CodigoIva1, -- ENT(6) - xmi.CodigoIva2, -- ENT(6) - xmi.CodigoIva3, -- ENT(6) - xmi.CodigoIva4, -- ENT(6) - xmi.Intracomunitaria -- TINYINT(1) - FROM vn2008.XDiario x - JOIN vn.company c ON c.id = x.empresa_id - LEFT JOIN XDiario_movConta_IVA xmi ON xmi.id = x.id - LEFT JOIN (SELECT ASIEN, FECREGCON, FECHA_EX - FROM (SELECT ASIEN, FECREGCON, FECHA_EX - FROM vn2008.XDiario - ORDER BY ASIEN, FECREGCON DESC, FECHA_EX DESC - ) sub GROUP BY ASIEN - )sub2 ON sub2.ASIEN = x.ASIEN - WHERE x.enlazadoSage = 0 - AND c.companyCode; - - - --- Prepara Metálicos - - UPDATE sage.movConta m - JOIN (SELECT Asiento, SUBSTR(c.socialName,1,35) Nombre, c.fi, n.SiglaNacion - FROM sage.movConta m - JOIN vn.client c ON c.id = m.CodigoCuenta-4300000000 - LEFT JOIN Naciones n ON n.countryFk = c.countryFk - WHERE Metalico347 = TRUE AND - CargoAbono = "H" - ) AS sub ON m.Asiento = sub.Asiento - SET - m.Metalico347 = TRUE, - m.Contrapartida = "", - m.TipoFactura = "I", - m.CifDni = sub.fi , - m.Nombre = sub.Nombre, - m.SiglaNacion = sub.SiglaNacion - WHERE m.enlazadoSage = FALSE; - --- Elimina cuentas de cliente/proveedor que no se utilizarán en la importación - DELETE cp - FROM clientesProveedores cp - JOIN (SELECT cp.codigoCuenta - FROM clientesProveedores cp - LEFT JOIN movConta mc ON mc.codigoCuenta = cp.codigoCuenta AND mc.enlazadoSage = FALSE - WHERE mc.codigoCuenta IS NULL - GROUP BY cp.codigoCuenta - ) sub ON sub.codigoCuenta = cp.codigoCuenta ; - --- Elimina cuentas contables que no se utilizarán en la importación - DELETE pc - FROM planCuentasPGC pc - JOIN ( SELECT pc.codigoCuenta - FROM planCuentasPGC pc - LEFT JOIN movConta mc ON mc.codigoCuenta = pc.codigoCuenta AND mc.enlazadoSage = FALSE - WHERE mc.codigoCuenta IS NULL - GROUP BY pc.codigoCuenta - ) sub ON sub.codigoCuenta = pc.codigoCuenta ; - - - - -/*UPDATE sage.movConta m - JOIN (SELECT DISTINCT(Asiento) - FROM sage.movConta - WHERE Metalico347 = TRUE - ) AS sub ON m.Asiento = sub.Asiento -SET - m.Metalico347 = TRUE, - m.Contrapartida = "", - m.TipoFactura = "I";*/ - - - -/*-- Actualiza las facturas DUA para excluirlas del 347 y marcarlas como intracomunitarias -/*UPDATE sage.movConta mc - SET - mc.Intracomunitaria = 1, - mc.Exclusion347 = 1 -WHERE - mc.CodigoCuenta = '4700000999'; */ - - --- MARCAR EN CASO DE SER INTRACOMUNITARIA -/* -UPDATE sage.movConta mc - SET - mc.Intracomunitaria = 1 -WHERE - mc.CodigoTransaccion1 IN (20,29); -*/ - - - -- LAS FACTURAS RTECTIFICATIVAS QUE TIENEN CUENTA DE IVA 477.2 SALE CON T.T. 1, TODAS ESTAS FACTURAS DEBEN DE TENER T.T. 15 - - /*UPDATE sage.movConta mc - JOIN - (SELECT - Asiento - FROM - sage.movConta - WHERE - CodigoCuenta = 4770000002) sub ON sub.Asiento = mc.Asiento -SET - CodigoTransaccion1 = CASE - WHEN CodigoTransaccion1 = 1 THEN 15 - ELSE CodigoTransaccion1 - END, - CodigoTransaccion2 = CASE - WHEN CodigoTransaccion2 = 1 THEN 15 - ELSE CodigoTransaccion2 - END, - CodigoTransaccion3 = CASE - WHEN CodigoTransaccion3 = 1 THEN 15 - ELSE CodigoTransaccion3 - END, - CodigoTransaccion4 = CASE - WHEN CodigoTransaccion4 = 1 THEN 15 - ELSE CodigoTransaccion4 - END -WHERE - serie = 'R'; - -*/ - -/* -Nombre Tipo Longitud Descripción campo / Valor por defecto -MovPosicion Guid contador 16 Automático, no informar -Ejercicio Entero 2 -1 -- Al informar este valor se calcula automát. A partir de la fecha de asiento -CodigoEmpresa Entero 2 Empresa de Sage 200c donde va destinado el asiento -Asiento Entero Largo 4 Número de asiento -CargoAbono Texto 1 "D" - Debe / "H" - Haber -CodigoCuenta Texto 15 Cuenta contable del movimiento -Contrapartida Texto 15 Es informativo, no es necesario informarlo -FechaAsiento Fecha 8 Fecha del asiento -TipoDocumento Texto 6 -DocumentoConta Texto 9 -Comentario Texto 40 Comentario del asiento -ImporteAsiento Doble 19 Importe del movimiento -CodigoDiario Entero 2 -CodigoCanal Texto 10 Centro coste analítico (no necesario informar) -CodigoActividad Texto 1 -FechaVencimiento Fecha 8 Si se tienen que generar efectos, será la fecha de vto. Del efecto. No informar -NumeroPeriodo Entero 2 -1 -- Al informar este valor se calcula automát. A partir de la fecha de asiento -CodigoUsuario Entero 2 -FechaGrabacion Fecha 8 -TipoEntrada Texto 2 -CodigoDepartamento Texto 10 Centro coste analítico (no necesario informar) -CodigoSeccion Texto 10 Centro coste analítico (no necesario informar) -CodigoDivisa Texto 3 -ImporteCambio Doble 19 -ImporteDivisa Doble 19 -FactorCambio Doble 19 -CodigoProyecto Texto 10 Centro coste analítico (no necesario informar) -LibreN1 Entero Largo 4 Campo libre numérico -LibreN2 Entero Largo 4 Campo libre numérico -LibreA1 Texto 15 Campo libre alfanumérico -LibreA2 Texto 15 Campo libre alfanumérico -IdDelegacion Texto 10 Centro coste analítico (no necesario informar) -OrdenMovimientos Contador 4 Número de orden de cada movimiento dentro de un mismo asiento, autonumerar para cada asiento -MovCartera Guid 16 -IdProcesoIME Guid 16 guid igual para todos los registros que correspondan a una misma importación. -TipoCarteraIME Entero 2 0 - Para que no genere cartera -TipoAnaliticaIME Entero 2 -StatusTraspasadoIME Byte 1 0 - Para que quede marcado el movimiento como no importado todavía. -TipoImportacionIME Byte 1 0 - Alta -BaseIva1 Doble 19 Base para el IVA 1 (idéntico para cada posible IVA hasta el 4) (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -PorBaseCorrectora1 Doble 19 Base correctora (en caso de que la haya) para el IVA 1 (idéntico para cada posible IVA hasta el 4) (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -PorIva1 Doble 19 Porcentaje IVA 1 (idéntico para cada posible IVA hasta el 4) (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -CuotaIva1 Doble 19 Cuota IVA 1 (idéntico para cada posible IVA hasta el 4) (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -PorRecargoEquivalencia1 Doble 19 Si hay recargo - Porcentaje de recargo para el IVA 1 (idéntico para cada posible IVA hasta el 4) (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -RecargoEquivalencia1 Doble 19 Si hay recargo - Importe de Recargo para el IVA 1 (idéntico para cada posible IVA hasta el 4) (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -CodigoTransaccion1 Byte 1 Ver con dpto. de contabilidad - Depende de la naturaleza del asiento (Nacional, Intracoumunitario, etc…) (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -BaseIva2 Doble 19 0 -PorBaseCorrectora2 Doble 19 0 -PorIva2 Doble 19 0 -CuotaIva2 Doble 19 0 -PorRecargoEquivalencia2 Doble 19 0 -RecargoEquivalencia2 Doble 19 0 -CodigoTransaccion2 Byte 1 0 -BaseIva3 Doble 19 0 -PorBaseCorrectora3 Doble 19 0 -PorIva3 Doble 19 0 -CuotaIva3 Doble 19 0 -PorRecargoEquivalencia3 Doble 19 0 -RecargoEquivalencia3 Doble 19 0 -CodigoTransaccion3 Byte 1 0 -BaseIva4 Doble 19 0 -PorBaseCorrectora4 Doble 19 0 -PorIva4 Doble 19 0 -CuotaIva4 Doble 19 0 -PorRecargoEquivalencia4 Doble 19 0 -RecargoEquivalencia4 Doble 19 0 -CodigoTransaccion4 Byte 1 0 -Año Entero 2 Ejercicio de la factura en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -Serie Texto 10 Serie de la factura en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -Factura Entero Largo 4 Número de la factura en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -SuFacturaNo Texto 40 Número de la factura del proveedor para factura recibidas, en el caso de que el asiento sea de una factura. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -FechaFactura Fecha 8 Fecha de la factura en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -ImporteFactura Doble 19 Importe de la factura en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -TipoFactura Texto 1 "E" - Factura emitida / "R" - Factura Recibida - en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -CodigoCuentaFactura Texto 15 Cuenta contable del cliente / proveedor en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -CifDni Texto 13 CIF del cliente / proveedor en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -Nombre Texto 35 Nombre del cliente / proveedor en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -CodigoRetencion Entero 2 Código de retención de la factura en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -BaseRetencion Doble 19 Base de retención de la factura en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -PorRetencion Doble 19 Porcentaje de retención de la factura en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -ImporteRetencion Doble 19 Importe de retención de la factura en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -AbonoIva Entero 2 0 -CodigoActividadF Texto 1 ('') -Intracomunitaria Entero 2 0 -CodigoTerritorio Entero 2 0 -SiglaNacion Texto 2 Sigla de la nación de la factura en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -RetencionInformativa Entero 2 0 -EjercicioFacturaOriginal Entero 2 0 -SerieFacturaOriginal Texto 10 ('') -NumeroFacturaOriginal Entero Largo 4 0 -EjercicioFactura Entero 2 Ejercicio de la factura en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -CobroPagoRetencion Texto 1 ('') -FechaOperacion Fecha 8 Normalmente Fecha Factura en el caso de que sea un asiento de facturas. (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -Exclusion347 Entero 2 0 -MovIdentificadorIME Guid contador 16 (newid()) -Previsiones Texto 1 ('') -MantenerAsiento Byte 1 -1 si se quiere mantener el número de asiento que se informa en la importación o "0" si se quiere que se asigne automáticamente el asiento en Sage 200c -OrdenMovIME Entero 2 0 -Metalico347 Entero 2 0 -ClaveOperacionFactura_ Texto 1 Ver con dpto. de contabilidad - Depende de la naturaleza del asiento (Nacional, Intracoumunitario, etc…) (Solamente se informa en el movimiento de la factura - cuenta cliente / proveedor) -SerieAgrupacion_ Texto 10 ('') -NumeroFacturaInicial_ Entero Largo 4 0 -NumeroFacturaFinal_ Entero Largo 4 0 -IdAsientoExterno Texto 50 ('') -IdDiarioExterno Texto 10 ('') -IdFacturaExterno Texto 50 ('') -IdMovimiento Texto 40 ('') -IdCuadre Entero 2 ((0)) -FechaCuadre Fecha 8 (getdate()) -TipoCuadre Texto 4 ('') -AgrupacionCuadre Entero Largo 4 ((0)) -StatusSaldo Entero 2 ((0)) -StatusConciliacion Entero 2 ((0)) -CodigoConciliacion Entero Largo 4 ((0)) -FechaConciliacion Fecha 8 -TipoConciliacion Entero 2 ((0)) -IndicadorContaBanco Texto 1 ('') -Descripcion3 Texto 40 ('') -Descripcion4 Texto 40 ('') -Descripcion5 Texto 40 ('') -Descripcion6 Texto 40 ('') -Descripcion7 Texto 40 ('') -Descripcion8 Texto 50 ('') -Descripcion9 Texto 50 ('') -Descripcion2 Texto 250 ('') -Descripcion1 Texto 250 ('') -Punteo1 Entero 2 ((0)) -Punteo9 Entero 2 ((0)) -Punteo8 Entero 2 ((0)) -Punteo7 Entero 2 ((0)) -Punteo6 Entero 2 ((0)) -Punteo5 Entero 2 ((0)) -Punteo4 Entero 2 ((0)) -Punteo3 Entero 2 ((0)) -Punteo2 Entero 2 ((0)) -CodigoIva1 Entero 2 ((0)) -CodigoIva2 Entero 2 ((0)) -CodigoIva3 Entero 2 ((0)) -CodigoIva4 Entero 2 ((0)) -CriterioIva Byte 1 ((0)) -FechaMaxVencimiento Fecha 8 -TipoCriterioCaja Byte 1 ((0)) -MovFacturaOrigenIME Texto 50 ('') -IdFacturaExternoFinal Texto 50 ('') -IdFacturaExternoInicial Texto 50 ('') -IdFacturaExternoOriginal Texto 50 ('') -NumFacturasExternoAgrupacion Entero Largo 4 ((0)) -CodigoMedioCobro Texto 1 ('') -MedioCobro Texto 31 ('') -IvaDeducible1 Entero 2 ((-1)) -IvaDeducible2 Entero 2 ((-1)) -IvaDeducible3 Entero 2 ((-1)) -IvaDeducible4 Entero 2 ((-1)) -TipoRectificativa Entero 2 ((0)) -FechaFacturaOriginal Fecha 8 -BaseImponibleOriginal Doble 19 ((0)) -CuotaIvaOriginal Doble 19 ((0)) -ClaseAbonoRectificativas Entero 2 ((0)) -RecargoEquivalenciaOriginal Doble 19 ((0)) -ObjetoFactura Texto 500 ('') -*/ -END ;; -DELIMITER ; -/*!50003 SET sql_mode = @saved_sql_mode */ ; -/*!50003 SET character_set_client = @saved_cs_client */ ; -/*!50003 SET character_set_results = @saved_cs_results */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 DROP PROCEDURE IF EXISTS `pgc_add` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -22394,7 +22381,7 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `planCuentasPgcAdd` */; +/*!50003 DROP PROCEDURE IF EXISTS `planCuentasPgcAdd__` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -22404,7 +22391,7 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `planCuentasPgcAdd`() +CREATE DEFINER=`root`@`%` PROCEDURE `planCuentasPgcAdd__`() BEGIN TRUNCATE TABLE planCuentasPGC; @@ -22459,7 +22446,7 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `XDiario_movConta_IVA_InvoiceInAdd` */; +/*!50003 DROP PROCEDURE IF EXISTS `XDiario_movConta_IVA_InvoiceInAdd_Manager__` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -22469,554 +22456,7 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `XDiario_movConta_IVA_InvoiceInAdd`(IN vInvoiceInFk INT, IN vXDiarioId INT) -BEGIN - - DECLARE vDone BOOL DEFAULT FALSE; - DECLARE vBase DOUBLE; - DECLARE vVat DOUBLE; - DECLARE vRate DOUBLE; - DECLARE vTransactionCode INT; - DECLARE vCounter INT DEFAULT 0; - DECLARE vTransactionCodeOld INT; - DECLARE vTaxCode INT; - DECLARE vTaxCodeOld INT; - DECLARE vOperationCode VARCHAR(1); - DECLARE vIsIntracommunity BOOL DEFAULT FALSE; - DECLARE vDuaExcluded INT; - - DECLARE rs CURSOR FOR -- IVA - SELECT it.taxableBase BASEEURO, - CAST((( it.taxableBase / 100) * t.PorcentajeIva) AS DECIMAL (10,2)) vat, - t.PorcentajeIva rate, - it.transactionTypeSageFk transactionCode, - it.taxTypeSageFk taxCode, - t.isIntracommunity, - tt.ClaveOperacionDefecto operationCode, - id.id - FROM vn.invoiceIn i - JOIN vn.invoiceInTax it ON it.InvoiceInFk = i.id - JOIN TiposIva t ON t.CodigoIva = it.taxTypeSageFk - JOIN TiposTransacciones tt ON tt.CodigoTransaccion = it.transactionTypeSageFk - LEFT JOIN tmp.invoiceDua id ON id.id = vXDiarioId - WHERE i.id = vInvoiceInFk - AND i.id> 70000; -- los DUAS no son vInvoiceInFk, pero se pasan en el mismo parametro comparten id en tablas distintas de InvoiceIN (100000) dua(20000) - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; - - DELETE FROM XDiario_movConta_IVA - WHERE id = vXDiarioId; - - INSERT INTO XDiario_movConta_IVA(id, LibreA1) - VALUES (vXDiarioId, vInvoiceInFk); - - OPEN rs; - FETCH rs INTO vBase, - vVat, - vRate, - vTransactionCode, - vTaxCode, - vIsIntracommunity, - vOperationCode, - vDuaExcluded; - - SET vTransactionCodeOld=vTransactionCode; - SET vTaxCodeOld=vTaxCode; - - WHILE NOT vDone DO - IF vOperationCode IS NOT NULL THEN - UPDATE XDiario_movConta_IVA - SET ClaveOperacionFactura = vOperationCode - WHERE id = vXDiarioId; - END IF; - - IF vTransactionCode IS NULL THEN - SET vTransactionCode = vTransactionCodeOld; - END IF; - - IF vTaxCodeOld IS NULL THEN - SET vTaxCode = vTaxCodeOld; - END IF; - - SET vCounter = vCounter + 1; - CASE vCounter - WHEN 1 THEN - UPDATE XDiario_movConta_IVA - SET BaseIva1 = vBase, - PorIva1 = vRate, - CuotaIva1 = vVat, - CodigoTransaccion1 = vTransactionCode, - CodigoIva1 = vTaxCode - WHERE id = vXDiarioId; - WHEN 2 THEN - UPDATE XDiario_movConta_IVA - SET BaseIva2 = vBase, - PorIva2 = vRate, - CuotaIva2 = vVat, - CodigoTransaccion2 = vTransactionCode, - CodigoIva2 = vTaxCode - WHERE id = vXDiarioId; - WHEN 3 THEN - UPDATE XDiario_movConta_IVA - SET BaseIva3 = vBase, - PorIva3 = vRate, - CuotaIva3 = vVat, - CodigoTransaccion3 = vTransactionCode, - CodigoIva3 = vTaxCode - WHERE id = vXDiarioId; - WHEN 4 THEN - UPDATE XDiario_movConta_IVA - SET BaseIva4 = vBase, - PorIva4 = vRate, - CuotaIva4 = vVat, - CodigoTransaccion4 = vTransactionCode, - CodigoIva4 = vTaxCode - WHERE id = vXDiarioId; - ELSE - SELECT vXDiarioId INTO vXDiarioId; - END CASE; - - IF vIsIntracommunity THEN - UPDATE XDiario_movConta_IVA - SET Intracomunitaria = TRUE - WHERE id = vXDiarioId; - END IF; - - SET vTransactionCodeOld=vTransactionCode; - SET vTaxCodeOld=vTaxCode; - - FETCH rs INTO vBase, - vVat, - vRate, - vTransactionCode, - vTaxCode, - vIsIntracommunity, - vOperationCode, - vDuaExcluded; - END WHILE; - CLOSE rs; - - UPDATE XDiario_movConta_IVA xmi - JOIN tmp.invoiceInList ii ON ii.id = vInvoiceInFk - JOIN vn2008.XDiario x ON x.id = xmi.id - LEFT JOIN tmp.invoiceDua id ON id.id = xmi.id - JOIN vn.supplier s ON s.id = ii.supplierFk - JOIN Naciones n ON n.countryFk = s.countryFk - SET xmi.CodigoDivisa = ii.currencyFk, - xmi.Año = YEAR(ii.issued), - xmi.Serie = ii.serial, - xmi.Factura = ii.serialNumber, -- x.FACTURA, DUAS¿? - xmi.FechaFactura = ii.issued, - xmi.ImporteFactura = IFNULL(xmi.BaseIva1, 0) + IFNULL(xmi.CuotaIva1, 0) + - IFNULL(xmi.BaseIva2, 0) + IFNULL(xmi.CuotaIva2, 0) + - IFNULL(xmi.BaseIva3, 0) + IFNULL(xmi.CuotaIva3, 0) + - IFNULL(xmi.BaseIva4, 0) + IFNULL(xmi.CuotaIva4, 0), - xmi.TipoFactura = IF(id.id,IF( ii.serial = 'D', 'R','I'), 'R'), -- MARCAR I para informativa - xmi.CodigoCuentaFactura = x.SUBCTA, - xmi.CifDni = IF(LEFT(TRIM(s.nif),2) = n.SiglaNacion, SUBSTRING(TRIM(s.nif),3) ,s.nif), - xmi.Nombre = s.name, - xmi.SiglaNacion = n.SiglaNacion, - xmi.EjercicioFactura = YEAR(ii.issued), - xmi.FechaOperacion = ii.issued, - xmi.MantenerAsiento = TRUE, - xmi.SuFacturaNo = ii.supplierRef, - xmi.IvaDeducible1 = IF(id.id, FALSE, IF(IFNULL(xmi.BaseIva1, FALSE) = FALSE, FALSE, ii.isVatDeductible)), - xmi.IvaDeducible2 = IF(id.id, FALSE, IF(IFNULL(xmi.BaseIva2, FALSE) = FALSE, FALSE, ii.isVatDeductible)), - xmi.IvaDeducible3 = IF(id.id, FALSE, IF(IFNULL(xmi.BaseIva3, FALSE) = FALSE, FALSE, ii.isVatDeductible)), - xmi.IvaDeducible4 = IF(id.id, FALSE, IF(IFNULL(xmi.BaseIva4, FALSE) = FALSE, FALSE, ii.isVatDeductible)), - xmi.FechaFacturaOriginal = x.FECHA_EX - WHERE xmi.id = vXDiarioId; - - -- RETENCIONES - - UPDATE XDiario_movConta_IVA xmi - JOIN vn.invoiceIn ii ON ii.id = vInvoiceInFk - JOIN vn2008.XDiario x ON x.id = xmi.id - JOIN vn.supplier s ON s.id = supplierFk - JOIN vn.invoiceInTax iit ON iit.invoiceInFk = ii.id - JOIN TiposRetencion t ON t.CodigoRetencion = ii.withholdingSageFk - JOIN (SELECT SUM(BASEEURO) taxableBase, SUM(EURODEBE) taxBase - FROM vn.XDiario - WHERE BASEEURO <> 0 AND ASIEN = (SELECT ASIEN FROM vn.XDiario WHERE id = vXDiarioId) - )sub - SET xmi.CodigoRetencion = t.CodigoRetencion, - xmi.ClaveOperacionFactura = IF( t.Retencion = 'ARRENDAMIENTO Y SUBARRENDAMIENTO', 'R', xmi.ClaveOperacionFactura), - xmi.BaseRetencion = IF (t.CodigoRetencion = 2, sub.taxableBase + sub.taxBase, sub.taxableBase), - xmi.PorRetencion = t.PorcentajeRetencion, - xmi.ImporteRetencion = iit.taxableBase * - 1 - WHERE xmi.id = vXDiarioId AND iit.expenceFk = 4751000000; - -END ;; -DELIMITER ; -/*!50003 SET sql_mode = @saved_sql_mode */ ; -/*!50003 SET character_set_client = @saved_cs_client */ ; -/*!50003 SET character_set_results = @saved_cs_results */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `XDiario_movConta_IVA_InvoiceInAddTest` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_general_ci */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `XDiario_movConta_IVA_InvoiceInAddTest`( - IN vInvoiceInFk INT, IN vXDiarioId INT) -BEGIN -/* - DECLARE done BOOL DEFAULT FALSE; - DECLARE vBase DOUBLE; - DECLARE vVat DOUBLE; - DECLARE vRate DOUBLE; - DECLARE vTransactionCode INT; - DECLARE vCounter INT DEFAULT 0; - - -- IVA - DECLARE rs CURSOR FOR - SELECT - x.BASEEURO, - x.EURODEBE vat, - IFNULL(tc2.rate,tc1.rate), - IFNULL(tc2.transactionCode,tc1.transactionCode) - FROM vn.invoiceInTax iit - JOIN vn.taxCode tc1 ON tc1.id = iit.taxCodeFk - JOIN vn2008.XDiario x ON x.ASIEN = (SELECT ASIEN FROM vn2008.XDiario WHERE id = vXDiarioId) - LEFT JOIN vn.invoiceInEntry iie ON iie.invoiceInFk = iit.invoiceInFk - LEFT JOIN vn.invoiceInIntrastat iii ON iii.invoiceInFk = iie.invoiceInAwbFk - LEFT JOIN vn.intrastat i ON i.id = iii.intrastatFk - LEFT JOIN vn.taxCode tc2 ON tc2.id = i.taxCodeFk - WHERE iit.invoiceInFk = vInvoiceInFk - AND iit.taxableBase <> 0 AND x.BASEEURO AND x.IVA = IFNULL(tc2.rate,tc1.rate) - AND x.CLAVE = vInvoiceInFk - GROUP BY x.id; - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; - - DELETE FROM XDiario_movConta_IVA - WHERE id = vXDiarioId; - - INSERT INTO XDiario_movConta_IVA(id, LibreA1) - VALUES (vXDiarioId, vInvoiceInFk); - - OPEN rs; - - FETCH rs INTO vBase, - vVat, - vRate, - vTransactionCode; - - WHILE NOT done DO - - SET vCounter = vCounter + 1; - - CASE vCounter - - WHEN 1 THEN - UPDATE XDiario_movConta_IVA - SET BaseIva1 = vBase, - PorIva1 = vVat, - CuotaIva1 = vRate, - CodigoTransaccion1 = vTransactionCode - WHERE id = vXDiarioId; - - WHEN 2 THEN - UPDATE XDiario_movConta_IVA - SET BaseIva2 = vBase, - PorIva2 = vVat, - CuotaIva2 = vRate, - CodigoTransaccion2 = vTransactionCode - WHERE id = vXDiarioId; - - - WHEN 3 THEN - UPDATE XDiario_movConta_IVA - SET BaseIva3 = vBase, - PorIva3 = vVat, - CuotaIva3 = vRate, - CodigoTransaccion3 = vTransactionCode - WHERE id = vXDiarioId; - - WHEN 4 THEN - UPDATE XDiario_movConta_IVA - SET BaseIva4 = vBase, - PorIva4 = vVat, - CuotaIva4 = vRate, - CodigoTransaccion4 = vTransactionCode - WHERE id = vXDiarioId; - - END CASE; - - FETCH rs INTO vBase, - vVat, - vRate, - vTransactionCode; - END WHILE; - - CLOSE rs; - - -- OTROS CAMPOS RELATIVOS A LAS FACTURAS - UPDATE XDiario_movConta_IVA xmi - JOIN vn.invoiceIn ii ON ii.id = vInvoiceInFk - JOIN vn2008.XDiario x ON x.id = xmi.id - LEFT JOIN vn.invoiceInTax iit ON iit.invoiceInFk = ii.id - LEFT JOIN vn.taxCode tc ON iit.taxCodeFk = tc.id - JOIN vn.invoiceInSerial iis ON iis.code = ii.serial - JOIN vn.taxArea ta ON ta.code = iis.taxAreaFk - JOIN vn.supplier s ON s.id = ii.supplierFk - SET xmi.Año = YEAR(ii.issued), - xmi.Serie = ii.serial, - xmi.Factura = supplierRef, - xmi.FechaFactura = ii.issued, - xmi.ImporteFactura = BaseIva1 + CuotaIva1 + BaseIva2 + CuotaIva2 + BaseIva3 + CuotaIva3 + BaseIva4 + CuotaIva4, - xmi.TipoFactura = 'R', - xmi.CodigoCuentaFactura = x.SUBCTA, - xmi.CifDni = s.nif, - xmi.Nombre = s.name, - xmi.SiglaNacion = 'ES', - xmi.EjercicioFactura = YEAR(ii.issued), - xmi.FechaOperacion = ii.issued, - xmi.MantenerAsiento = TRUE, - xmi.ClaveOperacionFactura = ta.ClaveOperacionFactura, - xmi.SuFacturaNo = ii.supplierRef - - WHERE xmi.id = vXDiarioId; - - -- RETENCIONES - UPDATE XDiario_movConta_IVA xmi - JOIN vn.invoiceIn ii ON ii.id = vInvoiceInFk - JOIN vn2008.XDiario x ON x.id = xmi.id - JOIN vn.supplier s ON s.id = supplierFk - JOIN vn.invoiceInTax iit ON iit.invoiceInFk = ii.id - JOIN vn.taxCode tc ON tc.id = iit.taxCodeFk - SET xmi.CodigoRetencion = - CASE - WHEN s.account LIKE '_____4____' THEN 2 - WHEN s.account LIKE '_____3____' AND ii.cplusTrascendency472Fk = 1 THEN 18 - WHEN s.account LIKE '_____3____'AND ii.cplusTrascendency472Fk = 1 THEN 19 - END, - xmi.BaseRetencion = iit.taxableBase, - xmi.PorRetencion = tc.rate, - xmi.ImporteRetencion = iit.taxableBase * (tc.rate / 100) - WHERE xmi.id = vXDiarioId AND iit.taxableBase < 0 AND s.account LIKE '_____4____'; -*/ - -END ;; -DELIMITER ; -/*!50003 SET sql_mode = @saved_sql_mode */ ; -/*!50003 SET character_set_client = @saved_cs_client */ ; -/*!50003 SET character_set_results = @saved_cs_results */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `XDiario_movConta_IVA_InvoiceInAdd_` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_general_ci */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `XDiario_movConta_IVA_InvoiceInAdd_`(IN vInvoiceInFk INT, IN vXDiarioId INT) -BEGIN - - DECLARE vDone BOOL DEFAULT FALSE; - DECLARE vBase DOUBLE; - DECLARE vVat DOUBLE; - DECLARE vRate DOUBLE; - DECLARE vTransactionCode INT; - DECLARE vCounter INT DEFAULT 0; - DECLARE vTransactionCodeOld INT; - DECLARE vTaxCode INT; - DECLARE vTaxCodeOld INT; - DECLARE vOperationCode VARCHAR(1); - DECLARE vIsIntracommunity BOOL DEFAULT FALSE; - DECLARE vDuaExcluded INT; - - DECLARE rs CURSOR FOR -- IVA - SELECT it.taxableBase BASEEURO, - ( it.taxableBase/100) * t.PorcentajeIva vat, - t.PorcentajeIva rate, - i. transactionTypeSageFk transactionCode, - it.taxTypeSageFk taxCode, - t.isIntracommunity, - tt.ClaveOperacionDefecto operationCode, - id.id - FROM vn.invoiceIn i - JOIN vn.invoiceInTax it ON it.InvoiceInFk = i.id - JOIN TiposIva t ON t.CodigoIva = it.taxTypeSageFk - JOIN TiposTransacciones tt ON tt.CodigoTransaccion = i.transactionTypeSageFk - LEFT JOIN tmp.invoiceDua id ON id.id = vXDiarioId - WHERE i.id = vInvoiceInFk; - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; - - DELETE FROM XDiario_movConta_IVA - WHERE id = vXDiarioId; - - OPEN rs; - FETCH rs INTO vBase, - vVat, - vRate, - vTransactionCode, - vTaxCode, - vIsIntracommunity, - vOperationCode, - vDuaExcluded; - - SET vTransactionCodeOld=vTransactionCode; - SET vTaxCodeOld=vTaxCode; - - IF vDuaExcluded IS NULL THEN - - WHILE NOT vDone DO - IF vOperationCode IS NOT NULL THEN - UPDATE XDiario_movConta_IVA - SET ClaveOperacionFactura = vOperationCode - WHERE id = vXDiarioId; - END IF; - - IF vTransactionCode IS NULL THEN - SET vTransactionCode = vTransactionCodeOld; - END IF; - - IF vTaxCodeOld IS NULL THEN - SET vTaxCode = vTaxCodeOld; - END IF; - - SET vCounter = vCounter + 1; - - CASE vCounter - WHEN 1 THEN - INSERT INTO XDiario_movConta_IVA(id, LibreA1, BaseIva1 , PorIva1 , CuotaIva1, CodigoTransaccion1, CodigoIva1) - VALUES (vXDiarioId, vInvoiceInFk,vBase, vRate, vVat, vTransactionCode, vTaxCode); - WHEN 2 THEN - UPDATE XDiario_movConta_IVA - SET BaseIva2 = vBase, - PorIva2 = vRate, - CuotaIva2 = vVat, - CodigoTransaccion2 = vTransactionCode, - CodigoIva2 = vTaxCode - WHERE id = vXDiarioId; - WHEN 3 THEN - UPDATE XDiario_movConta_IVA - SET BaseIva3 = vBase, - PorIva3 = vRate, - CuotaIva3 = vVat, - CodigoTransaccion3 = vTransactionCode, - CodigoIva3 = vTaxCode - WHERE id = vXDiarioId; - WHEN 4 THEN - UPDATE XDiario_movConta_IVA - SET BaseIva4 = vBase, - PorIva4 = vRate, - CuotaIva4 = vVat, - CodigoTransaccion4 = vTransactionCode, - CodigoIva4 = vTaxCode - WHERE id = vXDiarioId; - ELSE - SELECT vXDiarioId; - END CASE; - - IF vIsIntracommunity THEN - UPDATE XDiario_movConta_IVA - SET Intracomunitaria = TRUE - WHERE id = vXDiarioId; - END IF; - - SET vTransactionCodeOld=vTransactionCode; - SET vTaxCodeOld=vTaxCode; - - FETCH rs INTO vBase, - vVat, - vRate, - vTransactionCode, - vTaxCode, - vIsIntracommunity, - vOperationCode, - vDuaExcluded; - END WHILE; - ELSE - INSERT INTO XDiario_movConta_IVA(id, LibreA1) - VALUES (vXDiarioId, vInvoiceInFk); - END IF; - CLOSE rs; - - UPDATE XDiario_movConta_IVA xmi - JOIN tmp.invoiceInList ii ON ii.id = vInvoiceInFk - JOIN vn2008.XDiario x ON x.id = xmi.id - LEFT JOIN tmp.invoiceDua id ON id.id = xmi.id - JOIN vn.supplier s ON s.id = ii.supplierFk - JOIN Naciones n ON n.countryFk = s.countryFk - SET xmi.CodigoDivisa = ii.currencyFk, - xmi.Año = YEAR(ii.issued), - xmi.Serie = ii.serial, - xmi.Factura = ii.serialNumber, -- x.FACTURA, DUAS¿? - xmi.FechaFactura = ii.issued, - xmi.ImporteFactura = BaseIva1 + CuotaIva1 + BaseIva2 + CuotaIva2 + BaseIva3 + CuotaIva3 + BaseIva4 + CuotaIva4, - xmi.TipoFactura = IF(id.id,IF( ii.serial = 'D', 'R','I'), 'R'), -- MARCAR I para informativa - xmi.CodigoCuentaFactura = x.SUBCTA, - xmi.CifDni = IF(LEFT(TRIM(s.nif),2) = n.SiglaNacion, SUBSTRING(TRIM(s.nif),3) ,s.nif), - xmi.Nombre = s.name, - xmi.SiglaNacion = n.SiglaNacion, - xmi.EjercicioFactura = YEAR(ii.issued), - xmi.FechaOperacion = ii.issued, - xmi.MantenerAsiento = TRUE, - xmi.SuFacturaNo = ii.supplierRef, - xmi.IvaDeducible1 = ii.isVatDeductible, - xmi.IvaDeducible2 = ii.isVatDeductible, - xmi.IvaDeducible3 = ii.isVatDeductible, - xmi.IvaDeducible4 = ii.isVatDeductible, - xmi.FechaFacturaOriginal = x.FECHA_EX - WHERE xmi.id = vXDiarioId; - - -- RETENCIONES - /* UPDATE XDiario_movConta_IVA xmi - JOIN vn.invoiceIn ii ON ii.id = vInvoiceInFk - JOIN vn2008.XDiario x ON x.id = xmi.id - JOIN vn.supplier s ON s.id = supplierFk - JOIN vn.invoiceInTax iit ON iit.invoiceInFk = ii.id - JOIN TiposRetencion t ON t.CodigoRetencion = ii.withholdingSageFk - SET xmi.CodigoRetencion = t.CodigoRetencion, - xmi.BaseRetencion = iit.taxableBase, - xmi.PorRetencion = t.PorcentajeRetencion, - xmi.ImporteRetencion = iit.taxableBase * (t.PorcentajeRetencion / 100) - WHERE xmi.id = vXDiarioId AND iit.taxableBase < 0 ;*/ - - UPDATE XDiario_movConta_IVA xmi - JOIN vn.invoiceIn ii ON ii.id = vInvoiceInFk - JOIN vn2008.XDiario x ON x.id = xmi.id - JOIN vn.supplier s ON s.id = supplierFk - JOIN vn.invoiceInTax iit ON iit.invoiceInFk = ii.id - JOIN TiposRetencion t ON t.CodigoRetencion = ii.withholdingSageFk - JOIN (SELECT SUM(BASEEURO) taxableBase, SUM(EURODEBE) taxBase - FROM vn.XDiario - WHERE BASEEURO <> 0 AND ASIEN = (SELECT ASIEN FROM vn.XDiario WHERE id = vXDiarioId) - )sub - SET xmi.CodigoRetencion = t.CodigoRetencion, - xmi.BaseRetencion = IF (t.CodigoRetencion = 2, sub.taxableBase + sub.taxBase, sub.taxableBase), - xmi.PorRetencion = t.PorcentajeRetencion, - xmi.ImporteRetencion = iit.taxableBase * - 1 - WHERE xmi.id = vXDiarioId AND iit.expenceFk= 4751000000 ; - -END ;; -DELIMITER ; -/*!50003 SET sql_mode = @saved_sql_mode */ ; -/*!50003 SET character_set_client = @saved_cs_client */ ; -/*!50003 SET character_set_results = @saved_cs_results */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `XDiario_movConta_IVA_InvoiceInAdd_Manager` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_general_ci */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `XDiario_movConta_IVA_InvoiceInAdd_Manager`() +CREATE DEFINER=`root`@`%` PROCEDURE `XDiario_movConta_IVA_InvoiceInAdd_Manager__`() BEGIN DECLARE done BOOL DEFAULT FALSE; DECLARE vInvoiceFk INT; @@ -23040,6 +22480,7 @@ BEGIN DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; SELECT CONCAT(YEAR(CURDATE()), "-01-01") INTO vDated; + SELECT "2021-01-01" INTO vDated; DROP TEMPORARY TABLE IF EXISTS tmp.invoiceDua; CREATE TEMPORARY TABLE tmp.invoiceDua SELECT id @@ -23259,7 +22700,7 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `XDiario_movConta_IVA_InvoiceInAdd_Manager__` */; +/*!50003 DROP PROCEDURE IF EXISTS `XDiario_movConta_IVA_InvoiceInAdd__` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -23269,245 +22710,182 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `XDiario_movConta_IVA_InvoiceInAdd_Manager__`() +CREATE DEFINER=`root`@`%` PROCEDURE `XDiario_movConta_IVA_InvoiceInAdd__`(IN vInvoiceInFk INT, IN vXDiarioId INT) BEGIN - DECLARE done BOOL DEFAULT FALSE; - DECLARE vInvoiceFk INT; - DECLARE vXDiarioFk INT; - DECLARE vDated DATE; - DECLARE rs CURSOR FOR - SELECT IFNULL(ii.id,x.FACTURA) invoiceInFk, x.id XDiarioFk - FROM vn2008.XDiario x - JOIN(SELECT DISTINCT (x.ASIEN) - FROM vn2008.XDiario x - LEFT JOIN vn.invoiceIn ii ON x.CLAVE = ii.id - LEFT JOIN vn.invoiceInTax it ON it.invoiceInFk = ii.id - WHERE it.taxTypeSageFk IS NOT NULL AND - x.enlazadoSage = FALSE AND - x.FECHA >= vDated - ) sub ON sub.ASIEN =x.ASIEN -- Elimina las Facturas con IVA 0 (-) no se trasladan a sage - LEFT JOIN vn.invoiceIn ii ON x.CLAVE = ii.id - WHERE x.enlazadoSage = FALSE AND - x.FECHA >= vDated AND - ((SUBCTA<>"4700000999" AND ii.id IS NOT NULL) - OR (SUBCTA LIKE '472%' AND CONTRA ='4330002067' AND ii.id IS NULL)) ; + + DECLARE vDone BOOL DEFAULT FALSE; + DECLARE vBase DOUBLE; + DECLARE vVat DOUBLE; + DECLARE vRate DOUBLE; + DECLARE vTransactionCode INT; + DECLARE vCounter INT DEFAULT 0; + DECLARE vTransactionCodeOld INT; + DECLARE vTaxCode INT; + DECLARE vTaxCodeOld INT; + DECLARE vOperationCode VARCHAR(1); + DECLARE vIsIntracommunity BOOL DEFAULT FALSE; + DECLARE vDuaExcluded INT; - DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + DECLARE rs CURSOR FOR -- IVA + SELECT it.taxableBase BASEEURO, + CAST((( it.taxableBase / 100) * t.PorcentajeIva) AS DECIMAL (10,2)) vat, + t.PorcentajeIva rate, + it.transactionTypeSageFk transactionCode, + it.taxTypeSageFk taxCode, + t.isIntracommunity, + tt.ClaveOperacionDefecto operationCode, + id.id + FROM vn.invoiceIn i + JOIN vn.invoiceInTax it ON it.InvoiceInFk = i.id + JOIN TiposIva t ON t.CodigoIva = it.taxTypeSageFk + JOIN TiposTransacciones tt ON tt.CodigoTransaccion = it.transactionTypeSageFk + LEFT JOIN tmp.invoiceDua id ON id.id = vXDiarioId + WHERE i.id = vInvoiceInFk + AND i.id> 70000; -- los DUAS no son vInvoiceInFk, pero se pasan en el mismo parametro comparten id en tablas distintas de InvoiceIN (100000) dua(20000) + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; + + DELETE FROM XDiario_movConta_IVA + WHERE id = vXDiarioId; - SELECT CONCAT(YEAR(CURDATE()), "-01-01") INTO vDated; - DROP TEMPORARY TABLE IF EXISTS tmp.invoiceDua; - CREATE TEMPORARY TABLE tmp.invoiceDua - SELECT id - FROM vn2008.XDiario x - WHERE ASIEN IN (SELECT ASIEN - FROM vn.invoiceIn ii - JOIN vn2008.XDiario x ON x.CLAVE = ii.id - WHERE x.enlazadoSage = FALSE AND - x.SUBCTA = '4700000999' AND - x.FECHA >= vDated - ) AND - NOT CONTRA <=> "4330002067"; - - DROP TEMPORARY TABLE IF EXISTS tmp.invoiceInList; - CREATE TEMPORARY TABLE tmp.invoiceInList - SELECT i.id id, - i.supplierRef supplierRef, - i.serial serial, - i.supplierFk supplierFk, - i.issued issued, - i.isVatDeductible isVatDeductible, - i.serialNumber serialNumber, - IF(c.code = "EUR", '',c.code) currencyFk - FROM vn.invoiceIn i - JOIN vn.currency c ON c.id = i.currencyFk - WHERE i.bookEntried >= vDated - UNION ALL - SELECT d.id , - d.code , - 'D' , - d.companyFk , - d.issued , - FALSE, - d.id, - '' -- EUROS - FROM vn.dua d - WHERE d.issued IS NOT NULL AND - code IS NOT NULL; + INSERT INTO XDiario_movConta_IVA(id, LibreA1) + VALUES (vXDiarioId, vInvoiceInFk); OPEN rs; - FETCH rs INTO vInvoiceFk, vXDiarioFk; - WHILE NOT done DO - CALL XDiario_movConta_IVA_InvoiceInAdd(vInvoiceFk, vXDiarioFk); - FETCH rs INTO vInvoiceFk, vXDiarioFk; - END WHILE; + FETCH rs INTO vBase, + vVat, + vRate, + vTransactionCode, + vTaxCode, + vIsIntracommunity, + vOperationCode, + vDuaExcluded; + + SET vTransactionCodeOld=vTransactionCode; + SET vTaxCodeOld=vTaxCode; + + WHILE NOT vDone DO + IF vOperationCode IS NOT NULL THEN + UPDATE XDiario_movConta_IVA + SET ClaveOperacionFactura = vOperationCode + WHERE id = vXDiarioId; + END IF; + + IF vTransactionCode IS NULL THEN + SET vTransactionCode = vTransactionCodeOld; + END IF; + + IF vTaxCodeOld IS NULL THEN + SET vTaxCode = vTaxCodeOld; + END IF; + + SET vCounter = vCounter + 1; + CASE vCounter + WHEN 1 THEN + UPDATE XDiario_movConta_IVA + SET BaseIva1 = vBase, + PorIva1 = vRate, + CuotaIva1 = vVat, + CodigoTransaccion1 = vTransactionCode, + CodigoIva1 = vTaxCode + WHERE id = vXDiarioId; + WHEN 2 THEN + UPDATE XDiario_movConta_IVA + SET BaseIva2 = vBase, + PorIva2 = vRate, + CuotaIva2 = vVat, + CodigoTransaccion2 = vTransactionCode, + CodigoIva2 = vTaxCode + WHERE id = vXDiarioId; + WHEN 3 THEN + UPDATE XDiario_movConta_IVA + SET BaseIva3 = vBase, + PorIva3 = vRate, + CuotaIva3 = vVat, + CodigoTransaccion3 = vTransactionCode, + CodigoIva3 = vTaxCode + WHERE id = vXDiarioId; + WHEN 4 THEN + UPDATE XDiario_movConta_IVA + SET BaseIva4 = vBase, + PorIva4 = vRate, + CuotaIva4 = vVat, + CodigoTransaccion4 = vTransactionCode, + CodigoIva4 = vTaxCode + WHERE id = vXDiarioId; + ELSE + SELECT vXDiarioId INTO vXDiarioId; + END CASE; + + IF vIsIntracommunity THEN + UPDATE XDiario_movConta_IVA + SET Intracomunitaria = TRUE + WHERE id = vXDiarioId; + END IF; + + SET vTransactionCodeOld=vTransactionCode; + SET vTaxCodeOld=vTaxCode; + + FETCH rs INTO vBase, + vVat, + vRate, + vTransactionCode, + vTaxCode, + vIsIntracommunity, + vOperationCode, + vDuaExcluded; + END WHILE; CLOSE rs; - - DROP TEMPORARY TABLE tmp.invoiceDua; - DROP TEMPORARY TABLE tmp.invoiceInList; - - -- ASIENTOS CON IVA SOPORTADO 472. y 477. hay que informar 2 líneas la info de facturas una como tipo de factura emitida y otra como recibida - DROP TEMPORARY TABLE IF EXISTS tmp.XDiario_movConta_IVA; - CREATE TEMPORARY TABLE tmp.XDiario_movConta_IVA - SELECT - sub3.id, - mc.CodigoDivisa, - mc.BaseIva1, - mc.PorBaseCorrectora1, - mc.PorIva1, - mc.CuotaIva1, - mc.PorRecargoEquivalencia1, - mc.RecargoEquivalencia1, - mc.CodigoTransaccion1, - mc.CodigoIva1, - mc.BaseIva2, - mc.PorBaseCorrectora2, - mc.PorIva2, - mc.CuotaIva2, - mc.PorRecargoEquivalencia2, - mc.RecargoEquivalencia2, - mc.CodigoTransaccion2, - mc.CodigoIva2, - mc.BaseIva3, - mc.PorBaseCorrectora3, - mc.PorIva3, - mc.CuotaIva3, - mc.PorRecargoEquivalencia3, - mc.RecargoEquivalencia3, - mc.CodigoTransaccion3, - mc.CodigoIva3, - mc.BaseIva4, - mc.PorBaseCorrectora4, - mc.PorIva4, - mc.CuotaIva4, - mc.PorRecargoEquivalencia4, - mc.RecargoEquivalencia4, - mc.CodigoTransaccion4, - mc.CodigoIva4, - mc.Año, - mc.Serie, - mc.Factura, - mc.SuFacturaNo, - mc.FechaFactura, - mc.ImporteFactura, - 'E', - mc.CodigoCuentaFactura, - mc.CifDni, - mc.Nombre, - mc.CodigoRetencion, - mc.BaseRetencion, - mc.PorRetencion, - mc.ImporteRetencion, - mc.SiglaNacion, - mc.EjercicioFactura, - x.FECHA, - mc.Exclusion347, - mc.MantenerAsiento, - mc.Metalico347, - mc.ClaveOperacionFactura, - mc.TipoRectificativa, - mc.FechaFacturaOriginal, - mc.CuotaIvaOriginal, - mc.BaseImponibleOriginal, - mc.ClaseAbonoRectificativas, - mc.RecargoEquivalenciaOriginal, - mc.LibreA1, - mc.IvaDeducible1, - mc.IvaDeducible2, - mc.IvaDeducible3, - mc.IvaDeducible4, - mc.FechaGrabacion, - mc.Intracomunitaria, - mc.moveData - FROM sage.XDiario_movConta_IVA mc - JOIN vn.XDiario x ON x.id = mc.id - JOIN (SELECT x.ASIEN, x.id - FROM vn.XDiario x - JOIN(SELECT DISTINCT(x.ASIEN) ASIEN - FROM (SELECT DISTINCT(ASIEN) - FROM vn.XDiario x - WHERE SUBCTA LIKE '472%' AND - x.enlazadoSage = FALSE AND - x.FECHA >= vDated - ) sub JOIN vn.XDiario x ON x.ASIEN = sub.ASIEN - WHERE x.SUBCTA LIKE '477%' - )sub2 ON sub2.ASIEN = x.ASIEN - WHERE x.CONTRA IS NOT NULL AND x.SUBCTA LIKE '477%' - GROUP BY x.ASIEN - )sub3 ON sub3.ASIEN = x.ASIEN; - - INSERT INTO sage.XDiario_movConta_IVA - (`id`, - `CodigoDivisa`, - `BaseIva1`, - `PorBaseCorrectora1`, - `PorIva1`, - `CuotaIva1`, - `PorRecargoEquivalencia1`, - `RecargoEquivalencia1`, - `CodigoTransaccion1`, - `CodigoIva1`, - `BaseIva2`, - `PorBaseCorrectora2`, - `PorIva2`, - `CuotaIva2`, - `PorRecargoEquivalencia2`, - `RecargoEquivalencia2`, - `CodigoTransaccion2`, - `CodigoIva2`, - `BaseIva3`, - `PorBaseCorrectora3`, - `PorIva3`, - `CuotaIva3`, - `PorRecargoEquivalencia3`, - `RecargoEquivalencia3`, - `CodigoTransaccion3`, - `CodigoIva3`, - `BaseIva4`, - `PorBaseCorrectora4`, - `PorIva4`, - `CuotaIva4`, - `PorRecargoEquivalencia4`, - `RecargoEquivalencia4`, - `CodigoTransaccion4`, - `CodigoIva4`, - `Año`, - `Serie`, - `Factura`, - `SuFacturaNo`, - `FechaFactura`, - `ImporteFactura`, - `TipoFactura`, - `CodigoCuentaFactura`, - `CifDni`, - `Nombre`, - `CodigoRetencion`, - `BaseRetencion`, - `PorRetencion`, - `ImporteRetencion`, - `SiglaNacion`, - `EjercicioFactura`, - `FechaOperacion`, - `Exclusion347`, - `MantenerAsiento`, - `Metalico347`, - `ClaveOperacionFactura`, - `TipoRectificativa`, - `FechaFacturaOriginal`, - `CuotaIvaOriginal`, - `BaseImponibleOriginal`, - `ClaseAbonoRectificativas`, - `RecargoEquivalenciaOriginal`, - `LibreA1`, - `IvaDeducible1`, - `IvaDeducible2`, - `IvaDeducible3`, - `IvaDeducible4`, - `FechaGrabacion`, - `Intracomunitaria`, - `moveData`) - SELECT * - FROM tmp.XDiario_movConta_IVA; - DROP TEMPORARY TABLE tmp.XDiario_movConta_IVA; + + UPDATE XDiario_movConta_IVA xmi + JOIN tmp.invoiceInList ii ON ii.id = vInvoiceInFk + JOIN vn2008.XDiario x ON x.id = xmi.id + LEFT JOIN tmp.invoiceDua id ON id.id = xmi.id + JOIN vn.supplier s ON s.id = ii.supplierFk + JOIN Naciones n ON n.countryFk = s.countryFk + SET xmi.CodigoDivisa = ii.currencyFk, + xmi.Año = YEAR(ii.issued), + xmi.Serie = ii.serial, + xmi.Factura = ii.serialNumber, -- x.FACTURA, DUAS¿? + xmi.FechaFactura = ii.issued, + xmi.ImporteFactura = IFNULL(xmi.BaseIva1, 0) + IFNULL(xmi.CuotaIva1, 0) + + IFNULL(xmi.BaseIva2, 0) + IFNULL(xmi.CuotaIva2, 0) + + IFNULL(xmi.BaseIva3, 0) + IFNULL(xmi.CuotaIva3, 0) + + IFNULL(xmi.BaseIva4, 0) + IFNULL(xmi.CuotaIva4, 0), + xmi.TipoFactura = IF(id.id,IF( ii.serial = 'D', 'R','I'), 'R'), -- MARCAR I para informativa + xmi.CodigoCuentaFactura = x.SUBCTA, + xmi.CifDni = IF(LEFT(TRIM(s.nif),2) = n.SiglaNacion, SUBSTRING(TRIM(s.nif),3) ,s.nif), + xmi.Nombre = s.name, + xmi.SiglaNacion = n.SiglaNacion, + xmi.EjercicioFactura = YEAR(ii.issued), + xmi.FechaOperacion = ii.issued, + xmi.MantenerAsiento = TRUE, + xmi.SuFacturaNo = ii.supplierRef, + xmi.IvaDeducible1 = IF(id.id, FALSE, IF(IFNULL(xmi.BaseIva1, FALSE) = FALSE, FALSE, ii.isVatDeductible)), + xmi.IvaDeducible2 = IF(id.id, FALSE, IF(IFNULL(xmi.BaseIva2, FALSE) = FALSE, FALSE, ii.isVatDeductible)), + xmi.IvaDeducible3 = IF(id.id, FALSE, IF(IFNULL(xmi.BaseIva3, FALSE) = FALSE, FALSE, ii.isVatDeductible)), + xmi.IvaDeducible4 = IF(id.id, FALSE, IF(IFNULL(xmi.BaseIva4, FALSE) = FALSE, FALSE, ii.isVatDeductible)), + xmi.FechaFacturaOriginal = x.FECHA_EX + WHERE xmi.id = vXDiarioId; + + -- RETENCIONES + + UPDATE XDiario_movConta_IVA xmi + JOIN vn.invoiceIn ii ON ii.id = vInvoiceInFk + JOIN vn2008.XDiario x ON x.id = xmi.id + JOIN vn.supplier s ON s.id = supplierFk + JOIN vn.invoiceInTax iit ON iit.invoiceInFk = ii.id + JOIN TiposRetencion t ON t.CodigoRetencion = ii.withholdingSageFk + JOIN (SELECT SUM(BASEEURO) taxableBase, SUM(EURODEBE) taxBase + FROM vn.XDiario + WHERE BASEEURO <> 0 AND ASIEN = (SELECT ASIEN FROM vn.XDiario WHERE id = vXDiarioId) + )sub + SET xmi.CodigoRetencion = t.CodigoRetencion, + xmi.ClaveOperacionFactura = IF( t.Retencion = 'ARRENDAMIENTO Y SUBARRENDAMIENTO', 'R', xmi.ClaveOperacionFactura), + xmi.BaseRetencion = IF (t.CodigoRetencion = 2, sub.taxableBase + sub.taxBase, sub.taxableBase), + xmi.PorRetencion = t.PorcentajeRetencion, + xmi.ImporteRetencion = iit.taxableBase * - 1 + WHERE xmi.id = vXDiarioId AND iit.expenceFk = 4751000000; END ;; DELIMITER ; @@ -23515,7 +22893,7 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `XDiario_movConta_IVA_InvoiceOutAdd` */; +/*!50003 DROP PROCEDURE IF EXISTS `XDiario_movConta_IVA_InvoiceOutAdd_Manager__` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -23525,7 +22903,59 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `XDiario_movConta_IVA_InvoiceOutAdd`(IN vInvoiceOutFk INT, IN vXDiarioId INT) +CREATE DEFINER=`root`@`%` PROCEDURE `XDiario_movConta_IVA_InvoiceOutAdd_Manager__`() +BEGIN + + DECLARE done BOOL DEFAULT FALSE; + DECLARE vInvoiceFk INT; + DECLARE vXDiarioFk INT; + DECLARE vDated DATE; + + DECLARE rs CURSOR FOR + SELECT io.id invoiceOutFk, x.XDiarioFk + FROM vn.invoiceOut io + JOIN (SELECT MIN(id) XDiarioFk, refFk + FROM vn2008.XDiario x + JOIN (SELECT x.ASIEN, CONCAT(x.SERIE,x.FACTURA) AS refFk + FROM vn2008.XDiario x + JOIN vn.company c ON c.id = x.empresa_id + WHERE enlazadoSage = FALSE AND + x.FACTURA AND + c.companyCode AND + x.FECHA >= vDated + GROUP BY refFk + ) a ON a.ASIEN = x.ASIEN + GROUP BY refFk + ) x ON x.refFk = io.ref; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + SELECT CONCAT(YEAR(CURDATE()), "-01-01") INTO vDated; +SELECT "2021-01-01" INTO vDated; + OPEN rs; + FETCH rs INTO vInvoiceFk, vXDiarioFk; + WHILE NOT done DO + CALL XDiario_movConta_IVA_InvoiceOutAdd(vInvoiceFk, vXDiarioFk); + FETCH rs INTO vInvoiceFk, vXDiarioFk; + END WHILE; + CLOSE rs; + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `XDiario_movConta_IVA_InvoiceOutAdd__` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `XDiario_movConta_IVA_InvoiceOutAdd__`(IN vInvoiceOutFk INT, IN vXDiarioId INT) BEGIN DECLARE vDone BOOL DEFAULT FALSE; @@ -23738,57 +23168,6 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `XDiario_movConta_IVA_InvoiceOutAdd_Manager` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_general_ci */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `XDiario_movConta_IVA_InvoiceOutAdd_Manager`() -BEGIN - - DECLARE done BOOL DEFAULT FALSE; - DECLARE vInvoiceFk INT; - DECLARE vXDiarioFk INT; - DECLARE vDated DATE; - - DECLARE rs CURSOR FOR - SELECT io.id invoiceOutFk, x.XDiarioFk - FROM vn.invoiceOut io - JOIN (SELECT MIN(id) XDiarioFk, refFk - FROM vn2008.XDiario x - JOIN (SELECT x.ASIEN, CONCAT(x.SERIE,x.FACTURA) AS refFk - FROM vn2008.XDiario x - JOIN vn.company c ON c.id = x.empresa_id - WHERE enlazadoSage = FALSE AND - x.FACTURA AND - c.companyCode AND - x.FECHA >= vDated - GROUP BY refFk - ) a ON a.ASIEN = x.ASIEN - GROUP BY refFk - ) x ON x.refFk = io.ref; - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; - SELECT CONCAT(YEAR(CURDATE()), "-01-01") INTO vDated; - OPEN rs; - FETCH rs INTO vInvoiceFk, vXDiarioFk; - WHILE NOT done DO - CALL XDiario_movConta_IVA_InvoiceOutAdd(vInvoiceFk, vXDiarioFk); - FETCH rs INTO vInvoiceFk, vXDiarioFk; - END WHILE; - CLOSE rs; - -END ;; -DELIMITER ; -/*!50003 SET sql_mode = @saved_sql_mode */ ; -/*!50003 SET character_set_client = @saved_cs_client */ ; -/*!50003 SET character_set_results = @saved_cs_results */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -- -- Current Database: `salix` @@ -25715,6 +25094,33 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP FUNCTION IF EXISTS `lastDayOfYear` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` FUNCTION `lastDayOfYear`(vDate DATE) RETURNS date + NO SQL + DETERMINISTIC +BEGIN +/** + * Returns the date formatted to the first day of year. + * + * @param vDate The date to format + * @return The formatted date + */ + RETURN DATE_FORMAT(vDate, '%Y-12-31'); +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 DROP FUNCTION IF EXISTS `midnight` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -26856,6 +26262,32 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; +-- +-- Table structure for table `addressFilter` +-- + +DROP TABLE IF EXISTS `addressFilter`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `addressFilter` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `provinceFk` smallint(5) unsigned DEFAULT NULL, + `countryFk` mediumint(8) unsigned DEFAULT NULL, + `isLogifloraAllowed` tinyint(1) DEFAULT '0', + `isVNHSupplier` tinyint(1) DEFAULT '0' COMMENT 'corresponde al campo edi.VMPSettings.isVNHSupplier', + `isEarlyBird` tinyint(1) DEFAULT '0' COMMENT 'corresponde al campo edi.marketPlace.isEarlybird', + `warehouseFk` smallint(5) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `addressFilter_FK` (`provinceFk`), + KEY `addressFilter_FK_1` (`countryFk`), + KEY `addressFilter_FK_2` (`warehouseFk`), + CONSTRAINT `addressFilter_FK` FOREIGN KEY (`provinceFk`) REFERENCES `province` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `addressFilter_FK_1` FOREIGN KEY (`countryFk`) REFERENCES `country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `addressFilter_FK_2` FOREIGN KEY (`warehouseFk`) REFERENCES `warehouse` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDBDEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Establece los criterios para habilitar las compras directas a Floraholland'; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `addressForPackaging` -- @@ -33373,33 +32805,32 @@ DELIMITER ;; BEFORE INSERT ON `invoiceOut` FOR EACH ROW -- Edit trigger body code below this line. Do not edit lines above this one BEGIN - DECLARE vRef CHAR(9) DEFAULT '0000001'; - DECLARE vMaxId INT; - - SELECT IFNULL(MAX(id),0) INTO vMaxId - FROM invoiceOut - WHERE serial LIKE NEW.serial - AND ((Year(NEW.issued) = Year(issued) - AND companyFk = NEW.companyFk)); - - IF vMaxId THEN - - SELECT RIGHT(MAX(ref), LENGTH(ref)-1) + 1 - INTO vRef - FROM invoiceOut - WHERE serial LIKE NEW.serial - AND ((Year(NEW.issued) = Year(issued) - AND length(ref) > 6 - AND companyFk = NEW.companyFk) /*OR (NEW.serial LIKE 'B' AND length(ref) > 7)*/ ); - ELSE - SELECT CONCAT(sage200Company,RIGHT(YEAR(CURDATE()),1),'00001') INTO vRef - FROM company - WHERE id = NEW.companyFk; -/*Primer digito la empresa, segundo el año, despues la numeracion correlativa con 5 digitos*/ - END IF; - - SELECT CONCAT(NEW.serial, LPAD(vRef,7,'0')) INTO vRef; - SET NEW.ref = vRef; + DECLARE vRef CHAR(10) ; + + IF YEAR(NEW.issued) <= 2021 THEN + + SELECT CONCAT(NEW.serial, + IFNULL(RIGHT(MAX(i.ref), LENGTH(i.ref)-1) , + RPAD(CONCAT(c.sage200Company, RIGHT(YEAR(CURDATE()), 2)), 7,'0')) + 1) INTO vRef + FROM invoiceOut i + LEFT JOIN company c ON c.id = i.companyFk + WHERE i.serial = NEW.serial + AND i.issued BETWEEN util.firstDayOfYear(NEW.issued) AND util.dayEnd(util.lastDayOfYear(NEW.issued)) + AND c.id = NEW.companyFk; + ELSE + + SELECT CONCAT(NEW.serial, + IFNULL(RIGHT(MAX(i.ref), LENGTH(i.ref)-1) , + RPAD(CONCAT(c.sage200Company, RIGHT(YEAR(CURDATE()), 2)), 8,'0')) + 1) INTO vRef + FROM invoiceOut i + LEFT JOIN company c ON c.id = i.companyFk + WHERE i.serial = NEW.serial + AND i.issued BETWEEN util.firstDayOfYear(NEW.issued) AND util.dayEnd(util.lastDayOfYear(NEW.issued)) + AND c.id = NEW.companyFk; + END IF; + + SET NEW.ref = vRef; + END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -33739,6 +33170,12 @@ BEGIN END IF; + IF NEW.itemPackingTypeFk = '' THEN + + SET NEW.itemPackingTypeFk = NULL; + + END IF; + END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -33754,28 +33191,14 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`%`*/ /*!50003 TRIGGER `vn`.`item_afterUpdate` - AFTER UPDATE ON `item` FOR EACH ROW +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`item_afterUpdate` + AFTER UPDATE ON `item` + FOR EACH ROW BEGIN - DECLARE vStandardFlowerBox INT; - IF !(NEW.image <=> OLD.image) THEN CALL hedera.image_unref('catalog', OLD.image); CALL hedera.image_ref('catalog', NEW.image); END IF; - IF NEW.density = 0 THEN - CALL util.throw('error densidad = 0'); - END IF; - - IF !(NEW.packingOut <=> OLD.packingOut) THEN - SELECT standardFlowerBox * 1000 INTO vStandardFlowerBox - FROM volumeConfig; - - UPDATE itemCost ic - JOIN warehouse w ON w.id = ic.warehouseFk - SET cm3Delivery = IFNULL(vStandardFlowerBox / NEW.packingOut, cm3) - WHERE itemFk = NEW.id AND w.hasProduction; - END IF; END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -34919,7 +34342,7 @@ CREATE TABLE `itemTag` ( `intValue` int(11) DEFAULT NULL, `priority` int(2) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), - UNIQUE KEY `itemFk` (`itemFk`,`tagFk`,`value`) USING BTREE, + UNIQUE KEY `itemTagItemUq` (`itemFk`,`tagFk`), KEY `tagFk` (`tagFk`,`value`), KEY `priorityItem` (`priority`,`itemFk`), KEY `value` (`value`), @@ -35178,6 +34601,12 @@ DELIMITER ;; -- Edit trigger body code below this line. Do not edit lines above this one BEGIN + IF NEW.itemPackingTypeFk = '' THEN + + SET NEW.itemPackingTypeFk = NULL; + + END IF; + IF NEW.itemPackingTypeFk != OLD.itemPackingTypeFk THEN UPDATE vn.item @@ -36226,7 +35655,7 @@ CREATE TABLE `packingSite__` ( PRIMARY KEY (`code`), KEY `packingSite_FK` (`hostFk`), KEY `packingSite_FK_1` (`printerFk`), - CONSTRAINT `packingSite_FK` FOREIGN KEY (`hostFk`) REFERENCES `vn2008`.`config_host` (`config_host_id`), + CONSTRAINT `packingSite_FK` FOREIGN KEY (`hostFk`) REFERENCES `vn2008`.`config_host__` (`config_host_id`), CONSTRAINT `packingSite_FK_1` FOREIGN KEY (`printerFk`) REFERENCES `printer` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -37068,6 +36497,7 @@ CREATE TABLE `producer` ( `id` mediumint(3) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, `isVisible` tinyint(1) NOT NULL DEFAULT '1', + `created` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `name_UNIQUE` (`name`) ) ENGINE=InnoDBDEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; @@ -38985,6 +38415,28 @@ CREATE TABLE `sector` ( ) ENGINE=InnoDBDEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `sectorProductivity` +-- + +DROP TABLE IF EXISTS `sectorProductivity`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `sectorProductivity` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `workerFk` int(11) DEFAULT NULL, + `firstName` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, + `lastName` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, + `sector` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, + `ticketCount` int(11) DEFAULT NULL, + `saleCount` int(11) DEFAULT NULL, + `volume` decimal(10,6) DEFAULT NULL, + `hourWorked` decimal(10,2) DEFAULT NULL, + `dated` date DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDBDEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `sharingCart` -- @@ -40502,26 +39954,31 @@ CREATE TABLE `ticketCollection` ( /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`%`*/ /*!50003 TRIGGER ticketCollection_AFTER_DELETE +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER ticketCollection_afterDelete AFTER DELETE ON ticketCollection FOR EACH ROW BEGIN - DECLARE vTicketsInCollection INT; + DECLARE vSalesRemaining INT; - SELECT count(*) INTO vTicketsInCollection - FROM vn.ticketCollection tc + SELECT count(*) INTO vSalesRemaining + FROM vn.ticketCollection tc + JOIN sale s ON s.ticketFk = tc.ticketFk WHERE collectionFk = OLD.collectionFk AND tc.id != OLD.id; - IF vTicketsInCollection = 0 THEN + IF NOT vSalesRemaining THEN DELETE FROM vn.collection WHERE id = OLD.collectionFk; + ELSE + + UPDATE vn.collection + SET saleTotalCount = vSalesRemaining + WHERE id = OLD.collectionFk; + END IF; - - -- CALL vn.ticketStateUpdate(OLD.ticketFk, 'OK'); - + END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -50654,20 +50111,32 @@ proc: BEGIN END IF; CALL `cache`.available_refresh (vAvailableCalc, FALSE, vWarehouseFk, vShipped); - CALL buyUltimate (vWarehouseFk, vShipped); + CALL vn.buyUltimate (vWarehouseFk, vShipped); INSERT INTO tmp.ticketLot (warehouseFk, itemFk, available, buyFk, zoneFk) SELECT vWarehouseFk, - i.item_id, - IFNULL(i.available, 0), + a.item_id, + IFNULL(a.available, 0), bu.buyFk, vZoneFk - FROM `cache`.available i - JOIN tmp.item br ON br.itemFk = i.item_id - LEFT JOIN item it ON it.id = i.item_id - LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = i.item_id - WHERE i.calc_id = vAvailableCalc - AND i.available > 0; + FROM `cache`.available a + JOIN vn.address a ON a.id = @addressFk + JOIN vn.province p ON p.id = a.provinceFk + JOIN vn.item i ON i.id = a.item_id + JOIN vn.addressFilter af + LEFT JOIN edi.supplyOffer so ON so.srId = i.supplyResponseFk + LEFT JOIN edi.VMPSettings v ON v.VMPID = so.vmpID + LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = a.item_id + WHERE a.calc_id = vAvailableCalc + AND a.available > 0 + AND i.supplyResponseFk + AND (IFNULL(af.isEarlyBird,so.isEarlyBird) = so.isEarlyBird OR ISNULL(so.isEarlyBird)) + AND (IFNULL(af.isVNHSupplier,so.isVNHSupplier ) = so.isVNHSupplier OR ISNULL(so.isVNHSupplier)) + AND af.warehouseFk = vWarehouseFk + AND (ISNULL(af.provinceFk) OR af.provinceFk = a.provinceFk) + AND (ISNULL(af.countryFk) OR af.countryFk = p.countryFk) + AND (ISNULL(af.isLogifloraAllowed) OR af.isLogifloraAllowed = a.isLogifloraAllowed) + ; DROP TEMPORARY TABLE tmp.buyUltimate; @@ -50729,9 +50198,9 @@ DELIMITER ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8mb4 */ ; -/*!50003 SET character_set_results = utf8mb4 */ ; -/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; @@ -50778,7 +50247,7 @@ proc: BEGIN DECLARE vFrenchDiscount DECIMAL(3,2) DEFAULT 0.12; DECLARE vIsCatalonianBuyer BOOL; DECLARE visAnyVolumeAllowed BOOL; - + SELECT (COUNT(*) > 0) INTO vIsZonePremium FROM vn.zoneFilter zf WHERE zf.zoneFk = vZoneFk; @@ -50790,7 +50259,7 @@ proc: BEGIN FROM address WHERE id = vAddressFk; - SELECT (c.country = 'FRANCIA' AND vWarehouseFk IN (vVNHWarehouseFk, vFloramondoWarehouseFk)) + SELECT (c.country IN ('Francia','Suiza') AND vWarehouseFk IN (vVNHWarehouseFk, vFloramondoWarehouseFk)) INTO vIsFrenchVNHBuyer FROM vn.country c JOIN vn.province p ON p.countryFk = c.id @@ -50806,14 +50275,14 @@ proc: BEGIN SELECT travellingDays INTO vMaxLogifloraDays FROM edi.warehouseFloramondo WHERE warehouseFk = vWarehouseFk; - + -- Se eliminan los productos de tamaños no convencionales, salvo agencias que lo permitan SELECT a.isAnyVolumeAllowed INTO visAnyVolumeAllowed FROM vn.agency a JOIN vn.agencyMode am ON am.agencyFk = a.id JOIN vn.`zone`z ON z.agencyModeFk = am.id WHERE z.id = vZoneFk; - + IF NOT vIsAnyVolumeAllowed THEN DELETE tl.* @@ -50823,7 +50292,7 @@ proc: BEGIN WHERE it.isUnconventionalSize; END IF; - + -- Esto sirve para que los franceses compren sólo por las cuentas de VNH DELETE tl.* FROM tmp.ticketLot tl @@ -50861,7 +50330,7 @@ proc: BEGIN AND vWarehouseFk = tl.warehouseFk); END IF; - + -- Eliminem productes de la oferta que no deuen vore els francesos IF vIsFrenchVNHBuyer THEN @@ -50904,7 +50373,7 @@ proc: BEGIN JOIN item i ON i.id = tl.itemFk JOIN vn.zone z ON z.id = vZoneFk WHERE i.size > z.itemMaxSize; - + SET @rate2 := 0; SET @rate3 := 0; SET @minPrice := 0; @@ -50963,7 +50432,7 @@ proc: BEGIN tcc.rate3 - b.buyingValue - b.freightValue - b.packageValue - b.comissionValue FROM tmp.ticketComponentCalculate tcc JOIN buy b ON b.id = tcc.buyFk; - + -- Promo Francia IF vIsFrenchVNHBuyer THEN @@ -50984,7 +50453,7 @@ proc: BEGIN FROM tmp.ticketComponent tc JOIN tmp.ticketComponentCalculate tcc ON tcc.itemFk = tc.itemFk AND tcc.warehouseFk = tc.warehouseFk GROUP BY tc.itemFk, warehouseFk; - + -- RECOBRO INSERT INTO tmp.ticketComponent(warehouseFk, itemFk, componentFk, cost) SELECT tcb.warehouseFk, tcb.itemFk, vRecoveryComponent, @@ -51006,7 +50475,7 @@ proc: BEGIN JOIN workerMana wm ON c.salesPersonFk = wm.workerFk WHERE wm.isPricesModifierActivated HAVING manaAuto <> 0; - + -- Precios especiales INSERT INTO tmp.ticketComponent SELECT tcb.warehouseFk, @@ -51068,7 +50537,7 @@ proc: BEGIN DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponentCopy; CREATE TEMPORARY TABLE tmp.ticketComponentCopy ENGINE = MEMORY SELECT * FROM tmp.ticketComponent; - + -- Precio especial INSERT INTO tmp.ticketComponent SELECT tcc.warehouseFk, @@ -51204,31 +50673,16 @@ proc: BEGIN * @return tmp.ticketComponentPrice (warehouseFk, itemFk, rate, `grouping`, price, priceKg) */ DECLARE vClientFk INT; - -- DECLARE vMinimumDensityWeight INT DEFAULT 167; - -- DECLARE vBoxVolume BIGINT; - -- DECLARE vSpecialPriceComponent INT DEFAULT 10; - -- DECLARE vDeliveryComponent INT DEFAULT 15; - -- DECLARE vRecoveryComponent INT DEFAULT 17; - -- DECLARE vSellByPacketComponent INT DEFAULT 22; - -- DECLARE vBuyValueComponent INT DEFAULT 28; - -- DECLARE vMarginComponent INT DEFAULT 29; - -- DECLARE vDiscountLastItemComponent INT DEFAULT 32; - -- DECLARE vExtraBaggedComponent INT DEFAULT 38; - -- DECLARE vManaAutoComponent INT DEFAULT 39; - -- DECLARE vFrenchOffer INT DEFAULT 42; DECLARE vIsFrenchVNHBuyer BOOLEAN DEFAULT FALSE; DECLARE vVNHWarehouseFk INT DEFAULT 7; - -- DECLARE vFloramondoWarehouseFk INT DEFAULT 40; DECLARE vIsLogifloraAllowed BOOLEAN DEFAULT 0; - -- DECLARE vMaxLogifloraDays INT; - -- DECLARE vRangeLogifloraDays INT DEFAULT 3; DECLARE vVisibleCache INT; - -- DECLARE vRappelComponent INT DEFAULT 44; DECLARE vIsZonePremium BOOL; DECLARE vFrenchDiscount DECIMAL(3,2) DEFAULT 0.12; - -- DECLARE vIsCatalonianBuyer BOOL; DECLARE visAnyVolumeAllowed BOOL; + SELECT * FROM tmp.ticketLot; + SELECT (COUNT(*) > 0) INTO vIsZonePremium FROM vn.zoneFilter zf WHERE zf.zoneFk = vZoneFk; @@ -51246,15 +50700,8 @@ proc: BEGIN JOIN vn.province p ON p.countryFk = c.id JOIN vn.address a ON a.provinceFk = p.id WHERE a.id = vAddressFk; - /* - SELECT (p.name = 'Barcelona' AND vWarehouseFk = vVNHWarehouseFk) - INTO vIsCatalonianBuyer - FROM vn.province p - JOIN vn.address a ON a.provinceFk = p.id - WHERE a.id = vAddressFk; -- PAK 18/10/21 - */ - - + + /* -- Se eliminan los productos de tamaños no convencionales, salvo agencias que lo permitan SELECT a.isAnyVolumeAllowed INTO visAnyVolumeAllowed FROM vn.agency a @@ -51289,7 +50736,6 @@ proc: BEGIN DELETE tl FROM tmp.ticketLot tl JOIN item i ON i.id = tl.itemFk - -- LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = vWarehouseFk LEFT JOIN vn.buy b ON b.id = tl.buyFk LEFT JOIN vn.entry e ON e.id = b.entryFk LEFT JOIN vn.supplier s ON s.id = e.supplierFk @@ -51351,7 +50797,7 @@ proc: BEGIN JOIN item i ON i.id = tl.itemFk JOIN vn.zone z ON z.id = vZoneFk WHERE i.size > z.itemMaxSize; - + */ SET @rate2 := 0; SET @rate3 := 0; SET @minPrice := 0; @@ -51617,6 +51063,8 @@ proc: BEGIN SELECT * FROM tmp.ticketComponentRate ORDER BY price ) t GROUP BY itemFk, warehouseFk, `grouping`; + + SELECT * FROM tmp.ticketComponentPrice; DROP TEMPORARY TABLE tmp.ticketComponentCalculate, @@ -53601,11 +53049,11 @@ BEGIN INSERT INTO tmp.sale(ticketFk, saleFk, itemFk, isStowaway) SELECT s.ticketFk, s.id, s.itemFk, FALSE FROM vn.ticketCollection tc - JOIN vn.collection c ON c.id = tc.collectionFk + -- JOIN vn.collection c ON c.id = tc.collectionFk JOIN vn.sale s ON s.ticketFk = tc.ticketFk - JOIN vn.item i ON i.id = s.itemFk + -- JOIN vn.item i ON i.id = s.itemFk WHERE tc.collectionFk = vParamFk - AND (i.itemPackingTypeFk = c.itemPackingTypeFk OR ISNULL(c.itemPackingTypeFk)) + -- AND (IFNULL(i.itemPackingTypeFk,c.itemPackingTypeFk) = c.itemPackingTypeFk OR ISNULL(c.itemPackingTypeFk)) UNION ALL SELECT s.ticketFk, s.id, s.itemFk, FALSE FROM vn.sale s @@ -55243,8 +54691,7 @@ proc:BEGIN AND s.isPreparable AND (pb.H > 0 AND vItemPackingTypeFk = 'H' AND ISNULL(pb.collectionH) OR pb.V > 0 AND vItemPackingTypeFk = 'V' AND ISNULL(pb.collectionV) - OR pb.F > 0 AND vItemPackingTypeFk = 'F' AND ISNULL(pb.collectionF) - OR pb.P > 0 AND vItemPackingTypeFk = 'P' AND ISNULL(pb.collectionP)); + OR pb.N > 0 AND ISNULL(pb.collectionH)); SET vMaxTicketPrinted = vMaxTicketPrinted - vPrintedTickets; -- AutoPRINT @@ -55267,8 +54714,7 @@ proc:BEGIN AND s.isOK AND (pb.H > 0 AND vItemPackingTypeFk = 'H' AND ISNULL(pb.collectionH) OR pb.V > 0 AND vItemPackingTypeFk = 'V' AND ISNULL(pb.collectionV) - OR pb.F > 0 AND vItemPackingTypeFk = 'F' AND ISNULL(pb.collectionF) - OR pb.P > 0 AND vItemPackingTypeFk = 'P' AND ISNULL(pb.collectionP)) + OR pb.N > 0 AND ISNULL(pb.collectionH)) AND t.created < TIMESTAMPADD(MINUTE, - tc.pickingDelay , NOW()) ORDER BY HH, mm, @@ -55290,8 +54736,7 @@ proc:BEGIN JOIN vn.ticketStateToday tst ON tst.ticket = pb.ticketFk JOIN vn.state s ON s.id = tst.state WHERE ( pb.H > 0 AND vItemPackingTypeFk = 'H' AND ISNULL(pb.collectionH) - OR pb.V > 0 AND vItemPackingTypeFk = 'V' AND ISNULL(pb.collectionV) - OR pb.P > 0 AND vItemPackingTypeFk = 'P' AND ISNULL(pb.collectionP)) + OR pb.V > 0 AND vItemPackingTypeFk = 'V' AND ISNULL(pb.collectionV)) AND (pb.ubicacion IS NOT NULL OR a.isOwn = FALSE ) AND LENGTH(pb.problem) = 0 AND s.isPreparable @@ -59939,6 +59384,48 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `entry_clone` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `entry_clone`(vSelf INT) +BEGIN + + /* Clona una entrada + * + * @param vSelf Identificador de vn.entry + */ + + DECLARE vEntryFk INT; + + INSERT INTO vn.entry(supplierFk, dated, isInventory, notes, isRaid, commission, travelFk, currencyFk, + companyFk, loadPriority ) + SELECT supplierFk, dated, isInventory, notes, isRaid, commission, travelFk, currencyFk, + companyFk, loadPriority + FROM vn.entry e + WHERE e.id = vSelf; + + SET vEntryFk = LAST_INSERT_ID(); + + INSERT INTO vn.buy(entryFk, itemFk, quantity, buyingValue, freightValue, isIgnored, stickers, packing, `grouping`, groupingMode, containerFk, comissionValue, packageValue, packageFk, price1, price2, price3, minPrice, producer, workerFk, weight, itemOriginalFk ) + SELECT vEntryFk, itemFk, quantity, buyingValue, freightValue, isIgnored, stickers, packing, `grouping`, groupingMode, containerFk, comissionValue, packageValue, packageFk, price1, price2, price3, minPrice, producer, workerFk, weight, itemOriginalFk + FROM vn.buy b + WHERE b.entryFk = vSelf; + + SELECT vEntryFk; + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 DROP PROCEDURE IF EXISTS `entry_fixMisfit` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -64777,6 +64264,10 @@ DELIMITER ; DELIMITER ;; CREATE DEFINER=`root`@`%` PROCEDURE `itemCard`(IN `vBarcode` VARCHAR(22), IN `vWarehouseFk` INT, IN isBarcode BOOL) BEGIN + + /* + * @deprecated: Utilizar item_getInfo + */ DECLARE vCacheVisibleFk INT; DECLARE vCacheAvailableFk INT; @@ -68944,6 +68435,88 @@ BEGIN ORDER BY shipped, alertLevel DESC, isTicket, `order` DESC, isPicked DESC, `in` DESC, `out` DESC ) AS itemDiary; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `item_getInfo` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `item_getInfo`(IN `vBarcode` VARCHAR(22), IN `vWarehouseFk` INT) +BEGIN + + /* + * Devuelve información relativa al item correspondiente del vBarcode pasado + * + * @param vBarcode código relativo al ítem + * @param vWarehouseFk código del almacén + */ + + DECLARE vCacheVisibleFk INT; + DECLARE vCacheAvailableFk INT; + DECLARE vVisibleItemShelving INT; + DECLARE vItemFk INT; + + SELECT vn.barcodeToItem(vBarcode) INTO vItemFk; + + CALL cache.visible_refresh(vCacheVisibleFk, FALSE,vWarehouseFk); + CALL cache.available_refresh(vCacheAvailableFk, FALSE,vWarehouseFk, CURDATE()); + + SELECT SUM(visible) INTO vVisibleItemShelving + FROM vn.itemShelvingStock + WHERE itemFk = vItemFk AND warehouseFk = vWarehouseFk; + + CALL vn.buyUltimate(vWarehouseFk, CURDATE()); + + SELECT i.id, + i.longName, + i.tag5, + i.value5, + i.tag6, + i.value6, + i.tag7, + i.value7, + i.image, + i.size, + i.stems, + i.category, + i.minimum as min, + p.name as producer, + o.code as origin, + v.visible - IFNULL(vVisibleItemShelving,0) as unlocated, + a.available, + vVisibleItemShelving, + v.visible, + c.`grouping`, + c.packing, + CONCAT('https://verdnatura.es/vn-image-data/catalog/200x200/', i.image) as urlImage200, + CONCAT('https://verdnatura.es/vn-image-data/catalog/1600x900/', i.image) as urlImage, + i.itemPackingTypeFk, + i.comment as reference + FROM vn.item i + LEFT JOIN vn.producer p ON p.id = i.producerFk + LEFT JOIN vn.origin o ON o.id = i.originFk + LEFT JOIN cache.visible v ON v.calc_id = vCacheVisibleFk AND v.item_id = i.id + LEFT JOIN cache.available a ON a.calc_id = vCacheAvailableFk AND a.item_id = i.id + LEFT JOIN ( + SELECT b.itemFk, b2.`grouping`, b2.packing + FROM tmp.buyUltimate b + JOIN vn.buy b2 ON b2.id = b.buyFk + WHERE b.warehouseFk = vWarehouseFk + ) c ON i.id = c.itemFk + WHERE i.id = vItemFk; + + DROP TEMPORARY TABLE tmp.buyUltimate; + END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -69505,6 +69078,13 @@ BEGIN SET i.stems = it.`value` WHERE i.id = vItemFk; + -- Al insertar el tag categoria se modifica también en la tabla item + UPDATE item i + JOIN tag t ON t.overwrite = 'category' + JOIN itemTag it ON it.itemFk = i.id AND it.tagFk = t.id + SET i.category = it.`value` + WHERE i.id = vItemFk; + -- Comprueba si existe un genérico y lo asigna CALL vn.item_setGeneric(vItemFk); @@ -70132,9 +69712,9 @@ BEGIN JOIN warehouse wOut ON wOut.id = tr.warehouseOutFk WHERE vDated >= tr.shipped AND vDated < tr.landed AND NOT isRaid - -- AND wIn.valuatedInventory + AND wIn.valuatedInventory AND t.isInventory - -- AND e.isConfirmed + AND e.isConfirmed ON DUPLICATE KEY UPDATE inv.cantidad = inv.cantidad + (b.quantity); CALL vn.buyUltimate(NULL,vDateDayEnd); @@ -72887,6 +72467,226 @@ proc: BEGIN CREATE TEMPORARY TABLE tmp.ticket SELECT * FROM tmp.productionTicket; + CALL vn.prepareClientList(); + + DROP TEMPORARY TABLE IF EXISTS tmp.sale_getProblems; + CREATE TEMPORARY TABLE tmp.sale_getProblems + (INDEX (ticketFk)) ENGINE = MEMORY + SELECT tt.ticketFk, tt.clientFk, t.warehouseFk, t.shipped + FROM tmp.productionTicket tt + JOIN vn.ticket t ON t.id = tt.ticketFk; + + CALL vn.ticket_getProblems(vIsTodayRelative); + + DROP TEMPORARY TABLE IF EXISTS tmp.productionBuffer; + CREATE TEMPORARY TABLE tmp.productionBuffer + (PRIMARY KEY(ticketFk)) + ENGINE = MEMORY + SELECT tt.ticketFk + , tt.clientFk + , t.warehouseFk + , t.nickname + , t.packages + , IF(HOUR(t.shipped), HOUR(t.shipped), IFNULL(HOUR(zc.hour),HOUR(z.hour))) as HH + , IFNULL(HOUR(zc.hour),HOUR(z.hour)) as Departure + , IF(MINUTE(t.shipped), MINUTE(t.shipped), IFNULL(MINUTE(zc.hour), MINUTE(z.hour))) as mm + , t.routeFk + , IF(am.deliveryMethodFk = 2,z.`id`,0) as zona + , t.nickname addressNickname + , a.postalCode + , a.city + , p.name province + , CONCAT(z.`name`,' ',IFNULL(RIGHT(t.routeFk,3),'')) agency + , am.id agencyModeFk + , 0 AS `lines` + , CAST( 0 AS DECIMAL(5,2)) AS m3 + , CAST( 0 AS DECIMAL(5,2)) AS preparationRate + , "" as problem + , IFNULL(tls.state,2) AS state + , w.code workerCode + , DATE(t.shipped) shipped + , wk.code AS salesPersonCode + , p.id provinceFk + , tls.productionOrder + , ifnull(tls.alertLevel,0) alertLevel + , t.isBoxed as palletized + , IF(rm.isPickingAllowed ,rm.bufferFk, NULL) ubicacion + , tlu.lastUpdated + , ifnull(st.graphCategory,0) graphCategory + , pk.code as parking + , 0 AS H + , 0 AS V + , 0 AS N + , st.isOk + , ag.isOwn + FROM tmp.productionTicket tt + JOIN vn.ticket t on tt.ticketFk = t.id + LEFT JOIN vn.ticketStateToday tst ON tst.ticket = t.id + LEFT JOIN vn.state st ON st.id = tst.state + LEFT JOIN vn.client c ON c.id = t.clientFk + LEFT JOIN vn.worker wk ON wk.id = c.salesPersonFk + JOIN vn.address a on a.id = t.addressFk + LEFT JOIN vn.province p on p.id = a.provinceFk + JOIN vn.agencyMode am ON am.id = t.agencyModeFk + JOIN vn.agency ag ON ag.id = am.agencyFk + LEFT JOIN vn.ticketState tls on tls.ticket = tt.ticketFk + LEFT JOIN vn.ticketLastUpdated tlu ON tlu.ticketFk = tt.ticketFk + LEFT JOIN vn.worker w on w.id = tls.worker + LEFT JOIN vn.routesMonitor rm ON rm.routeFk = t.routeFk + LEFT JOIN vn.zone z ON z.id = t.zoneFk + LEFT JOIN vn.zoneClosure zc ON zc.zoneFk = t.zoneFk AND date(t.shipped) = zc.dated + LEFT JOIN vn.ticketParking tp ON tp.ticketFk = t.id + LEFT JOIN vn.parking pk ON pk.id = tp.parkingFk + WHERE t.warehouseFk = vWarehouseFk + AND am.deliveryMethodFk IN (1,2,3); + + ALTER TABLE tmp.productionBuffer + CHANGE COLUMN `problem` `problem` VARCHAR(255), + ADD COLUMN `collectionH` INT, + ADD COLUMN `collectionV` INT; + + -- Líneas y volumen por ticket + UPDATE tmp.productionBuffer pb + JOIN ( + SELECT tt.ticketFk, + COUNT(*) as `lines`, + sum(sv.volume) as m3, + IFNULL(sum(IF(sv.isPicked,sv.volume,0)) / sum(sv.volume),0) as rate + FROM tmp.productionTicket tt + JOIN vn.saleVolume sv on sv.ticketFk = tt.ticketFk + GROUP BY tt.ticketFk + ) m on m.ticketFk = pb.ticketFk + SET pb.`lines` = m.`lines`, + pb.m3 = m.m3, + pb.preparationRate = m.rate; + + DELETE FROM tmp.productionBuffer + WHERE `lines`= 0; + + -- Lineas por linea de encajado + UPDATE tmp.productionBuffer pb + JOIN ( SELECT ticketFk, + sum(sub.H) H, + sum(sub.V) V, + sum(sub.N) N + FROM ( + SELECT t.ticketFk, + sum(i.itemPackingTypeFk = 'H') H, + sum(i.itemPackingTypeFk = 'V') V, + sum(ISNULL(i.itemPackingTypeFk)) N + FROM tmp.productionTicket t + JOIN vn.sale s ON s.ticketFk = t.ticketFk + JOIN vn.item i ON i.id = s.itemFk + GROUP BY t.ticketFk, i.itemPackingTypeFk) sub + GROUP BY ticketFk + ) sub2 ON sub2.ticketFk = pb.ticketFk + SET pb.H = sub2.H, + pb.V = sub2.V, + pb.N = sub2.N; + + -- Colecciones segun tipo de encajado + UPDATE tmp.productionBuffer pb + JOIN vn.ticketCollection tc ON pb.ticketFk = tc.ticketFk + JOIN vn.collection c ON c.id = tc.collectionFk + SET pb.collectionH = c.id + WHERE c.itemPackingTypeFk = 'H' OR ISNULL(c.itemPackingTypeFk); + + UPDATE tmp.productionBuffer pb + JOIN vn.ticketCollection tc ON pb.ticketFk = tc.ticketFk + JOIN vn.collection c ON c.id = tc.collectionFk + SET pb.collectionV = c.id + WHERE c.itemPackingTypeFk = 'V' OR ISNULL(c.itemPackingTypeFk); + + -- Cajas + ALTER TABLE tmp.productionBuffer + ADD Cajas DOUBLE DEFAULT NULL; + + -- Problemas por ticket + UPDATE tmp.productionBuffer pb + JOIN tmp.ticket_problems tp ON tp.ticketFk = pb.ticketFk + SET pb.problem = TRIM(CAST(CONCAT( IFNULL(tp.itemShortage,''), + IFNULL(tp.itemDelay,''), + IF(tp.isFreezed,' CONGELADO',''), + IF(tp.hasHighRisk,' RIESGO',''), + IF(tp.hasTicketRequest, ' COD 100',''), + IF(tp.isTaxDataChecked, '',' FICHA INCOMPLETA'), + IF(tp.hasComponentLack,' COMPONENTES', ''), + IF(tp.isTooLittle,' PEQUEÑO', '') + ) as char(255))); + + -- Refresca la caché para el cierre dinámico de agencias + -- CALL cache.departure_timing(vWarehouseFk); +/* + -- Tickets de recogida + REPLACE tmp.productionBuffer( + shipped + , ticketFk + , agency + , clientFk + , addressNickname + , state + , workerCode + , alertLevel + , warehouseFk + ) + SELECT DATE(t.shipped) + , t.id + , am.name + , t.clientFk + , a.nickname + , s.id as state + , w.code + , ifnull(tls.alertLevel,0) alert_level + , vWarehouseFk + FROM vn.ticket t + JOIN vn.address a on a.id = t.addressFk + JOIN vn.agencyMode am ON am.id = t.agencyModeFk + LEFT JOIN vn2008.warehouse_pickup wp ON wp.agency_id = am.id + LEFT JOIN vn.ticketState tls on tls.ticket = t.id + LEFT JOIN vn.state s ON s.id = tls.state + LEFT JOIN vn.worker w on w.id = tls.worker + WHERE t.shipped between TIMESTAMPADD(WEEK,-1,CURDATE()) AND util.dayend(TIMESTAMPADD(DAY,-1,CURDATE())) + AND wp.warehouse_id = vWarehouseFk; +*/ + DROP TEMPORARY TABLE tmp.productionTicket; + DROP TEMPORARY TABLE tmp.ticket; + DROP TEMPORARY TABLE IF EXISTS tmp.risk; + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `productionControl__` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `productionControl__`(vWarehouseFk INT, vScopeDays INT) +proc: BEGIN + + DECLARE vEndingDate DATETIME DEFAULT TIMESTAMPADD(DAY,vScopeDays,util.dayEnd(CURDATE())); + + DECLARE vIsTodayRelative BOOLEAN; + + CALL util.debugAdd('vn.productionControl',CONCAT('warehouse: ',vWarehouseFk,' scopeDays:',vScopeDays)); + + SELECT isTodayRelative INTO vIsTodayRelative + FROM vn.worker + WHERE userFk = vn.getUser(); + + CALL vn.prepareTicketList(TIMESTAMPADD(DAY,-1,CURDATE()), vEndingDate); + + DROP TEMPORARY TABLE IF EXISTS tmp.ticket; + CREATE TEMPORARY TABLE tmp.ticket + SELECT * FROM tmp.productionTicket; + CALL vn.prepareClientList(); /* DROP TEMPORARY TABLE IF EXISTS tmp.ticketGetProblems; @@ -73171,7 +72971,9 @@ BEGIN JOIN vn.item i ON i.id = isa.itemFk JOIN vn.sector s ON s.id = isa.sectorFk AND s.warehouseFk = isa.warehouseFk - AND i.itemPackingTypeFk = IFNULL(s.itemPackingTypeFk , i.itemPackingTypeFk) + AND (i.itemPackingTypeFk = s.itemPackingTypeFk + -- OR ISNULL(i.itemPackingTypeFk) + OR ISNULL(s.itemPackingTypeFk)) JOIN vn.ticket t ON t.id = isa.ticketFk JOIN vn.client c ON c.id = t.clientFk JOIN tmp.productionBuffer pb ON pb.ticketFk = t.id @@ -73787,66 +73589,68 @@ DELIMITER ; DELIMITER ;; CREATE DEFINER=`root`@`%` PROCEDURE `reportLabelCollection_get`(vCollectionFk INT) BEGIN - +/** + * Obtiene los datos necesarios de una colección + * + * @param vCollectionFk La colección de la que sacar los datos + **/ DECLARE vItemPackingTypeFk VARCHAR(1); -- Si los sacadores NO son de V, pinta los colores SELECT c.itemPackingTypeFk INTO vItemPackingTypeFk - FROM vn.collection c - WHERE c.id = vCollectionFk; + FROM vn.collection c + WHERE c.id = vCollectionFk; - IF !(vItemPackingTypeFk <=> 'V') THEN + IF !(vItemPackingTypeFk <=> 'V') THEN - SELECT * FROM ( - SELECT CONCAT(tc.collectionFk,' ',LEFT(cc.code,4)) `level`, - tc.ticketFk, + SELECT * FROM ( + SELECT CONCAT(tc.collectionFk,' ',LEFT(cc.code,4)) `level`, + tc.ticketFk, LEFT(IF(t.routeFk IS null, am.name, zo.name ),12) agencyDescription, am.name, - t.clientFk, + t.clientFk, count(*) notes, w.code workerCode, tt.labelCount, IF(HOUR(t.shipped),TIME(t.shipped),TIME(zo.HOUR)) AS horaagencia, - t.shipped, - count(*) AS lineas, - t.nickName, - CONCAT(CAST(sv.litros / 1000 AS DECIMAL(5,2)), 'm3') m3 - FROM vn.ticket t + t.shipped, + count(*) lineas, + t.nickName, + CONCAT(CAST(SUM(sv.volume) AS DECIMAL(5,2)) , "m³") m3 + FROM vn.ticket t JOIN vn.ticketCollection tc ON tc.ticketFk = t.id - JOIN vn.collection c ON c.id = tc.collectionFk - JOIN vn.collectionColors cc - ON cc.shelve = tc.`level` - AND cc.wagon = tc.wagon - AND cc.trainFk = c.trainFk + JOIN vn.collection c ON c.id = tc.collectionFk + JOIN vn.collectionColors cc + ON cc.shelve = tc.`level` + AND cc.wagon = tc.wagon + AND cc.trainFk = c.trainFk JOIN vn.sale s ON s.ticketFk = t.id LEFT JOIN vn.saleVolume sv ON sv.saleFk = s.id - JOIN vn.worker w ON w.id = c.workerFk + JOIN vn.worker w ON w.id = c.workerFk JOIN vn.agencyMode am ON am.id = t.agencyModeFk LEFT JOIN vn.ticketTrolley tt ON tt.ticket = t.id LEFT JOIN vn.address a ON a.id = t.addressFk LEFT JOIN vn.route r ON r.id = t.routeFk - LEFT JOIN vn.zoneEstimatedDelivery ze ON ze.zoneFk = t.zoneFk - LEFT JOIN vn.agencyMode agm on r.agencyModeFk =agm.id - LEFT JOIN vn.zone zo ON t.zoneFk = zo.id + LEFT JOIN vn.zoneEstimatedDelivery ze ON ze.zoneFk = t.zoneFk + LEFT JOIN vn.agencyMode agm ON r.agencyModeFk =agm.id + LEFT JOIN vn.zone zo ON t.zoneFk = zo.id WHERE tc.collectionFk = vCollectionFk - GROUP BY t.id) sub + GROUP BY t.id) sub ORDER BY `level`; - - ELSE - - SELECT CONCAT(tc.collectionFk,' ', SUBSTRING('ABCDEFGH',tc.wagon, 1), '-',tc.level) `level`, + ELSE + SELECT CONCAT(tc.collectionFk,' ', SUBSTRING('ABCDEFGH',tc.wagon, 1), '-',tc.level) `level`, tc.ticketFk, LEFT(IF(t.routeFk IS null, am.name, zo.name ),12) agencyDescription, am.name, t.clientFk, - CAST(IF(ic.code = 'plant', CONCAT(MAX(i.size),' cm'),count(*)) AS CHAR) notes, + CAST(IF(ic.code = 'plant', CONCAT(MAX(i.size),' cm'),count(*)) AS CHAR) notes, w.code workerCode, tt.labelCount, - IF(HOUR(t.shipped),TIME(t.shipped),TIME(zo.HOUR)) as horaagencia, + IF(HOUR(t.shipped),TIME(t.shipped),TIME(zo.HOUR)) horaagencia, t.shipped, - count(*) AS lineas, + count(*) lineas, t.nickName, - CONCAT(CAST(sv.litros / 1000 AS DECIMAL(5,2)), 'm3') m3 + CONCAT(CAST(SUM(sv.volume) AS DECIMAL(5,2)) , "m³") m3 FROM vn.ticket t JOIN vn.ticketCollection tc ON tc.ticketFk = t.id JOIN vn.collection c ON c.id = tc.collectionFk @@ -73859,15 +73663,13 @@ BEGIN JOIN vn.agencyMode am on am.id = t.agencyModeFk LEFT JOIN vn.ticketTrolley tt ON tt.ticket = t.id LEFT JOIN vn.address a ON a.id = t.addressFk - LEFT JOIN vn.route r on r.id = t.routeFk + LEFT JOIN vn.route r ON r.id = t.routeFk LEFT JOIN vn.zoneEstimatedDelivery ze ON ze.zoneFk = t.zoneFk - LEFT JOIN vn.agencyMode agm on r.agencyModeFk =agm.id + LEFT JOIN vn.agencyMode agm ON r.agencyModeFk =agm.id LEFT JOIN vn.zone zo ON t.zoneFk = zo.id WHERE tc.collectionFk = vCollectionFk GROUP BY t.id; - END IF; - END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -75852,6 +75654,7 @@ BEGIN MAX(IF(st.semaphore <=> 1, TRUE, FALSE)) as isPreviousPrepared, MAX(IF(st.semaphore <=> 2, TRUE, FALSE)) as isPrepared, MAX(IF(st.semaphore <=> 3, TRUE, FALSE)) as isControlled, + MAX(IF(st.semaphore <=> 4, TRUE, FALSE)) as isPreControlled, ic.color, ip.productor, s.discount, @@ -75877,7 +75680,7 @@ BEGIN str.originalQuantity as startQuantity, -- eliminar cuando tengamos la nueva apk IFNULL(c.workerFk,getUser()) as workerFk, IFNULL(SUM(iss.quantity),0) as pickedQuantity, - i.packingShelve -- PAk 21/12/21 + i.packingShelve FROM vn.sale s JOIN tmp.ticket t ON t.id = s.ticketFk JOIN vn.ticket tt ON tt.id = t.id @@ -75895,7 +75698,7 @@ BEGIN LEFT JOIN vn.saleGroupDetail sgd ON sgd.saleFk = s.id LEFT JOIN vn.saleGroup sg ON sg.id = sgd.saleGroupFk LEFT JOIN vn.parking p ON p.id = sg.parkingFk - WHERE (i.itemPackingTypeFk = c.itemPackingTypeFk OR ISNULL(c.itemPackingTypeFk)) + -- WHERE (i.itemPackingTypeFk = c.itemPackingTypeFk OR ISNULL(c.itemPackingTypeFk)) GROUP BY s.id; DROP TEMPORARY TABLE tmp.ticket; @@ -76584,7 +76387,7 @@ proc: BEGIN LEAVE l; END IF; - SELECT t.refFk IS NULL AND (IFNULL(ts.alertLevel, 0) = 0 OR s.price = 0), + SELECT t.refFk IS NULL, s.ticketFk, s.itemFk , t.zoneFk, @@ -76801,7 +76604,7 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `sectorProductivity` */; +/*!50003 DROP PROCEDURE IF EXISTS `sectorProductivity_add` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -76811,7 +76614,7 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `sectorProductivity`() +CREATE DEFINER=`root`@`%` PROCEDURE `sectorProductivity_add`() BEGIN DECLARE vDatedFrom DATETIME; @@ -76821,13 +76624,14 @@ BEGIN CALL timeControl_calculateAll(vDatedFrom, vDatedTo); - SELECT sub.*, SUM(wp.volume) volume, IFNULL(CAST(tc.timeWorkDecimal AS DECIMAL (10,2)) , 0) AS hourWorked + INSERT INTO sectorProductivity(workerFk, firstName, lastName, sector, ticketCount, saleCount, volume, hourWorked, dated) + SELECT sub.*, SUM(wp.volume) volume, IFNULL(CAST(tc.timeWorkDecimal AS DECIMAL (10,2)) , 0) AS hourWorked, DATE(vDatedFrom) dated FROM( SELECT w.id workerFk, w.firstName, - w.lastName, - se.description, - COUNT(DISTINCT t.id) ticketCount, + w.lastName, + se.description sector, + COUNT(DISTINCT t.id) ticketCount, COUNT(st.saleFk) saleCount FROM vn.saleTracking st JOIN vn.worker w ON w.id = st.workerFk @@ -76839,9 +76643,9 @@ BEGIN AND se.code IN ('ALGEMESI ARTIFI','COMPLEMENTOS') GROUP BY w.id ) sub + LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = sub.workerFk LEFT JOIN bs.workerProductivity wp ON wp.workerFk = sub.workerFk - LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = sub.workerFk - WHERE wp.dated > vDatedFrom + WHERE wp.dated = vDatedFrom GROUP BY sub.workerFk; END ;; @@ -80970,6 +80774,9 @@ DELIMITER ; DELIMITER ;; CREATE DEFINER=`root`@`%` PROCEDURE `ticketStateToday_setOnchecking`(vParamFk INT) BEGIN + /* + * @deprecated:utilizar ticketStateToday_setState + */ DECLARE vAlertLevel INT; @@ -81004,6 +80811,11 @@ DELIMITER ;; CREATE DEFINER=`root`@`%` PROCEDURE `ticketStateToday_setOnPreviousChecking`(vParamFk INT) BEGIN + /* + * @deprecated:utilizar ticketStateToday_setState + */ + + /* * Cambia el estado del ticket al estado de "control previa" * @@ -81024,6 +80836,46 @@ BEGIN END IF; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `ticketStateToday_setState` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `ticketStateToday_setState`(vTicketFk INT, vStateCode VARCHAR(45)) +BEGIN + + /* Modifica el estado de un ticket de hoy + * + * @param vTicketFk el id del ticket + * @param vStateCode estado a modificar del ticket + * + */ + + DECLARE vAlertLevel INT; + + SELECT s.alertLevel INTO vAlertLevel + FROM state s + JOIN ticketStateToday tst ON tst.state = s.id + WHERE tst.ticket = vTicketFk + LIMIT 1; + + IF vAlertLevel < 2 THEN + + CALL vn.ticket_setState(vTicketFk, vStateCode); + + END IF; + END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -81038,11 +80890,15 @@ DELIMITER ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; CREATE DEFINER=`root`@`%` PROCEDURE `ticketStateUpdate`(vTicketFk INT, vStateCode VARCHAR(45)) BEGIN + /* + * @deprecated:utilizar ticket_setState + */ + DECLARE vAlertLevel INT; SELECT s.alertLevel INTO vAlertLevel @@ -81259,7 +81115,6 @@ BEGIN UPDATE vn.saleTracking st JOIN vn.state s ON s.code = 'OK PREVIOUS' - JOIN vncontrol.accion a ON a.accion_id = st.actionFk JOIN vn.state s2 ON s2.id = st.stateFk SET st.stateFk = s.id WHERE workerFk = vn.getUser() @@ -81279,8 +81134,8 @@ BEGIN SELECT s.ticketFk, s.itemFk, i.longName, - i.itemPackingTypeFk, - i.subName, + IFNULL(i.itemPackingTypeFk,' ') itemPackingTypeFk, + IFNULL(i.subName ,' ') subName, s.quantity originalQuantity , s.quantity, w.code workerCode, @@ -84210,6 +84065,47 @@ DELIMITER ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 DROP PROCEDURE IF EXISTS `ticket_setState` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`%` PROCEDURE `ticket_setState`(vTicketFk INT, vStateCode VARCHAR(45)) +BEGIN + + /* Modifica el estado de un ticket + * + * @param vTicketFk el id del ticket + * @param vStateCode estado a modificar del ticket + * + */ + + DECLARE vAlertLevel INT; + + SELECT s.alertLevel INTO vAlertLevel + FROM vn.state s + JOIN vn.ticketState ts ON ts.stateFk = s.id + WHERE ts.ticketFk = vTicketFk; + + IF !(vStateCode = 'ON_CHECKING' AND vAlertLevel > 1) THEN + + INSERT INTO vncontrol.inter(state_id, Id_Ticket, Id_Trabajador) + SELECT id, vTicketFk, account.myUser_getId() + FROM vn.state + WHERE `code` = vStateCode collate utf8_unicode_ci; + + END IF; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 DROP PROCEDURE IF EXISTS `ticket_splitItemPackingType` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -84316,6 +84212,7 @@ proc:BEGIN SELECT itemPackingTypeFk INTO vItemPackingTypeFk FROM tmp.saleGroup sg + WHERE NOT ISNULL(sg.itemPackingTypeFk) ORDER BY sg.totalLitros LIMIT 1; @@ -84330,215 +84227,6 @@ proc:BEGIN DROP TEMPORARY TABLE tmp.sale; DROP TEMPORARY TABLE tmp.saleGroup; -END ;; -DELIMITER ; -/*!50003 SET sql_mode = @saved_sql_mode */ ; -/*!50003 SET character_set_client = @saved_cs_client */ ; -/*!50003 SET character_set_results = @saved_cs_results */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `ticket_splitItemPackingType_beta` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8 */ ; -/*!50003 SET character_set_results = utf8 */ ; -/*!50003 SET collation_connection = utf8_general_ci */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `ticket_splitItemPackingType_beta`(vTicketFk INT) -proc:BEGIN - - /* - * Clona y reparte las ventas de un ticket en funcion del tipo de empaquetado - * - * @param vTicketFk Identificador de vn.ticket - * @return table tmp.ticketIPT(ticketFk, itemPackingTypeFk) - */ - - - DECLARE vItemPackingTypeFk VARCHAR(1); - - DECLARE vNewTicketFk INT; - - DECLARE vPackingTypesToSplit INT; - - DECLARE vDone INT DEFAULT FALSE; - - DECLARE cur1 CURSOR FOR - SELECT itemPackingTypeFk - FROM tmp.saleGroup - WHERE itemPackingTypeFk IS NOT NULL; - - DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; - - DROP TEMPORARY TABLE IF EXISTS tmp.sale; - CREATE TEMPORARY TABLE tmp.sale - (PRIMARY KEY (id)) - SELECT s.id, i.itemPackingTypeFk , sv.litros - FROM vn.sale s - JOIN vn.item i ON i.id = s.itemFk - JOIN vn.saleVolume sv ON sv.saleFk = s.id - WHERE s.ticketFk = vTicketFk; - - DROP TEMPORARY TABLE IF EXISTS tmp.saleGroup; - CREATE TEMPORARY TABLE tmp.saleGroup - SELECT itemPackingTypeFk , sum(litros) AS totalLitros - FROM tmp.sale - GROUP BY itemPackingTypeFk; - - SELECT COUNT(*) INTO vPackingTypesToSplit - FROM tmp.saleGroup - WHERE itemPackingTypeFk IS NOT NULL; - - DROP TEMPORARY TABLE IF EXISTS tmp.ticketIPT; - CREATE TEMPORARY TABLE tmp.ticketIPT - (ticketFk INT, - itemPackingTypeFk VARCHAR(1)); - - CASE vPackingTypesToSplit - - WHEN 0 THEN - - INSERT INTO tmp.ticketIPT(ticketFk, itemPackingTypeFk) - VALUES(vTicketFk, 'H'); - - WHEN 1 THEN - - INSERT INTO tmp.ticketIPT(ticketFk, itemPackingTypeFk) - SELECT vTicketFk, itemPackingTypeFk - FROM tmp.saleGroup - WHERE itemPackingTypeFk IS NOT NULL; - ELSE - - OPEN cur1; - - FETCH cur1 INTO vItemPackingTypeFk; - - INSERT INTO tmp.ticketIPT(ticketFk, itemPackingTypeFk) - VALUES(vTicketFk, vItemPackingTypeFk); - - read_loop: LOOP - - FETCH cur1 INTO vItemPackingTypeFk; - - IF vDone THEN - LEAVE read_loop; - END IF; - - CALL vn.ticket_Clone(vTicketFk, vNewTicketFk); - - INSERT INTO tmp.ticketIPT(ticketFk, itemPackingTypeFk) - VALUES(vNewTicketFk, vItemPackingTypeFk); - - END LOOP; - - CLOSE cur1; - - UPDATE vn.sale s - JOIN tmp.sale ts ON ts.id = s.id - JOIN tmp.ticketIPT t ON t.itemPackingTypeFk = ts.itemPackingTypeFk - SET s.ticketFk = t.ticketFk; - - SELECT itemPackingTypeFk INTO vItemPackingTypeFk - FROM tmp.saleGroup sg - ORDER BY sg.totalLitros - LIMIT 1; - - UPDATE vn.sale s - JOIN tmp.sale ts ON ts.id = s.id - JOIN tmp.ticketIPT t ON t.itemPackingTypeFk = vItemPackingTypeFk - SET s.ticketFk = t.ticketFk - WHERE ISNULL(ts.itemPackingTypeFk); - - END CASE; - - DROP TEMPORARY TABLE tmp.sale; - DROP TEMPORARY TABLE tmp.saleGroup; - -END ;; -DELIMITER ; -/*!50003 SET sql_mode = @saved_sql_mode */ ; -/*!50003 SET character_set_client = @saved_cs_client */ ; -/*!50003 SET character_set_results = @saved_cs_results */ ; -/*!50003 SET collation_connection = @saved_col_connection */ ; -/*!50003 DROP PROCEDURE IF EXISTS `ticket_splitItemPackingType__` */; -/*!50003 SET @saved_cs_client = @@character_set_client */ ; -/*!50003 SET @saved_cs_results = @@character_set_results */ ; -/*!50003 SET @saved_col_connection = @@collation_connection */ ; -/*!50003 SET character_set_client = utf8 */ ; -/*!50003 SET character_set_results = utf8 */ ; -/*!50003 SET collation_connection = utf8_general_ci */ ; -/*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ; -DELIMITER ;; -CREATE DEFINER=`root`@`%` PROCEDURE `ticket_splitItemPackingType__`(vTicketFk INT) -BEGIN - - /* - * Clona y reparte las ventas de un ticket en funcion del tipo de empaquetado - * - */ - - DECLARE vNewItemPackingTypeFk VARCHAR(1); - DECLARE vNewTicketFk INT; - DECLARE vCollectionFk INT; - DECLARE vSplittedLines INT; - DECLARE vPickedLines INT; - -- DECLARE vIsPickUp BOOL; - - SELECT collectionFk INTO vCollectionFk - FROM vn.ticketCollection tc - WHERE tc.ticketFk = vTicketFk - LIMIT 1; - - DROP TEMPORARY TABLE IF EXISTS tmp.ticketIPT; - CREATE TEMPORARY TABLE tmp.ticketIPT - SELECT DISTINCT s.ticketFk, i.itemPackingTypeFk - FROM vn.sale s - JOIN vn.item i ON i.id = s.itemFk - WHERE s.ticketFk = vTicketFk; - /* - SELECT count(*) INTO vIsPickUp - FROM vn.ticket t - JOIN vn.agencyMode am ON am.id = t.agencyModeFk - WHERE t.id = vTicketFk - AND am.name = 'REC_ALGEMESI'; - - WHILE NOT vIsPickUp AND (SELECT count(*) FROM tmp.ticketIPT WHERE ticketFk = vTicketFk ) > 1 DO - */ - WHILE (SELECT count(*) FROM tmp.ticketIPT WHERE ticketFk = vTicketFk ) > 1 DO - - SELECT MIN(itemPackingTypeFk) INTO vNewItemPackingTypeFk - FROM tmp.ticketIPT - WHERE ticketFk = vTicketFk; - - CALL vn.ticket_Clone(vTicketFk, vNewTicketFk); - - UPDATE tmp.ticketIPT - SET ticketFk = vNewTicketFk - WHERE itemPackingTypeFk = vNewItemPackingTypeFk; - - SELECT count(*), sum(isPicked != 0) INTO vSplittedLines, vPickedLines - FROM vn.sale s - JOIN vn.item i ON i.id = s.itemFk - WHERE s.ticketFk = vTicketFk - AND i.itemPackingTypeFk = vNewItemPackingTypeFk; - - UPDATE vn.sale s - JOIN vn.item i ON i.id = s.itemFk - SET s.ticketFk = vNewTicketFk - WHERE s.ticketFk = vTicketFk - AND i.itemPackingTypeFk = vNewItemPackingTypeFk; - - UPDATE vn.collection - SET saleTotalCount = saleTotalCount - vSplittedLines, - salePickedCount = salePickedCount - vPickedLines - WHERE id = vCollectionFk; - - END WHILE; - - END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; @@ -96716,4 +96404,4 @@ USE `vncontrol`; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2022-01-03 7:26:08 +-- Dump completed on 2022-01-13 7:46:58 diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 2900a285b..f0a5c37b5 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -304,6 +304,16 @@ export default { saveNewInsuranceCredit: 'vn-client-credit-insurance-insurance-create button[type="submit"]', anyCreditInsuranceLine: 'vn-client-credit-insurance-insurance-index vn-tbody > vn-tr', }, + clientDefaulter: { + anyClient: 'vn-client-defaulter-index vn-tbody > vn-tr', + firstClientName: 'vn-client-defaulter-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(2) > span', + firstSalesPersonName: 'vn-client-defaulter-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(3) > span', + firstObservation: 'vn-client-defaulter-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(6) > vn-textarea[ng-model="defaulter.observation"]', + allDefaulterCheckbox: 'vn-client-defaulter-index vn-thead vn-multi-check', + addObservationButton: 'vn-client-defaulter-index vn-button[icon="icon-notes"]', + observation: '.vn-dialog.shown vn-textarea[ng-model="$ctrl.defaulter.observation"]', + saveButton: 'button[response="accept"]' + }, clientContacts: { addContactButton: 'vn-client-contact vn-icon[icon="add_circle"]', name: 'vn-client-contact vn-textfield[ng-model="contact.name"]', @@ -526,6 +536,7 @@ export default { acceptDialog: '.vn-dialog.shown button[response="accept"]', acceptChangeHourButton: '.vn-dialog.shown button[response="accept"]', descriptorDeliveryDate: 'vn-ticket-descriptor slot-body > .attributes > vn-label-value:nth-child(4) > section > span', + descriptorDeliveryAgency: 'vn-ticket-descriptor slot-body > .attributes > vn-label-value:nth-child(5) > section > span', acceptInvoiceOutButton: '.vn-confirm.shown button[response="accept"]', acceptDeleteStowawayButton: '.vn-dialog.shown button[response="accept"]' }, @@ -603,10 +614,12 @@ export default { ticketBasicData: { agency: 'vn-autocomplete[ng-model="$ctrl.agencyModeId"]', zone: 'vn-autocomplete[ng-model="$ctrl.zoneId"]', + shipped: 'vn-date-picker[ng-model="$ctrl.shipped"]', nextStepButton: 'vn-step-control .buttons > section:last-child vn-button', finalizeButton: 'vn-step-control .buttons > section:last-child button[type=submit]', stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > vn-side-menu div:nth-child(4)', chargesReason: 'vn-ticket-basic-data-step-two div:nth-child(3) > vn-radio', + withoutNegatives: 'vn-check[ng-model="$ctrl.ticket.withoutNegatives"]', }, ticketComponents: { base: 'vn-ticket-components > vn-side-menu div:nth-child(1) > div:nth-child(2)' diff --git a/e2e/paths/02-client/21_defaulter.spec.js b/e2e/paths/02-client/21_defaulter.spec.js new file mode 100644 index 000000000..89b5c5761 --- /dev/null +++ b/e2e/paths/02-client/21_defaulter.spec.js @@ -0,0 +1,73 @@ +import selectors from '../../helpers/selectors.js'; +import getBrowser from '../../helpers/puppeteer'; + +describe('Client defaulter path', () => { + let browser; + let page; + + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + await page.loginAndModule('insurance', 'client'); + await page.accessToSection('client.defaulter.index'); + }); + + afterAll(async() => { + await browser.close(); + }); + + it('should count the amount of clients in the turns section', async() => { + const result = await page.countElement(selectors.clientDefaulter.anyClient); + + expect(result).toEqual(5); + }); + + it('should check contain expected client', async() => { + const clientName = + await page.waitToGetProperty(selectors.clientDefaulter.firstClientName, 'innerText'); + const salesPersonName = + await page.waitToGetProperty(selectors.clientDefaulter.firstSalesPersonName, 'innerText'); + + expect(clientName).toEqual('Ororo Munroe'); + expect(salesPersonName).toEqual('salesPerson'); + }); + + it('should first observation not changed', async() => { + const expectedObservation = 'Madness, as you know, is like gravity, all it takes is a little push'; + const result = await page.waitToGetProperty(selectors.clientDefaulter.firstObservation, 'value'); + + expect(result).toContain(expectedObservation); + }); + + it('should not add empty observation', async() => { + await page.waitToClick(selectors.clientDefaulter.allDefaulterCheckbox); + + await page.waitToClick(selectors.clientDefaulter.addObservationButton); + await page.write(selectors.clientDefaulter.observation, ''); + await page.waitToClick(selectors.clientDefaulter.saveButton); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain(`The message can't be empty`); + }); + + it('shoul checked all defaulters', async() => { + await page.loginAndModule('insurance', 'client'); + await page.accessToSection('client.defaulter.index'); + + await page.waitToClick(selectors.clientDefaulter.allDefaulterCheckbox); + }); + + it('should add observation for all clients', async() => { + await page.waitToClick(selectors.clientDefaulter.addObservationButton); + await page.write(selectors.clientDefaulter.observation, 'My new observation'); + await page.waitToClick(selectors.clientDefaulter.saveButton); + }); + + it('should first observation changed', async() => { + const message = await page.waitForSnackbar(); + const result = await page.waitToGetProperty(selectors.clientDefaulter.firstObservation, 'value'); + + expect(message.text).toContain('Observation saved!'); + expect(result).toContain('My new observation'); + }); +}); diff --git a/e2e/paths/05-ticket/06_basic_data_steps.spec.js b/e2e/paths/05-ticket/06_basic_data_steps.spec.js index a5f9a60cf..fa118c25d 100644 --- a/e2e/paths/05-ticket/06_basic_data_steps.spec.js +++ b/e2e/paths/05-ticket/06_basic_data_steps.spec.js @@ -83,4 +83,62 @@ describe('Ticket Edit basic data path', () => { await page.waitToClick(selectors.ticketBasicData.finalizeButton); await page.waitForState('ticket.card.summary'); }); + + it(`should not find ticket`, async() => { + await page.doSearch('29'); + const count = await page.countElement(selectors.ticketsIndex.searchResult); + + expect(count).toEqual(0); + }); + + it(`should split ticket without negatives`, async() => { + const newAgency = 'Silla247'; + const newDate = new Date(); + newDate.setDate(newDate.getDate() - 1); + + await page.accessToSearchResult('14'); + await page.accessToSection('ticket.card.basicData.stepOne'); + + await page.autocompleteSearch(selectors.ticketBasicData.agency, newAgency); + await page.pickDate(selectors.ticketBasicData.shipped, newDate); + + await page.waitToClick(selectors.ticketBasicData.nextStepButton); + + await page.waitToClick(selectors.ticketBasicData.withoutNegatives); + await page.waitToClick(selectors.ticketBasicData.finalizeButton); + + await page.waitForState('ticket.card.summary'); + + const newTicketAgency = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryAgency, 'innerText'); + const newTicketDate = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText'); + + expect(newAgency).toEqual(newTicketAgency); + expect(newTicketDate).toContain(newDate.getDate()); + }); + + it(`should new ticket have sale of old ticket`, async() => { + await page.accessToSection('ticket.card.sale'); + await page.waitForState('ticket.card.sale'); + + const item = await page.waitToGetProperty(selectors.ticketSales.firstSaleId, 'innerText'); + + expect(item).toEqual('4'); + }); + + it(`should old ticket have old date and agency`, async() => { + const oldDate = new Date(); + const oldAgency = 'Super-Man delivery'; + + await page.accessToSearchResult('14'); + + const oldTicketAgency = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryAgency, 'innerText'); + const oldTicketDate = await page + .waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText'); + + expect(oldTicketAgency).toEqual(oldAgency); + expect(oldTicketDate).toContain(oldDate.getDate()); + }); }); diff --git a/e2e/paths/12-entry/07_buys.spec.js b/e2e/paths/12-entry/07_buys.spec.js index a39e88ce6..4487394df 100644 --- a/e2e/paths/12-entry/07_buys.spec.js +++ b/e2e/paths/12-entry/07_buys.spec.js @@ -9,7 +9,7 @@ describe('Entry import, create and edit buys path', () => { browser = await getBrowser(); page = browser.page; await page.loginAndModule('buyer', 'entry'); - await page.accessToSearchResult('1'); + await page.accessToSearchResult('3'); }); afterAll(async() => { @@ -19,7 +19,7 @@ describe('Entry import, create and edit buys path', () => { it('should count the summary buys and find there only one at this point', async() => { const buysCount = await page.countElement(selectors.entrySummary.anyBuyLine); - expect(buysCount).toEqual(1); + expect(buysCount).toEqual(2); }); it('should navigate to the buy section and then click the import button opening the import form', async() => { @@ -41,11 +41,10 @@ describe('Entry import, create and edit buys path', () => { await page.waitForTextInField(selectors.entryBuys.ref, '200573095, 200573106, 200573117, 200573506'); await page.waitForTextInField(selectors.entryBuys.observation, '729-6340 2846'); - await page.autocompleteSearch(selectors.entryBuys.firstImportedItem, 'Ranged Reinforced weapon pistol 9mm'); - const itemName = 'Melee Reinforced weapon heavy shield 1x0.5m'; - await page.autocompleteSearch(selectors.entryBuys.secondImportedItem, itemName); - await page.autocompleteSearch(selectors.entryBuys.thirdImportedItem, 'Container medical box 1m'); - await page.autocompleteSearch(selectors.entryBuys.fourthImportedItem, 'Container ammo box 1m'); + await page.autocompleteSearch(selectors.entryBuys.firstImportedItem, 'Ranged weapon longbow 2m'); + await page.autocompleteSearch(selectors.entryBuys.secondImportedItem, 'Ranged weapon longbow 2m'); + await page.autocompleteSearch(selectors.entryBuys.thirdImportedItem, 'Ranged weapon sniper rifle 300mm'); + await page.autocompleteSearch(selectors.entryBuys.fourthImportedItem, 'Melee weapon heavy shield 1x0.5m'); await page.waitToClick(selectors.entryBuys.importBuysButton); @@ -57,7 +56,7 @@ describe('Entry import, create and edit buys path', () => { }); it('should count the buys to find 4 buys have been added', async() => { - await page.waitForNumberOfElements(selectors.entryBuys.anyBuyLine, 5); + await page.waitForNumberOfElements(selectors.entryBuys.anyBuyLine, 6); }); it('should delete the four buys that were just added', async() => { diff --git a/front/core/styles/icons/salixfont.css b/front/core/styles/icons/salixfont.css index 0ce465db7..ff2eaa1f5 100644 --- a/front/core/styles/icons/salixfont.css +++ b/front/core/styles/icons/salixfont.css @@ -23,71 +23,63 @@ -moz-osx-font-smoothing: grayscale; } -.icon-isTooLittle:before { - content: "\e91b"; -} -.icon-frozen:before { - content: "\e900"; -} -.icon-Person:before { - content: "\e901"; -} -.icon-handmadeArtificial:before { - content: "\e902"; -} -.icon-fruit:before { - content: "\e903"; -} -.icon-funeral:before { - content: "\e904"; -} -.icon-treatments:before { - content: "\e905"; -} -.icon-preserved:before { - content: "\e906"; -} -.icon-greenery:before { - content: "\e907"; -} -.icon-plant:before { - content: "\e908"; -} -.icon-handmade:before { - content: "\e909"; + +.icon-100:before { + content: "\e95a"; } .icon-accessory:before { content: "\e90a"; } -.icon-artificial:before { - content: "\e90b"; +.icon-account:before { + content: "\e92a"; } -.icon-flower:before { - content: "\e90c"; -} -.icon-fixedPrice:before { - content: "\e90d"; +.icon-actions:before { + content: "\e960"; } .icon-addperson:before { content: "\e90e"; } -.icon-supplierfalse:before { - content: "\e90f"; +.icon-agency:before { + content: "\e938"; } -.icon-invoice-out:before { - content: "\e910"; +.icon-albaran:before { + content: "\e94d"; } -.icon-invoice-in:before { - content: "\e911"; +.icon-anonymous:before { + content: "\e930"; } -.icon-invoice-in-create:before { - content: "\e912"; +.icon-apps:before { + content: "\e951"; +} +.icon-artificial:before { + content: "\e90b"; +} +.icon-attach:before { + content: "\e92e"; +} +.icon-barcode:before { + content: "\e971"; +} +.icon-basket:before { + content: "\e914"; } .icon-basketadd:before { content: "\e913"; } -.icon-basket:before { - content: "\e914"; +.icon-bin:before { + content: "\e96f"; +} +.icon-botanical:before { + content: "\e972"; +} +.icon-bucket:before { + content: "\e97a"; +} +.icon-buscaman:before { + content: "\e93b"; +} +.icon-buyrequest:before { + content: "\e932"; } .icon-calc_volum .path1:before { content: "\e915"; @@ -112,309 +104,294 @@ 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 { - 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-calendar:before { + content: "\e93d"; } .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-client:before { + content: "\e928"; } .icon-clone:before { content: "\e973"; } -.icon-photo:before { - content: "\e974"; +.icon-columnadd:before { + content: "\e954"; } -.icon-sms:before { - content: "\e975"; +.icon-columndelete:before { + content: "\e953"; } -.icon-eye:before { - content: "\e976"; +.icon-components:before { + content: "\e946"; } -.icon-doc:before { - content: "\e977"; +.icon-consignatarios:before { + content: "\e93f"; } -.icon-package:before { - content: "\e978"; +.icon-control:before { + content: "\e949"; } -.icon-settings:before { - content: "\e979"; +.icon-credit:before { + content: "\e927"; } -.icon-bucket:before { - content: "\e97a"; +.icon-defaulter:before { + content: "\e94b"; } -.icon-mandatory:before { - content: "\e97b"; +.icon-deletedTicket:before { + content: "\e935"; } -.icon-recovery:before { - content: "\e97c"; +.icon-deleteline:before { + content: "\e955"; } -.icon-payment:before { - content: "\e97e"; +.icon-delivery:before { + content: "\e939"; } -.icon-invoices:before { - content: "\e97f"; +.icon-deliveryprices:before { + content: "\e91c"; } -.icon-grid:before { - content: "\e980"; -} -.icon-logout:before { - content: "\e981"; -} -.icon-web:before { - content: "\e982"; -} -.icon-albaran:before { - content: "\e983"; +.icon-details:before { + content: "\e961"; } .icon-dfiscales:before { content: "\e984"; } +.icon-disabled:before { + content: "\e921"; +} +.icon-doc:before { + content: "\e977"; +} +.icon-entry:before { + content: "\e934"; +} +.icon-exit:before { + content: "\e92f"; +} +.icon-eye:before { + content: "\e976"; +} +.icon-fixedPrice:before { + content: "\e90d"; +} +.icon-flower:before { + content: "\e90c"; +} +.icon-frozen:before { + content: "\e900"; +} +.icon-fruit:before { + content: "\e903"; +} +.icon-funeral:before { + content: "\e904"; +} +.icon-greenery:before { + content: "\e907"; +} +.icon-greuge:before { + content: "\e944"; +} +.icon-grid:before { + content: "\e980"; +} +.icon-handmade:before { + content: "\e909"; +} +.icon-handmadeArtificial:before { + content: "\e902"; +} +.icon-headercol:before { + content: "\e958"; +} +.icon-history:before { + content: "\e968"; +} +.icon-info:before { + content: "\e952"; +} +.icon-inventory:before { + content: "\e92b"; +} +.icon-invoice:before { + content: "\e923"; +} +.icon-invoice-in:before { + content: "\e911"; +} +.icon-invoice-in-create:before { + content: "\e912"; +} +.icon-invoice-out:before { + content: "\e910"; +} +.icon-isTooLittle:before { + content: "\e91b"; +} +.icon-item:before { + content: "\e956"; +} +.icon-languaje:before { + content: "\e926"; +} +.icon-lines:before { + content: "\e942"; +} +.icon-linesprepaired:before { + content: "\e948"; +} +.icon-logout:before { + content: "\e936"; +} +.icon-mana:before { + content: "\e96a"; +} +.icon-mandatory:before { + content: "\e97b"; +} +.icon-net:before { + content: "\e931"; +} +.icon-niche:before { + content: "\e96c"; +} +.icon-no036:before { + content: "\e920"; +} +.icon-noPayMethod:before { + content: "\e905"; +} +.icon-notes:before { + content: "\e941"; +} +.icon-noweb:before { + content: "\e91f"; +} +.icon-onlinepayment:before { + content: "\e91d"; +} +.icon-package:before { + content: "\e978"; +} +.icon-payment:before { + content: "\e97e"; +} +.icon-pbx:before { + content: "\e93c"; +} +.icon-Person:before { + content: "\e901"; +} +.icon-pets:before { + content: "\e947"; +} +.icon-photo:before { + content: "\e924"; +} +.icon-planta:before { + content: "\e908"; +} +.icon-polizon:before { + content: "\e95e"; +} +.icon-preserved:before { + content: "\e906"; +} +.icon-recovery:before { + content: "\e97c"; +} +.icon-regentry:before { + content: "\e964"; +} +.icon-reserva:before { + content: "\e959"; +} +.icon-revision:before { + content: "\e94a"; +} +.icon-risk:before { + content: "\e91e"; +} +.icon-services:before { + content: "\e94c"; +} +.icon-settings:before { + content: "\e979"; +} +.icon-shipment-01:before { + content: "\e929"; +} +.icon-sign:before { + content: "\e95d"; +} +.icon-sms:before { + content: "\e975"; +} +.icon-solclaim:before { + content: "\e95f"; +} +.icon-solunion:before { + content: "\e94e"; +} +.icon-splitline:before { + content: "\e93e"; +} +.icon-splur:before { + content: "\e970"; +} +.icon-stowaway:before { + content: "\e94f"; +} +.icon-supplier:before { + content: "\e925"; +} +.icon-supplierfalse:before { + content: "\e90f"; +} +.icon-tags:before { + content: "\e96d"; +} +.icon-tax:before { + content: "\e940"; +} +.icon-thermometer:before { + content: "\e933"; +} +.icon-ticket:before { + content: "\e96b"; +} +.icon-ticketAdd:before { + content: "\e945"; +} +.icon-traceability:before { + content: "\e962"; +} +.icon-transaction:before { + content: "\e966"; +} +.icon-treatments:before { + content: "\e922"; +} +.icon-unavailable:before { + content: "\e92c"; +} +.icon-volume:before { + content: "\e96e"; +} +.icon-wand:before { + content: "\e93a"; +} +.icon-web:before { + content: "\e982"; +} +.icon-wiki:before { + content: "\e92d"; +} +.icon-worker:before { + content: "\e957"; +} +.icon-zone:before { + content: "\e943"; +} diff --git a/front/core/styles/icons/salixfont.eot b/front/core/styles/icons/salixfont.eot index 98a111250..9325d3dae 100644 Binary files a/front/core/styles/icons/salixfont.eot and b/front/core/styles/icons/salixfont.eot differ diff --git a/front/core/styles/icons/salixfont.svg b/front/core/styles/icons/salixfont.svg index 5a77169f5..22c33c181 100644 --- a/front/core/styles/icons/salixfont.svg +++ b/front/core/styles/icons/salixfont.svg @@ -12,19 +12,19 @@ - + - + - - + + - + - - + + @@ -37,30 +37,31 @@ - + - - - - + + + + - - + + - + + - + - + - - + + @@ -72,21 +73,20 @@ - - + + - + - + - + - @@ -97,8 +97,6 @@ - - @@ -107,10 +105,8 @@ - - @@ -121,7 +117,6 @@ - @@ -130,11 +125,8 @@ - - + - - \ No newline at end of file diff --git a/front/core/styles/icons/salixfont.ttf b/front/core/styles/icons/salixfont.ttf index e0b54f54d..05df06213 100644 Binary files a/front/core/styles/icons/salixfont.ttf and b/front/core/styles/icons/salixfont.ttf differ diff --git a/front/core/styles/icons/salixfont.woff b/front/core/styles/icons/salixfont.woff index 4fa201895..70fca2294 100644 Binary files a/front/core/styles/icons/salixfont.woff and b/front/core/styles/icons/salixfont.woff differ diff --git a/front/package-lock.json b/front/package-lock.json new file mode 100644 index 000000000..a2f192f01 --- /dev/null +++ b/front/package-lock.json @@ -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=" + } + } +} diff --git a/loopback/common/models/loggable.js b/loopback/common/models/loggable.js index 956762be2..28a6075d0 100644 --- a/loopback/common/models/loggable.js +++ b/loopback/common/models/loggable.js @@ -291,7 +291,8 @@ module.exports = function(Self) { * @param {*} properties Modified object properties */ function removeUnloggable(definition, properties) { - const propList = Object.keys(properties); + const objectCopy = Object.assign({}, properties); + const propList = Object.keys(objectCopy); const propDefs = new Map(); for (let property in definition.properties) { @@ -302,10 +303,15 @@ module.exports = function(Self) { for (let property of propList) { const propertyDef = propDefs.get(property); + const firstChar = property.substring(0, 1); + const isPrivate = firstChar == '$'; - if (!propertyDef) return; + if (isPrivate || !propertyDef) + delete properties[property]; - if (propertyDef.log === false) + if (!propertyDef) continue; + + if (propertyDef.log === false || isPrivate) delete properties[property]; else if (propertyDef.logValue === false) properties[property] = null; diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 4be9085db..856ee57d8 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -210,6 +210,7 @@ "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 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 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", @@ -217,5 +218,6 @@ "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día", "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" + "You don't have privileges to create pay back": "No tienes permisos para crear un abono", + "The item is required": "El artículo es requerido" } \ No newline at end of file diff --git a/modules/account/back/model-config.json b/modules/account/back/model-config.json index 96372f427..c697bd3b9 100644 --- a/modules/account/back/model-config.json +++ b/modules/account/back/model-config.json @@ -20,6 +20,9 @@ "MailForward": { "dataSource": "vn" }, + "RoleConfig": { + "dataSource": "vn" + }, "RoleInherit": { "dataSource": "vn" }, diff --git a/modules/account/back/models/account-config.js b/modules/account/back/models/account-config.js index 83fe3332f..49e120a08 100644 --- a/modules/account/back/models/account-config.js +++ b/modules/account/back/models/account-config.js @@ -114,17 +114,22 @@ module.exports = Self => { 'bcryptPassword', 'updated' ], - include: { - relation: 'roles', - scope: { - include: { - relation: 'inherits', - scope: { - fields: ['name'] + include: [ + { + relation: 'roles', + scope: { + include: { + relation: 'inherits', + scope: { + fields: ['name'] + } } } + }, { + relation: 'role', + fields: ['name'] } - } + ] }); let info = { diff --git a/modules/account/back/models/role-config.js b/modules/account/back/models/role-config.js new file mode 100644 index 000000000..b5cfb7b83 --- /dev/null +++ b/modules/account/back/models/role-config.js @@ -0,0 +1,103 @@ + +module.exports = Self => { + Self.getSynchronizer = async function() { + return await Self.findOne({fields: ['id']}); + }; + + Object.assign(Self.prototype, { + async init() { + const [row] = await Self.rawSql('SELECT VERSION() AS `version`'); + if (row.version.includes('MariaDB')) + this.dbType = 'MariaDB'; + else + this.dbType = 'MySQL'; + }, + + async syncUser(userName, info, password) { + const mysqlHost = '%'; + + let mysqlUser = userName; + if (this.dbType == 'MySQL') mysqlUser = `!${mysqlUser}`; + + const [row] = await Self.rawSql( + `SELECT COUNT(*) AS nRows + FROM mysql.user + WHERE User = ? + AND Host = ?`, + [mysqlUser, mysqlHost] + ); + let userExists = row.nRows > 0; + + let isUpdatable = true; + if (this.dbType == 'MariaDB') { + const [row] = await Self.rawSql( + `SELECT Priv AS priv + FROM mysql.global_priv + WHERE User = ? + AND Host = ?`, + [mysqlUser, mysqlHost] + ); + const priv = row && JSON.parse(row.priv); + const role = priv && priv.default_role; + isUpdatable = !row || (role && role.startsWith('z-')); + } + + if (!isUpdatable) { + console.warn(`RoleConfig.syncUser(): User '${userName}' cannot be updated, not managed by me`); + return; + } + + if (info.hasAccount) { + if (password) { + if (!userExists) { + await Self.rawSql('CREATE USER ?@? IDENTIFIED BY ?', + [mysqlUser, mysqlHost, password] + ); + userExists = true; + } else { + switch (this.dbType) { + case 'MariaDB': + await Self.rawSql('ALTER USER ?@? IDENTIFIED BY ?', + [mysqlUser, mysqlHost, password] + ); + break; + default: + await Self.rawSql('SET PASSWORD FOR ?@? = PASSWORD(?)', + [mysqlUser, mysqlHost, password] + ); + } + } + } + + if (userExists && this.dbType == 'MariaDB') { + let role = `z-${info.user.role().name}`; + + try { + await Self.rawSql('REVOKE ALL, GRANT OPTION FROM ?@?', + [mysqlUser, mysqlHost] + ); + } catch (err) { + if (err.code == 'ER_REVOKE_GRANTS') + console.warn(`${err.code}: ${err.sqlMessage}: ${err.sql}`); + else + throw err; + } + await Self.rawSql('GRANT ? TO ?@?', + [role, mysqlUser, mysqlHost] + ); + + if (role) { + await Self.rawSql('SET DEFAULT ROLE ? FOR ?@?', + [role, mysqlUser, mysqlHost] + ); + } else { + await Self.rawSql('SET DEFAULT ROLE NONE FOR ?@?', + [mysqlUser, mysqlHost] + ); + } + } + } else if (userExists) + await Self.rawSql('DROP USER ?@?', [mysqlUser, mysqlHost]); + } + }); +}; diff --git a/modules/account/back/models/role-config.json b/modules/account/back/models/role-config.json new file mode 100644 index 000000000..c2abfcc38 --- /dev/null +++ b/modules/account/back/models/role-config.json @@ -0,0 +1,21 @@ +{ + "name": "RoleConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "account.roleConfig" + } + }, + "mixins": { + "AccountSynchronizer": {} + }, + "properties": { + "id": { + "type": "number", + "id": true + }, + "mysqlPassword": { + "type": "string" + } + } +} diff --git a/modules/client/back/methods/defaulter/filter.js b/modules/client/back/methods/defaulter/filter.js new file mode 100644 index 000000000..c06d1c51b --- /dev/null +++ b/modules/client/back/methods/defaulter/filter.js @@ -0,0 +1,90 @@ + +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; +const buildFilter = require('vn-loopback/util/filter').buildFilter; +const mergeFilters = require('vn-loopback/util/filter').mergeFilters; + +module.exports = Self => { + Self.remoteMethodCtx('filter', { + description: 'Find all instances of the model matched by filter from the data source.', + accessType: 'READ', + accepts: [ + { + arg: 'filter', + type: 'object', + description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', + http: {source: 'query'} + }, + { + arg: 'search', + type: 'string', + description: `If it's and integer searchs by id, otherwise it searchs by name` + } + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/filter`, + verb: 'GET' + } + }); + + Self.filter = async(ctx, filter, options) => { + const conn = Self.dataSource.connector; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const where = buildFilter(ctx.args, (param, value) => { + switch (param) { + case 'search': + return {or: [ + {'d.clientFk': value}, + {'d.clientName': {like: `%${value}%`}} + ]}; + } + }); + + filter = mergeFilters(ctx.args.filter, {where}); + + const stmts = []; + + const stmt = new ParameterizedSQL( + `SELECT * + FROM ( + SELECT + DISTINCT c.id clientFk, + c.name clientName, + c.salesPersonFk, + u.name salesPersonName, + d.amount, + co.created, + CONCAT(DATE(co.created), ' ', co.text) observation, + uw.id workerFk, + uw.name workerName, + c.creditInsurance, + d.defaulterSinced + FROM vn.defaulter d + JOIN vn.client c ON c.id = d.clientFk + LEFT JOIN vn.clientObservation co ON co.clientFk = c.id + LEFT JOIN account.user u ON u.id = c.salesPersonFk + LEFT JOIN account.user uw ON uw.id = co.workerFk + WHERE + d.created = CURDATE() + AND d.amount > 0 + ORDER BY co.created DESC) d` + ); + + stmt.merge(conn.makeWhere(filter.where)); + stmt.merge(`GROUP BY d.clientFk`); + stmt.merge(conn.makeOrderBy(filter.order)); + + const itemsIndex = stmts.push(stmt) - 1; + const sql = ParameterizedSQL.join(stmts, ';'); + const result = await conn.executeStmt(sql, myOptions); + + return itemsIndex === 0 ? result : result[itemsIndex]; + }; +}; diff --git a/modules/client/back/methods/defaulter/specs/filter.spec.js b/modules/client/back/methods/defaulter/specs/filter.spec.js new file mode 100644 index 000000000..145bb5132 --- /dev/null +++ b/modules/client/back/methods/defaulter/specs/filter.spec.js @@ -0,0 +1,63 @@ +const models = require('vn-loopback/server/server').models; + +describe('defaulter filter()', () => { + const authUserId = 9; + it('should all return the tickets matching the filter', async() => { + const tx = await models.Defaulter.beginTransaction({}); + + try { + const options = {transaction: tx}; + const filter = {}; + const ctx = {req: {accessToken: {userId: authUserId}}, args: {filter: filter}}; + + const result = await models.Defaulter.filter(ctx, null, options); + const firstRow = result[0]; + + expect(firstRow.clientFk).toEqual(1101); + expect(result.length).toEqual(5); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should return the defaulter with id', async() => { + const tx = await models.Defaulter.beginTransaction({}); + + try { + const options = {transaction: tx}; + const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 1101}}; + + const result = await models.Defaulter.filter(ctx, null, options); + const firstRow = result[0]; + + expect(firstRow.clientFk).toEqual(1101); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should return the defaulter matching the client name', async() => { + const tx = await models.Defaulter.beginTransaction({}); + + try { + const options = {transaction: tx}; + const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 'bruce'}}; + + const result = await models.Defaulter.filter(ctx, null, options); + const firstRow = result[0]; + + expect(firstRow.clientName).toEqual('Bruce Wayne'); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/client/back/methods/sms/send.js b/modules/client/back/methods/sms/send.js index 4e088d6ee..08daf83a1 100644 --- a/modules/client/back/methods/sms/send.js +++ b/modules/client/back/methods/sms/send.js @@ -52,12 +52,13 @@ module.exports = Self => { let response; try { if (process.env.NODE_ENV !== 'production') - params.fake = 1; - - const jsonTest = { - json: params - }; - response = await got.post(smsConfig.uri, jsonTest).json(); + response = {result: [{status: 'ok'}]}; + else { + const jsonTest = { + json: params + }; + response = await got.post(smsConfig.uri, jsonTest).json(); + } } catch (e) { console.error(e); } diff --git a/modules/client/back/models/defaulter.js b/modules/client/back/models/defaulter.js new file mode 100644 index 000000000..13bb1a614 --- /dev/null +++ b/modules/client/back/models/defaulter.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/defaulter/filter')(Self); +}; diff --git a/modules/client/back/models/defaulter.json b/modules/client/back/models/defaulter.json index 8d50356f1..829326435 100644 --- a/modules/client/back/models/defaulter.json +++ b/modules/client/back/models/defaulter.json @@ -8,6 +8,9 @@ } }, "properties": { + "id": { + "type": "Number" + }, "created": { "type": "Date" }, diff --git a/modules/client/front/defaulter/index.html b/modules/client/front/defaulter/index.html new file mode 100644 index 000000000..121556df2 --- /dev/null +++ b/modules/client/front/defaulter/index.html @@ -0,0 +1,186 @@ + + + + + + + + + +
+
+
Total
+ + +
+
+
+ + +
+
+ + + + + + + + Client + Comercial + + Balance D. + + + Author + + Last observation + + Credit I. + + From + + + + + + + + + + + {{::defaulter.clientName}} + + + + + {{::defaulter.salesPersonName | dashIfEmpty}} + + + {{::defaulter.amount}} + + + {{::defaulter.workerName | dashIfEmpty}} + + + + + + + {{::defaulter.creditInsurance}} + {{::defaulter.defaulterSinced | date: 'dd/MM/yyyy'}} + + + +
+
+ + + + + + + + + + + + + + Filter by selection + + + Exclude selection + + + Remove filter + + + Remove all filters + + + Copy value + + + + + + + +
+
{{$ctrl.$t('Add observation to all selected clients', {total: $ctrl.checked.length})}}
+ + + + +
+
+ + + + +
diff --git a/modules/client/front/defaulter/index.js b/modules/client/front/defaulter/index.js new file mode 100644 index 000000000..76afeb160 --- /dev/null +++ b/modules/client/front/defaulter/index.js @@ -0,0 +1,65 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; +import UserError from 'core/lib/user-error'; + +export default class Controller extends Section { + constructor($element, $) { + super($element, $); + this.defaulter = {}; + } + + get balanceDueTotal() { + let balanceDueTotal = 0; + + if (this.checked.length > 0) { + for (let defaulter of this.checked) + balanceDueTotal += defaulter.amount; + + return balanceDueTotal; + } + + return balanceDueTotal; + } + + get checked() { + const clients = this.$.model.data || []; + const checkedLines = []; + for (let defaulter of clients) { + if (defaulter.checked) + checkedLines.push(defaulter); + } + + return checkedLines; + } + + onResponse() { + if (!this.defaulter.observation) + throw new UserError(`The message can't be empty`); + + const params = []; + for (let defaulter of this.checked) { + params.push({ + text: this.defaulter.observation, + clientFk: defaulter.clientFk + }); + } + + this.$http.post(`ClientObservations`, params) .then(() => { + this.vnApp.showMessage(this.$t('Observation saved!')); + this.$state.reload(); + }); + } + + exprBuilder(param, value) { + switch (param) { + case 'clientName': + case 'salesPersonFk': + return {[`d.${param}`]: value}; + } + } +} + +ngModule.vnComponent('vnClientDefaulterIndex', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/client/front/defaulter/index.spec.js b/modules/client/front/defaulter/index.spec.js new file mode 100644 index 000000000..6428952ec --- /dev/null +++ b/modules/client/front/defaulter/index.spec.js @@ -0,0 +1,98 @@ +import './index'; +import crudModel from 'core/mocks/crud-model'; + +describe('client defaulter', () => { + describe('Component vnClientDefaulterIndex', () => { + let controller; + let $httpBackend; + + beforeEach(ngModule('client')); + + beforeEach(inject(($componentController, _$httpBackend_) => { + $httpBackend = _$httpBackend_; + const $element = angular.element(''); + controller = $componentController('vnClientDefaulterIndex', {$element}); + controller.$.model = crudModel; + controller.$.model.data = [ + {clientFk: 1101, amount: 125}, + {clientFk: 1102, amount: 500}, + {clientFk: 1103, amount: 250} + ]; + })); + + describe('checked() getter', () => { + it('should return the checked lines', () => { + const data = controller.$.model.data; + data[1].checked = true; + data[2].checked = true; + + const checkedRows = controller.checked; + + const firstCheckedRow = checkedRows[0]; + const secondCheckedRow = checkedRows[1]; + + expect(firstCheckedRow.clientFk).toEqual(1102); + expect(secondCheckedRow.clientFk).toEqual(1103); + }); + }); + + describe('balanceDueTotal() getter', () => { + it('should return balance due total', () => { + const data = controller.$.model.data; + data[1].checked = true; + data[2].checked = true; + + const checkedRows = controller.checked; + const expectedAmount = checkedRows[0].amount + checkedRows[1].amount; + + const result = controller.balanceDueTotal; + + expect(result).toEqual(expectedAmount); + }); + }); + + describe('onResponse()', () => { + it('should return error for empty message', () => { + let error; + try { + controller.onResponse(); + } catch (e) { + error = e; + } + + expect(error).toBeDefined(); + expect(error.message).toBe(`The message can't be empty`); + }); + + it('should return saved message', () => { + const data = controller.$.model.data; + data[1].checked = true; + controller.defaulter = {observation: 'My new observation'}; + + const params = [{text: controller.defaulter.observation, clientFk: data[1].clientFk}]; + + jest.spyOn(controller.vnApp, 'showMessage'); + $httpBackend.expect('POST', `ClientObservations`, params).respond(200, params); + + controller.onResponse(); + $httpBackend.flush(); + + expect(controller.vnApp.showMessage).toHaveBeenCalledWith('Observation saved!'); + }); + }); + + describe('exprBuilder()', () => { + it('should search by sales person', () => { + let expr = controller.exprBuilder('salesPersonFk', '5'); + + expect(expr).toEqual({'d.salesPersonFk': '5'}); + }); + + it('should search by client name', () => { + let expr = controller.exprBuilder('clientName', '1foo'); + + expect(expr).toEqual({'d.clientName': '1foo'}); + }); + }); + }); +}); diff --git a/modules/client/front/defaulter/locale/es.yml b/modules/client/front/defaulter/locale/es.yml new file mode 100644 index 000000000..172a3125d --- /dev/null +++ b/modules/client/front/defaulter/locale/es.yml @@ -0,0 +1,7 @@ +Last observation: Última observación +Add observation: Añadir observación +Search client: Buscar clientes +Add observation to all selected clients: Añadir observación a {{total}} cliente(s) seleccionado(s) +Credit I.: Crédito A. +Balance D.: Saldo V. +Worker who made the last observation: Trabajador que ha realizado la última observación \ No newline at end of file diff --git a/modules/client/front/index.js b/modules/client/front/index.js index 758b94e3f..6b35d392a 100644 --- a/modules/client/front/index.js +++ b/modules/client/front/index.js @@ -44,3 +44,4 @@ import './dms/create'; import './dms/edit'; import './consumption'; import './consumption-search-panel'; +import './defaulter'; diff --git a/modules/client/front/locale/es.yml b/modules/client/front/locale/es.yml index 1a5a570a7..107931377 100644 --- a/modules/client/front/locale/es.yml +++ b/modules/client/front/locale/es.yml @@ -33,6 +33,7 @@ Search client by id or name: Buscar clientes por identificador o nombre # Sections Clients: Clientes +Defaulter: Morosos New client: Nuevo cliente Fiscal data: Datos fiscales Billing data: Forma de pago diff --git a/modules/client/front/routes.json b/modules/client/front/routes.json index 765fbc637..753948f8e 100644 --- a/modules/client/front/routes.json +++ b/modules/client/front/routes.json @@ -6,7 +6,8 @@ "dependencies": ["worker", "invoiceOut"], "menus": { "main": [ - {"state": "client.index", "icon": "person"} + {"state": "client.index", "icon": "person"}, + {"state": "client.defaulter.index", "icon": "icon-defaulter"} ], "card": [ {"state": "client.card.basicData", "icon": "settings"}, @@ -360,6 +361,18 @@ "params": { "client": "$ctrl.client" } + }, + { + "url": "/defaulter", + "state": "client.defaulter", + "component": "ui-view", + "description": "Defaulter" + }, + { + "url": "/index?q", + "state": "client.defaulter.index", + "component": "vn-client-defaulter-index", + "description": "Defaulter" } ] } diff --git a/modules/entry/back/methods/entry/importBuys.js b/modules/entry/back/methods/entry/importBuys.js index f3bf37dde..fb2f5f452 100644 --- a/modules/entry/back/methods/entry/importBuys.js +++ b/modules/entry/back/methods/entry/importBuys.js @@ -52,23 +52,59 @@ module.exports = Self => { } try { - const entry = await models.Entry.findById(id, null, myOptions); + const entry = await models.Entry.findById(id, { + include: [{ + relation: 'travel', + scope: { + fields: ['warehouseInFk', 'landed'], + } + }] + }, myOptions); + await entry.updateAttributes({ observation: args.observation, ref: args.ref }, myOptions); + const travel = entry.travel(); + await Self.rawSql('CALL buyUltimate(?, ?)', [ + travel.warehouseInFk, + travel.landed + ], myOptions); + + const buyUltimate = await Self.rawSql(` + SELECT * + FROM tmp.buyUltimate + WHERE warehouseFk = ? + `, [travel.warehouseInFk], myOptions); + + const lastItemBuys = new Map(); + for (const buy of buyUltimate) + lastItemBuys.set(buy.itemFk, buy); + const buys = []; for (let buy of args.buys) { + if (!buy.itemFk) + throw new Error('The item is required'); + + const lastItemBuy = lastItemBuys.get(buy.itemFk); + + if (!lastItemBuy) continue; + + const lastBuy = await models.Buy.findById(lastItemBuy.buyFk, null, myOptions); + const stickers = 1; + const quantity = (stickers * buy.packing); buys.push({ entryFk: entry.id, itemFk: buy.itemFk, - stickers: 1, - quantity: 1, + stickers: stickers, + quantity: quantity, packing: buy.packing, grouping: buy.grouping, buyingValue: buy.buyingValue, - packageFk: buy.packageFk + packageFk: buy.packageFk, + groupingMode: lastBuy.groupingMode, + weight: lastBuy.weight }); await models.ItemMatchProperties.upsert({ @@ -79,6 +115,8 @@ module.exports = Self => { }, myOptions); } + if (!buys.length) return; + const createdBuys = await models.Buy.create(buys, myOptions); const buyIds = createdBuys.map(buy => buy.id); diff --git a/modules/entry/back/methods/entry/lastItemBuys.js b/modules/entry/back/methods/entry/lastItemBuys.js new file mode 100644 index 000000000..7e83f1e5f --- /dev/null +++ b/modules/entry/back/methods/entry/lastItemBuys.js @@ -0,0 +1,91 @@ +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; +const mergeFilters = require('vn-loopback/util/filter').mergeFilters; + +module.exports = Self => { + Self.remoteMethod('lastItemBuys', { + description: 'Returns a list of items from last buys', + accepts: [ + { + arg: 'id', + type: 'number', + required: true, + description: 'origin itemId', + http: {source: 'path'} + }, + { + arg: 'filter', + type: 'object', + description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string` + } + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/:id/lastItemBuys`, + verb: 'GET' + } + }); + + Self.lastItemBuys = async(id, filter, options) => { + const conn = Self.dataSource.connector; + const models = Self.app.models; + const where = {isActive: true}; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + filter = mergeFilters(filter, {where}); + + const entry = await models.Entry.findById(id, { + include: [{ + relation: 'travel', + scope: { + fields: ['warehouseInFk', 'landed'], + } + }] + }, myOptions); + + const travel = entry.travel(); + + const stmts = []; + let stmt; + + stmt = new ParameterizedSQL(`CALL buyUltimate(?, ?)`, [ + travel.warehouseInFk, + travel.landed + ]); + stmts.push(stmt); + + stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.item'); + stmt = new ParameterizedSQL( + `CREATE TEMPORARY TABLE tmp.item + (PRIMARY KEY (id)) + ENGINE = MEMORY + SELECT + i.*, + p.name AS producerName, + nk.name AS inkName + FROM item i + JOIN producer p ON p.id = i.producerFk + JOIN ink nk ON nk.id = i.inkFk + JOIN tmp.buyUltimate bu ON i.id = bu.itemFk + AND bu.warehouseFk = ? + `, [travel.warehouseInFk]); + stmts.push(stmt); + + stmt = new ParameterizedSQL('SELECT * FROM tmp.item'); + stmt.merge(conn.makeSuffix(filter)); + + const itemsIndex = stmts.push(stmt) - 1; + + stmts.push('DROP TEMPORARY TABLE tmp.item'); + + const sql = ParameterizedSQL.join(stmts, ';'); + const result = await conn.executeStmt(sql, myOptions); + + return result[itemsIndex]; + }; +}; diff --git a/modules/entry/back/methods/entry/specs/importBuys.spec.js b/modules/entry/back/methods/entry/specs/importBuys.spec.js index f6da44f2a..9cf6f4300 100644 --- a/modules/entry/back/methods/entry/specs/importBuys.spec.js +++ b/modules/entry/back/methods/entry/specs/importBuys.spec.js @@ -3,9 +3,7 @@ const LoopBackContext = require('loopback-context'); describe('entry import()', () => { const buyerId = 35; - const companyId = 442; - const travelId = 1; - const supplierId = 1; + const entryId = 3; const activeCtx = { accessToken: {userId: buyerId}, }; @@ -51,25 +49,17 @@ describe('entry import()', () => { const tx = await models.Entry.beginTransaction({}); try { const options = {transaction: tx}; - const newEntry = await models.Entry.create({ - dated: new Date(), - supplierFk: supplierId, - travelFk: travelId, - companyFk: companyId, - observation: 'The entry', - ref: 'Entry ref' - }, options); - await models.Entry.importBuys(ctx, newEntry.id, options); + await models.Entry.importBuys(ctx, entryId, options); - const updatedEntry = await models.Entry.findById(newEntry.id, null, options); + const updatedEntry = await models.Entry.findById(entryId, null, options); const entryBuys = await models.Buy.find({ - where: {entryFk: newEntry.id} + where: {entryFk: entryId} }, options); expect(updatedEntry.observation).toEqual(expectedObservation); expect(updatedEntry.ref).toEqual(expectedRef); - expect(entryBuys.length).toEqual(2); + expect(entryBuys.length).toEqual(4); await tx.rollback(); } catch (e) { diff --git a/modules/entry/back/methods/entry/specs/lastItemBuys.spec.js b/modules/entry/back/methods/entry/specs/lastItemBuys.spec.js new file mode 100644 index 000000000..3789113e7 --- /dev/null +++ b/modules/entry/back/methods/entry/specs/lastItemBuys.spec.js @@ -0,0 +1,26 @@ +const models = require('vn-loopback/server/server').models; + +describe('Entry lastItemBuys()', () => { + const entryId = 3; + it('should return the items that have been bought', async() => { + const filter = {where: {}}; + const result = await models.Entry.lastItemBuys(entryId, filter); + + expect(result.length).toBeGreaterThan(1); + }); + + it('should return the items matching color "brown"', async() => { + const brownInkCode = 'BRW'; + const filter = {where: {inkFk: brownInkCode}}; + const result = await models.Entry.lastItemBuys(entryId, filter); + + expect(result.length).toEqual(2); + }); + + it('should return the items with a name containing "Ranged"', async() => { + const filter = {where: {name: {like: '%Ranged%'}}}; + const result = await models.Entry.lastItemBuys(entryId, filter); + + expect(result.length).toEqual(3); + }); +}); diff --git a/modules/entry/back/models/entry.js b/modules/entry/back/models/entry.js index 88611963f..573e5b1cb 100644 --- a/modules/entry/back/models/entry.js +++ b/modules/entry/back/models/entry.js @@ -5,4 +5,5 @@ module.exports = Self => { require('../methods/entry/addBuy')(Self); require('../methods/entry/importBuys')(Self); require('../methods/entry/importBuysPreview')(Self); + require('../methods/entry/lastItemBuys')(Self); }; diff --git a/modules/entry/front/basic-data/index.html b/modules/entry/front/basic-data/index.html index 4b7661a8f..f75834045 100644 --- a/modules/entry/front/basic-data/index.html +++ b/modules/entry/front/basic-data/index.html @@ -35,6 +35,13 @@ {{::agencyModeName}} - {{::warehouseInName}} ({{::shipped | date: 'dd/MM/yyyy'}}) → {{::warehouseOutName}} ({{::landed | date: 'dd/MM/yyyy'}}) + + + + @@ -121,4 +128,94 @@ ng-click="watcher.loadOriginalData()"> - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + ID + Agency + Warehouse Out + Warehouse In + Shipped + Landed + + + + + + + {{::travel.id}} + + + {{::travel.agency.name}} + {{::travel.warehouseOut.name}} + {{::travel.warehouseIn.name}} + {{::travel.shipped | date: 'dd/MM/yyyy'}} + {{::travel.landed | date: 'dd/MM/yyyy'}} + + + + + + + + \ No newline at end of file diff --git a/modules/entry/front/basic-data/index.js b/modules/entry/front/basic-data/index.js index 141a365fa..80870c3f3 100644 --- a/modules/entry/front/basic-data/index.js +++ b/modules/entry/front/basic-data/index.js @@ -1,10 +1,68 @@ import ngModule from '../module'; 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', { template: require('./index.html'), - controller: Section, bindings: { entry: '<' - } + }, + controller: Controller }); diff --git a/modules/entry/front/basic-data/style.scss b/modules/entry/front/basic-data/style.scss new file mode 100644 index 000000000..508aa9091 --- /dev/null +++ b/modules/entry/front/basic-data/style.scss @@ -0,0 +1,3 @@ +.travelFilter{ + width: 950px; +} diff --git a/modules/entry/front/buy/import/index.html b/modules/entry/front/buy/import/index.html index de6125985..ccb1a5dac 100644 --- a/modules/entry/front/buy/import/index.html +++ b/modules/entry/front/buy/import/index.html @@ -59,7 +59,7 @@ + ng-model="$ctrl.itemFilterParams.size" + ng-keydown="$ctrl.onKeyPress($event)"> @@ -135,6 +138,7 @@ @@ -142,6 +146,7 @@ @@ -155,7 +160,7 @@ @@ -186,8 +191,8 @@ {{::item.name}} {{::item.size}} - {{::item.producer.name}} - {{::item.ink.name}} + {{::item.producerName}} + {{::item.inkName}} diff --git a/modules/entry/front/buy/import/index.js b/modules/entry/front/buy/import/index.js index a88476240..a2a28ef69 100644 --- a/modules/entry/front/buy/import/index.js +++ b/modules/entry/front/buy/import/index.js @@ -141,6 +141,11 @@ class Controller extends Section { filter.where = where; this.$.itemsModel.applyFilter(filter); } + + onKeyPress($event) { + if ($event.key === 'Enter') + this.filter(); + } } Controller.$inject = ['$element', '$scope']; diff --git a/modules/invoiceIn/back/methods/invoice-in/getTotals.js b/modules/invoiceIn/back/methods/invoice-in/getTotals.js new file mode 100644 index 000000000..918467010 --- /dev/null +++ b/modules/invoiceIn/back/methods/invoice-in/getTotals.js @@ -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; + }; +}; diff --git a/modules/invoiceIn/back/methods/invoice-in/specs/getTotals.spec.js b/modules/invoiceIn/back/methods/invoice-in/specs/getTotals.spec.js new file mode 100644 index 000000000..8f5059c0f --- /dev/null +++ b/modules/invoiceIn/back/methods/invoice-in/specs/getTotals.spec.js @@ -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; + } + }); +}); diff --git a/modules/invoiceIn/back/methods/invoice-in/specs/toBook.spec.js b/modules/invoiceIn/back/methods/invoice-in/specs/toBook.spec.js new file mode 100644 index 000000000..5f8b50782 --- /dev/null +++ b/modules/invoiceIn/back/methods/invoice-in/specs/toBook.spec.js @@ -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; + } + }); +}); diff --git a/modules/invoiceIn/back/methods/invoice-in/summary.js b/modules/invoiceIn/back/methods/invoice-in/summary.js index 3693245cc..265aa06e7 100644 --- a/modules/invoiceIn/back/methods/invoice-in/summary.js +++ b/modules/invoiceIn/back/methods/invoice-in/summary.js @@ -20,6 +20,7 @@ module.exports = Self => { }); Self.summary = async(id, options) => { + const models = Self.app.models; const myOptions = {}; 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 getTotals(id); + summaryObj.totals = await models.InvoiceIn.getTotals(id, myOptions); 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]; - } }; diff --git a/modules/invoiceIn/back/methods/invoice-in/toBook.js b/modules/invoiceIn/back/methods/invoice-in/toBook.js new file mode 100644 index 000000000..588d53f1f --- /dev/null +++ b/modules/invoiceIn/back/methods/invoice-in/toBook.js @@ -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; + } + }; +}; diff --git a/modules/invoiceIn/back/models/invoice-in.js b/modules/invoiceIn/back/models/invoice-in.js index 7754890ca..3b5aa65d9 100644 --- a/modules/invoiceIn/back/models/invoice-in.js +++ b/modules/invoiceIn/back/models/invoice-in.js @@ -2,4 +2,6 @@ module.exports = Self => { require('../methods/invoice-in/filter')(Self); require('../methods/invoice-in/summary')(Self); require('../methods/invoice-in/clone')(Self); + require('../methods/invoice-in/toBook')(Self); + require('../methods/invoice-in/getTotals')(Self); }; diff --git a/modules/invoiceIn/front/descriptor/index.html b/modules/invoiceIn/front/descriptor/index.html index 0cdd5f8b8..a51743091 100644 --- a/modules/invoiceIn/front/descriptor/index.html +++ b/modules/invoiceIn/front/descriptor/index.html @@ -1,8 +1,16 @@ + + To book + + @@ -10,7 +18,7 @@ Clone Invoice @@ -26,7 +34,7 @@ - {{$ctrl.invoiceIn.supplier.nickname}} + {{$ctrl.invoiceIn.supplier.nickname}} @@ -46,7 +54,9 @@ icon="icon-invoice-in"> + + + + \ No newline at end of file diff --git a/modules/invoiceIn/front/descriptor/index.js b/modules/invoiceIn/front/descriptor/index.js index a767f4b5c..952692496 100644 --- a/modules/invoiceIn/front/descriptor/index.js +++ b/modules/invoiceIn/front/descriptor/index.js @@ -51,6 +51,43 @@ class Controller extends Descriptor { return this.getData(`InvoiceIns/${this.id}`, {filter}) .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', { diff --git a/modules/invoiceIn/front/descriptor/index.spec.js b/modules/invoiceIn/front/descriptor/index.spec.js index df72f5b45..46815c155 100644 --- a/modules/invoiceIn/front/descriptor/index.spec.js +++ b/modules/invoiceIn/front/descriptor/index.spec.js @@ -8,19 +8,70 @@ describe('vnInvoiceInDescriptor', () => { beforeEach(inject(($componentController, _$httpBackend_) => { $httpBackend = _$httpBackend_; - controller = $componentController('vnInvoiceInDescriptor', {$element: null}); + const $element = angular.element(''); + + controller = $componentController('vnInvoiceInDescriptor', {$element}); + controller.invoiceIn = {id: 1}; + $httpBackend.when('GET', `InvoiceIns/${controller.invoiceIn.id}`).respond({id: 1}); })); describe('loadData()', () => { it(`should perform a get query to store the invoice in data into the controller`, () => { - const id = 1; - const response = {id: 1}; + expect(controller.invoiceIn).toEqual({id: 1}); + }); + }); - $httpBackend.expectGET(`InvoiceIns/${id}`).respond(response); - controller.id = id; + describe('onAcceptToBook()', () => { + 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(); - 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(); }); }); }); diff --git a/modules/invoiceIn/front/locale/es.yml b/modules/invoiceIn/front/locale/es.yml index f837c834b..46415480d 100644 --- a/modules/invoiceIn/front/locale/es.yml +++ b/modules/invoiceIn/front/locale/es.yml @@ -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 +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 transaction: Sage transaccion -Foreign value: Divisa -Due day: Vencimiento -Invoice list: Listado de facturas recibidas -InvoiceIn cloned: Factura clonada +Search invoices in by reference: Buscar facturas recibidas por referencia +To book: Contabilizar diff --git a/modules/invoiceIn/front/search-panel/index.html b/modules/invoiceIn/front/search-panel/index.html index d26bc063e..609fa56d8 100644 --- a/modules/invoiceIn/front/search-panel/index.html +++ b/modules/invoiceIn/front/search-panel/index.html @@ -21,6 +21,20 @@ ng-model="filter.fi"> + + + + {{::id}} - {{::nickname}} + + + { Self.remoteMethodCtx('createPdf', { @@ -57,39 +57,37 @@ module.exports = Self => { hasPdf: true }, myOptions); - const response = got.stream(`${origin}/api/report/invoice`, { - searchParams: { + return axios.get(`${origin}/api/report/invoice`, { + responseType: 'stream', + params: { authorization: auth.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 year = issued.getFullYear().toString(); - const month = (issued.getMonth() + 1).toString(); - const day = issued.getDate().toString(); + const container = await models.InvoiceContainer.container(year); + const rootPath = container.client.root; + const fileName = `${year}${invoiceOut.ref}.pdf`; + const src = path.join(rootPath, year, month, day); + fileSrc = path.join(src, fileName); - const container = await models.InvoiceContainer.container(year); - 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}); - 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); - writeStream.on('open', () => response.pipe(writeStream)); - writeStream.on('finish', () => writeStream.end()); - - return new Promise(resolve => { - writeStream.on('close', () => resolve(invoiceOut)); + throw e; }); } catch (e) { if (tx) await tx.rollback(); - if (fs.existsSync(fileSrc)) - await fs.unlink(fileSrc); throw e; } }; diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/createPdf.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/createPdf.spec.js index 2f503d11c..7600f065f 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/createPdf.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/createPdf.spec.js @@ -1,24 +1,28 @@ const models = require('vn-loopback/server/server').models; -const got = require('got'); +const LoopBackContext = require('loopback-context'); const fs = require('fs-extra'); +const axios = require('axios'); describe('InvoiceOut createPdf()', () => { const userId = 1; - const ctx = { - req: { - - accessToken: {userId: userId}, - headers: {origin: 'http://localhost:5000'}, - } + const activeCtx = { + accessToken: {userId: userId, id: 'DEFAULT_TOKEN'}, + headers: {origin: 'http://localhost:5000'} }; + const ctx = {req: activeCtx}; it('should create a new PDF file and set true the hasPdf property', async() => { const invoiceId = 1; + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); const response = { - pipe: () => {}, - on: () => {}, + data: { + pipe: () => {}, + on: () => {}, + } }; - spyOn(got, 'stream').and.returnValue(response); + spyOn(axios, 'get').and.returnValue(new Promise(resolve => resolve(response))); spyOn(models.InvoiceContainer, 'container').and.returnValue({ client: {root: '/path'} }); @@ -32,9 +36,10 @@ describe('InvoiceOut createPdf()', () => { const options = {transaction: tx}; 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(); } catch (e) { diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index b6e7e0261..7738845f9 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -19,6 +19,10 @@ class Controller extends Section { this.id = value.id; } + get hasInvoicing() { + return this.aclService.hasAny(['invoicing']); + } + loadData() { const filter = { include: [ @@ -51,8 +55,13 @@ class Controller extends Section { deleteInvoiceOut() { return this.$http.post(`InvoiceOuts/${this.invoiceOut.id}/delete`) - .then(() => this.$state.go('invoiceOut.index')) - .then(() => this.$state.reload()) + .then(() => { + 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'))); } diff --git a/modules/invoiceOut/front/descriptor-menu/index.spec.js b/modules/invoiceOut/front/descriptor-menu/index.spec.js index 19822f094..fced12e0d 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.spec.js +++ b/modules/invoiceOut/front/descriptor-menu/index.spec.js @@ -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()', () => { it('should make a query to the email invoice endpoint and show a message snackbar', () => { jest.spyOn(controller.vnApp, 'showMessage'); diff --git a/modules/invoiceOut/front/descriptor-menu/locale/es.yml b/modules/invoiceOut/front/descriptor-menu/locale/es.yml index 9c99037f7..a76f6aad3 100644 --- a/modules/invoiceOut/front/descriptor-menu/locale/es.yml +++ b/modules/invoiceOut/front/descriptor-menu/locale/es.yml @@ -14,4 +14,4 @@ InvoiceOut booked: Factura asentada Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura? Regenerate PDF invoice: Regenerar PDF factura 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 \ No newline at end of file +The email can't be empty: El correo no puede estar vacío diff --git a/modules/item/front/waste/index/style.scss b/modules/item/front/waste/index/style.scss index 09e3a2a4c..faac46139 100644 --- a/modules/item/front/waste/index/style.scss +++ b/modules/item/front/waste/index/style.scss @@ -11,7 +11,7 @@ vn-item-waste-detail { padding-bottom: 7px; padding-bottom: 4px; font-weight: lighter; - background-color: #fde6ca; + background-color: $color-bg; border-bottom: 1px solid #f7931e; white-space: nowrap; overflow: hidden; diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index 1f1d4d88a..047095abc 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -133,6 +133,10 @@ module.exports = Self => { const where = buildFilter(ctx.args, (param, value) => { switch (param) { + case 'search': + return /^\d+$/.test(value) + ? {'t.id': {inq: value}} + : {'t.nickname': {like: `%${value}%`}}; case 'from': return {'t.shipped': {gte: value}}; case 'to': diff --git a/modules/order/front/locale/es.yml b/modules/order/front/locale/es.yml index 62f711659..37481b1a4 100644 --- a/modules/order/front/locale/es.yml +++ b/modules/order/front/locale/es.yml @@ -27,4 +27,5 @@ Confirm: Confirmar Real hour: Hora real T. Hour: Hora T. Theoretical hour: Hora Teórica -Go to the order: Ir al pedido \ No newline at end of file +Go to the order: Ir al pedido +Basket: Cesta \ No newline at end of file diff --git a/modules/order/front/summary/index.html b/modules/order/front/summary/index.html index 67bc26fce..b4562c317 100644 --- a/modules/order/front/summary/index.html +++ b/modules/order/front/summary/index.html @@ -7,7 +7,7 @@ - Ticket #{{$ctrl.summary.id}} - {{$ctrl.summary.client.name}} + Basket #{{$ctrl.summary.id}} - {{$ctrl.summary.client.name}} ({{$ctrl.summary.client.salesPersonFk}}) { type: 'number', description: 'Action id', required: true + }, + { + arg: 'isWithoutNegatives', + type: 'boolean', + description: 'Is whithout negatives', + required: true }], returns: { type: ['object'], @@ -127,6 +133,19 @@ module.exports = Self => { } } + if (args.isWithoutNegatives) { + const query = `CALL ticket_getMovable(?,?,?)`; + const params = [args.id, args.shipped, args.warehouseFk]; + const [salesMovable] = await Self.rawSql(query, params, myOptions); + + const salesNewTicket = salesMovable.filter(sale => (sale.movable ? sale.movable : 0) >= sale.quantity); + + if (salesNewTicket.length) { + const newTicket = await models.Ticket.transferSales(ctx, args.id, null, salesNewTicket, myOptions); + args.id = newTicket.id; + } + } + const originalTicket = await models.Ticket.findOne({ where: {id: args.id}, fields: [ @@ -230,6 +249,7 @@ module.exports = Self => { await models.Chat.sendCheckingPresence(ctx, salesPersonId, message); } + res.id = args.id; if (tx) await tx.commit(); return res; diff --git a/modules/ticket/back/methods/ticket/getVolume.js b/modules/ticket/back/methods/ticket/getVolume.js index 376c9ee4e..6029020ba 100644 --- a/modules/ticket/back/methods/ticket/getVolume.js +++ b/modules/ticket/back/methods/ticket/getVolume.js @@ -9,10 +9,14 @@ module.exports = Self => { description: 'ticket id', http: {source: 'path'} }], - returns: { - type: ['Object'], - root: true + returns: [{ + arg: 'saleVolume', + type: ['object'] }, + { + arg: 'packingTypeVolume', + type: ['object'] + }], http: { path: `/:id/getVolume`, verb: 'GET' @@ -25,7 +29,21 @@ module.exports = Self => { if (typeof options == 'object') Object.assign(myOptions, options); - return Self.rawSql(`SELECT * FROM vn.saleVolume - WHERE ticketFk = ?`, [ticketFk], myOptions); + const saleVolume = await Self.rawSql(` + 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]; }; }; diff --git a/modules/ticket/back/methods/ticket/priceDifference.js b/modules/ticket/back/methods/ticket/priceDifference.js index 1856cb08f..e0ffac55a 100644 --- a/modules/ticket/back/methods/ticket/priceDifference.js +++ b/modules/ticket/back/methods/ticket/priceDifference.js @@ -40,6 +40,12 @@ module.exports = Self => { type: 'number', description: 'The warehouse id', required: true + }, + { + arg: 'shipped', + type: 'date', + description: 'shipped', + required: true }], returns: { type: ['object'], @@ -104,19 +110,34 @@ module.exports = Self => { totalDifference: 0.00, }; - const query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`; - const params = [args.id, args.landed, args.addressId, args.zoneId, args.warehouseId]; + // Get items movable + const ticketOrigin = await models.Ticket.findById(args.id, null, myOptions); + const differenceShipped = ticketOrigin.shipped.getTime() > args.shipped.getTime(); + const differenceWarehouse = ticketOrigin.warehouseFk != args.warehouseId; + + salesObj.haveDifferences = differenceShipped || differenceWarehouse; + + let query = `CALL ticket_getMovable(?,?,?)`; + let params = [args.id, args.shipped, args.warehouseId]; + const [salesMovable] = await Self.rawSql(query, params, myOptions); + + const itemMovable = new Map(); + for (sale of salesMovable) { + const saleMovable = sale.movable ? sale.movable : 0; + itemMovable.set(sale.id, saleMovable); + } + + // Sale price component, one per sale + query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`; + params = [args.id, args.landed, args.addressId, args.zoneId, args.warehouseId]; const [difComponents] = await Self.rawSql(query, params, myOptions); const map = new Map(); - - // Sale price component, one per sale for (difComponent of difComponents) map.set(difComponent.saleFk, difComponent); for (sale of salesObj.items) { const difComponent = map.get(sale.id); - if (difComponent) { sale.component = difComponent; @@ -129,6 +150,7 @@ module.exports = Self => { salesObj.totalUnitPrice += sale.price; salesObj.totalUnitPrice = round(salesObj.totalUnitPrice); + sale.movable = itemMovable.get(sale.id); } if (tx) await tx.commit(); diff --git a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js index 9fa69b595..2aa2a07c4 100644 --- a/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js +++ b/modules/ticket/back/methods/ticket/specs/componentUpdate.spec.js @@ -45,7 +45,8 @@ describe('ticket componentUpdate()', () => { shipped: today, landed: tomorrow, isDeleted: false, - option: 1 + option: 1, + isWithoutNegatives: false }; let ctx = { @@ -94,7 +95,8 @@ describe('ticket componentUpdate()', () => { shipped: today, landed: tomorrow, isDeleted: false, - option: 1 + option: 1, + isWithoutNegatives: false }; const ctx = { @@ -134,4 +136,60 @@ describe('ticket componentUpdate()', () => { throw e; } }); + + it('should change warehouse and without negatives', async() => { + const tx = await models.SaleComponent.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const saleToTransfer = 27; + const originDate = today; + const newDate = tomorrow; + const ticketID = 14; + newDate.setHours(0, 0, 0, 0, 0); + originDate.setHours(0, 0, 0, 0, 0); + + const args = { + id: ticketID, + clientFk: 1104, + agencyModeFk: 2, + addressFk: 4, + zoneFk: 9, + warehouseFk: 1, + companyFk: 442, + shipped: newDate, + landed: tomorrow, + isDeleted: false, + option: 1, + isWithoutNegatives: true + }; + + const ctx = { + args: args, + req: { + accessToken: {userId: 9}, + headers: {origin: 'http://localhost'}, + __: value => { + return value; + } + } + }; + await models.Ticket.componentUpdate(ctx, options); + + const [newTicketID] = await models.Ticket.rawSql('SELECT MAX(id) as id FROM ticket', null, options); + const oldTicket = await models.Ticket.findById(ticketID, null, options); + const newTicket = await models.Ticket.findById(newTicketID.id, null, options); + const newTicketSale = await models.Sale.findOne({where: {ticketFk: args.id}}, options); + + expect(oldTicket.shipped).toEqual(originDate); + expect(newTicket.shipped).toEqual(newDate); + expect(newTicketSale.id).toEqual(saleToTransfer); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); diff --git a/modules/ticket/back/methods/ticket/specs/getVolume.spec.js b/modules/ticket/back/methods/ticket/specs/getVolume.spec.js index 35134e4d0..cba3948db 100644 --- a/modules/ticket/back/methods/ticket/specs/getVolume.spec.js +++ b/modules/ticket/back/methods/ticket/specs/getVolume.spec.js @@ -8,9 +8,15 @@ describe('ticket getVolume()', () => { const options = {transaction: tx}; 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(); } catch (e) { diff --git a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js index fed899d77..e9aa5030a 100644 --- a/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js +++ b/modules/ticket/back/methods/ticket/specs/priceDifference.spec.js @@ -15,6 +15,7 @@ describe('sale priceDifference()', () => { ctx.args = { id: 16, landed: tomorrow, + shipped: tomorrow, addressId: 126, agencyModeId: 7, zoneId: 3, @@ -45,6 +46,7 @@ describe('sale priceDifference()', () => { ctx.args = { id: 1, landed: new Date(), + shipped: new Date(), addressId: 121, zoneId: 3, warehouseId: 1 @@ -59,4 +61,38 @@ describe('sale priceDifference()', () => { expect(error).toEqual(new UserError(`The sales of this ticket can't be modified`)); }); + + it('should return ticket movable', async() => { + const tx = await models.Ticket.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + + const ctx = {req: {accessToken: {userId: 1106}}}; + ctx.args = { + id: 11, + shipped: tomorrow, + landed: tomorrow, + addressId: 122, + agencyModeId: 7, + zoneId: 3, + warehouseId: 1 + }; + + const result = await models.Ticket.priceDifference(ctx, options); + const firstItem = result.items[0]; + const secondtItem = result.items[1]; + + expect(firstItem.movable).toEqual(440); + expect(secondtItem.movable).toEqual(1980); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); }); diff --git a/modules/ticket/front/basic-data/step-one/index.js b/modules/ticket/front/basic-data/step-one/index.js index 215f36a46..f532265e2 100644 --- a/modules/ticket/front/basic-data/step-one/index.js +++ b/modules/ticket/front/basic-data/step-one/index.js @@ -201,7 +201,8 @@ class Controller extends Component { addressId: this.ticket.addressFk, agencyModeId: this.ticket.agencyModeFk, zoneId: this.ticket.zoneFk, - warehouseId: this.ticket.warehouseFk + warehouseId: this.ticket.warehouseFk, + shipped: this.ticket.shipped }; return this.$http.post(query, params).then(res => { diff --git a/modules/ticket/front/basic-data/step-two/index.html b/modules/ticket/front/basic-data/step-two/index.html index 439f2b527..092c9e746 100644 --- a/modules/ticket/front/basic-data/step-two/index.html +++ b/modules/ticket/front/basic-data/step-two/index.html @@ -9,6 +9,7 @@ Item Description + Movable Quantity Price (PPU) New (PPU) @@ -31,6 +32,13 @@ tabindex="-1"> + + + {{::sale.movable}} + + {{::sale.quantity}} {{::sale.price | currency: 'EUR': 2}} {{::sale.component.newPrice | currency: 'EUR': 2}} @@ -66,6 +74,13 @@ +
+ + +
diff --git a/modules/ticket/front/basic-data/step-two/index.js b/modules/ticket/front/basic-data/step-two/index.js index 7ffdb8315..c12647aa5 100644 --- a/modules/ticket/front/basic-data/step-two/index.js +++ b/modules/ticket/front/basic-data/step-two/index.js @@ -20,6 +20,7 @@ class Controller extends Component { this.getTotalNewPrice(); this.getTotalDifferenceOfPrice(); this.loadDefaultTicketAction(); + this.ticketHaveNegatives(); } loadDefaultTicketAction() { @@ -63,6 +64,22 @@ class Controller extends Component { this.totalPriceDifference = totalPriceDifference; } + ticketHaveNegatives() { + let haveNegatives = false; + let haveNotNegatives = false; + const haveDifferences = this.ticket.sale.haveDifferences; + + this.ticket.sale.items.forEach(item => { + if (item.quantity > item.movable) + haveNegatives = true; + else + haveNotNegatives = true; + }); + + this.ticket.withoutNegatives = false; + this.haveNegatives = (haveNegatives && haveNotNegatives && haveDifferences); + } + onSubmit() { if (!this.ticket.option) { return this.vnApp.showError( @@ -70,8 +87,8 @@ class Controller extends Component { ); } - let query = `tickets/${this.ticket.id}/componentUpdate`; - let params = { + const query = `tickets/${this.ticket.id}/componentUpdate`; + const params = { clientFk: this.ticket.clientFk, nickname: this.ticket.nickname, agencyModeFk: this.ticket.agencyModeFk, @@ -82,16 +99,20 @@ class Controller extends Component { shipped: this.ticket.shipped, landed: this.ticket.landed, isDeleted: this.ticket.isDeleted, - option: parseInt(this.ticket.option) + option: parseInt(this.ticket.option), + isWithoutNegatives: this.ticket.withoutNegatives }; - this.$http.post(query, params).then(res => { - this.vnApp.showMessage( - this.$t(`The ticket has been unrouted`) - ); - this.card.reload(); - this.$state.go('ticket.card.summary', {id: this.$params.id}); - }); + this.$http.post(query, params) + .then(res => { + this.ticketToMove = res.data.id; + this.vnApp.showMessage( + this.$t(`The ticket has been unrouted`) + ); + }) + .finally(() => { + this.$state.go('ticket.card.summary', {id: this.ticketToMove}); + }); } } diff --git a/modules/ticket/front/basic-data/step-two/index.spec.js b/modules/ticket/front/basic-data/step-two/index.spec.js index ea8268716..ac85a7818 100644 --- a/modules/ticket/front/basic-data/step-two/index.spec.js +++ b/modules/ticket/front/basic-data/step-two/index.spec.js @@ -64,5 +64,103 @@ describe('Ticket', () => { expect(controller.totalPriceDifference).toEqual(0.3); }); }); + + describe('ticketHaveNegatives()', () => { + it('should show if ticket have any negative, have differences, but not all sale are negative', () => { + controller.ticket = { + sale: { + items: [ + { + item: 1, + quantity: 2, + movable: 1 + }, + { + item: 2, + quantity: 1, + movable: 5 + } + ], + haveDifferences: true + } + }; + + controller.ticketHaveNegatives(); + + expect(controller.haveNegatives).toEqual(true); + }); + + it('should not show if ticket not have any negative', () => { + controller.ticket = { + sale: { + items: [ + { + item: 1, + quantity: 2, + movable: 1 + }, + { + item: 2, + quantity: 2, + movable: 1 + } + ], + haveDifferences: true + } + }; + + controller.ticketHaveNegatives(); + + expect(controller.haveNegatives).toEqual(false); + }); + + it('should not show if all sale are negative', () => { + controller.ticket = { + sale: { + items: [ + { + item: 1, + quantity: 2, + movable: 1 + }, + { + item: 2, + quantity: 2, + movable: 1 + } + ], + haveDifferences: true + } + }; + + controller.ticketHaveNegatives(); + + expect(controller.haveNegatives).toEqual(false); + }); + + it('should not show if ticket not have differences', () => { + controller.ticket = { + sale: { + items: [ + { + item: 1, + quantity: 2, + movable: 1 + }, + { + item: 2, + quantity: 1, + movable: 2 + } + ], + haveDifferences: false + } + }; + + controller.ticketHaveNegatives(); + + expect(controller.haveNegatives).toEqual(false); + }); + }); }); }); diff --git a/modules/ticket/front/basic-data/step-two/locale/es.yml b/modules/ticket/front/basic-data/step-two/locale/es.yml index a2a07991b..e1f1e0bfc 100644 --- a/modules/ticket/front/basic-data/step-two/locale/es.yml +++ b/modules/ticket/front/basic-data/step-two/locale/es.yml @@ -5,4 +5,7 @@ Charge difference to: Cargar diferencia a The ticket has been unrouted: El ticket ha sido desenrutado Price: Precio New price: Nuevo precio -Price difference: Diferencia de precio \ No newline at end of file +Price difference: Diferencia de precio +Create without negatives: Crear sin negativos +Clone this ticket with the changes and only sales availables: Clona este ticket con los cambios y solo las ventas disponibles. +Movable: Movible \ No newline at end of file diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index 142f44989..9d4381f7c 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -149,7 +149,10 @@ class Controller extends Section { return this.$http.post(`Tickets/${this.id}/setDeleted`) .then(() => this.reload()) .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')); }); } diff --git a/modules/ticket/front/descriptor-menu/index.spec.js b/modules/ticket/front/descriptor-menu/index.spec.js index e9486bcd0..288c7508b 100644 --- a/modules/ticket/front/descriptor-menu/index.spec.js +++ b/modules/ticket/front/descriptor-menu/index.spec.js @@ -78,9 +78,22 @@ describe('Ticket Component vnTicketDescriptorMenu', () => { describe('deleteTicket()', () => { 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.$state, 'go').mockReturnValue('ok'); jest.spyOn(controller.vnApp, 'showSuccess'); + controller.$state.current.name = 'ticket.card.something'; $httpBackend.expectPOST(`Tickets/${ticket.id}/setDeleted`).respond(); controller.deleteTicket(); diff --git a/modules/ticket/front/locale/es.yml b/modules/ticket/front/locale/es.yml index 6e502ed7d..752dd7b36 100644 --- a/modules/ticket/front/locale/es.yml +++ b/modules/ticket/front/locale/es.yml @@ -37,6 +37,7 @@ Observation type: Tipo de observación Original: Original Package size: Bultos Package type: Tipo de porte +Packing type: Encajado Phone: Teléfono PPU: Ud. Price: Precio diff --git a/modules/ticket/front/summary/index.html b/modules/ticket/front/summary/index.html index 42a77a394..99fb949b6 100644 --- a/modules/ticket/front/summary/index.html +++ b/modules/ticket/front/summary/index.html @@ -20,7 +20,7 @@ on-change="$ctrl.changeState(value)"> diff --git a/modules/ticket/front/summary/index.js b/modules/ticket/front/summary/index.js index 913c89774..60394b5b3 100644 --- a/modules/ticket/front/summary/index.js +++ b/modules/ticket/front/summary/index.js @@ -41,9 +41,9 @@ class Controller extends Summary { }); } - get isTicketModule() { - const path = this.$state.getCurrentPath()[1]; - return path.state.name === 'ticket'; + get isOnTicketCard() { + const currentState = this.$state.current.name; + return currentState.startsWith('ticket.card'); } get isEditable() { diff --git a/modules/ticket/front/volume/index.html b/modules/ticket/front/volume/index.html index 70bd4f5fb..8f17a9475 100644 --- a/modules/ticket/front/volume/index.html +++ b/modules/ticket/front/volume/index.html @@ -6,22 +6,17 @@ data="$ctrl.sales" limit="20">
- - - -
- - - - -
+
+ + + + +
@@ -29,6 +24,7 @@ Item Description + Packing type Quantity m³ per quantity @@ -55,6 +51,7 @@ tabindex="-1"> + {{::sale.item.itemPackingTypeFk}} {{::sale.quantity}} {{::sale.saleVolume.volume | number:3}} diff --git a/modules/ticket/front/volume/index.js b/modules/ticket/front/volume/index.js index ead46024b..81491bca0 100644 --- a/modules/ticket/front/volume/index.js +++ b/modules/ticket/front/volume/index.js @@ -23,24 +23,19 @@ class Controller extends Section { if (value) this.applyVolumes(); } - get volumes() { - return this._volumes; - } - - set volumes(value) { - this._volumes = value; - - if (value) this.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 => { - this.volumes.forEach(volume => { - if (sale.id === volume.saleFk) - sale.saleVolume = volume; - }); + const volumes = new Map(); + for (const volume of saleVolume) + volumes.set(volume.saleFk, volume); + + for (const sale of this.sales) + sale.saleVolume = volumes.get(sale.id); + + this.packingTypeVolume = res.data.packingTypeVolume; }); } } diff --git a/modules/ticket/front/volume/index.spec.js b/modules/ticket/front/volume/index.spec.js index 5f6f433fb..6ab968503 100644 --- a/modules/ticket/front/volume/index.spec.js +++ b/modules/ticket/front/volume/index.spec.js @@ -33,17 +33,20 @@ describe('ticket', () => { }); }); - describe('volumes() setter', () => { - it('should set volumes property on controller an then call applyVolumes() method', () => { - jest.spyOn(controller, 'applyVolumes'); - - controller.volumes = [{id: 1}]; - - expect(controller.applyVolumes).toHaveBeenCalledWith(); - }); - }); - describe('applyVolumes()', () => { + const ticket = 1; + const response = + { + saleVolume: [ + {saleFk: 1, volume: 0.012}, + {saleFk: 2, volume: 0.015} + ], + packingTypeVolume: [ + {code: 'V', volume: 1}, + {code: 'H', volume: 2} + ] + }; + it(`should not apply volumes to the sales if sales property is not defined on controller`, () => { controller.sales = [{id: 1, name: 'Sale one'}, {id: 2, name: 'Sale two'}]; @@ -58,29 +61,32 @@ describe('ticket', () => { }); it(`should apply volumes to the sales if sales and volumes properties are defined on controller`, () => { - controller.sales = [{id: 1, name: 'Sale one'}, {id: 2, name: 'Sale two'}]; - controller.volumes = [{saleFk: 1, volume: 0.012}, {saleFk: 2, volume: 0.015}]; + const expectedResultOne = response.saleVolume[0].volume; + const expectedResultTwo = response.saleVolume[1].volume; + $httpBackend.expectGET(`Tickets/${ticket}/getVolume`).respond(response); + controller.sales = [ + {id: 1, name: 'Sale one', ticketFk: ticket}, + {id: 2, name: 'Sale two'} + ]; + $httpBackend.flush(); - expect(controller.sales[0].saleVolume.volume).toEqual(0.012); - expect(controller.sales[1].saleVolume.volume).toEqual(0.015); + expect(controller.sales[0].saleVolume.volume).toEqual(expectedResultOne); + expect(controller.sales[1].saleVolume.volume).toEqual(expectedResultTwo); + }); + + it(`should apply packing volumes to the sales if sales and volumes properties are defined on controller`, () => { + const expectedResultOne = response.packingTypeVolume[0].code; + const expectedResultTwo = response.packingTypeVolume[1].code; + $httpBackend.expectGET(`Tickets/${ticket}/getVolume`).respond(response); + controller.sales = [ + {id: 1, name: 'Sale one', ticketFk: ticket}, + {id: 2, name: 'Sale two'} + ]; + $httpBackend.flush(); + + expect(controller.packingTypeVolume[0].code).toEqual(expectedResultOne); + expect(controller.packingTypeVolume[1].code).toEqual(expectedResultTwo); }); }); - - /* - it('should join the sale volumes to its respective sale', () => { - controller.ticket = {id: 1}; - let response = {volumes: [ - {saleFk: 1, m3: 0.008}, - {saleFk: 2, m3: 0.003} - ]}; - - $httpBackend.expectGET(`tickets/1/getVolume`).respond(response); - controller.onDataChange(); - $httpBackend.flush(); - - expect($scope.model.data[0].volume.m3).toBe(0.008); - expect($scope.model.data[1].volume.m3).toBe(0.003); - }); - */ }); }); diff --git a/modules/travel/back/methods/travel/filter.js b/modules/travel/back/methods/travel/filter.js index 024448bfe..586b4e5aa 100644 --- a/modules/travel/back/methods/travel/filter.js +++ b/modules/travel/back/methods/travel/filter.js @@ -10,64 +10,68 @@ module.exports = Self => { accepts: [ { arg: 'filter', - type: 'Object', + type: 'object', description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', http: {source: 'query'} }, { arg: 'search', - type: 'String', + type: 'string', description: 'Searchs the travel by id', http: {source: 'query'} }, { arg: 'id', - type: 'Integer', + type: 'integer', description: 'The travel id', http: {source: 'query'} }, { arg: 'shippedFrom', - type: 'Date', + type: 'date', description: 'The shipped from date filter', http: {source: 'query'} }, { arg: 'shippedTo', - type: 'Date', + type: 'date', description: 'The shipped to date filter', http: {source: 'query'} }, { arg: 'landedFrom', - type: 'Date', + type: 'date', description: 'The landed from date filter', http: {source: 'query'} }, { arg: 'landedTo', - type: 'Date', + type: 'date', description: 'The landed to date filter', http: {source: 'query'} }, { arg: 'agencyFk', - type: 'Number', + type: 'number', description: 'The agencyModeFk id', http: {source: 'query'} }, { arg: 'warehouseOutFk', - type: 'Number', + type: 'number', description: 'The warehouseOutFk filter', http: {source: 'query'} }, { arg: 'warehouseInFk', - type: 'Number', + type: 'number', description: 'The warehouseInFk filter', http: {source: 'query'} }, { arg: 'totalEntries', - type: 'Number', + type: 'number', description: 'The totalEntries filter', http: {source: 'query'} }, { arg: 'ref', type: 'string', description: 'The reference' - } + }, { + arg: 'continent', + type: 'string', + description: 'The continent code' + }, ], returns: { type: ['Object'], @@ -102,6 +106,7 @@ module.exports = Self => { case 'warehouseOutFk': case 'warehouseInFk': case 'totalEntries': + case 'continent': param = `t.${param}`; return {[param]: value}; } @@ -129,11 +134,15 @@ module.exports = Self => { t.totalEntries, am.name agencyModeName, win.name warehouseInName, - wout.name warehouseOutName + wout.name warehouseOutName, + cnt.code continent FROM vn.travel t JOIN vn.agencyMode am ON am.id = t.agencyFk JOIN vn.warehouse win ON win.id = t.warehouseInFk - JOIN vn.warehouse wout ON wout.id = t.warehouseOutFk) AS t` + JOIN vn.warehouse wout ON wout.id = t.warehouseOutFk + JOIN warehouse wo ON wo.id = t.warehouseOutFk + JOIN country c ON c.id = wo.countryFk + LEFT JOIN continent cnt ON cnt.id = c.continentFk) AS t` ); stmt.merge(conn.makeSuffix(filter)); diff --git a/modules/travel/back/methods/travel/specs/filter.spec.js b/modules/travel/back/methods/travel/specs/filter.spec.js index ababe961e..c739866a0 100644 --- a/modules/travel/back/methods/travel/specs/filter.spec.js +++ b/modules/travel/back/methods/travel/specs/filter.spec.js @@ -70,4 +70,16 @@ describe('Travel filter()', () => { expect(result.length).toEqual(1); }); + + it('should return the travel matching "continent"', async() => { + const ctx = { + args: { + continent: 'EU', + } + }; + + const result = await app.models.Travel.filter(ctx); + + expect(result.length).toEqual(5); + }); }); diff --git a/modules/travel/front/search-panel/index.html b/modules/travel/front/search-panel/index.html index 8e7f4140d..8d4edec1a 100644 --- a/modules/travel/front/search-panel/index.html +++ b/modules/travel/front/search-panel/index.html @@ -93,6 +93,15 @@ value-field="id"> + + + + diff --git a/modules/travel/front/summary/index.html b/modules/travel/front/summary/index.html index 90a2ea27f..e74682fb9 100644 --- a/modules/travel/front/summary/index.html +++ b/modules/travel/front/summary/index.html @@ -22,7 +22,7 @@ @@ -37,7 +37,7 @@ diff --git a/modules/worker/back/methods/worker/holidays.js b/modules/worker/back/methods/worker/holidays.js index e11d13002..bcf4d7f51 100644 --- a/modules/worker/back/methods/worker/holidays.js +++ b/modules/worker/back/methods/worker/holidays.js @@ -112,6 +112,13 @@ module.exports = Self => { const contracts = await models.WorkerLabour.find(filter, myOptions); + let [firstContract] = contracts; + let payedHolidays; + + if (firstContract.payedHolidays) + payedHolidays = firstContract.payedHolidays; + else payedHolidays = 0; + let totalHolidays = 0; let holidaysEnjoyed = 0; @@ -166,8 +173,7 @@ module.exports = Self => { return isLeapYear(year) ? 366 : 365; } - - return {totalHolidays, holidaysEnjoyed}; + return {totalHolidays, holidaysEnjoyed, payedHolidays}; }; function isLeapYear(year) { diff --git a/modules/worker/back/models/worker-labour.json b/modules/worker/back/models/worker-labour.json index b80090e57..5d2b56bfc 100644 --- a/modules/worker/back/models/worker-labour.json +++ b/modules/worker/back/models/worker-labour.json @@ -9,16 +9,19 @@ "properties": { "businessFk": { "id": true, - "type": "Number" + "type": "number" }, "workerFk": { - "type": "Number" + "type": "number" }, "started": { "type": "date" }, "ended": { "type": "date" + }, + "payedHolidays": { + "type": "number" } }, "relations": { diff --git a/modules/worker/front/calendar/index.html b/modules/worker/front/calendar/index.html index ce8bd6275..7ef586b36 100644 --- a/modules/worker/front/calendar/index.html +++ b/modules/worker/front/calendar/index.html @@ -28,6 +28,9 @@ {{'Used' | translate}} {{$ctrl.contractHolidays.holidaysEnjoyed}} {{'of' | translate}} {{$ctrl.contractHolidays.totalHolidays || 0}} {{'days' | translate}} +
+ {{'Paid holidays' | translate}} {{$ctrl.contractHolidays.payedHolidays}} {{'days' | translate}} +
diff --git a/modules/worker/front/calendar/index.js b/modules/worker/front/calendar/index.js index 014a35b63..6e0cf0d9a 100644 --- a/modules/worker/front/calendar/index.js +++ b/modules/worker/front/calendar/index.js @@ -71,6 +71,10 @@ class Controller extends Section { } } + get payedHolidays() { + return this._businessId; + } + buildYearFilter() { const now = new Date(); now.setFullYear(now.getFullYear() + 1); diff --git a/modules/worker/front/calendar/locale/es.yml b/modules/worker/front/calendar/locale/es.yml index 464ad9750..8e9f9cdf8 100644 --- a/modules/worker/front/calendar/locale/es.yml +++ b/modules/worker/front/calendar/locale/es.yml @@ -8,4 +8,5 @@ days: días Choose an absence type from the right menu: Elige un tipo de ausencia desde el menú de la derecha To start adding absences, click an absence type from the right menu and then on the day you want to add an absence: Para empezar a añadir ausencias, haz clic en un tipo de ausencia desde el menu de la derecha y después en el día que quieres añadir la ausencia You can just add absences within the current year: Solo puedes añadir ausencias dentro del año actual -Current day: Día actual \ No newline at end of file +Current day: Día actual +Paid holidays: Vacaciones pagadas \ No newline at end of file diff --git a/package.json b/package.json index dc132131a..e5b817e20 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "node": ">=14" }, "dependencies": { + "axios": "^0.25.0", "bmp-js": "^0.1.0", "compression": "^1.7.3", "fs-extra": "^5.0.0", @@ -42,6 +43,7 @@ "strong-error-handler": "^2.3.2", "uuid": "^3.3.3", "vn-loopback": "file:./loopback", + "vn-print": "file:./print", "xml2js": "^0.4.23" }, "devDependencies": { diff --git a/print/boot.js b/print/boot.js index 8cd0eaad7..d5c06264c 100644 --- a/print/boot.js +++ b/print/boot.js @@ -1,11 +1,9 @@ const express = require('express'); const path = require('path'); const fs = require('fs'); -const puppeteer = require('puppeteer'); const templatesPath = path.resolve(__dirname, './templates'); const componentsPath = path.resolve(__dirname, './core/components'); -const config = require('./core/config'); module.exports = async app => { global.appPath = __dirname; @@ -53,21 +51,4 @@ module.exports = async app => { app.use(`/api/${templateName}/assets`, express.static(assetsDir)); }); }); - - // Instantiate Puppeteer browser - async function launchBrowser() { - config.browser = await puppeteer.launch({ - headless: true, - args: [ - '--no-sandbox', - '--disable-setuid-sandbox', - '--single-process', - '--no-zygote' - ] - }); - - config.browser.on('disconnected', launchBrowser); - } - - launchBrowser(); }; diff --git a/print/common/css/layout.css b/print/common/css/layout.css index 4f521bea4..c1af4807d 100644 --- a/print/common/css/layout.css +++ b/print/common/css/layout.css @@ -6,6 +6,8 @@ .grid { font-family: Arial, Helvetica, sans-serif; font-size: 16px !important; + max-width: 1200px; + margin: 0 auto; width: 100% } diff --git a/print/config/print.json b/print/config/print.json index ceb7cbb28..d288c585d 100755 --- a/print/config/print.json +++ b/print/config/print.json @@ -48,6 +48,12 @@ "pool": true }, "storage": { - "root": "./storage/dms" + "root": "./storage/dms", + "invoice": { + "root": "./storage/pdfs/invoice" + }, + "signature": { + "root": "./storage/signatures" + } } } \ No newline at end of file diff --git a/print/core/component.js b/print/core/component.js index 12474566e..37656c240 100644 --- a/print/core/component.js +++ b/print/core/component.js @@ -27,29 +27,50 @@ class Component { get locale() { if (!this._locale) - this.getLocale(); + this._locale = this.getLocales(); return this._locale; } - getLocale() { - const mergedLocale = {messages: {}}; + getLocales() { + const mergedLocales = {messages: {}}; const localePath = path.resolve(__dirname, `${this.path}/locale`); if (!fs.existsSync(localePath)) - return mergedLocale; + return mergedLocales; const localeDir = fs.readdirSync(localePath); - localeDir.forEach(locale => { + for (const locale of localeDir) { const fullPath = path.join(localePath, '/', locale); const yamlLocale = fs.readFileSync(fullPath, 'utf8'); const jsonLocale = yaml.safeLoad(yamlLocale); const localeName = locale.replace('.yml', ''); - mergedLocale.messages[localeName] = jsonLocale; - }); + mergedLocales.messages[localeName] = jsonLocale; + } - this._locale = mergedLocale; + return mergedLocales; + } + + async getUserLocale() { + let locale = this.args.auth.locale; + + // Fetches user locale from mixing method getLocale() + if (this.args.recipientId) { + const component = await this.component(); + locale = await component.getLocale(this.args.recipientId); + } + + const messages = this.locale.messages; + const userTranslations = messages[locale]; + + if (!userTranslations) { + const fallbackLocale = config.i18n.fallbackLocale; + + return messages[fallbackLocale]; + } + + return userTranslations; } get stylesheet() { @@ -75,7 +96,7 @@ class Component { build() { const fullPath = path.resolve(__dirname, this.path); if (!fs.existsSync(fullPath)) - throw new Error(`Sample "${this.name}" not found`); + throw new Error(`Template "${this.name}" not found`); const component = require(`${this.path}/${this.name}`); component.i18n = this.locale; diff --git a/print/core/components/report-header/report-header.html b/print/core/components/report-header/report-header.html index 2667f14ed..0479e5caf 100644 --- a/print/core/components/report-header/report-header.html +++ b/print/core/components/report-header/report-header.html @@ -1,5 +1,9 @@
- Verdnatura + Verdnatura
{{companyName}}. {{company.street}}. {{company.postCode}} {{company.city}}. diff --git a/print/core/components/report-header/report-header.js b/print/core/components/report-header/report-header.js index 58c06bc1a..50c3a1337 100755 --- a/print/core/components/report-header/report-header.js +++ b/print/core/components/report-header/report-header.js @@ -10,9 +10,16 @@ module.exports = { }, computed: { companyName() { - if (!this.company.name) return; + if (this.company.name) + return this.company.name.toUpperCase(); - return this.company.name.toUpperCase(); + return; + }, + companyGroup() { + if (this.company.groupName) + return this.company.groupName.toLowerCase(); + + return; }, companyPhone() { if (!this.company.phone) return; @@ -30,8 +37,15 @@ module.exports = { methods: { getCompany(code) { return db.findOne(` - SELECT s.name, s.street, s.postCode, s.city, s.phone + SELECT + s.name, + s.street, + s.postCode, + s.city, + s.phone, + cg.code AS groupName FROM company c + JOIN companyGroup cg ON cg.id = c.companyGroupFk JOIN supplier s ON s.id = c.id WHERE c.code = ?`, [code]); }, diff --git a/print/core/email.js b/print/core/email.js index 620c1e083..bc8345cab 100644 --- a/print/core/email.js +++ b/print/core/email.js @@ -19,22 +19,7 @@ class Email extends Component { } async getSubject() { - const component = await this.component(); - let locale = this.args.auth.locale; - - if (this.args.recipientId) - locale = await component.getLocale(this.args.recipientId); - - const messages = this.locale.messages; - const userTranslations = messages[locale]; - - if (!userTranslations) { - const fallbackLocale = config.i18n.fallbackLocale; - - return messages[fallbackLocale].subject; - } - - return userTranslations.subject; + return (await this.getUserLocale())['subject']; } /** @@ -63,6 +48,7 @@ class Email extends Component { const reportName = fileName.replace('.pdf', ''); const report = new Report(reportName, this.args); fileCopy.content = await report.toPdfStream(); + fileCopy.filename = await report.getFileName(); } attachments.push(fileCopy); diff --git a/print/core/report.js b/print/core/report.js index b20b8e5df..093f5e99e 100644 --- a/print/core/report.js +++ b/print/core/report.js @@ -2,6 +2,7 @@ const fs = require('fs'); const path = require('path'); const config = require('./config'); const Component = require('./component'); +const puppeteer = require('puppeteer'); if (!process.env.OPENSSL_CONF) process.env.OPENSSL_CONF = '/etc/ssl/'; @@ -17,6 +18,10 @@ class Report extends Component { return `../templates/reports/${this.name}`; } + async getName() { + return (await this.getUserLocale())['reportName']; + } + async toPdfStream() { const template = await this.render(); const defaultOptions = Object.assign({}, config.pdf); @@ -27,7 +32,17 @@ class Report extends Component { if (fs.existsSync(fullPath)) options = require(optionsPath); - const page = (await config.browser.pages())[0]; + const browser = await puppeteer.launch({ + headless: true, + args: [ + '--no-sandbox', + '--disable-setuid-sandbox', + '--single-process', + '--no-zygote' + ] + }); + + const page = (await browser.pages())[0]; await page.emulateMedia('screen'); await page.setContent(template); @@ -47,8 +62,43 @@ class Report extends Component { const buffer = await page.pdf(options); + await browser.close(); + return buffer; } + + /** + * Returns all the params that ends with id + * + * @return {array} List of identifiers + */ + getIdentifiers() { + const identifiers = []; + const args = this.args; + const keys = Object.keys(args); + + for (let arg of keys) { + if (arg.endsWith('Id')) + identifiers.push(arg); + } + + return identifiers; + } + + async getFileName() { + const args = this.args; + const identifiers = this.getIdentifiers(args); + const name = await this.getName(); + const params = []; + params.push(name); + + for (let id of identifiers) + params.push(args[id]); + + const fileName = params.join('_'); + + return `${fileName}.pdf`; + } } module.exports = Report; diff --git a/print/core/router.js b/print/core/router.js index c0f20dd9a..cd64ba07e 100644 --- a/print/core/router.js +++ b/print/core/router.js @@ -1,43 +1,30 @@ -const path = require('path'); -const fs = require('fs'); const db = require('./database'); module.exports = app => { - const methodsPath = path.resolve(__dirname, '../methods'); - const methodsDir = fs.readdirSync(methodsPath); - const methods = []; + const routes = require('../methods/routes'); - // Get all methods - for (let method of methodsDir) { - if (method.includes('.js')) - methods.push(method.replace('.js', '')); - } - - // Auth middleware - const paths = []; - for (let method of methods) - paths.push(`/api/${method}/*`); - - app.use(paths, async function(req, res, next) { - const token = getToken(req); - const query = `SELECT at.id, at.userId, eu.email, u.lang, at.ttl, at.created - FROM salix.AccessToken at - JOIN account.user u ON u.id = at.userid - JOIN account.emailUser eu ON eu.userFk = u.id - WHERE at.id = ?`; + const paths = routes.map(route => route.url); + app.use(paths, async function(request, response, next) { try { + const token = getToken(request); + const query = `SELECT at.id, at.userId, eu.email, u.lang, at.ttl, at.created + FROM salix.AccessToken at + JOIN account.user u ON u.id = at.userid + JOIN account.emailUser eu ON eu.userFk = u.id + WHERE at.id = ?`; + const auth = await db.findOne(query, [token]); if (!auth || isTokenExpired(auth.created, auth.ttl)) throw new Error('Invalid authorization token'); - const args = Object.assign({}, req.query); - const props = Object.assign(args, req.body); + const args = Object.assign({}, request.query); + const props = Object.assign(args, request.body); props.authorization = auth.id; - req.args = props; - req.args.auth = { + response.locals = props; + response.locals.auth = { userId: auth.userId, token: auth.id, email: auth.email, @@ -50,6 +37,10 @@ module.exports = app => { } }); + // Register routes + for (let route of routes) + app.use(route.url, route.cb); + function getToken(request) { const headers = request.headers; const queryParams = request.query; @@ -68,8 +59,4 @@ module.exports = app => { return false; } - - // Mount methods - for (let method of methods) - require(`../methods/${method}`)(app); }; diff --git a/print/core/smtp.js b/print/core/smtp.js index 36a76dbaf..50a413673 100644 --- a/print/core/smtp.js +++ b/print/core/smtp.js @@ -25,14 +25,17 @@ module.exports = { throw err; }).finally(async() => { const attachments = []; - for (let attachment of options.attachments) { - const fileName = attachment.filename; - const filePath = attachment.path; - if (fileName.includes('.png')) return; + if (options.attachments) { + for (let attachment of options.attachments) { + const fileName = attachment.filename; + const filePath = attachment.path; + if (fileName.includes('.png')) return; - if (fileName || filePath) - attachments.push(filePath ? filePath : fileName); + if (fileName || filePath) + attachments.push(filePath ? filePath : fileName); + } } + const fileNames = attachments.join(',\n'); await db.rawSql(` INSERT INTO vn.mail (receiver, replyTo, sent, subject, body, attachment, status) diff --git a/print/core/storage.js b/print/core/storage.js new file mode 100644 index 000000000..063a2fbec --- /dev/null +++ b/print/core/storage.js @@ -0,0 +1,28 @@ +const config = require('./config.js'); +const path = require('path'); +const fs = require('fs-extra'); + +module.exports = { + async write(stream, options) { + const storage = config.storage[options.type]; + + if (!storage) return; + + const src = path.join(storage.root, options.path); + const fileSrc = path.join(src, options.fileName); + + await fs.mkdir(src, {recursive: true}); + + const writeStream = fs.createWriteStream(fileSrc); + writeStream.on('open', () => writeStream.write(stream)); + writeStream.on('finish', () => writeStream.end()); + + return new Promise(resolve => { + writeStream.on('close', () => resolve()); + }); + }, + + load(type, data) { + + } +}; diff --git a/print/core/stylesheet.js b/print/core/stylesheet.js index ffa141968..42a44fb57 100644 --- a/print/core/stylesheet.js +++ b/print/core/stylesheet.js @@ -7,9 +7,8 @@ class Stylesheet { } mergeStyles() { - this.files.forEach(file => { + for (const file of this.files) this.css.push(fs.readFileSync(file)); - }); return this.css.join('\n'); } diff --git a/print/methods/closure.js b/print/methods/closure.js deleted file mode 100644 index 07bd1768d..000000000 --- a/print/methods/closure.js +++ /dev/null @@ -1,311 +0,0 @@ -const db = require('../core/database'); -const Email = require('../core/email'); -const Report = require('../core/report'); -const smtp = require('../core/smtp'); -const config = require('../core/config'); - -module.exports = app => { - app.get('/api/closure/all', async function(req, res, next) { - try { - const reqArgs = req.args; - if (!reqArgs.to) - throw new Error('The argument to is required'); - - res.status(200).json({ - message: 'Task executed successfully' - }); - - const tickets = await db.rawSql(` - SELECT - t.id - FROM expedition e - JOIN ticket t ON t.id = e.ticketFk - JOIN warehouse wh ON wh.id = t.warehouseFk AND wh.hasComission - JOIN ticketState ts ON ts.ticketFk = t.id - JOIN alertLevel al ON al.id = ts.alertLevel - WHERE al.code = 'PACKED' - AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY) - AND util.dayEnd(?) - AND t.refFk IS NULL - GROUP BY e.ticketFk`, [reqArgs.to, reqArgs.to]); - const ticketIds = tickets.map(ticket => ticket.id); - - await closeAll(ticketIds, req.args); - await db.rawSql(` - UPDATE ticket t - JOIN ticketState ts ON t.id = ts.ticketFk - JOIN alertLevel al ON al.id = ts.alertLevel - JOIN agencyMode am ON am.id = t.agencyModeFk - JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk - JOIN zone z ON z.id = t.zoneFk - SET t.routeFk = NULL - WHERE DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY) - AND util.dayEnd(?) - AND al.code NOT IN('DELIVERED','PACKED') - AND t.routeFk - AND z.name LIKE '%MADRID%'`, [reqArgs.to, reqArgs.to]); - } catch (error) { - next(error); - } - }); - - app.get('/api/closure/by-ticket', async function(req, res, next) { - try { - const reqArgs = req.args; - if (!reqArgs.ticketId) - throw new Error('The argument ticketId is required'); - - res.status(200).json({ - message: 'Task executed successfully' - }); - - const tickets = await db.rawSql(` - SELECT - t.id - FROM expedition e - JOIN ticket t ON t.id = e.ticketFk - JOIN ticketState ts ON ts.ticketFk = t.id - JOIN alertLevel al ON al.id = ts.alertLevel - WHERE al.code = 'PACKED' - AND t.id = ? - AND t.refFk IS NULL - GROUP BY e.ticketFk`, [reqArgs.ticketId]); - const ticketIds = tickets.map(ticket => ticket.id); - - await closeAll(ticketIds, reqArgs); - } catch (error) { - next(error); - } - }); - - app.get('/api/closure/by-agency', async function(req, res, next) { - try { - const reqArgs = req.args; - if (!reqArgs.agencyModeId) - throw new Error('The argument agencyModeId is required'); - - if (!reqArgs.warehouseId) - throw new Error('The argument warehouseId is required'); - - if (!reqArgs.to) - throw new Error('The argument to is required'); - - res.status(200).json({ - message: 'Task executed successfully' - }); - - const agenciesId = reqArgs.agencyModeId.split(','); - const tickets = await db.rawSql(` - SELECT - t.id - FROM expedition e - JOIN ticket t ON t.id = e.ticketFk - JOIN ticketState ts ON ts.ticketFk = t.id - JOIN alertLevel al ON al.id = ts.alertLevel - WHERE al.code = 'PACKED' - AND t.agencyModeFk IN(?) - AND t.warehouseFk = ? - AND DATE(t.shipped) BETWEEN DATE_ADD(:to, INTERVAL -2 DAY) - AND util.dayEnd(?) - AND t.refFk IS NULL - GROUP BY e.ticketFk`, [ - agenciesId, - reqArgs.warehouseId, - reqArgs.to, - reqArgs.to - ]); - const ticketIds = tickets.map(ticket => ticket.id); - - await closeAll(ticketIds, reqArgs); - } catch (error) { - next(error); - } - }); - - app.get('/api/closure/by-route', async function(req, res, next) { - try { - const reqArgs = req.args; - if (!reqArgs.routeId) - throw new Error('The argument routeId is required'); - - res.status(200).json({ - message: 'Task executed successfully' - }); - - const tickets = await db.rawSql(` - SELECT - t.id - FROM expedition e - JOIN ticket t ON t.id = e.ticketFk - JOIN ticketState ts ON ts.ticketFk = t.id - JOIN alertLevel al ON al.id = ts.alertLevel - WHERE al.code = 'PACKED' - AND t.routeFk = ? - AND t.refFk IS NULL - GROUP BY e.ticketFk`, [reqArgs.routeId]); - const ticketIds = tickets.map(ticket => ticket.id); - await closeAll(ticketIds, reqArgs); - - // Send route report to the agency - const agencyMail = await db.findValue(` - SELECT am.reportMail - FROM route r - JOIN agencyMode am ON am.id = r.agencyModeFk - WHERE r.id = ?`, [reqArgs.routeId]); - - if (agencyMail) { - const args = Object.assign({ - routeId: reqArgs.routeId, - recipient: agencyMail - }, reqArgs); - - const email = new Email('driver-route', args); - await email.send(); - } - } catch (error) { - next(error); - } - }); - - async function closeAll(ticketIds, reqArgs) { - const failedtickets = []; - const tickets = await db.rawSql(` - SELECT - t.id, - t.clientFk, - c.name clientName, - c.email recipient, - c.salesPersonFk, - c.isToBeMailed, - c.hasToInvoice, - co.hasDailyInvoice, - eu.email salesPersonEmail - FROM ticket t - JOIN client c ON c.id = t.clientFk - JOIN province p ON p.id = c.provinceFk - JOIN country co ON co.id = p.countryFk - LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk - WHERE t.id IN(?)`, [ticketIds]); - - for (const ticket of tickets) { - try { - await db.rawSql(`CALL vn.ticket_closeByTicket(?)`, [ticket.id]); - - if (!ticket.salesPersonFk || !ticket.isToBeMailed) continue; - - if (!ticket.recipient) { - const body = `No se ha podido enviar el albarán ${ticket.id} - al cliente ${ticket.clientFk} porque no tiene un email especificado.

- Para dejar de recibir esta notificación, asígnale un email o desactiva - la notificación por email para este cliente.`; - smtp.send({ - to: ticket.salesPersonEmail, - subject: 'No se ha podido enviar el albarán', - html: body - }); - - continue; - } - - const hasToInvoice = ticket.hasToInvoice && ticket.hasDailyInvoice; - if (hasToInvoice) { - const invoice = await db.findOne(` - SELECT io.id, io.ref, io.serial, cny.code companyCode - FROM ticket t - JOIN invoiceOut io ON io.ref = t.refFk - JOIN company cny ON cny.id = io.companyFk - WHERE t.id = ? - `, [ticket.id]); - - const args = Object.assign({ - invoiceId: invoice.id, - recipientId: ticket.clientFk, - recipient: ticket.recipient, - replyTo: ticket.salesPersonEmail - }, reqArgs); - - let mailOptions = {}; - if (invoice.serial == 'E' && invoice.companyCode == 'VNL') { - const exportation = new Report('exportation', args); - const stream = await exportation.toPdfStream(); - const fileName = `exportation-${invoice.ref}.pdf`; - mailOptions = { - overrideAttachments: false, - attachments: [{ - filename: fileName, - content: stream - }] - }; - } - - const email = new Email('invoice', args); - await email.send(mailOptions); - } else { - const args = Object.assign({ - ticketId: ticket.id, - recipientId: ticket.clientFk, - recipient: ticket.recipient, - replyTo: ticket.salesPersonEmail - }, reqArgs); - - const email = new Email('delivery-note-link', args); - await email.send(); - } - } catch (error) { - // Domain not found - if (error.responseCode == 450) - return invalidEmail(ticket); - - // Save tickets on a list of failed ids - failedtickets.push({ - id: ticket.id, - stacktrace: error - }); - } - } - - // Send email with failed tickets - if (failedtickets.length > 0) { - let body = 'This following tickets have failed:

'; - - for (ticket of failedtickets) { - body += `Ticket: ${ticket.id} -
${ticket.stacktrace}

`; - } - - smtp.send({ - to: config.app.reportEmail, - subject: '[API] Nightly ticket closure report', - html: body - }); - } - } - - async function invalidEmail(ticket) { - await db.rawSql(`UPDATE client SET email = NULL WHERE id = ?`, [ - ticket.clientFk - ]); - - const oldInstance = `{"email": "${ticket.recipient}"}`; - const newInstance = `{"email": ""}`; - await db.rawSql(` - INSERT INTO clientLog (originFk, userFk, action, changedModel, oldInstance, newInstance) - VALUES (?, NULL, 'UPDATE', 'Client', ?, ?)`, [ - ticket.clientFk, - oldInstance, - newInstance - ]); - - const body = `No se ha podido enviar el albarán ${ticket.id} - al cliente ${ticket.clientFk} - ${ticket.clientName} - porque la dirección de email "${ticket.recipient}" no es correcta o no está disponible.

- Para evitar que se repita este error, se ha eliminado la dirección de email de la ficha del cliente. - Actualiza la dirección de email con una correcta.`; - - smtp.send({ - to: ticket.salesPersonEmail, - subject: 'No se ha podido enviar el albarán', - html: body - }); - } -}; diff --git a/print/methods/closure/closeAll.js b/print/methods/closure/closeAll.js new file mode 100644 index 000000000..7af3676f2 --- /dev/null +++ b/print/methods/closure/closeAll.js @@ -0,0 +1,58 @@ +const db = require('vn-print/core/database'); +const closure = require('./closure'); + +module.exports = async function(request, response, next) { + try { + const reqArgs = request.query; + if (!reqArgs.to) + throw new Error('The argument to is required'); + + response.status(200).json({ + message: 'Success' + }); + + const tickets = await db.rawSql(` + SELECT + t.id, + t.clientFk, + c.name clientName, + c.email recipient, + c.salesPersonFk, + c.isToBeMailed, + c.hasToInvoice, + co.hasDailyInvoice, + eu.email salesPersonEmail + FROM ticket t + JOIN agencyMode am ON am.id = t.agencyModeFk + JOIN warehouse wh ON wh.id = t.warehouseFk AND wh.hasComission + JOIN ticketState ts ON ts.ticketFk = t.id + JOIN alertLevel al ON al.id = ts.alertLevel + JOIN client c ON c.id = t.clientFk + JOIN province p ON p.id = c.provinceFk + JOIN country co ON co.id = p.countryFk + LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk + WHERE al.code = 'PACKED' + AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY) + AND util.dayEnd(?) + AND t.refFk IS NULL + GROUP BY t.id`, [reqArgs.to, reqArgs.to]); + + await closure.start(tickets, response.locals); + + await db.rawSql(` + UPDATE ticket t + JOIN ticketState ts ON t.id = ts.ticketFk + JOIN alertLevel al ON al.id = ts.alertLevel + JOIN agencyMode am ON am.id = t.agencyModeFk + JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk + JOIN zone z ON z.id = t.zoneFk + SET t.routeFk = NULL + WHERE DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY) + AND util.dayEnd(?) + AND al.code NOT IN('DELIVERED','PACKED') + AND t.routeFk + AND z.name LIKE '%MADRID%'`, [reqArgs.to, reqArgs.to]); + } catch (error) { + next(error); + } +}; diff --git a/print/methods/closure/closeByAgency.js b/print/methods/closure/closeByAgency.js new file mode 100644 index 000000000..7807de23a --- /dev/null +++ b/print/methods/closure/closeByAgency.js @@ -0,0 +1,58 @@ +const db = require('vn-print/core/database'); +const closure = require('./closure'); + +module.exports = async function(request, response, next) { + try { + const reqArgs = request.query; + + if (!reqArgs.agencyModeId) + throw new Error('The argument agencyModeId is required'); + + if (!reqArgs.warehouseId) + throw new Error('The argument warehouseId is required'); + + if (!reqArgs.to) + throw new Error('The argument to is required'); + + response.status(200).json({ + message: 'Success' + }); + + const agencyIds = reqArgs.agencyModeId.split(','); + const tickets = await db.rawSql(` + SELECT + t.id, + t.clientFk, + c.name clientName, + c.email recipient, + c.salesPersonFk, + c.isToBeMailed, + c.hasToInvoice, + co.hasDailyInvoice, + eu.email salesPersonEmail + FROM expedition e + JOIN ticket t ON t.id = e.ticketFk + JOIN ticketState ts ON ts.ticketFk = t.id + JOIN alertLevel al ON al.id = ts.alertLevel + JOIN client c ON c.id = t.clientFk + JOIN province p ON p.id = c.provinceFk + JOIN country co ON co.id = p.countryFk + LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk + WHERE al.code = 'PACKED' + AND t.agencyModeFk IN(?) + AND t.warehouseFk = ? + AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY) + AND util.dayEnd(?) + AND t.refFk IS NULL + GROUP BY e.ticketFk`, [ + agencyIds, + reqArgs.warehouseId, + reqArgs.to, + reqArgs.to + ]); + + await closure.start(tickets, response.locals); + } catch (error) { + next(error); + } +}; diff --git a/print/methods/closure/closeByRoute.js b/print/methods/closure/closeByRoute.js new file mode 100644 index 000000000..2c0bfd1eb --- /dev/null +++ b/print/methods/closure/closeByRoute.js @@ -0,0 +1,61 @@ +const db = require('vn-print/core/database'); +const Email = require('vn-print/core/email'); +const closure = require('./closure'); + +module.exports = async function(request, response, next) { + try { + const reqArgs = request.query; + + if (!reqArgs.routeId) + throw new Error('The argument routeId is required'); + + response.status(200).json({ + message: 'Success' + }); + + const tickets = await db.rawSql(` + SELECT + t.id, + t.clientFk, + c.name clientName, + c.email recipient, + c.salesPersonFk, + c.isToBeMailed, + c.hasToInvoice, + co.hasDailyInvoice, + eu.email salesPersonEmail + FROM expedition e + JOIN ticket t ON t.id = e.ticketFk + JOIN ticketState ts ON ts.ticketFk = t.id + JOIN alertLevel al ON al.id = ts.alertLevel + JOIN client c ON c.id = t.clientFk + JOIN province p ON p.id = c.provinceFk + JOIN country co ON co.id = p.countryFk + LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk + WHERE al.code = 'PACKED' + AND t.routeFk = ? + AND t.refFk IS NULL + GROUP BY e.ticketFk`, [reqArgs.routeId]); + + await closure.start(tickets, response.locals); + + // Send route report to the agency + const agencyMail = await db.findValue(` + SELECT am.reportMail + FROM route r + JOIN agencyMode am ON am.id = r.agencyModeFk + WHERE r.id = ?`, [reqArgs.routeId]); + + if (agencyMail) { + const args = Object.assign({ + routeId: Number.parseInt(reqArgs.routeId), + recipient: agencyMail + }, response.locals); + + const email = new Email('driver-route', args); + await email.send(); + } + } catch (error) { + next(error); + } +}; diff --git a/print/methods/closure/closeByTicket.js b/print/methods/closure/closeByTicket.js new file mode 100644 index 000000000..c71b3ecd0 --- /dev/null +++ b/print/methods/closure/closeByTicket.js @@ -0,0 +1,43 @@ +const db = require('vn-print/core/database'); +const closure = require('./closure'); + +module.exports = async function(request, response, next) { + try { + const reqArgs = request.query; + + if (!reqArgs.ticketId) + throw new Error('The argument ticketId is required'); + + response.status(200).json({ + message: 'Success' + }); + + const tickets = await db.rawSql(` + SELECT + t.id, + t.clientFk, + c.name clientName, + c.email recipient, + c.salesPersonFk, + c.isToBeMailed, + c.hasToInvoice, + co.hasDailyInvoice, + eu.email salesPersonEmail + FROM expedition e + JOIN ticket t ON t.id = e.ticketFk + JOIN ticketState ts ON ts.ticketFk = t.id + JOIN alertLevel al ON al.id = ts.alertLevel + JOIN client c ON c.id = t.clientFk + JOIN province p ON p.id = c.provinceFk + JOIN country co ON co.id = p.countryFk + LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk + WHERE al.code = 'PACKED' + AND t.id = ? + AND t.refFk IS NULL + GROUP BY e.ticketFk`, [reqArgs.ticketId]); + + await closure.start(tickets, response.locals); + } catch (error) { + next(error); + } +}; diff --git a/print/methods/closure/closure.js b/print/methods/closure/closure.js new file mode 100644 index 000000000..8cce8237c --- /dev/null +++ b/print/methods/closure/closure.js @@ -0,0 +1,153 @@ +const db = require('vn-print/core/database'); +const Report = require('vn-print/core/report'); +const Email = require('vn-print/core/email'); +const smtp = require('vn-print/core/smtp'); +const config = require('vn-print/core/config'); +const storage = require('vn-print/core/storage'); + +module.exports = { + async start(tickets, reqArgs) { + if (tickets.length == 0) return; + + const failedtickets = []; + for (const ticket of tickets) { + try { + await db.rawSql('START TRANSACTION'); + + await db.rawSql(`CALL vn.ticket_closeByTicket(?)`, [ticket.id]); + + const invoiceOut = await db.findOne(` + SELECT io.id, io.ref, io.serial, cny.code companyCode, io.issued + FROM ticket t + JOIN invoiceOut io ON io.ref = t.refFk + JOIN company cny ON cny.id = io.companyFk + WHERE t.id = ? + `, [ticket.id]); + + const mailOptions = { + overrideAttachments: true, + attachments: [] + }; + + const isToBeMailed = ticket.recipient && ticket.salesPersonFk && ticket.isToBeMailed; + + if (invoiceOut) { + const args = Object.assign({ + invoiceId: invoiceOut.id, + recipientId: ticket.clientFk, + recipient: ticket.recipient, + replyTo: ticket.salesPersonEmail + }, reqArgs); + + const invoiceReport = new Report('invoice', args); + const stream = await invoiceReport.toPdfStream(); + + const issued = invoiceOut.issued; + const year = issued.getFullYear().toString(); + const month = (issued.getMonth() + 1).toString(); + const day = issued.getDate().toString(); + + const fileName = `${year}${invoiceOut.ref}.pdf`; + + // Store invoice + storage.write(stream, { + type: 'invoice', + path: `${year}/${month}/${day}`, + fileName: fileName + }); + + await db.rawSql('UPDATE invoiceOut SET hasPdf = true WHERE id = ?', [invoiceOut.id]); + + if (isToBeMailed) { + const invoiceAttachment = { + filename: fileName, + content: stream + }; + + if (invoiceOut.serial == 'E' && invoiceOut.companyCode == 'VNL') { + const exportation = new Report('exportation', args); + const stream = await exportation.toPdfStream(); + const fileName = `CITES-${invoiceOut.ref}.pdf`; + + mailOptions.attachments.push({ + filename: fileName, + content: stream + }); + } + + mailOptions.attachments.push(invoiceAttachment); + + const email = new Email('invoice', args); + await email.send(mailOptions); + } + } else if (isToBeMailed) { + const args = Object.assign({ + ticketId: ticket.id, + recipientId: ticket.clientFk, + recipient: ticket.recipient, + replyTo: ticket.salesPersonEmail + }, reqArgs); + + const email = new Email('delivery-note-link', args); + await email.send(); + } + await db.rawSql('COMMIT'); + } catch (error) { + await db.rawSql('ROLLBACK'); + // Domain not found + if (error.responseCode == 450) + return invalidEmail(ticket); + + // Save tickets on a list of failed ids + failedtickets.push({ + id: ticket.id, + stacktrace: error + }); + } + } + + // Send email with failed tickets + if (failedtickets.length > 0) { + let body = 'This following tickets have failed:

'; + + for (const ticket of failedtickets) { + body += `Ticket: ${ticket.id} +
${ticket.stacktrace}

`; + } + + smtp.send({ + to: config.app.reportEmail, + subject: '[API] Nightly ticket closure report', + html: body + }); + } + }, + + async invalidEmail(ticket) { + await db.rawSql(`UPDATE client SET email = NULL WHERE id = ?`, [ + ticket.clientFk + ]); + + const oldInstance = `{"email": "${ticket.recipient}"}`; + const newInstance = `{"email": ""}`; + await db.rawSql(` + INSERT INTO clientLog (originFk, userFk, action, changedModel, oldInstance, newInstance) + VALUES (?, NULL, 'UPDATE', 'Client', ?, ?)`, [ + ticket.clientFk, + oldInstance, + newInstance + ]); + + const body = `No se ha podido enviar el albarán ${ticket.id} + al cliente ${ticket.clientFk} - ${ticket.clientName} + porque la dirección de email "${ticket.recipient}" no es correcta o no está disponible.

+ Para evitar que se repita este error, se ha eliminado la dirección de email de la ficha del cliente. + Actualiza la dirección de email con una correcta.`; + + smtp.send({ + to: ticket.salesPersonEmail, + subject: 'No se ha podido enviar el albarán', + html: body + }); + } +}; diff --git a/print/methods/closure/index.js b/print/methods/closure/index.js new file mode 100644 index 000000000..fcca76f71 --- /dev/null +++ b/print/methods/closure/index.js @@ -0,0 +1,9 @@ +const express = require('express'); +const router = new express.Router(); + +router.get('/all', require('./closeAll')); +router.get('/by-ticket', require('./closeByTicket')); +router.get('/by-agency', require('./closeByAgency')); +router.get('/by-route', require('./closeByRoute')); + +module.exports = router; diff --git a/print/methods/csv.js b/print/methods/csv.js deleted file mode 100644 index 4f4cdf2af..000000000 --- a/print/methods/csv.js +++ /dev/null @@ -1,31 +0,0 @@ -module.exports = app => { - app.use('/api/csv/delivery-note', require('./csv/delivery-note')(app)); - app.use('/api/csv/invoice', require('./csv/invoice')(app)); - - app.toCSV = function toCSV(rows) { - const [columns] = rows; - let content = Object.keys(columns).join('\t'); - for (let row of rows) { - const values = Object.values(row); - const finalValues = values.map(value => { - if (value instanceof Date) return formatDate(value); - if (value === null) return ''; - return value; - }); - content += '\n'; - content += finalValues.join('\t'); - } - return content; - }; - - function formatDate(date) { - return new Intl.DateTimeFormat('es', { - year: 'numeric', - month: 'numeric', - day: 'numeric', - hour: '2-digit', - minute: '2-digit', - second: '2-digit' - }).format(date); - } -}; diff --git a/print/methods/csv/csv.js b/print/methods/csv/csv.js new file mode 100644 index 000000000..d8725582d --- /dev/null +++ b/print/methods/csv/csv.js @@ -0,0 +1,31 @@ +function toCSV(rows) { + const [columns] = rows; + let content = Object.keys(columns).join('\t'); + for (let row of rows) { + const values = Object.values(row); + const finalValues = values.map(value => { + if (value instanceof Date) return formatDate(value); + if (value === null) return ''; + return value; + }); + content += '\n'; + content += finalValues.join('\t'); + } + return content; +} + +function formatDate(date) { + return new Intl.DateTimeFormat('es', { + year: 'numeric', + month: 'numeric', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }).format(date); +} + +module.exports = { + toCSV, + formatDate +}; diff --git a/print/methods/csv/delivery-note/download.js b/print/methods/csv/delivery-note/download.js new file mode 100644 index 000000000..d369d5f4a --- /dev/null +++ b/print/methods/csv/delivery-note/download.js @@ -0,0 +1,24 @@ +const path = require('path'); +const db = require('vn-print/core/database'); + +const {toCSV} = require('../csv'); +const sqlPath = path.join(__dirname, 'sql'); + +module.exports = async function(request, response, next) { + try { + const reqArgs = request.query; + if (!reqArgs.ticketId) + throw new Error('The argument ticketId is required'); + + const ticketId = reqArgs.ticketId; + const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [ticketId]); + const content = toCSV(sales); + const fileName = `ticket_${ticketId}.csv`; + + response.setHeader('Content-type', 'text/csv'); + response.setHeader('Content-Disposition', `inline; filename="${fileName}"`); + response.end(content); + } catch (error) { + next(error); + } +}; diff --git a/print/methods/csv/delivery-note/index.js b/print/methods/csv/delivery-note/index.js deleted file mode 100644 index 9ef0e33fa..000000000 --- a/print/methods/csv/delivery-note/index.js +++ /dev/null @@ -1,82 +0,0 @@ -const express = require('express'); -const router = new express.Router(); -const path = require('path'); -const db = require('../../../core/database'); -const sqlPath = path.join(__dirname, 'sql'); - -module.exports = app => { - router.get('/preview', async function(req, res, next) { - try { - const reqArgs = req.args; - if (!reqArgs.ticketId) - throw new Error('The argument ticketId is required'); - - const ticketId = reqArgs.ticketId; - const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [ticketId]); - const content = app.toCSV(sales); - const fileName = `ticket_${ticketId}.csv`; - - res.setHeader('Content-type', 'application/json; charset=utf-8'); - res.setHeader('Content-Disposition', `inline; filename="${fileName}"`); - res.end(content); - } catch (error) { - next(error); - } - }); - - router.get('/download', async function(req, res, next) { - try { - const reqArgs = req.args; - if (!reqArgs.ticketId) - throw new Error('The argument ticketId is required'); - - const ticketId = reqArgs.ticketId; - const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [ticketId]); - const content = app.toCSV(sales); - const fileName = `ticket_${ticketId}.csv`; - - res.setHeader('Content-type', 'text/csv'); - res.setHeader('Content-Disposition', `inline; filename="${fileName}"`); - res.end(content); - } catch (error) { - next(error); - } - }); - - const Email = require('../../../core/email'); - router.get('/send', async function(req, res, next) { - try { - const reqArgs = req.args; - if (!reqArgs.ticketId) - throw new Error('The argument ticketId is required'); - - const ticketId = reqArgs.ticketId; - const ticket = await db.findOneFromDef(`${sqlPath}/ticket`, [ticketId]); - const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [ticketId]); - - const args = Object.assign({ - ticketId: (String(ticket.id)), - recipientId: ticket.clientFk, - recipient: ticket.recipient, - replyTo: ticket.salesPersonEmail - }, reqArgs); - - const content = app.toCSV(sales); - const fileName = `ticket_${ticketId}.csv`; - const email = new Email('delivery-note', args); - await email.send({ - overrideAttachments: true, - attachments: [{ - filename: fileName, - content: content - }] - }); - - res.status(200).json({message: 'ok'}); - } catch (error) { - next(error); - } - }); - - return router; -}; diff --git a/print/methods/csv/delivery-note/send.js b/print/methods/csv/delivery-note/send.js new file mode 100644 index 000000000..478f20f57 --- /dev/null +++ b/print/methods/csv/delivery-note/send.js @@ -0,0 +1,40 @@ +const path = require('path'); +const db = require('vn-print/core/database'); +const Email = require('vn-print/core/email'); + +const {toCSV} = require('../csv'); +const sqlPath = path.join(__dirname, 'sql'); + +module.exports = async function(request, response, next) { + try { + const reqArgs = request.query; + if (!reqArgs.ticketId) + throw new Error('The argument ticketId is required'); + + const ticketId = reqArgs.ticketId; + const ticket = await db.findOneFromDef(`${sqlPath}/ticket`, [ticketId]); + const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [ticketId]); + + const args = Object.assign({ + ticketId: (String(ticket.id)), + recipientId: ticket.clientFk, + recipient: ticket.recipient, + replyTo: ticket.salesPersonEmail + }, response.locals); + + const content = toCSV(sales); + const fileName = `ticket_${ticketId}.csv`; + const email = new Email('delivery-note', args); + await email.send({ + overrideAttachments: true, + attachments: [{ + filename: fileName, + content: content + }] + }); + + response.status(200).json({message: 'Success'}); + } catch (error) { + next(error); + } +}; diff --git a/print/methods/csv/index.js b/print/methods/csv/index.js new file mode 100644 index 000000000..6bdd1b60d --- /dev/null +++ b/print/methods/csv/index.js @@ -0,0 +1,9 @@ +const express = require('express'); +const router = new express.Router(); + +router.get('/delivery-note/download', require('./delivery-note/download')); +router.get('/delivery-note/send', require('./delivery-note/send')); +router.get('/invoice/download', require('./invoice/download')); +router.get('/invoice/send', require('./invoice/send')); + +module.exports = router; diff --git a/print/methods/csv/invoice/download.js b/print/methods/csv/invoice/download.js new file mode 100644 index 000000000..593d2d8d0 --- /dev/null +++ b/print/methods/csv/invoice/download.js @@ -0,0 +1,24 @@ +const path = require('path'); +const db = require('vn-print/core/database'); + +const {toCSV} = require('../csv'); +const sqlPath = path.join(__dirname, 'sql'); + +module.exports = async function(request, response, next) { + try { + const reqArgs = request.query; + if (!reqArgs.invoiceId) + throw new Error('The argument invoiceId is required'); + + const invoiceId = reqArgs.invoiceId; + const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [invoiceId]); + const content = toCSV(sales); + const fileName = `invoice_${invoiceId}.csv`; + + response.setHeader('Content-type', 'text/csv'); + response.setHeader('Content-Disposition', `inline; filename="${fileName}"`); + response.end(content); + } catch (error) { + next(error); + } +}; diff --git a/print/methods/csv/invoice/index.js b/print/methods/csv/invoice/index.js deleted file mode 100644 index 8f325be02..000000000 --- a/print/methods/csv/invoice/index.js +++ /dev/null @@ -1,82 +0,0 @@ -const express = require('express'); -const router = new express.Router(); -const path = require('path'); -const db = require('../../../core/database'); -const sqlPath = path.join(__dirname, 'sql'); - -module.exports = app => { - router.get('/preview', async function(req, res, next) { - try { - const reqArgs = req.args; - if (!reqArgs.invoiceId) - throw new Error('The argument invoiceId is required'); - - const invoiceId = reqArgs.invoiceId; - const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [invoiceId]); - const content = app.toCSV(sales); - const fileName = `invoice_${invoiceId}.csv`; - - res.setHeader('Content-type', 'application/json; charset=utf-8'); - res.setHeader('Content-Disposition', `inline; filename="${fileName}"`); - res.end(content); - } catch (error) { - next(error); - } - }); - - router.get('/download', async function(req, res, next) { - try { - const reqArgs = req.args; - if (!reqArgs.invoiceId) - throw new Error('The argument invoiceId is required'); - - const invoiceId = reqArgs.invoiceId; - const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [invoiceId]); - const content = app.toCSV(sales); - const fileName = `invoice_${invoiceId}.csv`; - - res.setHeader('Content-type', 'text/csv'); - res.setHeader('Content-Disposition', `inline; filename="${fileName}"`); - res.end(content); - } catch (error) { - next(error); - } - }); - - const Email = require('../../../core/email'); - router.get('/send', async function(req, res, next) { - try { - const reqArgs = req.args; - if (!reqArgs.invoiceId) - throw new Error('The argument invoiceId is required'); - - const invoiceId = reqArgs.invoiceId; - const invoice = await db.findOneFromDef(`${sqlPath}/invoice`, [invoiceId]); - const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [invoiceId]); - - const args = Object.assign({ - invoiceId: (String(invoice.id)), - recipientId: invoice.clientFk, - recipient: invoice.recipient, - replyTo: invoice.salesPersonEmail - }, reqArgs); - - const content = app.toCSV(sales); - const fileName = `invoice_${invoiceId}.csv`; - const email = new Email('invoice', args); - await email.send({ - overrideAttachments: true, - attachments: [{ - filename: fileName, - content: content - }] - }); - - res.status(200).json({message: 'ok'}); - } catch (error) { - next(error); - } - }); - - return router; -}; diff --git a/print/methods/csv/invoice/send.js b/print/methods/csv/invoice/send.js new file mode 100644 index 000000000..919d7aeb1 --- /dev/null +++ b/print/methods/csv/invoice/send.js @@ -0,0 +1,40 @@ +const path = require('path'); +const db = require('vn-print/core/database'); +const Email = require('vn-print/core/email'); + +const {toCSV} = require('../csv'); +const sqlPath = path.join(__dirname, 'sql'); + +module.exports = async function(request, response, next) { + try { + const reqArgs = request.query; + if (!reqArgs.invoiceId) + throw new Error('The argument invoiceId is required'); + + const invoiceId = reqArgs.invoiceId; + const invoice = await db.findOneFromDef(`${sqlPath}/invoice`, [invoiceId]); + const sales = await db.rawSqlFromDef(`${sqlPath}/sales`, [invoiceId]); + + const args = Object.assign({ + invoiceId: (String(invoice.id)), + recipientId: invoice.clientFk, + recipient: invoice.recipient, + replyTo: invoice.salesPersonEmail + }, response.locals); + + const content = toCSV(sales); + const fileName = `invoice_${invoiceId}.csv`; + const email = new Email('invoice', args); + await email.send({ + overrideAttachments: true, + attachments: [{ + filename: fileName, + content: content + }] + }); + + response.status(200).json({message: 'Success'}); + } catch (error) { + next(error); + } +}; diff --git a/print/methods/email.js b/print/methods/email.js deleted file mode 100644 index cc4590e5d..000000000 --- a/print/methods/email.js +++ /dev/null @@ -1,33 +0,0 @@ -const Email = require('../core/email'); - -module.exports = app => { - app.get(`/api/email/:name`, async(req, res, next) => { - try { - const reportName = req.params.name; - const email = new Email(reportName, req.args); - - await email.send(); - - res.status(200).json({ - message: 'Sent' - }); - } catch (e) { - next(e); - } - }); - - app.get(`/api/email/:name/preview`, async(req, res, next) => { - try { - const reportName = req.params.name; - const args = req.args; - args.isPreview = true; - - const email = new Email(reportName, args); - const rendered = await email.render(); - - res.send(rendered); - } catch (e) { - next(e); - } - }); -}; diff --git a/print/methods/email/email.js b/print/methods/email/email.js new file mode 100644 index 000000000..5d6882f7d --- /dev/null +++ b/print/methods/email/email.js @@ -0,0 +1,16 @@ +const Email = require('vn-print/core/email'); + +module.exports = async function(request, response, next) { + try { + const templateName = request.params.name; + const args = response.locals; + const email = new Email(templateName, args); + await email.send(); + + response.status(200).json({ + message: 'Sent' + }); + } catch (error) { + next(error); + } +}; diff --git a/print/methods/email/index.js b/print/methods/email/index.js new file mode 100644 index 000000000..10c2d2325 --- /dev/null +++ b/print/methods/email/index.js @@ -0,0 +1,7 @@ +const express = require('express'); +const router = new express.Router(); + +router.get('/:name', require('./email')); +router.get('/:name/preview', require('./preview')); + +module.exports = router; diff --git a/print/methods/email/preview.js b/print/methods/email/preview.js new file mode 100644 index 000000000..e6a1aaf35 --- /dev/null +++ b/print/methods/email/preview.js @@ -0,0 +1,14 @@ +const Email = require('vn-print/core/email'); + +module.exports = async function(request, response, next) { + try { + const templateName = request.params.name; + const args = Object.assign({isPreview: true}, response.locals); + const email = new Email(templateName, args); + const template = await email.render(); + + response.send(template); + } catch (error) { + next(error); + } +}; diff --git a/print/methods/report.js b/print/methods/report.js deleted file mode 100644 index 750fec4c8..000000000 --- a/print/methods/report.js +++ /dev/null @@ -1,54 +0,0 @@ -const Report = require('../core/report'); - -module.exports = app => { - app.get(`/api/report/:name`, async(req, res, next) => { - try { - const reportName = req.params.name; - const fileName = getFileName(reportName, req.args); - const report = new Report(reportName, req.args); - if (req.args.preview) { - const template = await report.render(); - res.send(template); - } else { - const stream = await report.toPdfStream(); - - res.setHeader('Content-type', 'application/pdf'); - res.setHeader('Content-Disposition', `inline; filename="${fileName}"`); - res.end(stream); - } - } catch (error) { - next(error); - } - }); - - /** - * Returns all the params that ends with id - * @param {object} args - Params object - * - * @return {array} List of identifiers - */ - function getIdentifiers(args) { - const identifiers = []; - const keys = Object.keys(args); - - for (let arg of keys) { - if (arg.endsWith('Id')) - identifiers.push(arg); - } - - return identifiers; - } - - function getFileName(name, args) { - const identifiers = getIdentifiers(args); - const params = []; - params.push(name); - - for (let id of identifiers) - params.push(args[id]); - - const fileName = params.join('_'); - - return `${fileName}.pdf`; - } -}; diff --git a/print/methods/report/document.js b/print/methods/report/document.js new file mode 100644 index 000000000..b24abf4ac --- /dev/null +++ b/print/methods/report/document.js @@ -0,0 +1,17 @@ +const Report = require('vn-print/core/report'); + +module.exports = async function(request, response, next) { + try { + const reportName = request.params.name; + const args = response.locals; + const report = new Report(reportName, args); + const stream = await report.toPdfStream(); + const fileName = await report.getFileName(); + + response.setHeader('Content-type', 'application/pdf'); + response.setHeader('Content-Disposition', `inline; filename="${fileName}"`); + response.end(stream); + } catch (error) { + next(error); + } +}; diff --git a/print/methods/report/index.js b/print/methods/report/index.js new file mode 100644 index 000000000..c422c76df --- /dev/null +++ b/print/methods/report/index.js @@ -0,0 +1,7 @@ +const express = require('express'); +const router = new express.Router(); + +router.get('/:name', require('./document')); +router.get('/:name/preview', require('./preview')); + +module.exports = router; diff --git a/print/methods/report/preview.js b/print/methods/report/preview.js new file mode 100644 index 000000000..0d6ad6f43 --- /dev/null +++ b/print/methods/report/preview.js @@ -0,0 +1,13 @@ +const Report = require('vn-print/core/report'); + +module.exports = async function(request, response, next) { + try { + const reportName = request.params.name; + const report = new Report(reportName, request.query); + const template = await report.render(); + + response.send(template); + } catch (error) { + next(error); + } +}; diff --git a/print/methods/routes.js b/print/methods/routes.js new file mode 100644 index 000000000..0c452028e --- /dev/null +++ b/print/methods/routes.js @@ -0,0 +1,18 @@ +module.exports = [ + { + url: '/api/report', + cb: require('./report') + }, + { + url: '/api/email', + cb: require('./email') + }, + { + url: '/api/csv', + cb: require('./csv') + }, + { + url: '/api/closure', + cb: require('./closure') + }, +]; diff --git a/print/package-lock.json b/print/package-lock.json new file mode 100644 index 000000000..c824de5df --- /dev/null +++ b/print/package-lock.json @@ -0,0 +1,1676 @@ +{ + "name": "vn-print", + "version": "2.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/mime-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.0.tgz", + "integrity": "sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM=" + }, + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "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" + } + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "datauri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/datauri/-/datauri-2.0.0.tgz", + "integrity": "sha512-zS2HSf9pI5XPlNZgIqJg/wCJpecgU/HA6E/uv2EfaWnW1EiTGLfy/EexTIsC9c99yoCOTXlqeeWk4FkCSuO3/g==", + "requires": { + "image-size": "^0.7.3", + "mimer": "^1.0.0" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "denque": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", + "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==" + }, + "dijkstrajs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz", + "integrity": "sha1-082BIh4+pAdCz83lVtTpnpjdxxs=" + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extract-zip": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "requires": { + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "requires": { + "pend": "~1.2.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "requires": { + "agent-base": "5", + "debug": "4" + } + }, + "iconv-lite": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", + "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "image-size": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz", + "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "intl": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/intl/-/intl-1.2.5.tgz", + "integrity": "sha1-giRKIZDE5Bn4Nx9ao02qNCDiq94=" + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "requires": { + "has": "^1.0.3" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "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" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonexport": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonexport/-/jsonexport-3.2.0.tgz", + "integrity": "sha512-GbO9ugb0YTZatPd/hqCGR0FSwbr82H6OzG04yzdrG7XOe4QZ0jhQ+kOsB29zqkzoYJLmLxbbrFiuwbQu891XnQ==" + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "juice": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/juice/-/juice-5.2.0.tgz", + "integrity": "sha512-0l6GZmT3efexyaaay3SchKT5kG311N59TEFP5lfvEy0nz9SNqjx311plJ3b4jze7arsmDsiHQLh/xnAuk0HFTQ==", + "requires": { + "cheerio": "^0.22.0", + "commander": "^2.15.1", + "cross-spawn": "^6.0.5", + "deep-extend": "^0.6.0", + "mensch": "^0.3.3", + "slick": "^1.12.2", + "web-resource-inliner": "^4.3.1" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=" + }, + "lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" + }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" + }, + "lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=" + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=" + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "mensch": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/mensch/-/mensch-0.3.4.tgz", + "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==" + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==" + }, + "mime-db": { + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", + "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==" + }, + "mime-types": { + "version": "2.1.29", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", + "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", + "requires": { + "mime-db": "1.46.0" + } + }, + "mimer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimer/-/mimer-1.1.0.tgz", + "integrity": "sha512-y9dVfy2uiycQvDNiAYW6zp49ZhFlXDMr5wfdOiMbdzGM/0N5LNR6HTUn3un+WUQcM0koaw8FMTG1bt5EnHJdvQ==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "mysql2": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-1.7.0.tgz", + "integrity": "sha512-xTWWQPjP5rcrceZQ7CSTKR/4XIDeH/cRkNH/uzvVGQ7W5c7EJ0dXeJUusk7OKhIoHj7uFKUxDVSCfLIl+jluog==", + "requires": { + "denque": "^1.4.1", + "generate-function": "^2.3.1", + "iconv-lite": "^0.5.0", + "long": "^4.0.0", + "lru-cache": "^5.1.1", + "named-placeholders": "^1.1.2", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.1" + } + }, + "named-placeholders": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", + "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", + "requires": { + "lru-cache": "^4.1.3" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "nodemailer": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-4.7.0.tgz", + "integrity": "sha512-IludxDypFpYw4xpzKdMAozBSkzKHmNBvGanUREjJItgJ2NYcK/s8+PggVhj7c2yGFQykKsnnmv1+Aqo0ZfjHmw==" + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "puppeteer": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-2.1.1.tgz", + "integrity": "sha512-LWzaDVQkk1EPiuYeTOj+CZRIjda4k2s5w4MK4xoH2+kgWV/SDlkYHmxatDdtYrciHUKSXTsGgPgPP8ILVdBsxg==", + "requires": { + "@types/mime-types": "^2.1.0", + "debug": "^4.1.0", + "extract-zip": "^1.6.6", + "https-proxy-agent": "^4.0.0", + "mime": "^2.0.3", + "mime-types": "^2.1.25", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^6.1.0" + } + }, + "qrcode": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.4.4.tgz", + "integrity": "sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q==", + "requires": { + "buffer": "^5.4.3", + "buffer-alloc": "^1.2.0", + "buffer-from": "^1.1.1", + "dijkstrajs": "^1.0.1", + "isarray": "^2.0.1", + "pngjs": "^3.3.0", + "yargs": "^13.2.4" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" + }, + "serialize-javascript": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", + "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "slick": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz", + "integrity": "sha1-vQSN23TefRymkV+qSldXCzVQwtc=" + }, + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sqlstring": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz", + "integrity": "sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg==" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "strftime": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/strftime/-/strftime-0.10.0.tgz", + "integrity": "sha1-s/D6QZKVICpaKJ9ta+n0kJphcZM=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "valid-data-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-2.0.0.tgz", + "integrity": "sha512-dyCZnv3aCey7yfTgIqdZanKl7xWAEEKCbgmR7SKqyK6QT/Z07ROactrgD1eA37C69ODRj7rNOjzKWVPh0EUjBA==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vue": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.12.tgz", + "integrity": "sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg==" + }, + "vue-i18n": { + "version": "8.24.1", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.24.1.tgz", + "integrity": "sha512-iqM+npjvI9SGOAYkw1Od/y4O74gpvn5WOHeb3K125TmDJssvR62tDMMLIasPmKNbePZ1BMZ6d5jOBsrB/cK8Lw==" + }, + "vue-server-renderer": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.12.tgz", + "integrity": "sha512-3LODaOsnQx7iMFTBLjki8xSyOxhCtbZ+nQie0wWY4iOVeEtTg1a3YQAjd82WvKxrWHHTshjvLb7OXMc2/dYuxw==", + "requires": { + "chalk": "^1.1.3", + "hash-sum": "^1.0.2", + "he": "^1.1.0", + "lodash.template": "^4.5.0", + "lodash.uniq": "^4.5.0", + "resolve": "^1.2.0", + "serialize-javascript": "^3.1.0", + "source-map": "0.5.6" + } + }, + "web-resource-inliner": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-4.3.4.tgz", + "integrity": "sha512-agVAgRhOOi4GVlvKK34oM23tDgH8390HfLnZY2HZl8OFBwKNvUJkH7t89AT2iluQP8w9VHAAKX6Z8EN7/9tqKA==", + "requires": { + "async": "^3.1.0", + "chalk": "^2.4.2", + "datauri": "^2.0.0", + "htmlparser2": "^4.0.0", + "lodash.unescape": "^4.0.1", + "request": "^2.88.0", + "safer-buffer": "^2.1.2", + "valid-data-url": "^2.0.0", + "xtend": "^4.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "dom-serializer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.2.0.tgz", + "integrity": "sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "entities": "^2.0.0" + }, + "dependencies": { + "domhandler": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz", + "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==", + "requires": { + "domelementtype": "^2.1.0" + } + } + } + }, + "domelementtype": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", + "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==" + }, + "domhandler": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", + "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", + "requires": { + "domelementtype": "^2.0.1" + } + }, + "domutils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.5.0.tgz", + "integrity": "sha512-Ho16rzNMOFk2fPwChGh3D2D9OEHAfG19HgmRR2l+WLSsIstNsAYBzePH412bL0y5T44ejABIVfTHQ8nqi/tBCg==", + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0" + }, + "dependencies": { + "domhandler": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz", + "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==", + "requires": { + "domelementtype": "^2.1.0" + } + } + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, + "htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", + "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/print/templates/email/buyer-week-waste/buyer-week-waste.html b/print/templates/email/buyer-week-waste/buyer-week-waste.html index 3b0c71160..273706c9f 100644 --- a/print/templates/email/buyer-week-waste/buyer-week-waste.html +++ b/print/templates/email/buyer-week-waste/buyer-week-waste.html @@ -51,8 +51,8 @@

diff --git a/print/templates/email/campaign-metrics/campaign-metrics.js b/print/templates/email/campaign-metrics/campaign-metrics.js index 0ace0fc25..2bd93b725 100755 --- a/print/templates/email/campaign-metrics/campaign-metrics.js +++ b/print/templates/email/campaign-metrics/campaign-metrics.js @@ -21,6 +21,7 @@ module.exports = { }, props: { recipientId: { + type: [Number, String], required: true }, from: { diff --git a/print/templates/email/claim-pickup-order/claim-pickup-order.js b/print/templates/email/claim-pickup-order/claim-pickup-order.js index 4396b144a..cf4ba7d12 100755 --- a/print/templates/email/claim-pickup-order/claim-pickup-order.js +++ b/print/templates/email/claim-pickup-order/claim-pickup-order.js @@ -10,6 +10,7 @@ module.exports = { }, props: { claimId: { + type: [Number, String], required: true } } diff --git a/print/templates/email/client-debt-statement/client-debt-statement.js b/print/templates/email/client-debt-statement/client-debt-statement.js index c32e68943..f32f9e239 100755 --- a/print/templates/email/client-debt-statement/client-debt-statement.js +++ b/print/templates/email/client-debt-statement/client-debt-statement.js @@ -16,6 +16,7 @@ module.exports = { }, props: { recipientId: { + type: [Number, String], required: true }, from: { diff --git a/print/templates/email/client-welcome/client-welcome.js b/print/templates/email/client-welcome/client-welcome.js index f562339cc..eeb11bb78 100755 --- a/print/templates/email/client-welcome/client-welcome.js +++ b/print/templates/email/client-welcome/client-welcome.js @@ -18,6 +18,7 @@ module.exports = { }, props: { recipientId: { + type: [Number, String], required: true } } diff --git a/print/templates/email/client-welcome/locale/es.yml b/print/templates/email/client-welcome/locale/es.yml index ac43a7cc6..42426dc74 100644 --- a/print/templates/email/client-welcome/locale/es.yml +++ b/print/templates/email/client-welcome/locale/es.yml @@ -5,9 +5,7 @@ clientData: 'Tus datos para poder comprar en la web de Verdnatura (https://www.verdnatura.es) o en nuestras aplicaciones para iOS y Android (Ver tutorial de uso), son' + title="Google Play" target="_blank" style="color: #8dba25">Android, son' clientId: Identificador de cliente user: Usuario password: Contraseña diff --git a/print/templates/email/delivery-note-link/delivery-note-link.js b/print/templates/email/delivery-note-link/delivery-note-link.js index 009fe7b5b..471b370d9 100755 --- a/print/templates/email/delivery-note-link/delivery-note-link.js +++ b/print/templates/email/delivery-note-link/delivery-note-link.js @@ -10,6 +10,7 @@ module.exports = { }, props: { ticketId: { + type: [Number, String], required: true } } diff --git a/print/templates/email/delivery-note/delivery-note.js b/print/templates/email/delivery-note/delivery-note.js index 64839b8e0..ffd2fe202 100755 --- a/print/templates/email/delivery-note/delivery-note.js +++ b/print/templates/email/delivery-note/delivery-note.js @@ -10,7 +10,7 @@ module.exports = { }, props: { ticketId: { - type: String, + type: [Number, String], required: true } } diff --git a/print/templates/email/driver-route/driver-route.js b/print/templates/email/driver-route/driver-route.js index de1dd9c39..378cd82ce 100755 --- a/print/templates/email/driver-route/driver-route.js +++ b/print/templates/email/driver-route/driver-route.js @@ -10,7 +10,7 @@ module.exports = { }, props: { routeId: { - type: String, + type: [Number, String], required: true } } diff --git a/print/templates/email/invoice/invoice.js b/print/templates/email/invoice/invoice.js index b8d3b8282..d92b65cb3 100755 --- a/print/templates/email/invoice/invoice.js +++ b/print/templates/email/invoice/invoice.js @@ -18,7 +18,7 @@ module.exports = { }, props: { invoiceId: { - type: String, + type: [Number, String], required: true } } diff --git a/print/templates/email/letter-debtor-nd/letter-debtor-nd.js b/print/templates/email/letter-debtor-nd/letter-debtor-nd.js index ba9f7957d..5e010d1ba 100755 --- a/print/templates/email/letter-debtor-nd/letter-debtor-nd.js +++ b/print/templates/email/letter-debtor-nd/letter-debtor-nd.js @@ -30,9 +30,11 @@ module.exports = { required: true }, recipientId: { + type: [Number, String], required: true }, companyId: { + type: [Number, String], required: true } } diff --git a/print/templates/email/letter-debtor-st/letter-debtor-st.js b/print/templates/email/letter-debtor-st/letter-debtor-st.js index 56fc7c8a8..a514097cf 100755 --- a/print/templates/email/letter-debtor-st/letter-debtor-st.js +++ b/print/templates/email/letter-debtor-st/letter-debtor-st.js @@ -1,5 +1,4 @@ const Component = require(`${appPath}/core/component`); -const db = require(`${appPath}/core/database`); const emailHeader = new Component('email-header'); const emailFooter = new Component('email-footer'); const attachment = new Component('attachment'); @@ -28,9 +27,11 @@ module.exports = { }, props: { recipientId: { + type: [Number, String], required: true }, companyId: { + type: [Number, String], required: true }, } diff --git a/print/templates/email/payment-update/payment-update.js b/print/templates/email/payment-update/payment-update.js index eb6690c02..2b92976a3 100755 --- a/print/templates/email/payment-update/payment-update.js +++ b/print/templates/email/payment-update/payment-update.js @@ -26,6 +26,7 @@ module.exports = { }, props: { recipientId: { + type: [Number, String], required: true } } diff --git a/print/templates/email/printer-setup/printer-setup.js b/print/templates/email/printer-setup/printer-setup.js index f6f168163..95dff8ebb 100755 --- a/print/templates/email/printer-setup/printer-setup.js +++ b/print/templates/email/printer-setup/printer-setup.js @@ -24,6 +24,7 @@ module.exports = { }, props: { recipientId: { + type: [Number, String], required: true } } diff --git a/print/templates/email/sepa-core/sepa-core.js b/print/templates/email/sepa-core/sepa-core.js index 76f8d842f..743c6719c 100755 --- a/print/templates/email/sepa-core/sepa-core.js +++ b/print/templates/email/sepa-core/sepa-core.js @@ -16,9 +16,11 @@ module.exports = { }, props: { recipientId: { + type: [Number, String], required: true }, companyId: { + type: [Number, String], required: true } } diff --git a/print/templates/email/supplier-campaign-metrics/supplier-campaign-metrics.js b/print/templates/email/supplier-campaign-metrics/supplier-campaign-metrics.js index 20113d8ea..3cf290e4d 100755 --- a/print/templates/email/supplier-campaign-metrics/supplier-campaign-metrics.js +++ b/print/templates/email/supplier-campaign-metrics/supplier-campaign-metrics.js @@ -21,6 +21,7 @@ module.exports = { }, props: { recipientId: { + type: [Number, String], required: true }, from: { diff --git a/print/templates/reports/campaign-metrics/campaign-metrics.js b/print/templates/reports/campaign-metrics/campaign-metrics.js index 07d261a61..6669ce067 100755 --- a/print/templates/reports/campaign-metrics/campaign-metrics.js +++ b/print/templates/reports/campaign-metrics/campaign-metrics.js @@ -25,6 +25,7 @@ module.exports = { }, props: { recipientId: { + type: [Number, String], required: true }, from: { diff --git a/print/templates/reports/campaign-metrics/locale/es.yml b/print/templates/reports/campaign-metrics/locale/es.yml index 8a4cc4637..c455be5a8 100644 --- a/print/templates/reports/campaign-metrics/locale/es.yml +++ b/print/templates/reports/campaign-metrics/locale/es.yml @@ -1,3 +1,4 @@ +reportName: consumo-cliente title: Consumo Client: Cliente clientData: Datos del cliente diff --git a/print/templates/reports/claim-pickup-order/claim-pickup-order.js b/print/templates/reports/claim-pickup-order/claim-pickup-order.js index 0d1228a4e..fa2124057 100755 --- a/print/templates/reports/claim-pickup-order/claim-pickup-order.js +++ b/print/templates/reports/claim-pickup-order/claim-pickup-order.js @@ -32,6 +32,7 @@ module.exports = { }, props: { claimId: { + type: [Number, String], required: true } } diff --git a/print/templates/reports/claim-pickup-order/locale/es.yml b/print/templates/reports/claim-pickup-order/locale/es.yml index 9faf9ac06..faa6eac33 100644 --- a/print/templates/reports/claim-pickup-order/locale/es.yml +++ b/print/templates/reports/claim-pickup-order/locale/es.yml @@ -1,3 +1,4 @@ +reportName: orden-de-recogida title: Ord. recogida claimId: Reclamación clientId: Cliente diff --git a/print/templates/reports/client-debt-statement/client-debt-statement.js b/print/templates/reports/client-debt-statement/client-debt-statement.js index 09b99590b..f006b0a92 100755 --- a/print/templates/reports/client-debt-statement/client-debt-statement.js +++ b/print/templates/reports/client-debt-statement/client-debt-statement.js @@ -69,6 +69,7 @@ module.exports = { }, props: { recipientId: { + type: [Number, String], required: true }, from: { diff --git a/print/templates/reports/client-debt-statement/locale/es.yml b/print/templates/reports/client-debt-statement/locale/es.yml index ccdce7b5b..2c8e18ee1 100644 --- a/print/templates/reports/client-debt-statement/locale/es.yml +++ b/print/templates/reports/client-debt-statement/locale/es.yml @@ -1,3 +1,4 @@ +reportName: extracto-cliente title: Extracto clientId: Cliente clientData: Datos del cliente diff --git a/print/templates/reports/client-debt-statement/locale/fr.yml b/print/templates/reports/client-debt-statement/locale/fr.yml index 12534f9ff..4edb29d8a 100644 --- a/print/templates/reports/client-debt-statement/locale/fr.yml +++ b/print/templates/reports/client-debt-statement/locale/fr.yml @@ -1,3 +1,4 @@ +reportName: releve-de-compte title: Relevé de compte clientId: Client clientData: Données client diff --git a/print/templates/reports/cmr-authorization/cmr-authorization.js b/print/templates/reports/cmr-authorization/cmr-authorization.js index da08b6ec8..1adc75fa6 100755 --- a/print/templates/reports/cmr-authorization/cmr-authorization.js +++ b/print/templates/reports/cmr-authorization/cmr-authorization.js @@ -8,9 +8,8 @@ module.exports = { this.ticket = await this.findOneFromDef('ticket', [this.ticketId]); if (!this.ticket) throw new Error('Something went wrong'); - - this.client = await this.findOneFromDef('client', [this.ticket.clientFk]); + this.client = await this.findOneFromDef('client', [this.ticket.clientFk]); }, computed: { issued: function() { @@ -23,6 +22,7 @@ module.exports = { }, props: { ticketId: { + type: [Number, String], required: true } } diff --git a/print/templates/reports/cmr-authorization/locale/es.yml b/print/templates/reports/cmr-authorization/locale/es.yml index 779dc0c8f..37e40202d 100644 --- a/print/templates/reports/cmr-authorization/locale/es.yml +++ b/print/templates/reports/cmr-authorization/locale/es.yml @@ -1,3 +1,4 @@ +reportName: autorizacion-cmr description: '{socialName} una sociedad debidamente constituida con responsabilidad limitada y registrada conforme al derecho de sociedades de {country} y aquí representada por ___________________. {socialName}, con domicilio en {address}, diff --git a/print/templates/reports/credit-request/locale/es.yml b/print/templates/reports/credit-request/locale/es.yml index e4e9739a5..cd6f92dc5 100644 --- a/print/templates/reports/credit-request/locale/es.yml +++ b/print/templates/reports/credit-request/locale/es.yml @@ -1,3 +1,4 @@ +reportName: solicitud-de-credito fields: title: Solicitud de crédito date: Fecha diff --git a/print/templates/reports/delivery-note/delivery-note.js b/print/templates/reports/delivery-note/delivery-note.js index 9b3328d05..0ee7c8c91 100755 --- a/print/templates/reports/delivery-note/delivery-note.js +++ b/print/templates/reports/delivery-note/delivery-note.js @@ -117,7 +117,7 @@ module.exports = { }, props: { ticketId: { - type: String, + type: [Number, String], required: true } } diff --git a/print/templates/reports/delivery-note/locale/en.yml b/print/templates/reports/delivery-note/locale/en.yml index 8a3ff834b..16d0954e2 100644 --- a/print/templates/reports/delivery-note/locale/en.yml +++ b/print/templates/reports/delivery-note/locale/en.yml @@ -1,3 +1,4 @@ +reportName: delivery-note title: Delivery note ticketId: Delivery note clientId: Client diff --git a/print/templates/reports/delivery-note/locale/es.yml b/print/templates/reports/delivery-note/locale/es.yml index f9c2e02f3..ca670ad59 100644 --- a/print/templates/reports/delivery-note/locale/es.yml +++ b/print/templates/reports/delivery-note/locale/es.yml @@ -1,3 +1,4 @@ +reportName: albaran title: Albarán ticketId: Albarán clientId: Cliente diff --git a/print/templates/reports/delivery-note/locale/fr.yml b/print/templates/reports/delivery-note/locale/fr.yml index 72ca771e1..6b3779a5b 100644 --- a/print/templates/reports/delivery-note/locale/fr.yml +++ b/print/templates/reports/delivery-note/locale/fr.yml @@ -1,3 +1,4 @@ +reportName: bon-de-livraison title: Bon de livraison ticketId: BL clientId: Client diff --git a/print/templates/reports/delivery-note/locale/pt.yml b/print/templates/reports/delivery-note/locale/pt.yml index e83087142..1a9c1fbd1 100644 --- a/print/templates/reports/delivery-note/locale/pt.yml +++ b/print/templates/reports/delivery-note/locale/pt.yml @@ -1,3 +1,4 @@ +reportName: nota-de-entrega title: Nota de Entrega ticketId: Nota de Entrega clientId: Cliente diff --git a/print/templates/reports/driver-route/driver-route.js b/print/templates/reports/driver-route/driver-route.js index 0b2638239..c34de37cc 100755 --- a/print/templates/reports/driver-route/driver-route.js +++ b/print/templates/reports/driver-route/driver-route.js @@ -39,6 +39,7 @@ module.exports = { }, props: { routeId: { + type: [Number, String], required: true } } diff --git a/print/templates/reports/driver-route/locale/es.yml b/print/templates/reports/driver-route/locale/es.yml index 4f0f3ac3c..4c922ba64 100644 --- a/print/templates/reports/driver-route/locale/es.yml +++ b/print/templates/reports/driver-route/locale/es.yml @@ -1,3 +1,4 @@ +reportName: hoja-de-ruta title: Hoja de ruta information: Información date: Fecha diff --git a/print/templates/reports/entry-order/entry-order.js b/print/templates/reports/entry-order/entry-order.js index de396df2c..52a56bf03 100755 --- a/print/templates/reports/entry-order/entry-order.js +++ b/print/templates/reports/entry-order/entry-order.js @@ -40,7 +40,7 @@ module.exports = { }, props: { entryId: { - type: String, + type: [Number, String], required: true } } diff --git a/print/templates/reports/entry-order/locale/es.yml b/print/templates/reports/entry-order/locale/es.yml index 3c29d6401..5c633aeaa 100644 --- a/print/templates/reports/entry-order/locale/es.yml +++ b/print/templates/reports/entry-order/locale/es.yml @@ -1,3 +1,4 @@ +reportName: pedido-de-entrada title: Pedido supplierName: Proveedor supplierStreet: Dirección diff --git a/print/templates/reports/exportation/exportation.js b/print/templates/reports/exportation/exportation.js index f63d17930..fbf663249 100755 --- a/print/templates/reports/exportation/exportation.js +++ b/print/templates/reports/exportation/exportation.js @@ -28,6 +28,7 @@ module.exports = { }, props: { invoiceId: { + type: [Number, String], required: true } } diff --git a/print/templates/reports/exportation/locale/es.yml b/print/templates/reports/exportation/locale/es.yml index d5fb78b4c..a689e245b 100644 --- a/print/templates/reports/exportation/locale/es.yml +++ b/print/templates/reports/exportation/locale/es.yml @@ -1,3 +1,4 @@ +reportName: carta-CITES title: 'Carta CITES' toAttention: 'A la atención del Sr. Administrador de la Aduana de la Farga de Moles.' declaration: 'Por la presente DECLARO, bajo mi responsabilidad, que las mercancías detalladas en la factura diff --git a/print/templates/reports/extra-community/locale/es.yml b/print/templates/reports/extra-community/locale/es.yml index 1112b0fe8..36201400f 100644 --- a/print/templates/reports/extra-community/locale/es.yml +++ b/print/templates/reports/extra-community/locale/es.yml @@ -1,3 +1,4 @@ +reportName: orden-de-carga title: Orden de carga reference: Referencia information: Información diff --git a/print/templates/reports/invoice-incoterms/invoice-incoterms.js b/print/templates/reports/invoice-incoterms/invoice-incoterms.js index 95bf1f397..99e23e15f 100755 --- a/print/templates/reports/invoice-incoterms/invoice-incoterms.js +++ b/print/templates/reports/invoice-incoterms/invoice-incoterms.js @@ -32,7 +32,7 @@ module.exports = { }, props: { invoiceId: { - type: String, + type: [Number, String], required: true } } diff --git a/print/templates/reports/invoice-incoterms/locale/es.yml b/print/templates/reports/invoice-incoterms/locale/es.yml index 9828564d7..a69805935 100644 --- a/print/templates/reports/invoice-incoterms/locale/es.yml +++ b/print/templates/reports/invoice-incoterms/locale/es.yml @@ -1,3 +1,4 @@ +reportName: factura title: Factura invoice: Factura clientId: Cliente diff --git a/print/templates/reports/invoice/invoice.js b/print/templates/reports/invoice/invoice.js index b56a5533c..bd85a812c 100755 --- a/print/templates/reports/invoice/invoice.js +++ b/print/templates/reports/invoice/invoice.js @@ -115,7 +115,7 @@ module.exports = { }, props: { invoiceId: { - type: String, + type: [Number, String], required: true } } diff --git a/print/templates/reports/invoice/locale/en.yml b/print/templates/reports/invoice/locale/en.yml new file mode 100644 index 000000000..4e4688b55 --- /dev/null +++ b/print/templates/reports/invoice/locale/en.yml @@ -0,0 +1,36 @@ +reportName: invoice +title: Invoice +invoice: Invoice +clientId: Client +invoiceData: Invoice data +fiscalId: FI / NIF +invoiceRef: Invoice {0} +deliveryNote: Delivery note +shipped: Shipped +date: Date +reference: Ref. +quantity: Qty. +concept: Concept +price: PSP/u +discount: Disc. +vat: VAT +amount: Amount +type: Type +taxBase: Tax base +tax: Tax +fee: Fee +total: Total +subtotal: Subtotal +taxBreakdown: Tax breakdown +notes: Notes +intrastat: Intrastat +code: Code +description: Description +stems: Stems +netKg: Net kg +rectifiedInvoices: Rectified invoices +issued: Issued +plantPassport: Plant passport +observations: Observations +wireTransfer: "Pay method: Transferencia" +accountNumber: "Account number: {0}" \ No newline at end of file diff --git a/print/templates/reports/invoice/locale/es.yml b/print/templates/reports/invoice/locale/es.yml index 6fdfc8a14..d37e77943 100644 --- a/print/templates/reports/invoice/locale/es.yml +++ b/print/templates/reports/invoice/locale/es.yml @@ -1,3 +1,4 @@ +reportName: factura title: Factura invoice: Factura clientId: Cliente diff --git a/print/templates/reports/letter-debtor/letter-debtor.js b/print/templates/reports/letter-debtor/letter-debtor.js index bdb3a504a..354b1d8d8 100755 --- a/print/templates/reports/letter-debtor/letter-debtor.js +++ b/print/templates/reports/letter-debtor/letter-debtor.js @@ -63,9 +63,11 @@ module.exports = { }, props: { recipientId: { + type: [Number, String], required: true }, companyId: { + type: [Number, String], required: true } } diff --git a/print/templates/reports/letter-debtor/locale/es.yml b/print/templates/reports/letter-debtor/locale/es.yml index a9bd8c796..6c66f0717 100644 --- a/print/templates/reports/letter-debtor/locale/es.yml +++ b/print/templates/reports/letter-debtor/locale/es.yml @@ -1,3 +1,4 @@ +reportName: extracto-de-cuenta title: Extracto claimId: Reclamación clientId: Cliente diff --git a/print/templates/reports/letter-debtor/locale/fr.yml b/print/templates/reports/letter-debtor/locale/fr.yml index eff39d783..277c1162f 100644 --- a/print/templates/reports/letter-debtor/locale/fr.yml +++ b/print/templates/reports/letter-debtor/locale/fr.yml @@ -1,3 +1,4 @@ +reportName: releve-de-compte title: Relevé de compte claimId: Réclamation clientId: Client diff --git a/print/templates/reports/receipt/locale/es.yml b/print/templates/reports/receipt/locale/es.yml index 67b9a948f..41be106df 100644 --- a/print/templates/reports/receipt/locale/es.yml +++ b/print/templates/reports/receipt/locale/es.yml @@ -1,3 +1,4 @@ +reportName: receipt title: 'Recibo' date: 'Fecha' payed: 'En {0}, a {1} de {2} de {3}' diff --git a/print/templates/reports/receipt/receipt.js b/print/templates/reports/receipt/receipt.js index d34735bb7..d7f4dd6da 100755 --- a/print/templates/reports/receipt/receipt.js +++ b/print/templates/reports/receipt/receipt.js @@ -25,6 +25,7 @@ module.exports = { }, props: { receiptId: { + type: [Number, String], required: true } } diff --git a/print/templates/reports/sepa-core/locale/es.yml b/print/templates/reports/sepa-core/locale/es.yml index bb9cc4e49..5f3f08fc3 100644 --- a/print/templates/reports/sepa-core/locale/es.yml +++ b/print/templates/reports/sepa-core/locale/es.yml @@ -1,3 +1,4 @@ +reportName: orden-de-domiciliacion title: Orden de domiciliación de adeudo SEPA CORE description: Mediante la firma de esta orden de domiciliación, el deudor autoriza (A) al acreedor a enviar instrucciones a la entidad del deudor para adeudar su cuenta diff --git a/print/templates/reports/sepa-core/locale/fr.yml b/print/templates/reports/sepa-core/locale/fr.yml index 45a9039ea..354c06114 100644 --- a/print/templates/reports/sepa-core/locale/fr.yml +++ b/print/templates/reports/sepa-core/locale/fr.yml @@ -1,3 +1,4 @@ +reportName: direct-debit title: Direct Debit description: En signant ce formulaire de mandat, vous autorisez VERDNATURA LEVANTE SL à envoyer des instructions à votre banque pour débiter votre compte, et (B) votre banque diff --git a/print/templates/reports/sepa-core/locale/pt.yml b/print/templates/reports/sepa-core/locale/pt.yml index e7127d06b..5459779ec 100644 --- a/print/templates/reports/sepa-core/locale/pt.yml +++ b/print/templates/reports/sepa-core/locale/pt.yml @@ -1,3 +1,4 @@ +reportName: autorizacao-de-debito title: Autorização de débito directo SEPA CORE description: Ao subscrever esta autorização, está a autorizar a (A) Verdnatura Levante S.L. a enviar instruções ao seu banco para debitar a sua conta e (B) seu banco a diff --git a/print/templates/reports/sepa-core/sepa-core.js b/print/templates/reports/sepa-core/sepa-core.js index 55487d829..7e3dd3566 100755 --- a/print/templates/reports/sepa-core/sepa-core.js +++ b/print/templates/reports/sepa-core/sepa-core.js @@ -40,9 +40,11 @@ const rptSepaCore = { }, props: { recipientId: { + type: [Number, String], required: true }, companyId: { + type: [Number, String], required: true } } diff --git a/print/templates/reports/supplier-campaign-metrics/locale/es.yml b/print/templates/reports/supplier-campaign-metrics/locale/es.yml index 31c1e17dd..1a38541fa 100644 --- a/print/templates/reports/supplier-campaign-metrics/locale/es.yml +++ b/print/templates/reports/supplier-campaign-metrics/locale/es.yml @@ -1,3 +1,4 @@ +reportName: consumo-proveedor title: Consumo Supplier: Proveedor supplierData: Datos del proveedor diff --git a/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.js b/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.js index c37155556..1a460daa9 100755 --- a/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.js +++ b/print/templates/reports/supplier-campaign-metrics/supplier-campaign-metrics.js @@ -49,6 +49,7 @@ module.exports = { }, props: { recipientId: { + type: [Number, String], required: true }, from: { diff --git a/print/templates/reports/zone/zone.js b/print/templates/reports/zone/zone.js index 61c6cddfe..d611e1e53 100755 --- a/print/templates/reports/zone/zone.js +++ b/print/templates/reports/zone/zone.js @@ -13,6 +13,7 @@ module.exports = { }, props: { routeId: { + type: [Number, String], required: true } } diff --git a/storage/pdfs/invoice/.keep b/storage/pdfs/invoice/.keep deleted file mode 100644 index e69de29bb..000000000