#6321 - Negative tickets #1945

Merged
jsegarra merged 146 commits from 6321_negative_tickets into dev 2025-02-11 08:45:33 +00:00
10 changed files with 179 additions and 238 deletions
Showing only changes of commit 550b0871f0 - Show all commits

View File

@ -4073,17 +4073,17 @@ UPDATE vn.worker
-- Negativos -- Negativos
INSERT INTO `vn`.`item` (id,name,`size`,stems,minPrice,isToPrint,family,box,originFk,doPhoto,image,inkFk,intrastatFk,hasMinPrice,created,typeFk,generic,density,relevancy,expenseFk,isActive,longName,subName,tag5,value5,tag6,value6,tag7,value7,minimum,upToDown,hasKgPrice,isFloramondo,isFragile,stemMultiplier,isLaid,lastUsed,editorFk,isBoxPickingMode) INSERT INTO `vn`.`item` (id, name, `size`, stems, minPrice, isToPrint, family, box, originFk, doPhoto, image, inkFk, intrastatFk, hasMinPrice, created, typeFk, generic, density, relevancy, expenseFk, isActive, longName, subName, tag5, value5, tag6, value6, tag7, value7, minimum, upToDown, hasKgPrice, isFloramondo, isFragile, stemMultiplier, isLaid, lastUsed, editorFk, isBoxPickingMode)
VALUES VALUES
(88,'Lack negative',200,1,10.0,0,'VT',0,2,0,'','WHT',6021010,1,'2024-07-19 11:27:32.000',1,0,167,0,'4751000000',1,'Lack negative origin','Stark Industries','Color','White','Categoria','supply','Tallos','1',3,0,0,0,0,1.0,0,'2024-07-19 11:27:32.000',100,0); (88, 'Lack negative', 200, 1, 10.0, 0, 'VT', 0, 2, 0, '', 'WHT', 6021010, 1, util.VN_CURDATE(), 1, 0, 167, 0, '4751000000', 1, 'Lack negative origin', 'Stark Industries', 'Color', 'White', 'Categoria', 'supply', 'Tallos', '1', 3, 0, 0, 0, 0, 1.0, 0, util.VN_CURDATE(), 100, 0);
jsegarra marked this conversation as resolved Outdated

deja un espacio despues de cada coma igual que el resto del archivo
No puedes hacer el insert de este item junto con los otros?

Año 2024 no

deja un espacio despues de cada coma igual que el resto del archivo No puedes hacer el insert de este item junto con los otros? Año 2024 no

Con esto lo he cambiado rapdiamente ,(?!\s)

Con esto lo he cambiado rapdiamente `,(?!\s) `
INSERT INTO `vn`.`ticket` (id, clientFk,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,problem,risk) INSERT INTO `vn`.`ticket` (id, clientFk, 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, problem, risk)
VALUES VALUES
(1000000, 1,1,'2001-01-01 00:00:00.000','employee',NULL,131,NULL,NULL,0,0,0,0,NULL,0,'2024-07-19 23:32:48.000',1,NULL,NULL,NULL,1,442,1,'2001-01-01',0,0,1,1.00,0.00,0.00,NULL,NULL,NULL,NULL,9,'',NULL); (1000000, 1, 1, util.VN_CURDATE(), 'employee', NULL, 131, NULL, NULL, 0, 0, 0, 0, NULL, 0, CURDATE(), 1, NULL, NULL, NULL, 1, 442, 1, util.VN_CURDATE(), 0, 0, 1, 1.00, 0.00, 0.00, NULL, NULL, NULL, NULL, 9, '', NULL);
INSERT INTO `vn`.`sale` (id, itemFk,ticketFk,concept,quantity,originalQuantity,price,discount,priceFixed,reserved,isPicked,isPriceFixed,created,isAdded,total,editorFk,problem) INSERT INTO `vn`.`sale` (id, itemFk, ticketFk, concept, quantity, originalQuantity, price, discount, priceFixed, reserved, isPicked, isPriceFixed, created, isAdded, total, editorFk, problem)
VALUES VALUES
(43, 88,1000000,'Chest medical box 2',15.00,155.0,10.00,0,0.00,0,0,0,'2024-07-19 23:33:08.000',0,1550.00,100,''); (43, 88, 1000000, 'Chest medical box 2', 15.00, 155.0, 10.00, 0, 0.00, 0, 0, 0, CURDATE(), 0, 1550.00, 100, '');
-- Negativos -- Negativos
-- Item proposal -- Item proposal

