Merge pull request 'Revert "Merge branch 'dev' into test"' (!2064) from test_revert into test
gitea/salix/pipeline/head This commit looks good Details
gitea/salix/pipeline/pr-dev This commit looks good Details

Reviewed-on: #2064
Reviewed-by: Pablo Natek <pablone@verdnatura.es>
This commit is contained in:
Alex Moreno 2024-02-21 13:47:38 +00:00
commit cbe23d8df5
32 changed files with 309 additions and 486 deletions

View File

@ -0,0 +1,20 @@
module.exports = Self => {
Self.remoteMethod('getSectors', {
description: 'Get all sectors',
accessType: 'READ',
returns: {
type: 'Object',
root: true
},
http: {
path: `/getSectors`,
verb: 'GET'
}
});
Self.getSectors = async() => {
const query = `CALL vn.sector_get()`;
const [result] = await Self.rawSql(query);
return result;
};
};

View File

@ -0,0 +1,11 @@
const {models} = require('vn-loopback/server/server');
describe('getSectors()', () => {
it('return list of sectors', async() => {
let response = await models.Collection.getSectors();
expect(response.length).toBeGreaterThan(0);
expect(response[0].id).toEqual(1);
expect(response[0].description).toEqual('First sector');
});
});

View File

@ -1,5 +1,6 @@
module.exports = Self => { module.exports = Self => {
require('../methods/collection/getCollection')(Self); require('../methods/collection/getCollection')(Self);
require('../methods/collection/getSectors')(Self);
require('../methods/collection/setSaleQuantity')(Self); require('../methods/collection/setSaleQuantity')(Self);
require('../methods/collection/previousLabel')(Self); require('../methods/collection/previousLabel')(Self);
require('../methods/collection/getTickets')(Self); require('../methods/collection/getTickets')(Self);

View File

@ -1750,6 +1750,8 @@ USE `vn`;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
INSERT INTO `agencyTermConfig` VALUES ('6240000000','4721000015',21.0000000000,'Adquisiciones intracomunitarias de servicios');
INSERT INTO `alertLevel` VALUES ('FREE',0,1); INSERT INTO `alertLevel` VALUES ('FREE',0,1);
INSERT INTO `alertLevel` VALUES ('ON_PREPARATION',1,1); INSERT INTO `alertLevel` VALUES ('ON_PREPARATION',1,1);
INSERT INTO `alertLevel` VALUES ('PACKED',2,0); INSERT INTO `alertLevel` VALUES ('PACKED',2,0);

View File

@ -653,7 +653,6 @@ INSERT INTO `vn`.`expense`(`id`, `name`, `isWithheld`)
(7001000000, 'Mercaderia', 0), (7001000000, 'Mercaderia', 0),
(7050000000, 'Prestacion de servicios', 1); (7050000000, 'Prestacion de servicios', 1);
INSERT INTO `vn`.`agencyTermConfig` VALUES ('6240000000','4721000015',21.0000000000,'Adquisiciones intracomunitarias de servicios');
INSERT INTO `vn`.`invoiceOutExpense`(`id`, `invoiceOutFk`, `amount`, `expenseFk`, `created`) INSERT INTO `vn`.`invoiceOutExpense`(`id`, `invoiceOutFk`, `amount`, `expenseFk`, `created`)
VALUES VALUES

View File

@ -47,12 +47,12 @@ BEGIN
, tp.reino_id , tp.reino_id
, a.tipo_id , a.tipo_id
, t.empresa_id , t.empresa_id
, a.expenseFk , 7000000000
+ IF(e.empresa_grupo = e2.empresa_grupo + IF(e.empresa_grupo = e2.empresa_grupo
,1 ,1
,IF(e2.empresa_grupo,2,0) ,IF(e2.empresa_grupo,2,0)
) * 100000 ) * 1000000
+ tp.reino_id * 1000 as Gasto + tp.reino_id * 10000 as Gasto
FROM vn2008.Movimientos m FROM vn2008.Movimientos m
JOIN vn2008.Tickets t on t.Id_Ticket = m.Id_Ticket JOIN vn2008.Tickets t on t.Id_Ticket = m.Id_Ticket
JOIN vn2008.Consignatarios cs on cs.Id_Consigna = t.Id_Consigna JOIN vn2008.Consignatarios cs on cs.Id_Consigna = t.Id_Consigna

View File

@ -8,7 +8,6 @@ BEGIN
*/ */
DECLARE vTaxRowLimit INT; DECLARE vTaxRowLimit INT;
DECLARE vLines INT; DECLARE vLines INT;
DECLARE vHasDistinctTransactions INT;
SELECT taxRowLimit INTO vTaxRowLimit FROM invoiceInConfig; SELECT taxRowLimit INTO vTaxRowLimit FROM invoiceInConfig;
@ -20,17 +19,5 @@ BEGIN
IF vLines >= vTaxRowLimit THEN IF vLines >= vTaxRowLimit THEN
CALL util.throw (CONCAT('The maximum number of lines is ', vTaxRowLimit)); CALL util.throw (CONCAT('The maximum number of lines is ', vTaxRowLimit));
END IF; END IF;
SELECT COUNT(DISTINCT transactionTypeSageFk) INTO vHasDistinctTransactions
FROM invoiceIn ii
JOIN invoiceInTax iit ON iit.invoiceInFk = ii.id
JOIN invoiceInSerial iis ON iis.code = ii.serial
WHERE ii.id = vInvoiceInFk
AND iis.taxAreaFk = 'CEE'
AND transactionTypeSageFk;
IF vHasDistinctTransactions > 1 THEN
CALL util.throw ('This invoice does not allow different types of transactions');
END IF;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -0,0 +1,70 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemProposal_Add`(vSaleFk INT, vMateFk INT, vQuantity INT)
BEGIN
/**
* Añade un nuevo articulo para sustituir a otro, y actualiza la memoria de sustituciones.
*
* @param vSaleFk id de la tabla sale
* @param vMateFk articulo sustituto
* @ param vQuantity cantidad que se va a sustituir
*/
DECLARE vTicketFk INT;
DECLARE vItemFk INT;
DECLARE vWarehouseFk SMALLINT;
DECLARE vDate DATE;
DECLARE vGrouping INT;
DECLARE vBox INT;
DECLARE vPacking INT;
DECLARE vRoundQuantity INT DEFAULT 1;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
SELECT s.ticketFk, LEAST(s.quantity, vQuantity), s.itemFk,t.shipped,t.warehouseFk
INTO vTicketFk, vQuantity, vItemFk,vDate,vWarehouseFk
FROM sale s
JOIN ticket t ON t.id = s.ticketFk
WHERE s.id = vSaleFk;
CALL buyUltimate(vWarehouseFk, vDate);
SELECT `grouping`, groupingMode, packing INTO vGrouping, vBox, vPacking
FROM buy b
JOIN tmp.buyUltimate tmp ON b.id = tmp.buyFk
WHERE tmp.itemFk = vMateFk AND tmp.WarehouseFk = vWarehouseFk;
IF vBox = 2 AND vPacking > 0 THEN
SET vRoundQuantity = vPacking;
END IF;
IF vBox = 1 AND vGrouping > 0 THEN
SET vRoundQuantity = vGrouping;
END IF;
START TRANSACTION;
UPDATE sale
SET quantity = quantity - vQuantity
WHERE id = vSaleFk;
INSERT INTO sale(ticketFk, itemFk, quantity, concept)
SELECT vTicketFk,
vMateFk,
CEIL(vQuantity / vRoundQuantity) * vRoundQuantity,
CONCAT('+ ',i.longName)
FROM item i
WHERE id = vMateFk;
SELECT LAST_INSERT_ID() INTO vSaleFk;
CALL sale_calculateComponent(vSaleFk, NULL);
INSERT INTO itemProposal(itemFk, mateFk, counter)
VALUES(vItemFk, vMateFk, 1)
ON DUPLICATE KEY UPDATE counter = counter + 1;
COMMIT;
END$$
DELIMITER ;

View File

@ -20,10 +20,6 @@ BEGIN
SELECT barcodeToItem(vBarcode) INTO vItemFk; SELECT barcodeToItem(vBarcode) INTO vItemFk;
SET vPacking = COALESCE(vPacking, GREATEST(vn.itemPacking(vBarcode,vWarehouseFk), 1));
SET vQuantity = vQuantity * vPacking;
IF (SELECT COUNT(*) FROM shelving WHERE code = vShelvingFk COLLATE utf8_unicode_ci) = 0 THEN IF (SELECT COUNT(*) FROM shelving WHERE code = vShelvingFk COLLATE utf8_unicode_ci) = 0 THEN
INSERT IGNORE INTO parking(code) VALUES(vShelvingFk); INSERT IGNORE INTO parking(code) VALUES(vShelvingFk);

View File

@ -17,6 +17,7 @@ BEGIN
CALL productionControl(vWarehouseFk, 0); CALL productionControl(vWarehouseFk, 0);
-- Products with vn.item.isBoxPickingMode = TRUE, pay atention to vn.itemShelving.packing
CREATE OR REPLACE TEMPORARY TABLE tmp.sale CREATE OR REPLACE TEMPORARY TABLE tmp.sale
(saleFk INT PRIMARY KEY) (saleFk INT PRIMARY KEY)
SELECT SELECT
@ -28,7 +29,7 @@ BEGIN
MAKETIME(pb.HH,pb.mm,0) etd, MAKETIME(pb.HH,pb.mm,0) etd,
pb.routeFk, pb.routeFk,
FLOOR(s.quantity / ish.packing) stickers, FLOOR(s.quantity / ish.packing) stickers,
IF(i.isBoxPickingMode, ish.packing, i.packingOut) packing, ish.packing,
b.packagingFk b.packagingFk
FROM sale s FROM sale s
JOIN item i ON i.id = s.itemFk JOIN item i ON i.id = s.itemFk
@ -51,8 +52,8 @@ BEGIN
LEFT JOIN ticketState ts ON ts.ticketFk = s.ticketFk LEFT JOIN ticketState ts ON ts.ticketFk = s.ticketFk
LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = vWarehouseFk LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = vWarehouseFk
LEFT JOIN buy b ON b.id = lb.buy_id LEFT JOIN buy b ON b.id = lb.buy_id
WHERE IF(i.isBoxPickingMode, ish.packing, i.packingOut) WHERE s.quantity BETWEEN ish.packing AND (ish.visible - IFNULL(tISS.reserve,0))
<= LEAST(s.quantity, ish.visible - IFNULL(tISS.reserve,0)) AND i.isBoxPickingMode
AND NOT pb.problem AND NOT pb.problem
AND sgd.saleFk IS NULL AND sgd.saleFk IS NULL
AND p.sectorFk = vSectorFk AND p.sectorFk = vSectorFk
@ -63,13 +64,47 @@ BEGIN
GROUP BY s.id GROUP BY s.id
ORDER BY etd; ORDER BY etd;
SELECT * -- Remaining products, vn.item.packingOut
FROM tmp.sale INSERT IGNORE INTO tmp.sale
WHERE stickers; SELECT
s.ticketFk,
s.id saleFk,
s.itemFk,
s.concept,
s.quantity,
MAKETIME(pb.HH,pb.mm,0) etd,
pb.routeFk,
s.quantity / i.packingOut stickers,
i.packingOut,
pc.defaultBigPackageFk
FROM sale s
JOIN item i ON i.id = s.itemFk
JOIN itemShelving ish ON ish.itemFk = s.itemFk
JOIN shelving sh ON sh.code = ish.shelvingFk
JOIN parking p ON p.id = sh.parkingFk
JOIN tmp.productionBuffer pb ON pb.ticketFk = s.ticketFk
JOIN agencyMode am ON am.id = pb.agencyModeFk
JOIN packagingConfig pc
LEFT JOIN routesMonitor rm ON rm.routeFk = pb.routeFk
LEFT JOIN itemShelvingStock iss ON iss.itemFk = s.itemFk AND iss.sectorFk = p.sectorFk
LEFT JOIN saleGroupDetail sgd ON sgd.saleFk = s.id
LEFT JOIN ticketState ts ON ts.ticketFk = s.ticketFk
WHERE s.quantity >= i.packingOut
AND NOT pb.problem
AND s.quantity > 0
AND sgd.saleFk IS NULL
AND p.sectorFk = vSectorFk
AND ts.isPreviousPreparable
AND iss.visible >= s.quantity
AND ((rm.bufferFk AND rm.isPickingAllowed)
OR am.code = 'REC_ALG')
AND pb.shipped = vDated
GROUP BY s.id
ORDER BY etd;
SELECT * FROM tmp.sale;
DROP TEMPORARY TABLE tmp.productionBuffer; DROP TEMPORARY TABLE tmp.productionBuffer;
DROP TEMPORARY TABLE tmp.sale; DROP TEMPORARY TABLE tmp.sale;
END$$ END$$
DELIMITER ; DELIMITER ;
CALL `vn`.`sale_getBoxPickingList`(1, curdate());

View File

@ -8,25 +8,6 @@ BEGIN
* @param vSaleGroupFk Identificador de vn.saleGroup * @param vSaleGroupFk Identificador de vn.saleGroup
* @param vSectorCollectionFk Identificador de vn.sectorCollection * @param vSectorCollectionFk Identificador de vn.sectorCollection
*/ */
DECLARE vHasSaleGroup INT;
DECLARE vHasSectorCollection INT;
SELECT COUNT(id) INTO vHasSaleGroup
FROM saleGroup
WHERE id = vSaleGroupFk;
IF !vHasSaleGroup THEN
CALL util.throw ("invalid saleGroup");
END IF;
SELECT COUNT(id) INTO vHasSectorCollection
FROM sectorCollection
WHERE id = vSectorCollectionFk;
IF !vHasSectorCollection THEN
CALL util.throw ("invalid sectorCollection");
END IF;
REPLACE sectorCollectionSaleGroup REPLACE sectorCollectionSaleGroup
SET sectorCollectionFk = vSectorCollectionFk, SET sectorCollectionFk = vSectorCollectionFk,
saleGroupFk = vSaleGroupFk; saleGroupFk = vSaleGroupFk;

View File

@ -0,0 +1,13 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`sector_get`()
BEGIN
/**
* Obtiene los sectores
*/
SELECT s.id,s.description,s.warehouseFk
FROM vn.sector s;
END$$
DELIMITER ;

View File

@ -9,8 +9,6 @@ BEGIN
* @return tmp.ticketAmount (ticketFk, taxableBase, tax, code) * @return tmp.ticketAmount (ticketFk, taxableBase, tax, code)
* @return tmp.ticketTax (ticketFk, pgcFk, taxableBase, rate, code) Impuesto desglosado para cada ticket. * @return tmp.ticketTax (ticketFk, pgcFk, taxableBase, rate, code) Impuesto desglosado para cada ticket.
*/ */
-- Mantengo el drop porque si no da error en los tests de back de salix
-- Table 'addressCompany' was locked with a READ lock and can't be updated'
DROP TEMPORARY TABLE IF EXISTS tmp.addressCompany; DROP TEMPORARY TABLE IF EXISTS tmp.addressCompany;
CREATE TEMPORARY TABLE tmp.addressCompany CREATE TEMPORARY TABLE tmp.addressCompany
(INDEX (addressFk, companyFk)) (INDEX (addressFk, companyFk))
@ -26,11 +24,11 @@ BEGIN
SET areaFk = vTaxArea; SET areaFk = vTaxArea;
END IF; END IF;
-- Solo se calcula la base imponible (taxableBase) y /* Solo se calcula la base imponible (taxableBase) y el impuesto se calculará posteriormente
-- el impuesto se calculará posteriormente * No se debería cambiar el sistema por problemas con los decimales
-- No se debería cambiar el sistema por problemas con los decimales */
DROP TEMPORARY TABLE IF EXISTS tmp.ticketTax;
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketTax CREATE TEMPORARY TABLE tmp.ticketTax
(PRIMARY KEY (ticketFk, code, rate)) (PRIMARY KEY (ticketFk, code, rate))
ENGINE = MEMORY ENGINE = MEMORY
SELECT * FROM ( SELECT * FROM (
@ -45,21 +43,22 @@ BEGIN
JOIN item i ON i.id = s.itemFk JOIN item i ON i.id = s.itemFk
JOIN ticket t ON t.id = tmpTicket.ticketFk JOIN ticket t ON t.id = tmpTicket.ticketFk
JOIN supplier su ON su.id = t.companyFk JOIN supplier su ON su.id = t.companyFk
JOIN tmp.addressTaxArea ata ON ata.addressFk = t.addressFk JOIN tmp.addressTaxArea ata
AND ata.companyFk = t.companyFk ON ata.addressFk = t.addressFk AND ata.companyFk = t.companyFk
JOIN itemTaxCountry itc ON itc.itemFk = i.id JOIN itemTaxCountry itc
AND itc.countryFk = su.countryFk ON itc.itemFk = i.id AND itc.countryFk = su.countryFk
JOIN bookingPlanner bp ON bp.countryFk = su.countryFk JOIN bookingPlanner bp
ON bp.countryFk = su.countryFk
AND bp.taxAreaFk = ata.areaFk AND bp.taxAreaFk = ata.areaFk
AND bp.taxClassFk = itc.taxClassFk AND bp.taxClassFk = itc.taxClassFk
JOIN pgc ON pgc.code = bp.pgcFk JOIN pgc ON pgc.code = bp.pgcFk
JOIN taxClass tc ON tc.id = bp.taxClassFk JOIN taxClass tc ON tc.id = bp.taxClassFk
GROUP BY tmpTicket.ticketFk, pgc.code, pgc.rate GROUP BY tmpTicket.ticketFk, pgc.code, pgc.rate
HAVING taxableBase HAVING taxableBase <> 0) t3
) t3
ORDER BY priority; ORDER BY priority;
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketServiceTax DROP TEMPORARY TABLE IF EXISTS tmp.ticketServiceTax;
CREATE TEMPORARY TABLE tmp.ticketServiceTax
(PRIMARY KEY (ticketFk, code, rate)) (PRIMARY KEY (ticketFk, code, rate))
ENGINE = MEMORY ENGINE = MEMORY
SELECT tt.ticketFk, SELECT tt.ticketFk,
@ -71,22 +70,24 @@ BEGIN
JOIN ticketService ts ON ts.ticketFk = tt.ticketFk JOIN ticketService ts ON ts.ticketFk = tt.ticketFk
JOIN ticket t ON t.id = tt.ticketFk JOIN ticket t ON t.id = tt.ticketFk
JOIN supplier su ON su.id = t.companyFk JOIN supplier su ON su.id = t.companyFk
JOIN tmp.addressTaxArea ata ON ata.addressFk = t.addressFk JOIN tmp.addressTaxArea ata
AND ata.companyFk = t.companyFk ON ata.addressFk = t.addressFk AND ata.companyFk = t.companyFk
JOIN bookingPlanner bp ON bp.countryFk = su.countryFk JOIN bookingPlanner bp
ON bp.countryFk = su.countryFk
AND bp.taxAreaFk = ata.areaFk AND bp.taxAreaFk = ata.areaFk
AND bp.taxClassFk = ts.taxClassFk AND bp.taxClassFk = ts.taxClassFk
JOIN pgc ON pgc.code = bp.pgcFk JOIN pgc ON pgc.code = bp.pgcFk
JOIN taxClass tc ON tc.id = bp.taxClassFk JOIN taxClass tc ON tc.id = bp.taxClassFk
GROUP BY tt.ticketFk, pgc.code GROUP BY tt.ticketFk, pgc.code
HAVING taxableBase; HAVING taxableBase <> 0;
INSERT INTO tmp.ticketTax (ticketFk, pgcFk, taxableBase, rate, code) INSERT INTO tmp.ticketTax (ticketFk, pgcFk, taxableBase, rate, code)
SELECT ts.ticketFk, ts.pgcFk, ts.taxableBase, ts.rate, ts.code SELECT ts.ticketFk, ts.pgcFk, ts.taxableBase, ts.rate, ts.code
FROM tmp.ticketServiceTax ts FROM tmp.ticketServiceTax ts
ON DUPLICATE KEY UPDATE ticketTax.taxableBase = VALUES (taxableBase) + ticketTax.taxableBase ; ON DUPLICATE KEY UPDATE ticketTax.taxableBase = VALUES (taxableBase) + ticketTax.taxableBase ;
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketAmount DROP TEMPORARY TABLE IF EXISTS tmp.ticketAmount;
CREATE TEMPORARY TABLE tmp.ticketAmount
(INDEX (ticketFk)) (INDEX (ticketFk))
ENGINE = MEMORY ENGINE = MEMORY
SELECT ticketFk, SELECT ticketFk,
@ -96,8 +97,7 @@ BEGIN
FROM tmp.ticketTax FROM tmp.ticketTax
GROUP BY ticketFk, code; GROUP BY ticketFk, code;
DROP TEMPORARY TABLE DROP TEMPORARY TABLE tmp.addressCompany;
tmp.addressCompany, DROP TEMPORARY TABLE tmp.addressTaxArea;
tmp.addressTaxArea;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -4,6 +4,7 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`ticket_beforeUpdate`
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
DECLARE vNewTime TIME; DECLARE vNewTime TIME;
DECLARE vHasTicketRefund BOOL;
SET NEW.editorFk = account.myUser_getId(); SET NEW.editorFk = account.myUser_getId();
@ -63,5 +64,14 @@ BEGIN
CALL vn.routeUpdateM3(NEW.routeFk); CALL vn.routeUpdateM3(NEW.routeFk);
END IF; END IF;
SELECT COUNT(*) INTO vHasTicketRefund
FROM ticketRefund
WHERE originalTicketFk = NEW.id
OR refundTicketFk = NEW.id;
IF vHasTicketRefund AND NEW.clientFk <> OLD.clientFk THEN
CALL util.throw('The ticket has a refund associated');
END IF;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -1,3 +0,0 @@
USE vn;
ALTER TABLE vn.agencyTermConfig
ADD CONSTRAINT agencyTermConfig_expense_FK FOREIGN KEY (expenseFk) REFERENCES vn.expense(id) ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -1,11 +0,0 @@
USE vn;
ALTER TABLE vn2008.gastos_resumen MODIFY COLUMN Id_Gasto varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL;
DELETE gr.*
FROM vn2008.gastos_resumen gr LEFT JOIN vn.expense e ON gr.Id_Gasto = e.id
WHERE e.id IS NULL;
ALTER TABLE vn2008.gastos_resumen
ADD CONSTRAINT gastos_resumen_expense_FK
FOREIGN KEY (Id_Gasto) REFERENCES vn.expense(id) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -1,5 +0,0 @@
USE vn;
ALTER TABLE vn.invoiceOutTaxConfig MODIFY COLUMN expenseFk varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL NULL;
ALTER TABLE vn.invoiceOutTaxConfig
ADD CONSTRAINT invoiceOutTaxConfig_expense_FK FOREIGN KEY (expenseFk) REFERENCES vn.expense(id) ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -1,5 +0,0 @@
USE edi;
ALTER TABLE edi.item_groupToOffer MODIFY COLUMN expenseFk varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT '7001000000' NULL;
ALTER TABLE edi.item_groupToOffer
ADD CONSTRAINT item_groupToOffer_expense_FK FOREIGN KEY (expenseFk) REFERENCES vn.expense(id) ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -1,14 +0,0 @@
USE vn;
-- Eliminar la clave primaria actual
ALTER TABLE bs.ventas_contables DROP PRIMARY KEY;
-- Agregar la nueva clave primaria incluyendo el campo `gasto`
ALTER TABLE bs.ventas_contables ADD PRIMARY KEY (`year`, `month`, `grupo`, `reino_id`, `tipo_id`, `empresa_id`, `gasto`);
DELETE vc.* FROM bs.ventas_contables vc LEFT JOIN vn.expense e ON e.id = vc.gasto WHERE e.id IS NULL;
ALTER TABLE bs.ventas_contables
MODIFY COLUMN gasto VARCHAR(10)
CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL;
ALTER TABLE bs.ventas_contables ADD CONSTRAINT ventas_contables_expense_FK FOREIGN KEY (gasto) REFERENCES vn.expense(id) ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -1,8 +0,0 @@
DELETE FROM vn.expense
WHERE id ='' AND id IS NULL AND isWithheld = FALSE;
UPDATE vn.expense
SET id='7002090000'
WHERE id='7002009000';
UPDATE vn.expense
SET id='7001090000'
WHERE id='7001009000';

View File

@ -1,44 +0,0 @@
UPDATE vn.expense
SET id = CASE id
WHEN 7000010000 THEN 7001001000
WHEN 7000020000 THEN 7001002000
WHEN 7000030000 THEN 7001003000
WHEN 7000040000 THEN 7001004000
WHEN 7000050000 THEN 7001005000
WHEN 7000060000 THEN 7001006000
WHEN 7000070000 THEN 7001007000
WHEN 7002060000 THEN 7001206000
WHEN 7002070000 THEN 7001207000
WHEN 7002030000 THEN 7001203000
WHEN 7002040000 THEN 7001204000
WHEN 7002050000 THEN 7001205000
WHEN 7002020000 THEN 7001202000
WHEN 7002010000 THEN 7001201000
WHEN 7001060000 THEN 7001106000
WHEN 7001070000 THEN 7001107000
WHEN 7001030000 THEN 7001103000
WHEN 7001040000 THEN 7001104000
WHEN 7001050000 THEN 7001105000
WHEN 7001020000 THEN 7001102000
WHEN 7001010000 THEN 7001101000
WHEN 7000080000 THEN 7040008000
WHEN 7001080000 THEN 7000108000
WHEN 7002080000 THEN 7001208000
WHEN 7000090000 THEN 7001009000
WHEN 7002090000 THEN 7001209000
WHEN 7002100000 THEN 7001210000
WHEN 7001090000 THEN 7001109000
WHEN 7001100000 THEN 7001110000
WHEN 7000120000 THEN 7001012000
WHEN 7002120000 THEN 7001212000
WHEN 7000130000 THEN 7001013000
WHEN 7000140000 THEN 7001014000
ELSE id
END
WHERE id IN (7000010000, 7000020000, 7000030000, 7000040000, 7000050000,
7000060000, 7000070000, 7002060000, 7002070000, 7002030000,
7002040000, 7002050000, 7002020000, 7002010000, 7001060000,
7001070000, 7001030000, 7001040000, 7001050000, 7001020000,
7001010000, 7000080000, 7001080000, 7002080000, 7000090000,
7002090000, 7002100000, 7001090000, 7001100000,
7000120000, 7002120000, 7000130000, 7000140000);

View File

@ -1,6 +0,0 @@
UPDATE vn.expense
SET id = CASE id
WHEN 7000100000 THEN 7001010000
ELSE id
END
WHERE id IN (7000100000);

View File

@ -1,37 +0,0 @@
REVOKE UPDATE ON vn.ticket FROM employee;
GRANT UPDATE (id,
warehouseFk,
shipped,
nickname,
refFk,
addressFk,
workerFk,
observations,
isSigned,
isLabeled,
isPrinted,
packages,
location,
hour,
created,
isBlocked,
solution,
routeFk,
priority,
hasPriority,
companyFk,
agencyModeFk,
landed,
isBoxed,
isDeleted,
zoneFk,
zonePrice,
zoneBonus,
totalWithVat,
totalWithoutVat,
weight,
clonedFrom,
cmrFk,
editorFk)
ON vn.ticket TO employee;

View File

@ -46,19 +46,23 @@ module.exports = Self => {
const stmts = []; const stmts = [];
let stmt; let stmt;
stmts.push(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket`);
stmts.push(new ParameterizedSQL( stmts.push(new ParameterizedSQL(
`CREATE OR REPLACE TEMPORARY TABLE tmp.ticket `CREATE TEMPORARY TABLE tmp.ticket
(KEY (ticketFk)) (KEY (ticketFk))
ENGINE = MEMORY ENGINE = MEMORY
SELECT id ticketFk SELECT id ticketFk
FROM ticket t FROM ticket t
WHERE shipped BETWEEN ? AND util.dayEnd(?) WHERE shipped BETWEEN ? AND ?
AND refFk IS NULL`, [args.from, args.to])); AND refFk IS NULL`, [args.from, args.to]));
stmts.push(`CALL vn.ticket_getTax(NULL)`); stmts.push(`CALL vn.ticket_getTax(NULL)`);
stmts.push(`DROP TEMPORARY TABLE IF EXISTS tmp.filter`);
stmts.push(new ParameterizedSQL( stmts.push(new ParameterizedSQL(
`CREATE OR REPLACE TEMPORARY TABLE tmp.filter `CREATE TEMPORARY TABLE tmp.filter
ENGINE = MEMORY ENGINE = MEMORY
SELECT co.code company, SELECT
co.code company,
cou.country, cou.country,
c.id clientId, c.id clientId,
c.socialName clientSocialName, c.socialName clientSocialName,
@ -84,13 +88,15 @@ module.exports = Self => {
GROUP BY ticketFk GROUP BY ticketFk
HAVING taxableBase < 0 HAVING taxableBase < 0
) negativeBase ON negativeBase.ticketFk = t.id ) negativeBase ON negativeBase.ticketFk = t.id
WHERE t.shipped BETWEEN ? AND util.dayEnd(?) WHERE t.shipped BETWEEN ? AND ?
AND t.refFk IS NULL AND t.refFk IS NULL
AND c.typeFk IN ('normal','trust') AND c.typeFk IN ('normal','trust')
GROUP BY t.clientFk, negativeBase.taxableBase GROUP BY t.clientFk, negativeBase.taxableBase
HAVING amount < 0`, [args.from, args.to])); HAVING amount < 0`, [args.from, args.to]));
stmt = new ParameterizedSQL(`SELECT * FROM tmp.filter`); stmt = new ParameterizedSQL(`
SELECT f.*
FROM tmp.filter f`);
if (args.filter) { if (args.filter) {
stmt.merge(conn.makeWhere(args.filter.where)); stmt.merge(conn.makeWhere(args.filter.where));

View File

@ -1,55 +0,0 @@
const {models} = require('vn-loopback/server/server');
const LoopBackContext = require('loopback-context');
describe('ItemShelving upsertItem()', () => {
const warehouseFk = 1;
let ctx;
let options;
let tx;
beforeEach(async() => {
ctx = {
req: {
accessToken: {userId: 9},
headers: {origin: 'http://localhost'}
},
args: {}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: ctx.req
});
options = {transaction: tx};
tx = await models.ItemShelving.beginTransaction({});
options.transaction = tx;
});
afterEach(async() => {
await tx.rollback();
});
it('should add two new records', async() => {
const shelvingFk = 'ZPP';
const items = [1, 1, 1, 2];
await models.ItemShelving.upsertItem(ctx, shelvingFk, items, warehouseFk, options);
const itemShelvings = await models.ItemShelving.find({where: {shelvingFk}}, options);
expect(itemShelvings.length).toEqual(2);
});
it('should update the visible items', async() => {
const shelvingFk = 'GVC';
const items = [2, 2];
const {visible: itemsBefore} = await models.ItemShelving.findOne({
where: {shelvingFk, itemFk: items[0]}
}, options);
await models.ItemShelving.upsertItem(ctx, shelvingFk, items, warehouseFk, options);
const {visible: itemsAfter} = await models.ItemShelving.findOne({
where: {shelvingFk, itemFk: items[0]}
}, options);
expect(itemsAfter).toEqual(itemsBefore + 2);
});
});

View File

@ -1,64 +0,0 @@
module.exports = Self => {
Self.remoteMethodCtx('upsertItem', {
description: 'Add a record or update it if it already exists.',
accessType: 'WRITE',
accepts: [{
arg: 'shelvingFk',
type: 'string',
required: true,
},
{
arg: 'items',
type: ['number'],
required: true,
description: 'array of item foreign keys'
},
{
arg: 'warehouseFk',
type: 'number',
required: true
}],
http: {
path: `/upsertItem`,
verb: 'POST'
}
});
Self.upsertItem = async(ctx, shelvingFk, items, warehouseFk, options) => {
const myOptions = {userId: ctx.req.accessToken.userId};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
const discardItems = new Set();
const itemCounts = items.reduce((acc, item) => {
acc[item] = (acc[item] || 0) + 1;
return acc;
}, {});
try {
for (let item of items) {
if (!discardItems.has(item)) {
let quantity = itemCounts[item];
discardItems.add(item);
await Self.rawSql('CALL vn.itemShelving_add(?, ?, ?, NULL, NULL, NULL, ?)',
[shelvingFk, item, quantity, warehouseFk], myOptions
);
}
}
if (tx) await tx.commit();
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -1,5 +1,4 @@
module.exports = Self => { module.exports = Self => {
require('../methods/item-shelving/deleteItemShelvings')(Self); require('../methods/item-shelving/deleteItemShelvings')(Self);
require('../methods/item-shelving/upsertItem')(Self);
require('../methods/item-shelving/getInventory')(Self); require('../methods/item-shelving/getInventory')(Self);
}; };

View File

@ -1,60 +1,49 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
describe('Ticket transferClient()', () => { describe('Ticket transferClient()', () => {
const originalTicketId = 8; const userId = 9;
const refundTicketId = 24; const activeCtx = {
const clientId = 1; accessToken: {userId: userId},
let ctx;
let options;
let tx;
beforeEach(async() => {
ctx = {
req: {
accessToken: {userId: 9},
headers: {origin: 'http://localhost'}
},
args: {}
}; };
const ctx = {req: activeCtx};
options = {transaction: tx};
tx = await models.Ticket.beginTransaction({});
options.transaction = tx;
});
afterEach(async() => {
await tx.rollback();
});
it('should throw an error as the ticket is not editable', async() => { it('should throw an error as the ticket is not editable', async() => {
const tx = await models.Ticket.beginTransaction({});
let error;
try { try {
const options = {transaction: tx};
const ticketId = 4; const ticketId = 4;
const clientId = 1; const clientId = 1;
await models.Ticket.transferClient(ctx, ticketId, clientId, options); await models.Ticket.transferClient(ctx, ticketId, clientId, options);
await tx.rollback();
} catch (e) { } catch (e) {
expect(e.message).toEqual(`This ticket is locked`); await tx.rollback();
error = e;
} }
expect(error.message).toEqual(`This ticket is locked`);
}); });
it('should be assigned a different clientFk in the original ticket', async() => { it('should be assigned a different clientFk', async() => {
await models.Ticket.transferClient(ctx, 2, clientId, options); const tx = await models.Ticket.beginTransaction({});
const afterTransfer = await models.Ticket.findById(2, null, options); let updatedTicket;
const ticketId = 10;
const clientId = 1;
expect(afterTransfer.clientFk).toEqual(clientId); try {
}); const options = {transaction: tx};
it('should be assigned a different clientFk in the original and refund ticket and claim', async() => { await models.Ticket.transferClient(ctx, ticketId, clientId, options);
await models.Ticket.transferClient(ctx, originalTicketId, clientId, options); updatedTicket = await models.Ticket.findById(ticketId, {fields: ['clientFk']}, options);
const [originalTicket, refundTicket] = await models.Ticket.find({ await tx.rollback();
where: {id: {inq: [originalTicketId, refundTicketId]}} } catch (e) {
}, options); await tx.rollback();
throw e;
}
const claim = await models.Claim.findOne({ expect(updatedTicket.clientFk).toEqual(clientId);
where: {ticketFk: originalTicketId}
}, options);
expect(originalTicket.clientFk).toEqual(clientId);
expect(refundTicket.clientFk).toEqual(clientId);
expect(claim.clientFk).toEqual(clientId);
}); });
}); });

View File

@ -2,17 +2,20 @@ module.exports = Self => {
Self.remoteMethodCtx('transferClient', { Self.remoteMethodCtx('transferClient', {
description: 'Transfering ticket to another client', description: 'Transfering ticket to another client',
accessType: 'WRITE', accessType: 'WRITE',
accepts: [{ accepts: [
{
arg: 'id', arg: 'id',
type: 'number', type: 'number',
required: true, required: true,
description: 'the ticket id', description: 'the ticket id',
http: {source: 'path'} http: {source: 'path'}
}, { },
{
arg: 'clientFk', arg: 'clientFk',
type: 'number', type: 'number',
required: true, required: true,
}], },
],
http: { http: {
path: `/:id/transferClient`, path: `/:id/transferClient`,
verb: 'PATCH' verb: 'PATCH'
@ -22,51 +25,21 @@ module.exports = Self => {
Self.transferClient = async(ctx, id, clientFk, options) => { Self.transferClient = async(ctx, id, clientFk, options) => {
const models = Self.app.models; const models = Self.app.models;
const myOptions = {}; const myOptions = {};
let tx;
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
await Self.isEditableOrThrow(ctx, id, myOptions); await Self.isEditableOrThrow(ctx, id, myOptions);
const ticketRefund = await models.TicketRefund.findOne({ const ticket = await models.Ticket.findById(
where: {or: [{originalTicketFk: id}, {refundTicketFk: id}]}, id,
include: [{relation: 'refundTicket'}, {relation: 'originalTicket'}] {fields: ['id', 'shipped', 'clientFk', 'addressFk']},
}, myOptions); myOptions
);
const client = await models.Client.findById(clientFk, {fields: ['id', 'defaultAddressFk']}, myOptions);
const {defaultAddressFk: addressFk} = await models.Client.findById(clientFk, await ticket.updateAttributes({
{fields: ['id', 'defaultAddressFk']}, myOptions); clientFk,
addressFk: client.defaultAddressFk,
const attributes = {clientFk, addressFk}; });
const tickets = [];
const ticketIds = [];
if (ticketRefund) {
const {refundTicket, originalTicket} = ticketRefund;
tickets.push(refundTicket(), originalTicket());
for (const ticket of tickets) {
await ticket.updateAttributes(attributes, myOptions);
ticketIds.push(ticket.id);
}
} else {
await Self.updateAll({id}, attributes, myOptions);
ticketIds.push(id);
}
await models.Claim.updateAll({ticketFk: {inq: ticketIds}}, {clientFk}, myOptions);
if (tx) await tx.commit();
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
}; };
}; };

View File

@ -36,7 +36,6 @@ describe('Worker new', () => {
payMethodFk: 1, payMethodFk: 1,
roleFk: 1 roleFk: 1
}; };
const req = {accessToken: {userId: 9}}; const req = {accessToken: {userId: 9}};
it('should return error if personal mail already exists', async() => { it('should return error if personal mail already exists', async() => {
@ -141,24 +140,15 @@ describe('Worker new', () => {
it('should create a new worker', async() => { it('should create a new worker', async() => {
const newWorker = await models.Worker.new({args: defaultWorker, req}); const newWorker = await models.Worker.new({args: defaultWorker, req});
await removeWorker(newWorker.id); await models.Worker.destroyById(newWorker.id);
await models.Address.destroyAll({clientFk: newWorker.id});
await models.Mandate.destroyAll({clientFk: newWorker.id});
await models.Client.destroyById(newWorker.id);
await models.VnUser.destroyById(newWorker.id);
expect(newWorker.id).toBeDefined(); expect(newWorker.id).toBeDefined();
}); });
it('should create a new client', async() => {
let newWorker;
let client;
try {
newWorker = await models.Worker.new({args: defaultWorker, req});
client = await models.Client.findById(newWorker.id);
} finally {
await removeWorker(newWorker.id);
}
expect(client).toBeDefined();
});
it('should create a new worker in client', async() => { it('should create a new worker in client', async() => {
const bruceWayneId = 1101; const bruceWayneId = 1101;
const client = await models.Client.findById(bruceWayneId, {fields: ['fi', 'email']}); const client = await models.Client.findById(bruceWayneId, {fields: ['fi', 'email']});
@ -180,11 +170,3 @@ describe('Worker new', () => {
expect(newWorker.id).toEqual(bruceWayneId); expect(newWorker.id).toEqual(bruceWayneId);
}); });
}); });
async function removeWorker(id) {
await models.Worker.destroyById(id);
await models.Address.destroyAll({clientFk: id});
await models.Mandate.destroyAll({clientFk: id});
await models.Client.destroyById(id);
await models.VnUser.destroyById(id);
}

View File

@ -44,6 +44,7 @@ fixtures:
- module - module
- defaultViewConfig - defaultViewConfig
vn: vn:
- agencyTermConfig
- alertLevel - alertLevel
- bookingPlanner - bookingPlanner
- businessType - businessType

View File

@ -1,6 +1,6 @@
{ {
"name": "salix-back", "name": "salix-back",
"version": "24.10.0", "version": "24.8.0",
"author": "Verdnatura Levante SL", "author": "Verdnatura Levante SL",
"description": "Salix backend", "description": "Salix backend",
"license": "GPL-3.0", "license": "GPL-3.0",