#6321 - Negative tickets #1945
|
@ -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
|
|||||||
|
|
||||||
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
|
||||||
|
|
|
@ -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
jgallego
commented
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
jgallego
commented
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
jsegarra
commented
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, '%'))
|
||||||
jgallego
commented
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)
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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(/^\+/);
|
||||||
|
});
|
||||||
|
});
|
|
@ -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
jgallego
commented
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
jsegarra
commented
Lo anoto para hablar con el Lo anoto para hablar con el
jsegarra
commented
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
jsegarra
commented
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})`;
|
||||||
|
|
|
@ -8,7 +8,7 @@ module.exports = Self => {
|
||||||
{
|
{
|
||||||
arg: 'itemFk',
|
arg: 'itemFk',
|
||||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
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
jgallego
commented
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
jgallego
commented
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
jgallego
commented
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
jsegarra
commented
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
jsegarra
commented
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
jgallego
commented
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
jsegarra
commented
La consulta que estas viendo está copiada y traducida desde access La consulta que estas viendo está copiada y traducida desde access
Solo la he migrado.
Este campo sirve para ordenar los resultados
jsegarra
commented
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
jgallego
commented
esto seria hasObservation esto seria hasObservation
jsegarra
commented
Okey, reemplazaré Okey, reemplazaré
jsegarra
commented
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
jgallego
commented
aqui falta el alias de la tabla, probablemente t.warehouse aqui falta el alias de la tabla, probablemente t.warehouse
jgallego
commented
, 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
jsegarra
commented
Valores como estos lo dejamos así o lo movemos a variables/consultas? Valores como estos lo dejamos así o lo movemos a variables/consultas?
jgallego
commented
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'
jsegarra
commented
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
jsegarra
commented
Resuelto Resuelto
jsegarra
commented
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,
|
||||||
jgallego
commented
AND s.quantity 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
jgallego
commented
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
jgallego
commented
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
jsegarra
commented
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
jgallego
commented
asumiendo que el amount es unsigned, deja AND r.amount asumiendo que el amount es unsigned, deja AND r.amount
jsegarra
commented
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
jgallego
commented
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
jsegarra
commented
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
jsegarra
commented
verias mejor mover el select a un procedimiento? y nos evitamos esta condición? verias mejor mover el select a un procedimiento? y nos evitamos esta condición?
@jgallego
jgallego
commented
no, con la funcion nativa de loopback va bien no, con la funcion nativa de loopback va bien
jsegarra
commented
Ok Ok
|
|||||||
const result = await conn.executeStmt(sql, myOptions);
|
const result = await conn.executeStmt(sql, myOptions);
|
||||||
|
|
|
@ -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
jgallego
commented
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;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,52 +38,37 @@ module.exports = Self => {
|
||||||
tx = await Self.beginTransaction({});
|
tx = await Self.beginTransaction({});
|
||||||
jgallego
commented
si el objetivo es contar tickets te sobraria la tabla sale, si el objetivo es contar tickets te sobraria la tabla sale,
si el objetivo es contar sales te sobraria la tabla ticket
jsegarra
commented
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
jgallego
commented
cambia esto por el /Sales/count asi usamos el nativo cambia esto por el /Sales/count asi usamos el nativo
jsegarra
commented
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);
|
||||||
|
|
||||||
jgallego
commented
en que caso devuelve un ticket = 0? en que caso devuelve un ticket = 0?
jsegarra
commented
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
jsegarra
commented
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};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
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)