View File

@ -1,8 +1,8 @@
DELIMITER $$ DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getLack`( CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getLack`(
vSelf INT,
vForce BOOLEAN, vForce BOOLEAN,
vDays INT, vDays INT,
jsegarra marked this conversation as resolved
Review

si esto es el id del artículo, lo ponemos en primer lugar y se llama vSelf

si esto es el id del artículo, lo ponemos en primer lugar y se llama vSelf
vId INT,
vLongname VARCHAR(255), vLongname VARCHAR(255),
vSupplierFk VARCHAR(255), vSupplierFk VARCHAR(255),
jgallego marked this conversation as resolved Outdated

si es varchar no es un Fk, mirando el codigo deduzco que producerName

si es varchar no es un Fk, mirando el codigo deduzco que producerName

cambiado

cambiado
vColor VARCHAR(255), vColor VARCHAR(255),
@ -58,7 +58,7 @@ BEGIN
WHERE w.isForTicket WHERE w.isForTicket
AND ic.display AND ic.display
AND it.code != 'GEN' AND it.code != 'GEN'
AND (vId IS NULL OR i.id = vId) AND (vSelf IS NULL OR i.id = vSelf)
AND (vLongname IS NULL OR i.name = vLongname) AND (vLongname IS NULL OR i.name = vLongname)
AND (vSupplierFk IS NULL OR p.`name` LIKE CONCAT('%', vSupplierFk, '%')) AND (vSupplierFk IS NULL OR p.`name` LIKE CONCAT('%', vSupplierFk, '%'))
Review

estas seguro que quieren esto? si hay un productor que se llama flor, saldran tambien todos los floral, floristeria... yo creo que conviene dejar el =

estas seguro que quieren esto? si hay un productor que se llama flor, saldran tambien todos los floral, floristeria... yo creo que conviene dejar el =
AND (vColor IS NULL OR vColor = i.inkFk) AND (vColor IS NULL OR vColor = i.inkFk)

View File

@ -25,9 +25,11 @@ BEGIN
DECLARE vNewSaleFk INT; DECLARE vNewSaleFk INT;
DECLARE vFinalPrice DECIMAL(10,2); DECLARE vFinalPrice DECIMAL(10,2);
DECLARE vIsRequiredTx BOOL DEFAULT NOT @@in_transaction;
DECLARE EXIT HANDLER FOR SQLEXCEPTION DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN BEGIN
ROLLBACK; CALL util.tx_rollback(vIsRequiredTx);
RESIGNAL; RESIGNAL;
END; END;
@ -62,7 +64,7 @@ BEGIN
WHERE tmp.itemFk = vNewItemFk AND tmp.WarehouseFk = vWarehouseFk; WHERE tmp.itemFk = vNewItemFk AND tmp.WarehouseFk = vWarehouseFk;
DROP TEMPORARY TABLE tmp.buyUltimate; DROP TEMPORARY TABLE tmp.buyUltimate;
IF vGroupingMode = 'packing' AND vPacking > 0 THEN IF vGroupingMode = 'packing' AND vPacking > 0 THEN
SET vRoundQuantity = vPacking; SET vRoundQuantity = vPacking;
END IF; END IF;
@ -129,6 +131,6 @@ BEGIN
VALUES(vItemFk, vNewItemFk, 1) VALUES(vItemFk, vNewItemFk, 1)
ON DUPLICATE KEY UPDATE counter = counter + 1; ON DUPLICATE KEY UPDATE counter = counter + 1;
COMMIT; CALL util.tx_commit(vIsRequiredTx);
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -73,10 +73,12 @@ module.exports = Self => {
query: [sale.ticketFk] query: [sale.ticketFk]
}; };
const salesPerson = await Self.rawSql(salesPersonQuery.sql, salesPersonQuery.query, myOptions); const salesPerson = await Self.rawSql(salesPersonQuery.sql, salesPersonQuery.query, myOptions);
if (tx) await tx.commit();
const url = await models.Url.getUrl(); const url = await models.Url.getUrl();
const substitution = await models.Item.findById(substitutionFk, { const substitution = await models.Item.findById(substitutionFk, {
fields: ['id', 'name', 'longName'] fields: ['id', 'name', 'longName']
}, myOptions); }, myOptions);
const message = $t('negativeReplaced', { const message = $t('negativeReplaced', {
oldItemId: sale.itemFk, oldItemId: sale.itemFk,
oldItem: sale.item().longName, oldItem: sale.item().longName,

View File

@ -0,0 +1,61 @@
const {models} = require('vn-loopback/server/server');
describe('Sale - replaceItem function', () => {
let options;
let tx;
const ctx = beforeAll.getCtx();
beforeAll.mockLoopBackContext();
beforeEach(async() => {
tx = await models.Sale.beginTransaction({});
options = {transaction: tx};
});
afterEach(async() => {
if (tx)
await tx.rollback();
});
it('should replace full item in sale and send notification', async() => {
const saleFk = 43;
const substitutionFk = 3;
const quantity = 15;
const ticketFk = 1000000;
const salesBefore = await models.Sale.find({where: {ticketFk}}, options);
const salesLength = salesBefore.length;
expect(1).toEqual(salesBefore.length);
await models.Sale.replaceItem(ctx, saleFk, substitutionFk, quantity, options);
const salesAfter = await models.Sale.find({where: {ticketFk}}, options);
expect(salesLength).toBeLessThan(salesAfter.length);
expect(salesAfter[0].id).toEqual(saleFk);
expect(salesAfter[salesLength].itemFk).toEqual(substitutionFk);
expect(salesAfter[salesLength].quantity).toEqual(quantity);
expect(salesAfter[0].quantity).toEqual(0);
expect(salesAfter[salesLength].concept).toMatch(/^\+/);
});
it('should replace half item in sale and send notification', async() => {
const saleFk = 43;
const substitutionFk = 3;
const quantity = 10;
const ticketFk = 1000000;
const salesBefore = await models.Sale.find({where: {ticketFk}}, options);
const salesLength = salesBefore.length;
expect(1).toEqual(salesBefore.length);
await models.Sale.replaceItem(ctx, saleFk, substitutionFk, quantity, options);
const salesAfter = await models.Sale.find({where: {ticketFk}}, options);
expect(salesLength).toBeLessThan(salesAfter.length);
expect(salesAfter[0].id).toEqual(saleFk);
expect(salesAfter[salesLength].itemFk).toEqual(substitutionFk);
expect(salesAfter[salesLength].quantity).toEqual(quantity);
expect(salesAfter[0].quantity).toEqual(5);
expect(salesAfter[salesLength].concept).toMatch(/^\+/);
});
});

View File

@ -15,7 +15,7 @@ module.exports = Self => {
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'itemFk', arg: 'id',
type: 'number', type: 'number',
description: 'The item id', description: 'The item id',
}, },
@ -80,7 +80,7 @@ module.exports = Self => {
Object.assign(myOptions, options); Object.assign(myOptions, options);
const filterKeyOrder = [ const filterKeyOrder = [
'days', 'itemFk', 'longname', 'supplier', 'id', 'force', 'days', 'longname', 'supplier',
'colour', 'size', 'originFk', 'colour', 'size', 'originFk',
'lack', 'warehouseFk' 'lack', 'warehouseFk'
]; ];
@ -88,13 +88,17 @@ module.exports = Self => {
delete ctx?.args?.ctx; delete ctx?.args?.ctx;
delete ctx?.args?.filter; delete ctx?.args?.filter;
if (filter)
ctx.args = Object.assign(ctx.args ?? {}, filter);
let procedureParams = [true]; Object.assign(filter, ctx.args ?? {});
procedureParams.push(...filterKeyOrder.map(clave => ctx.args[clave] ?? null));
if (!procedureParams[1])procedureParams[1] = 2; let procedureParams = [];
procedureParams.push(...filterKeyOrder.map(clave => filter[clave] ?? null));
jsegarra marked this conversation as resolved Outdated

si se va a migrar el proc tal cual confirmar con Juan pero yo no lo moveria que se llame a item_getLack de la BBDD directamente

si se va a migrar el proc tal cual confirmar con Juan pero yo no lo moveria que se llame a item_getLack de la BBDD directamente

Lo anoto para hablar con el

Lo anoto para hablar con el

La idea de hacer este movimiento, es poder aplicar filtros a la consulta. Esto justo se esta haciendo en "Monitor de ventas". Hay mucho código SQL definido en el método para poder aplicar los filtros que vienen por parámetros

La idea de hacer este movimiento, es poder aplicar filtros a la consulta. Esto justo se esta haciendo en "Monitor de ventas". Hay mucho código SQL definido en el método para poder aplicar los filtros que vienen por parámetros

Tras hablar con Juan, consideramos mejor enfoque modificar el procedimiento añadiendo tantos argumentos como filtros tengamos

Tras hablar con Juan, consideramos mejor enfoque modificar el procedimiento añadiendo tantos argumentos como filtros tengamos
// Default values
const forceIndex = filterKeyOrder.indexOf('force');
if (!procedureParams[forceIndex])procedureParams[forceIndex] = true;
const daysIndex = filterKeyOrder.indexOf('days');
if (!procedureParams[daysIndex])procedureParams[daysIndex] = 2;
const procedureArgs = Array(procedureParams.length).fill('?').join(', '); const procedureArgs = Array(procedureParams.length).fill('?').join(', ');
let query = `CALL vn.item_getLack(${procedureArgs})`; let query = `CALL vn.item_getLack(${procedureArgs})`;

View File

@ -8,7 +8,7 @@ module.exports = Self => {
{ {
arg: 'itemFk', arg: 'itemFk',
jsegarra marked this conversation as resolved Outdated

si estamos en la seccion ticket, yo el argumento lo llamaria itemFk, porque a mitad codigo, id puede dar confusion a que es el id de la entidad, en este caso ticket

si estamos en la seccion ticket, yo el argumento lo llamaria itemFk, porque a mitad codigo, id puede dar confusion a que es el id de la entidad, en este caso ticket
type: 'number', type: 'number',
description: 'The item id', description: 'The item as negative status',
}, },
{ {
arg: 'filter', arg: 'filter',
@ -43,6 +43,7 @@ module.exports = Self => {
st.code, st.code,
t.id, t.id,
t.nickname, t.nickname,
c.id customerId,
t.shipped, t.shipped,
s.quantity, s.quantity,
ag.name, ag.name,
@ -52,7 +53,7 @@ module.exports = Self => {
s.id saleFk, s.id saleFk,
s.itemFk, s.itemFk,
s.price price, s.price price,
jsegarra marked this conversation as resolved Outdated

es una chorrada pero comovas a cambiar cosas, no solemos poner los AS en los select

es una chorrada pero comovas a cambiar cosas, no solemos poner los AS en los select
al.code AS alertLevelCode, al.code alertLevelCode,
jsegarra marked this conversation as resolved Outdated

tls.alertLevel

tls.alertLevel
z.name zoneName, z.name zoneName,
z.id zoneFk, z.id zoneFk,
Format(z.hour, "hh:mm") theoreticalhour, Format(z.hour, "hh:mm") theoreticalhour,
@ -60,7 +61,7 @@ module.exports = Self => {
IF(ISNULL(sc.saleClonedFk),0,1) turno, IF(ISNULL(sc.saleClonedFk),0,1) turno,
jgallego marked this conversation as resolved Outdated

aqui puedes devolver el codigo y en front gestionas como necesites, sino estas haciendo 2 funciones por cada linea..lo cual tiene un coste en velocidad al select

aqui puedes devolver el codigo y en front gestionas como necesites, sino estas haciendo 2 funciones por cada linea..lo cual tiene un coste en velocidad al select

cual select? al de zona? El siguiente es de hora y a continuación son booleanos

cual select? al de zona? El siguiente es de hora y a continuación son booleanos

cambiado

cambiado
IF(ISNULL(tr.saleFk),0,1) peticionCompra, IF(ISNULL(tr.saleFk),0,1) peticionCompra,
DATE_FORMAT(IF(HOUR(t.shipped), t.shipped, IF(zc.hour, zc.hour, z.hour)),'%H:%i') minTimed, DATE_FORMAT(IF(HOUR(t.shipped), t.shipped, IF(zc.hour, zc.hour, z.hour)),'%H:%i') minTimed,
FALSE AS isBasket, FALSE isBasket,
substitution.hasSubstitution, substitution.hasSubstitution,
IF(d.code = 'spainTeamVip', 1, 0) hasToIgnore IF(d.code = 'spainTeamVip', 1, 0) hasToIgnore
jgallego marked this conversation as resolved Outdated

esto lo confirmamos con ellos, yo intentaria llevarlo a front sin este campo hasToIgnore y que se lo filtren, de lo contrario..mañana cuando cambien codigos esto habra que cambiarlo

esto lo confirmamos con ellos, yo intentaria llevarlo a front sin este campo hasToIgnore y que se lo filtren, de lo contrario..mañana cuando cambien codigos esto habra que cambiarlo

La consulta que estas viendo está copiada y traducida desde access
Solo la he migrado.
Este campo sirve para ordenar los resultados

La consulta que estas viendo está copiada y traducida desde access Solo la he migrado. Este campo sirve para ordenar los resultados

cambiado

cambiado
FROM sale s FROM sale s
@ -80,24 +81,24 @@ module.exports = Self => {
LEFT JOIN workerDepartment wd ON wd.workerFk = c.salesPersonFk LEFT JOIN workerDepartment wd ON wd.workerFk = c.salesPersonFk
LEFT JOIN department d ON d.id = wd.departmentFk LEFT JOIN department d ON d.id = wd.departmentFk
LEFT JOIN ( LEFT JOIN (
SELECT co.clientFk, IF(COUNT(*) > 0, FALSE, TRUE) AS hasSubstitution SELECT co.clientFk, IF(COUNT(*) > 0, FALSE, TRUE) hasSubstitution
jgallego marked this conversation as resolved Outdated

esto seria hasObservation

esto seria hasObservation

Okey, reemplazaré

Okey, reemplazaré

cambiado

cambiado
FROM clientObservation co FROM clientObservation co
INNER JOIN observationType ot ON ot.id = co.observationTypeFk INNER JOIN observationType ot ON ot.id = co.observationTypeFk
WHERE ot.code = 'substitution' WHERE ot.code = 'substitution'
GROUP BY co.clientFk GROUP BY co.clientFk
) AS substitution ON substitution.clientFk = c.id ) substitution ON substitution.clientFk = c.id
jgallego marked this conversation as resolved Outdated

aqui falta el alias de la tabla, probablemente t.warehouse

aqui falta el alias de la tabla, probablemente t.warehouse

, COUNT(*) hasObservation

Hemos invertido este booleano, ahora hay que mostrar el icono si aqui hay valor

, COUNT(*) hasObservation Hemos invertido este booleano, ahora hay que mostrar el icono si aqui hay valor
WHERE warehouseFk = ? WHERE t.warehouseFk = ?
AND s.itemFk = ? AND s.itemFk = ?
AND s.quantity <> 0 AND s.quantity <> 0
AND t.shipped >= util.VN_CURDATE() AND t.shipped BETWEEN util.VN_CURDATE() AND DATE_ADD(util.VN_CURDATE(), INTERVAL ? DAY)
AND t.shipped < DATE_ADD(util.VN_CURDATE(), INTERVAL ? DAY)
AND sgd.saleFk IS NULL AND sgd.saleFk IS NULL
AND (al.code IN ('FREE', 'ON_PREVIOUS') OR al.code IS NULL) AND (al.id = ? OR al.id IS NULL)
jgallego marked this conversation as resolved Outdated

Valores como estos lo dejamos así o lo movemos a variables/consultas?

Valores como estos lo dejamos así o lo movemos a variables/consultas?

si es alertLevel hay que usar el codigo, no el numero, en este caso 'ON_PREPARATION' o 'DELIVERED'

si es alertLevel hay que usar el codigo, no el numero, en este caso 'ON_PREPARATION' o 'DELIVERED'

Okey, hago la modificación aqui y en el front para que se pueda enviar array desde el VnSelect

Okey, hago la modificación aqui y en el front para que se pueda enviar array desde el VnSelect

Resuelto

Resuelto

Y he creado un registro en TicketConfig con valor default a FREE (por si cambian de criterio a futuro)

Y he creado un registro en TicketConfig con valor default a FREE (por si cambian de criterio a futuro)
UNION ALL UNION ALL
SELECT r.id, SELECT r.id,
Review

AND s.quantity
para proximas

AND s.quantity para proximas
NULL, NULL,
r.orderFk, r.orderFk,
c.name, c.name customerName,
c.id customerId,
r.shipment, r.shipment,
r.amount, r.amount,
ag.name, ag.name,
@ -131,21 +132,15 @@ module.exports = Self => {
INNER JOIN observationType ot ON ot.id = co.observationTypeFk INNER JOIN observationType ot ON ot.id = co.observationTypeFk
WHERE ot.code = 'substitution' WHERE ot.code = 'substitution'
GROUP BY co.clientFk GROUP BY co.clientFk
) AS substitution ON substitution.clientFk = c.id ) substitution ON substitution.clientFk = c.id
WHERE r.shipment >= util.VN_CURDATE() WHERE r.shipment BETWEEN util.VN_CURDATE() AND DATE_ADD(util.VN_CURDATE(), INTERVAL ? DAY)
AND r.warehouseFk = ? AND r.warehouseFk = ?
jsegarra marked this conversation as resolved Outdated

cambiar este tb

cambiar este tb
AND r.shipment < DATE_ADD(util.VN_CURDATE(), INTERVAL ? DAY)
AND r.created >= STR_TO_DATE(util.VN_CURDATE(), '%Y-%m-%d %H:%i:%s') AND r.created >= STR_TO_DATE(util.VN_CURDATE(), '%Y-%m-%d %H:%i:%s')
jgallego marked this conversation as resolved Outdated

igual que arriba, comparar esto es lentitud en el select, ahi puedes poner (util) curdate o now lo que tenga que ser

igual que arriba, comparar esto es lentitud en el select, ahi puedes poner (util) curdate o now lo que tenga que ser

cambiado

cambiado
AND NOT o.confirmed AND NOT o.confirmed
AND r.itemFk = ? AND r.itemFk = ?
AND r.amount <> 0 AND r.amount <> 0
jgallego marked this conversation as resolved Outdated

asumiendo que el amount es unsigned, deja AND r.amount

asumiendo que el amount es unsigned, deja AND r.amount

cambiado

cambiado
ORDER BY hasToIgnore, isBasket;`, ORDER BY hasToIgnore, isBasket;`,
[filter.where.warehouseFk, itemFk, 2, filter.where.warehouseFk, 2, itemFk]); [filter.where.warehouseFk, itemFk, 2, filter.where.stateFk ?? 0, 2, filter.where.warehouseFk, itemFk]);
jgallego marked this conversation as resolved Outdated

aqui lo dicho, sin numero los ids de los estados van a cambiar en breve

aqui lo dicho, sin numero los ids de los estados van a cambiar en breve

Ahora se usa el código

Ahora se usa el código
if (filter.where.stateFk) {
stmt.merge({
sql: `AND ts.alertLevel=?`, params: [filter.where.stateFk]});
}
const sql = ParameterizedSQL.join([stmt], ';'); const sql = ParameterizedSQL.join([stmt], ';');
jsegarra marked this conversation as resolved Outdated

verias mejor mover el select a un procedimiento? y nos evitamos esta condición?
@jgallego

verias mejor mover el select a un procedimiento? y nos evitamos esta condición? @jgallego

no, con la funcion nativa de loopback va bien

no, con la funcion nativa de loopback va bien

Ok

Ok
const result = await conn.executeStmt(sql, myOptions); const result = await conn.executeStmt(sql, myOptions);

View File

@ -1,136 +1,80 @@
const models = require('vn-loopback/server/server').models; const {models} = require('vn-loopback/server/server');
describe('Item Lack', () => { describe('Item Lack', () => {
jsegarra marked this conversation as resolved
Review

modules/ticket/back/methods/ticket/specs/closure.spec.js dile a chatgpt que coja este arhcivo como plantilla y cambie el tuyo para dejar los beginTransaction y los rollback en un beforeEach y afterEach

modules/ticket/back/methods/ticket/specs/closure.spec.js dile a chatgpt que coja este arhcivo como plantilla y cambie el tuyo para dejar los beginTransaction y los rollback en un beforeEach y afterEach
let options;
let tx;
const ctx = beforeAll.getCtx();
beforeAll.mockLoopBackContext();
beforeEach(async() => { beforeEach(async() => {
ctx = { tx = await models.Ticket.beginTransaction({});
req: { options = {transaction: tx};
accessToken: {}, });
headers: {origin: 'http://localhost'},
} afterEach(async() => {
}; if (tx)
await tx.rollback();
}); });
it('should return data with NO filters', async() => { it('should return data with NO filters', async() => {
const tx = await models.Ticket.beginTransaction({});
const options = {transaction: tx};
const filter = {}; const filter = {};
try { const result = await models.Ticket.itemLack(ctx, filter, options);
const result = await models.Ticket.itemLack(ctx, filter, options);
expect(result.length).toEqual(2); expect(result.length).toEqual(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return data with filter.id', async() => { it('should return data with filter.id', async() => {
const tx = await models.Ticket.beginTransaction({});
const options = {transaction: tx};
const filter = { const filter = {
itemFk: 88 id: 5
}; };
try { const result = await models.Ticket.itemLack(ctx, filter, options);
const result = await models.Ticket.itemLack(ctx, filter, options);
expect(result.length).toEqual(1); expect(result.length).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return data with filter.longname', async() => { it('should return data with filter.longname', async() => {
const tx = await models.Ticket.beginTransaction({});
const options = {transaction: tx};
const filter = { const filter = {
longname: 'Ranged weapon pistol 9mm' longname: 'Ranged weapon pistol 9mm'
}; };
try { const result = await models.Ticket.itemLack(ctx, filter, options);
const result = await models.Ticket.itemLack(ctx, filter, options);
expect(result.length).toEqual(1); expect(result.length).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return data with filter.color', async() => { it('should return data with filter.color', async() => {
const tx = await models.Ticket.beginTransaction({});
const options = {transaction: tx};
const filter = { const filter = {
colour: 'WHT' colour: 'WHT'
}; };
try { const result = await models.Ticket.itemLack(ctx, filter, options);
const result = await models.Ticket.itemLack(ctx, filter, options);
expect(result.length).toEqual(1); expect(result.length).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return data with filter.origen', async() => { it('should return data with filter.origen', async() => {
const tx = await models.Ticket.beginTransaction({});
const options = {transaction: tx};
const filter = { const filter = {
originFk: 1 originFk: 1
}; };
try { const result = await models.Ticket.itemLack(ctx, filter, options);
const result = await models.Ticket.itemLack(ctx, filter, options);
expect(result.length).toEqual(2); expect(result.length).toEqual(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return data with filter.size', async() => { it('should return data with filter.size', async() => {
const tx = await models.Ticket.beginTransaction({});
const options = {transaction: tx};
const filter = { const filter = {
size: '15' size: '15'
}; };
try { const result = await models.Ticket.itemLack(ctx, filter, options);
const result = await models.Ticket.itemLack(ctx, filter, options);
expect(result.length).toEqual(1); expect(result.length).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return data with filter.lack', async() => { it('should return data with filter.lack', async() => {
const tx = await models.Ticket.beginTransaction({});
const options = {transaction: tx};
const filter = { const filter = {
lack: '-15' lack: '-15'
}; };
try {
const result = await models.Ticket.itemLack(ctx, filter, options);
expect(result.length).toEqual(1); const result = await models.Ticket.itemLack(ctx, filter, options);
await tx.rollback();
} catch (e) { expect(result.length).toEqual(1);
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,99 +1,47 @@
const models = require('vn-loopback/server/server').models; const {models} = require('vn-loopback/server/server');
describe('Split', () => { describe('Split', () => {
beforeAll(async() => { let options;
ctx = { let tx;
req: { const ctx = beforeAll.getCtx();
accessToken: {userId: 9}, beforeAll.mockLoopBackContext();
headers: {origin: 'http://localhost'},
__: () => {} beforeEach(async() => {
} tx = await models.Ticket.beginTransaction({});
}; options = {transaction: tx};
});
afterEach(async() => {
if (tx)
await tx.rollback();
}); });
it('should split tickets with count 1', async() => { it('should split tickets with count 1', async() => {
const tx = await models.Ticket.beginTransaction({});
const options = {transaction: tx};
const data = const data =
{ticketFk: 7, sales: [1]} {ticketFk: 7, sales: [1]};
; const result = await models.Ticket.split(ctx, data, options);
try {
const result = await models.Ticket.split(ctx, data, options);
expect(1).toEqual(result.length); expect(data.ticketFk).toEqual(result.ticket);
expect(data.ticketFk).toEqual(result[0].ticket); expect('noSplit').toEqual(result.status);
expect('noSplit').toEqual(result[0].status);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should split tickets with count 2 and error', async() => { it('should split tickets with count 2 and error', async() => {
const tx = await models.Ticket.beginTransaction({});
const options = {transaction: tx};
const data = const data =
{ticketFk: 11, sales: [7]} {ticketFk: 11, sales: [7]}
; ;
try { const result = await models.Ticket.split(ctx, data, options);
const result = await models.Ticket.split(ctx, data, options);
expect(1).toEqual(result.length); expect(data.ticketFk).toEqual(result.ticket);
expect(data.ticketFk).toEqual(result[0].ticket); expect('error').toEqual(result.status);
expect('error').toEqual(result[0].status); expect('Can\'t transfer claimed sales').toEqual(result.message);
expect('Can\'t transfer claimed sales').toEqual(result[0].message);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
xit('should split tickets with count 2 and other error', async() => {
const tx = await models.Ticket.beginTransaction({});
const options = {transaction: tx};
const data =
{ticketFk: 16, sales: [1, 2]}
;
try {
const result = await models.Ticket.split(ctx, data, options);
expect(1).toEqual(result.length);
expect(data.ticketFk).toEqual(result[0].ticket);
expect('error').toEqual(result[0].status);
expect('Can\'t transfer claimed sales').toEqual(result[0].message);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should split tickets with count 2 and success', async() => { it('should split tickets with count 2 and success', async() => {
const tx = await models.Ticket.beginTransaction({});
const options = {transaction: tx};
const data = const data =
{ticketFk: 14, sales: [33]} {ticketFk: 14, sales: [33]};
; const result = await models.Ticket.split(ctx, data, options);
try {
const result = await models.Ticket.split(ctx, data, options);
expect(1).toEqual(result.length); expect(data.ticketFk).toEqual(result.ticket);
expect(data.ticketFk).toEqual(result[0].ticket); expect('split').toEqual(result.status);
expect('split').toEqual(result[0].status);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -38,52 +38,37 @@ module.exports = Self => {
tx = await Self.beginTransaction({}); tx = await Self.beginTransaction({});

si el objetivo es contar tickets te sobraria la tabla sale,
si el objetivo es contar sales te sobraria la tabla ticket

si el objetivo es contar tickets te sobraria la tabla sale, si el objetivo es contar sales te sobraria la tabla ticket

resuelto

resuelto
myOptions.transaction = tx; myOptions.transaction = tx;
} }
try { try {
const ticketsCount = await Self.rawSql(` const count = await models.Sale.count({
Select t.id tid, s.id sid, count(s.id) count ticketFk
FROM }, myOptions);
jsegarra marked this conversation as resolved Outdated

cambia esto por el /Sales/count asi usamos el nativo

cambia esto por el /Sales/count asi usamos el nativo

Okey, lo tomo de ticket/isEmpty

Okey, lo tomo de ticket/isEmpty
vn.ticket t if (count === 1)
LEFT JOIN vn.sale s return {ticket: ticketFk, status: 'noSplit'};
ON s.ticketFk = t.id // continue;
WHERE t.id =? GROUP BY t.id;`,
[ticketFk], myOptions);
for (const {tid, count} of ticketsCount) { const [, [{vNewTicket}]] = await Self.rawSql(`
try {
if (count === 1) {
result.push({ticket: tid, status: 'noSplit'});
continue;
}
const [, [{vNewTicket}]] = await Self.rawSql(`
CALL vn.ticket_clone(?, @vNewTicket); CALL vn.ticket_clone(?, @vNewTicket);
SELECT @vNewTicket vNewTicket;`, SELECT @vNewTicket vNewTicket;`,
[tid], myOptions); [ticketFk], myOptions);
if (vNewTicket === 0) continue; if (vNewTicket === 0) return result;
const sales = await models.Sale.find({ const sales = await models.Sale.find({
where: {id: {inq: ticket.sales}} where: {id: {inq: ticket.sales}}
}, myOptions); }, myOptions);

en que caso devuelve un ticket = 0?

en que caso devuelve un ticket = 0?

Diría que en ningún caso. Pero esta condición estaba en access y la puse

Diría que en ningún caso. Pero esta condición estaba en access y la puse

cambiado

cambiado
const updateIsPicked = sales.map(({sid}) => Self.rawSql(` const updateIsPicked = sales.map(({sid}) => Self.rawSql(`
UPDATE vn.sale SET isPicked = (id = ?) WHERE ticketFk = ?`, UPDATE vn.sale SET isPicked = (id = ?) WHERE ticketFk = ?`,
[sid, tid], myOptions)); [sid, ticketFk], myOptions));
await Promise.all(updateIsPicked); await Promise.all(updateIsPicked);
await Self.transferSales(ctx, tid, vNewTicket, sales, myOptions); await Self.transferSales(ctx, ticketFk, vNewTicket, sales, myOptions);
await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [tid, 'FIXING'], myOptions); await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [ticketFk, 'FIXING'], myOptions);
result.push({ticket: tid, newTicket: vNewTicket, status: 'split'}); if (tx) await tx.commit();
if (tx) await tx.commit(); return {ticket: ticketFk, newTicket: vNewTicket, status: 'split'};
} catch ({message}) {
result.push({ticket: tid, status: 'error', message});
}
}
return result;
} catch (e) { } catch (e) {
if (tx) await tx.rollback(); if (tx) await tx.rollback();
throw e; return {ticket: ticketFk, status: 'error', message: e.message};
} }
}; };
}; };