#6321 - Negative tickets #1945
|
@ -798,7 +798,8 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF
|
||||||
(34, 1, 1, 1, 3, util.VN_CURDATE(), util.VN_CURDATE(), 1103, 'BEJAR', 123, NULL, 0, 1, 16, 0, util.VN_CURDATE(), NULL, NULL, NULL, NULL),
|
(34, 1, 1, 1, 3, util.VN_CURDATE(), util.VN_CURDATE(), 1103, 'BEJAR', 123, NULL, 0, 1, 16, 0, util.VN_CURDATE(), NULL, NULL, NULL, NULL),
|
||||||
(35, 1, 1, 1, 3, util.VN_CURDATE(), util.VN_CURDATE(), 1102, 'Somewhere in Philippines', 123, NULL, 0, 1, 16, 0, util.VN_CURDATE(), NULL, NULL, NULL, NULL),
|
(35, 1, 1, 1, 3, util.VN_CURDATE(), util.VN_CURDATE(), 1102, 'Somewhere in Philippines', 123, NULL, 0, 1, 16, 0, util.VN_CURDATE(), NULL, NULL, NULL, NULL),
|
||||||
(36, 1, 1, 1, 3, util.VN_CURDATE(), util.VN_CURDATE(), 1102, 'Ant-Man Adventure', 123, NULL, 0, 1, 16, 0, util.VN_CURDATE(), NULL, NULL, NULL, NULL),
|
(36, 1, 1, 1, 3, util.VN_CURDATE(), util.VN_CURDATE(), 1102, 'Ant-Man Adventure', 123, NULL, 0, 1, 16, 0, util.VN_CURDATE(), NULL, NULL, NULL, NULL),
|
||||||
(37, 1, 1, 1, 3, util.VN_CURDATE(), util.VN_CURDATE(), 1110, 'Deadpool swords', 123, NULL, 0, 1, 16, 0, util.VN_CURDATE(), NULL, NULL, NULL, NULL);
|
(37, 1, 1, 1, 3, util.VN_CURDATE(), util.VN_CURDATE(), 1110, 'Deadpool swords', 123, NULL, 0, 1, 16, 0, util.VN_CURDATE(), NULL, NULL, NULL, NULL),
|
||||||
|
(1000000, NULL, 1, 1, NULL, util.VN_CURDATE(), util.VN_CURDATE(), 1, 'employee', 131, NULL, 0, 1, 1.00, 0.00, CURDATE(), NULL, NULL, '', NULL);
|
||||||
|
|
||||||
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
|
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1002,7 +1003,8 @@ VALUES
|
||||||
(14, 5, 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'VT', 1, NULL, NULL, 0, NULL, 0),
|
(14, 5, 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'VT', 1, NULL, NULL, 0, NULL, 0),
|
||||||
(15, 4, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'EMB', 0, NULL, NULL, 0, NULL, 0),
|
(15, 4, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'EMB', 0, NULL, NULL, 0, NULL, 0),
|
||||||
(16, 6, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'EMB', 0, NULL, NULL, 0, NULL, 0),
|
(16, 6, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'EMB', 0, NULL, NULL, 0, NULL, 0),
|
||||||
(71, 6, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL, 0);
|
(71, 6, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL, 0),
|
||||||
|
(88, 1, 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', 'Stark Industries', 10.0, 'VT', 0, NULL, NULL, 1, NULL, 0);
|
||||||
|
|
||||||
|
|
||||||
-- Update the taxClass after insert of the items
|
-- Update the taxClass after insert of the items
|
||||||
|
@ -1125,7 +1127,8 @@ INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `pric
|
||||||
(39, 1, 32, 'Ranged weapon longbow 200cm', 2, 103.49, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'),
|
(39, 1, 32, 'Ranged weapon longbow 200cm', 2, 103.49, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack'),
|
||||||
(40, 2, 34, 'Melee weapon combat fist 15cm', 10.00, 3.91, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasItemLost'),
|
(40, 2, 34, 'Melee weapon combat fist 15cm', 10.00, 3.91, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasItemLost'),
|
||||||
(41, 2, 35, 'Melee weapon combat fist 15cm', 8.00, 3.01, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasRounding,hasItemLost'),
|
(41, 2, 35, 'Melee weapon combat fist 15cm', 8.00, 3.01, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasRounding,hasItemLost'),
|
||||||
(42, 2, 36, 'Melee weapon combat fist 15cm', 6.00, 2.50, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasRounding,hasItemLost');
|
(42, 2, 36, 'Melee weapon combat fist 15cm', 6.00, 2.50, 0, 0, 0, util.VN_CURDATE(), 'hasComponentLack,hasRounding,hasItemLost'),
|
||||||
|
(43, 88, 1000000, 'Chest medical box 2', 15.00, 10.00, 0, 0, 0, CURDATE(), '');
|
||||||
|
|
||||||
INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
|
INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1457,7 +1460,14 @@ INSERT INTO `vn`.`itemTag`(`id`,`itemFk`,`tagFk`,`value`,`priority`)
|
||||||
(98, 14, 23, '1', 7),
|
(98, 14, 23, '1', 7),
|
||||||
(99, 15, 92, 'Trolley', 2),
|
(99, 15, 92, 'Trolley', 2),
|
||||||
(100, 16, 92, 'Pallet', 2),
|
(100, 16, 92, 'Pallet', 2),
|
||||||
(101, 71, 92, 'Shipping cost', 2);
|
(101, 71, 92, 'Shipping cost', 2),
|
||||||
|
(102, 88, 56, 'Chest', 1),
|
||||||
|
(103, 88, 58, 'ammo box', 2),
|
||||||
|
(104, 88, 27, '100cm', 3),
|
||||||
|
(105, 88, 36, 'Stark Industries', 4),
|
||||||
|
(106, 88, 1, 'White', 5),
|
||||||
|
(107, 88, 67, 'supply', 6),
|
||||||
|
(108, 88, 23, '13', 7);
|
||||||
|
|
||||||
INSERT INTO `vn`.`itemTypeTag`(`id`, `itemTypeFk`, `tagFk`, `priority`)
|
INSERT INTO `vn`.`itemTypeTag`(`id`, `itemTypeFk`, `tagFk`, `priority`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1585,7 +1595,8 @@ INSERT INTO `bs`.`waste`(`buyerFk`, `year`, `week`, `itemFk`, `itemTypeFk`, `sal
|
||||||
(15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 'grouping', NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
|
(15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 'grouping', NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
|
||||||
(16, 99,1,50.0000, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'packing', NULL, 0.00, 99.60, 99.40, 0, 1, 0, 1.00, '2024-07-30 08:13:51.000'),
|
(16, 99,1,50.0000, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'packing', NULL, 0.00, 99.60, 99.40, 0, 1, 0, 1.00, '2024-07-30 08:13:51.000'),
|
||||||
(17, 11, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'packing', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 2 MONTH),
|
(17, 11, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'packing', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 2 MONTH),
|
||||||
(18, 12, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'grouping', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 2 MONTH);
|
(18, 12, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'grouping', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 2 MONTH),
|
||||||
|
(10000002, 12, 88, 50.0000, 5000, '4', 1, 1.500, 1.500, 0.000, 1, 1, 'grouping', NULL, 0.00, 99.60, 99.40, 0, 1, 0, 1.00, util.VN_CURDATE() - INTERVAL 2 MONTH);
|
||||||
|
|
||||||
INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_id`, `agency_id`, `address_id`, `company_id`, `note`, `source_app`, `confirmed`,`total`, `date_make`, `first_row_stamp`, `confirm_date`)
|
INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_id`, `agency_id`, `address_id`, `company_id`, `note`, `source_app`, `confirmed`,`total`, `date_make`, `first_row_stamp`, `confirm_date`)
|
||||||
VALUES
|
VALUES
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getLack`(IN vForce BOOLEAN, IN vDays INT)
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getLack`(
|
||||||
|
vSelf INT,
|
||||||
|
vForce BOOLEAN,
|
||||||
|
vDays INT,
|
||||||
jsegarra marked this conversation as resolved
|
|||||||
|
vLongname VARCHAR(255),
|
||||||
|
vProducerName 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),
|
||||||
|
vSize INT,
|
||||||
|
vOrigen INT,
|
||||||
|
vLack INT,
|
||||||
|
vWarehouseFk INT
|
||||||
|
)
|
||||||
BEGIN
|
BEGIN
|
||||||
/**
|
/**
|
||||||
* Calcula una tabla con el máximo negativo visible para cada producto y almacen
|
* Calcula una tabla con el máximo negativo visible para cada producto y almacen
|
||||||
|
@ -47,6 +58,14 @@ BEGIN
|
||||||
WHERE w.isForTicket
|
WHERE w.isForTicket
|
||||||
AND ic.display
|
AND ic.display
|
||||||
AND it.code != 'GEN'
|
AND it.code != 'GEN'
|
||||||
|
AND (vSelf IS NULL OR i.id = vSelf)
|
||||||
|
AND (vLongname IS NULL OR i.name = vLongname)
|
||||||
|
AND (vProducerName IS NULL OR p.`name` LIKE CONCAT('%', vProducerName, '%'))
|
||||||
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 (vSize IS NULL OR vSize = i.`size`)
|
||||||
|
AND (vOrigen IS NULL OR vOrigen = w.id)
|
||||||
|
AND (vLack IS NULL OR vLack = sub.amount)
|
||||||
|
AND (vWarehouseFk IS NULL OR vWarehouseFk = w.id)
|
||||||
GROUP BY i.id, w.id
|
GROUP BY i.id, w.id
|
||||||
HAVING lack < 0;
|
HAVING lack < 0;
|
||||||
|
|
||||||
|
|
|
@ -82,14 +82,19 @@ BEGIN
|
||||||
AND it.priority = vPriority
|
AND it.priority = vPriority
|
||||||
LEFT JOIN vn.tag t ON t.id = it.tagFk
|
LEFT JOIN vn.tag t ON t.id = it.tagFk
|
||||||
LEFT JOIN vn.buy b ON b.id = bu.buyFk
|
LEFT JOIN vn.buy b ON b.id = bu.buyFk
|
||||||
|
LEFT JOIN vn.itemShelvingStock iss ON iss.itemFk = i.id
|
||||||
|
AND iss.warehouseFk = vWarehouseFk
|
||||||
|
LEFT JOIN vn.ink ink ON ink.id = i.tag5
|
||||||
JOIN itemTags its
|
JOIN itemTags its
|
||||||
WHERE a.available > 0
|
WHERE a.available > 0
|
||||||
AND (i.typeFk = its.typeFk OR NOT vShowType)
|
AND (i.typeFk = its.typeFk OR NOT vShowType)
|
||||||
AND i.id <> vSelf
|
AND i.id <> vSelf
|
||||||
ORDER BY `counter` DESC,
|
ORDER BY (a.available > 0) DESC,
|
||||||
|
`counter` DESC,
|
||||||
(t.name = its.name) DESC,
|
(t.name = its.name) DESC,
|
||||||
(it.value = its.value) DESC,
|
(it.value = its.value) DESC,
|
||||||
(i.tag5 = its.tag5) DESC,
|
(i.tag5 = its.tag5) DESC,
|
||||||
|
(ink.`showOrder`) DESC,
|
||||||
match5 DESC,
|
match5 DESC,
|
||||||
(i.tag6 = its.tag6) DESC,
|
(i.tag6 = its.tag6) DESC,
|
||||||
match6 DESC,
|
match6 DESC,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 ;
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
INSERT IGNORE INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
|
||||||
|
VALUES
|
||||||
|
('Ticket','itemLack','READ','ALLOW','ROLE','employee'),
|
||||||
|
('Ticket','itemLackDetail','READ','ALLOW','ROLE','employee'),
|
||||||
|
('Ticket','split','WRITE','ALLOW','ROLE','employee'),
|
||||||
|
('Sale','replaceItem','WRITE','ALLOW','ROLE','employee');
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE vn.ticketConfig ADD lackAlertPrice int(11) DEFAULT 30 NOT NULL COMMENT 'Value to alert when item proposal exceed price';
|
||||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
esto es lo que dices que ya no hacia falta? esto es lo que dices que ya no hacia falta?
|
|||||||
|
ALTER TABLE vn.ticketConfig ADD lackScopeDays int(11) DEFAULT 2 NOT NULL COMMENT 'Number of days to look back for ticket with negatives';
|
||||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
'Maximum percentage allowed before showing a price alert' lackDefaultAlertLevelCode quitar, lo usamos en el codigo 'Maximum percentage allowed before showing a price alert'
lackDefaultAlertLevelCode quitar, lo usamos en el codigo
|
|
@ -234,6 +234,7 @@
|
||||||
"It has been invoiced but the PDF of refund not be generated": "It has been invoiced but the PDF of refund not be generated",
|
"It has been invoiced but the PDF of refund not be generated": "It has been invoiced but the PDF of refund not be generated",
|
||||||
"Cannot add holidays on this day": "Cannot add holidays on this day",
|
"Cannot add holidays on this day": "Cannot add holidays on this day",
|
||||||
"Cannot send mail": "Cannot send mail",
|
"Cannot send mail": "Cannot send mail",
|
||||||
|
"This worker already exists": "This worker already exists",
|
||||||
"CONSTRAINT `chkParkingCodeFormat` failed for `vn`.`parking`": "CONSTRAINT `chkParkingCodeFormat` failed for `vn`.`parking`",
|
"CONSTRAINT `chkParkingCodeFormat` failed for `vn`.`parking`": "CONSTRAINT `chkParkingCodeFormat` failed for `vn`.`parking`",
|
||||||
"This postcode already exists": "This postcode already exists",
|
"This postcode already exists": "This postcode already exists",
|
||||||
"Original invoice not found": "Original invoice not found",
|
"Original invoice not found": "Original invoice not found",
|
||||||
|
@ -254,5 +255,7 @@
|
||||||
"Holidays to past days not available": "Holidays to past days not available",
|
"Holidays to past days not available": "Holidays to past days not available",
|
||||||
"Incorrect delivery order alert on route": "Incorrect delivery order alert on route: {{ route }} zone: {{ zone }}",
|
"Incorrect delivery order alert on route": "Incorrect delivery order alert on route: {{ route }} zone: {{ zone }}",
|
||||||
"Ticket has been delivered out of order": "The ticket {{ticket}} of route {{{fullUrl}}} has been delivered out of order.",
|
"Ticket has been delivered out of order": "The ticket {{ticket}} of route {{{fullUrl}}} has been delivered out of order.",
|
||||||
"clonedFromTicketWeekly": ", that is a cloned sale from ticket {{ ticketWeekly }}"
|
"clonedFromTicketWeekly": ", that is a cloned sale from ticket {{ ticketWeekly }}",
|
||||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
revisar traducción revisar traducción
jgallego
commented
No solemos poner (Negativos) , se asume que es la seccion No solemos poner (Negativos) , se asume que es la seccion
jsegarra
commented
Copié y pegué literal. Copié y pegué literal.
Okey, lo dejo para que empiece por "Susituido"
jgallego
commented
NO "negativeReplaced": "(Negativos) Sustituido el articulo SI "negativeReplaced": " Sustituido el articulo NO "negativeReplaced": "(Negativos) Sustituido el articulo
SI "negativeReplaced": " Sustituido el articulo
|
|||||||
|
"negativeReplaced": "Replaced item [#{{oldItemId}}]({{{oldItemUrl}}}) {{oldItem}} with [#{{newItemId}}]({{{newItemUrl}}}) {{newItem}} from ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
jgallego
commented
realmente esto seria: "The tag and priority can't be repeated" realmente esto seria: "The tag and priority can't be repeated"
jsegarra
commented
cambiado cambiado
jgallego
commented
en el archivo de ingles has metido castellano.. en el archivo de ingles has metido castellano..
jsegarra
commented
He usado la IA para la traducción He usado la IA para la traducción
|
|||||||
|
"The tag and priority can't be repeated": "The tag and priority can't be repeated"
|
||||||
}
|
}
|
||||||
|
|
|
@ -397,5 +397,6 @@
|
||||||
"Incorrect delivery order alert on route": "Alerta de orden de entrega incorrecta en ruta: {{ route }} zona: {{ zone }}",
|
"Incorrect delivery order alert on route": "Alerta de orden de entrega incorrecta en ruta: {{ route }} zona: {{ zone }}",
|
||||||
"Ticket has been delivered out of order": "El ticket {{ticket}} {{{fullUrl}}} no ha sido entregado en su orden.",
|
"Ticket has been delivered out of order": "El ticket {{ticket}} {{{fullUrl}}} no ha sido entregado en su orden.",
|
||||||
"Price cannot be blank": "El precio no puede estar en blanco",
|
"Price cannot be blank": "El precio no puede estar en blanco",
|
||||||
"clonedFromTicketWeekly": ", que es una linea clonada del ticket {{ticketWeekly}}"
|
"clonedFromTicketWeekly": ", que es una linea clonada del ticket {{ticketWeekly}}",
|
||||||
|
"negativeReplaced": "Sustituido el articulo [#{{oldItemId}}]({{{oldItemUrl}}}) {{oldItem}} por [#{{newItemId}}]({{{newItemUrl}}}) {{newItem}} del ticket [{{ticketId}}]({{{ticketUrl}}})"
|
||||||
}
|
}
|
||||||
|
|
|
@ -368,5 +368,6 @@
|
||||||
"ticketLostExpedition": "Le ticket [{{ticketId}}]({{{ticketUrl}}}) a l'expédition perdue suivante : {{expeditionId}}",
|
"ticketLostExpedition": "Le ticket [{{ticketId}}]({{{ticketUrl}}}) a l'expédition perdue suivante : {{expeditionId}}",
|
||||||
"The web user's email already exists": "L'email de l'internaute existe déjà",
|
"The web user's email already exists": "L'email de l'internaute existe déjà",
|
||||||
"Incorrect delivery order alert on route": "Alerte de bon de livraison incorrect sur l'itinéraire: {{ route }} zone : {{ zone }}",
|
"Incorrect delivery order alert on route": "Alerte de bon de livraison incorrect sur l'itinéraire: {{ route }} zone : {{ zone }}",
|
||||||
"Ticket has been delivered out of order": "Le ticket {{ticket}} de la route {{{fullUrl}}} a été livré hors service."
|
"Ticket has been delivered out of order": "Le ticket {{ticket}} de la route {{{fullUrl}}} a été livré hors service.",
|
||||||
|
"negativeReplaced": "Remplacé l'article [#{{oldItemId}}]({{{oldItemUrl}}}) {{oldItem}} par [#{{newItemId}}]({{{newItemUrl}}}) {{newItem}} du ticket [{{ticketId}}]({{{ticketUrl}}})"
|
||||||
jsegarra
commented
revisar traducción revisar traducción
jgallego
commented
frances? frances?
jsegarra
commented
He usado la IA para la traducción He usado la IA para la traducción
|
|||||||
}
|
}
|
|
@ -367,5 +367,6 @@
|
||||||
"ticketLostExpedition": "O ticket [{{ticketId}}]({{{ticketUrl}}}) tem a seguinte expedição perdida: {{expeditionId}}",
|
"ticketLostExpedition": "O ticket [{{ticketId}}]({{{ticketUrl}}}) tem a seguinte expedição perdida: {{expeditionId}}",
|
||||||
"The web user's email already exists": "O e-mail do utilizador da web já existe.",
|
"The web user's email already exists": "O e-mail do utilizador da web já existe.",
|
||||||
"Incorrect delivery order alert on route": "Alerta de ordem de entrega incorreta na rota: {{ route }} zona: {{ zone }}",
|
"Incorrect delivery order alert on route": "Alerta de ordem de entrega incorreta na rota: {{ route }} zona: {{ zone }}",
|
||||||
"Ticket has been delivered out of order": "O ticket {{ticket}} da rota {{{fullUrl}}} foi entregue fora de ordem."
|
"Ticket has been delivered out of order": "O ticket {{ticket}} da rota {{{fullUrl}}} foi entregue fora de ordem.",
|
||||||
|
"negativeReplaced": "Substituído o artigo [#{{oldItemId}}]({{{oldItemUrl}}}) {{oldItem}} por [#{{newItemId}}]({{{newItemUrl}}}) {{newItem}} do ticket [{{ticketId}}]({{{ticketUrl}}})"
|
||||||
jsegarra
commented
revisar traducción revisar traducción
jsegarra
commented
He usado la IA para la traducción He usado la IA para la traducción
|
|||||||
}
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('getSimilar', {
|
||||||
|
description: 'Returns list of items with similar item requested',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'filter',
|
||||||
|
type: 'Object',
|
||||||
|
required: true,
|
||||||
|
description: 'Filter defining where and paginated data',
|
||||||
|
http: {source: 'query'}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
type: ['Object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/getSimilar`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.getSimilar = async(ctx, filter, options) => {
|
||||||
|
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
const {where} = filter;
|
||||||
|
|
||||||
|
const query = [
|
||||||
|
filter.itemFk,
|
||||||
|
where.warehouseFk,
|
||||||
|
where.date,
|
||||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
asegurate que esto es necesario y solo el Date.vnNew() no funciona asegurate que esto es necesario y solo el Date.vnNew() no funciona
|
|||||||
|
where.showType,
|
||||||
|
where.scopeDays
|
||||||
jgallego marked this conversation as resolved
Outdated
jgallego
commented
aqui asume que te pasan siempre estos 3 parametros aqui asume que te pasan siempre estos 3 parametros
jsegarra
commented
Al procedimiento si, desde front son opcionales Al procedimiento si, desde front son opcionales
Los valores que ves, son los mismos que hay en la tabla de access
jsegarra
commented
creo que ya veo lo que quieres decir creo que ya veo lo que quieres decir
jsegarra
commented
cambiado cambiado
|
|||||||
|
];
|
||||||
|
const [results] = await Self.rawSql('CALL vn.item_getSimilar(?, ?, ?, ?, ?)', query, myOptions);
|
||||||
|
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,49 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
|
describe('Item get similar', () => {
|
||||||
|
let options;
|
||||||
|
let tx;
|
||||||
|
const ctx = beforeAll.getCtx();
|
||||||
|
beforeAll.mockLoopBackContext();
|
||||||
|
beforeEach(async() => {
|
||||||
|
tx = await models.Item.beginTransaction({});
|
||||||
|
options = {transaction: tx};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async() => {
|
||||||
|
if (tx)
|
||||||
|
await tx.rollback();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return similar items', async() => {
|
||||||
|
const filter = {
|
||||||
|
itemFk: 88, sales: 43,
|
||||||
|
where: {
|
||||||
|
'scopeDays': '2',
|
||||||
|
'showType': true,
|
||||||
|
'alertLevelCode': 'FREE',
|
||||||
|
'date': '2001-01-01T11:00:00.000Z',
|
||||||
|
'warehouseFk': 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = await models.Item.getSimilar(ctx, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty array is if not exists', async() => {
|
||||||
|
const filter = {
|
||||||
|
itemFk: 88, sales: 43,
|
||||||
|
where: {
|
||||||
|
'scopeDays': '2',
|
||||||
|
'showType': true,
|
||||||
|
'alertLevelCode': 'FREE',
|
||||||
|
'date': '2001-01-01T11:00:00.000Z',
|
||||||
|
'warehouseFk': 60
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = await models.Item.getSimilar(ctx, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(0);
|
||||||
|
});
|
||||||
|
});
|
|
@ -5,6 +5,7 @@ module.exports = Self => {
|
||||||
require('../methods/item/clone')(Self);
|
require('../methods/item/clone')(Self);
|
||||||
require('../methods/item/updateTaxes')(Self);
|
require('../methods/item/updateTaxes')(Self);
|
||||||
require('../methods/item/getBalance')(Self);
|
require('../methods/item/getBalance')(Self);
|
||||||
|
require('../methods/item/getSimilar')(Self);
|
||||||
require('../methods/item/lastEntriesFilter')(Self);
|
require('../methods/item/lastEntriesFilter')(Self);
|
||||||
require('../methods/item/getSummary')(Self);
|
require('../methods/item/getSummary')(Self);
|
||||||
require('../methods/item/getCard')(Self);
|
require('../methods/item/getCard')(Self);
|
||||||
|
|
|
@ -31,7 +31,7 @@ describe('route getSuggestedTickets()', () => {
|
||||||
const length = result.length;
|
const length = result.length;
|
||||||
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
|
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
|
||||||
|
|
||||||
expect(result.length).toEqual(4);
|
expect(result.length).toEqual(5);
|
||||||
expect(anyResult.zoneFk).toEqual(1);
|
expect(anyResult.zoneFk).toEqual(1);
|
||||||
expect(anyResult.agencyModeFk).toEqual(8);
|
expect(anyResult.agencyModeFk).toEqual(8);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe('route unlink()', () => {
|
||||||
let tickets = await models.Route.getSuggestedTickets(routeId, options);
|
let tickets = await models.Route.getSuggestedTickets(routeId, options);
|
||||||
|
|
||||||
expect(zoneAgencyModes.length).toEqual(4);
|
expect(zoneAgencyModes.length).toEqual(4);
|
||||||
expect(tickets.length).toEqual(3);
|
expect(tickets.length).toEqual(4);
|
||||||
|
|
||||||
await models.Route.unlink(agencyModeId, zoneId, options);
|
await models.Route.unlink(agencyModeId, zoneId, options);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('replaceItem', {
|
||||||
|
description: 'Replace item from sale',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'saleFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'substitutionFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'quantity',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/replaceItem`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.replaceItem = async(ctx, saleFk, substitutionFk, quantity, options) => {
|
||||||
|
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||||
|
let tx;
|
||||||
|
const $t = ctx.req.__;
|
||||||
|
|
||||||
|
const models = Self.app.models;
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const replaceItemQuery = {
|
||||||
|
sql: 'CALL sale_replaceItem(?,?,?)',
|
||||||
|
query: [saleFk, substitutionFk, quantity]
|
||||||
|
};
|
||||||
|
const resultReplaceItem = await Self.rawSql(replaceItemQuery.sql, replaceItemQuery.query, myOptions);
|
||||||
|
const sale = await models.Sale.findById(saleFk, {
|
||||||
|
fields: ['id', 'ticketFk', 'itemFk', 'quantity', 'price'],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'ticket',
|
||||||
|
scope: {
|
||||||
|
fields: ['id']
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
relation: 'item',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name', 'longName']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
const salesPersonQuery = {
|
||||||
|
sql: 'SELECT vn.client_getSalesPersonByTicket(?)',
|
||||||
|
query: [sale.ticketFk]
|
||||||
|
};
|
||||||
|
const salesPerson = await Self.rawSql(salesPersonQuery.sql, salesPersonQuery.query, myOptions);
|
||||||
|
const url = await models.Url.getUrl();
|
||||||
|
const substitution = await models.Item.findById(substitutionFk, {
|
||||||
|
fields: ['id', 'name', 'longName']
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
const message = $t('negativeReplaced', {
|
||||||
|
oldItemId: sale.itemFk,
|
||||||
|
oldItem: sale.item().longName,
|
||||||
|
oldItemUrl: `${url}item/${sale.itemFk}/summary`,
|
||||||
|
newItemId: substitution.id,
|
||||||
|
newItem: substitution.longName,
|
||||||
|
newItemUrl: `${url}item/${substitution.id}/summary`,
|
||||||
|
ticketId: sale.ticketFk,
|
||||||
|
ticketUrl: `${url}ticket/${sale.ticketFk}/sale`
|
||||||
|
});
|
||||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
yo estoy haciendo un refactor, hazle test de back a este archivo para yo asegurarme que no te lo rompo yo estoy haciendo un refactor, hazle test de back a este archivo para yo asegurarme que no te lo rompo
jsegarra
commented
hecho, 2 casos de prueba. Cuando reemplazas toda la cantidad y otro cuando reemplazas con menos hecho, 2 casos de prueba. Cuando reemplazas toda la cantidad y otro cuando reemplazas con menos
|
|||||||
|
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
|
||||||
|
|
||||||
|
return resultReplaceItem;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -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(/^\+/);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,111 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('itemLack', {
|
||||||
|
description: 'Get tickets as negative status',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'ctx',
|
||||||
alexm
commented
Cambiar descripccion Cambiar descripccion
jsegarra
commented
del accepts o del método? del accepts o del método?
|
|||||||
|
type: 'object',
|
||||||
|
http: {source: 'context'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'filter',
|
||||||
|
type: 'object',
|
||||||
|
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
description: 'The item id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'longname',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Article name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'supplier',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Supplier id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'colour',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Colour\'s item',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'size',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Size\'s item',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'origen',
|
||||||
|
type: 'string',
|
||||||
|
description: 'origen id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'warehouseFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'The warehouse id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'lack',
|
||||||
|
type: 'number',
|
||||||
|
description: 'The item id',
|
||||||
jsegarra marked this conversation as resolved
jgallego
commented
pon una descripcion que aporte al developer? pon una descripcion que aporte al developer?
|
|||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'days',
|
||||||
|
type: 'number',
|
||||||
|
description: 'The range days',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: [
|
||||||
|
{
|
||||||
|
arg: 'body',
|
||||||
|
type: ['object'],
|
||||||
|
root: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
http: {
|
||||||
|
path: `/itemLack`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.itemLack = async(ctx, filter, options) => {
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
const filterKeyOrder = [
|
||||||
|
'id', 'force', 'days', 'longname', 'supplier',
|
||||||
|
'colour', 'size', 'originFk',
|
||||||
|
'lack', 'warehouseFk'
|
||||||
|
];
|
||||||
|
|
||||||
|
delete ctx?.args?.ctx;
|
||||||
|
|
||||||
|
delete ctx?.args?.filter;
|
||||||
|
|
||||||
|
Object.assign(filter, ctx.args ?? {});
|
||||||
|
|
||||||
|
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(', ');
|
||||||
|
|
||||||
|
let query = `CALL vn.item_getLack(${procedureArgs})`;
|
||||||
|
|
||||||
|
const result = await Self.rawSql(query, procedureParams, myOptions);
|
||||||
|
|
||||||
|
const itemsIndex = 0;
|
||||||
|
return result[itemsIndex];
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,167 @@
|
||||||
|
const {ParameterizedSQL} = require('loopback-connector');
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('itemLackDetail', {
|
||||||
|
description: 'Retrieve detail from ticket as negative',
|
||||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
esta descripcion corresponde ? esta descripcion corresponde ?
|
|||||||
|
accessType: 'READ',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
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',
|
||||||
|
description: 'The item as negative status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'filter',
|
||||||
|
type: 'object',
|
||||||
|
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||||
|
http: {source: 'query'}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: [
|
||||||
|
{
|
||||||
|
arg: 'body',
|
||||||
|
type: ['object'],
|
||||||
|
root: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
http: {
|
||||||
|
path: `/itemLack/:itemFk`,
|
||||||
|
verb: 'GET',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.itemLackDetail = async(itemFk, filter, options) => {
|
||||||
|
const conn = Self.dataSource.connector;
|
||||||
|
|
||||||
|
const myOptions = {};
|
||||||
|
if (typeof options == 'object') Object.assign(myOptions, options);
|
||||||
|
const vDated = (Date.vnNew());
|
||||||
|
vDated.setHours(0, 0, 0, 0);
|
||||||
|
const scopeDays = filter.where.scopeDays ?? 0;
|
||||||
jgallego
commented
este dos? este dos?
jsegarra
commented
Este 2 lo he puesto para que cuando filter.where no tenga scopeDays no de error la consulta, sin embargo, para ser lo mas agnóstico posible a quien lo llame, si no me lo pasas, asigno un 0 que es más lógico Este 2 lo he puesto para que cuando filter.where no tenga scopeDays no de error la consulta, sin embargo, para ser lo mas agnóstico posible a quien lo llame, si no me lo pasas, asigno un 0 que es más lógico
jsegarra
commented
Si lo ves correcto, te pido fusionar Si lo ves correcto, te pido fusionar
jgallego
commented
mejora aun, no pases nada si no pasan nada. mejora aun, no pases nada si no pasan nada.
|
|||||||
|
let alertLevels = filter.where.alertLevelCode;
|
||||||
|
|
||||||
|
if (!alertLevels)
|
||||||
|
alertLevels = (await Self.app.models.AlertLevel.find({fields: ['code']})).map(({code}) => code);
|
||||||
|
|
||||||
|
const stmt = new ParameterizedSQL(`
|
||||||
|
SELECT s.id,
|
||||||
|
st.code,
|
||||||
|
t.id,
|
||||||
|
t.nickname,
|
||||||
|
c.id customerId,
|
||||||
jgallego marked this conversation as resolved
Outdated
jgallego
commented
yo estoy cambiando los alertLevel, no podemos poner numero en el codigo, si no hay ..null yo estoy cambiando los alertLevel, no podemos poner numero en el codigo, si no hay ..null
jsegarra
commented
ok, lo reviso ok, lo reviso
jsegarra
commented
Lo he valorado con otros compañeros y esto de momento lo dejamos así Lo he valorado con otros compañeros y esto de momento lo dejamos así
|
|||||||
|
t.shipped,
|
||||||
|
s.quantity,
|
||||||
|
ag.name,
|
||||||
|
ag.id agencyFk,
|
||||||
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
|
|||||||
|
tls.alertLevel alertLevel,
|
||||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
tls.alertLevel tls.alertLevel
|
|||||||
|
st.name stateName,
|
||||||
|
s.id saleFk,
|
||||||
|
s.itemFk,
|
||||||
|
s.price price,
|
||||||
|
al.code alertLevelCode,
|
||||||
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
|
|||||||
|
z.name zoneName,
|
||||||
|
z.id zoneFk,
|
||||||
|
z.hour theoreticalhour,
|
||||||
|
cn.isRookie,
|
||||||
|
sc.saleClonedFk turno,
|
||||||
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
|
|||||||
|
tr.saleFk peticionCompra,
|
||||||
|
DATE_FORMAT(IF(HOUR(t.shipped), t.shipped, IF(zc.hour, zc.hour, z.hour)),'%H:%i') minTimed,
|
||||||
|
FALSE isBasket,
|
||||||
|
substitution.hasObservation,
|
||||||
|
(d.code = 'spainTeamVip') hasToIgnore
|
||||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
(d.code = 'spainTeamVip') hasToIgnore (d.code = 'spainTeamVip') hasToIgnore
|
|||||||
|
FROM sale s
|
||||||
jgallego marked this conversation as resolved
jgallego
commented
esto hace que las consultas sean muy lentas, hay que buscar alternativa, busca si encuentras otra consulta similar por la BBDD esto hace que las consultas sean muy lentas, hay que buscar alternativa, busca si encuentras otra consulta similar por la BBDD
jsegarra
commented
cambiado cambiado
|
|||||||
|
LEFT JOIN saleGroupDetail sgd ON sgd.saleFk = s.id
|
||||||
|
JOIN ticket t ON t.id = s.ticketFk
|
||||||
|
LEFT JOIN zone z ON z.id = t.zoneFk
|
||||||
|
LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk
|
||||||
|
AND t.shipped BETWEEN zc.dated AND util.dayEnd(t.shipped)
|
||||||
|
JOIN client c ON c.id=t.clientFk
|
||||||
|
LEFT JOIN bs.clientNewBorn cn ON cn.clientFk=c.id
|
||||||
|
JOIN agencyMode ag ON ag.id=t.agencyModeFk
|
||||||
|
JOIN ticketState tls ON tls.ticketFk=t.id
|
||||||
|
LEFT JOIN state st ON st.id=tls.state
|
||||||
|
LEFT JOIN alertLevel al ON al.id = st.alertLevel
|
||||||
|
LEFT JOIN saleCloned sc ON sc.saleClonedFk = s.id
|
||||||
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
|
|||||||
|
LEFT JOIN ticketRequest tr ON tr.saleFk = s.id
|
||||||
|
LEFT JOIN workerDepartment wd ON wd.workerFk = c.salesPersonFk
|
||||||
|
LEFT JOIN department d ON d.id = wd.departmentFk
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT co.clientFk, COUNT(*) hasObservation
|
||||||
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
|
|||||||
|
FROM clientObservation co
|
||||||
|
JOIN observationType ot ON ot.id = co.observationTypeFk
|
||||||
|
WHERE ot.code = 'substitution'
|
||||||
|
GROUP BY co.clientFk
|
||||||
|
) substitution ON substitution.clientFk = c.id
|
||||||
|
WHERE t.warehouseFk = ?
|
||||||
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)
|
|||||||
|
AND s.itemFk = ?
|
||||||
|
AND s.quantity <> 0
|
||||||
jgallego
commented
AND s.quantity AND s.quantity
para proximas
|
|||||||
|
|
||||||
|
AND t.shipped BETWEEN ? AND (? + INTERVAL ? DAY)
|
||||||
|
|
||||||
|
AND sgd.saleFk IS NULL
|
||||||
|
AND (al.code IN (?) OR al.id IS NULL)
|
||||||
|
UNION ALL
|
||||||
|
SELECT r.id,
|
||||||
|
NULL,
|
||||||
|
r.orderFk,
|
||||||
|
c.name customerName,
|
||||||
|
c.id customerId,
|
||||||
|
r.shipment,
|
||||||
|
r.amount,
|
||||||
|
ag.name,
|
||||||
|
ag.id,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
r.itemFk,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
cn.isRookie,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
TRUE,
|
||||||
|
substitution.hasObservation,
|
||||||
|
d.code = 'spainTeamVip'
|
||||||
|
FROM hedera.orderRow r
|
||||||
|
JOIN hedera.order o ON o.id = r.orderFk
|
||||||
|
JOIN client c ON c.id = o.customer_id
|
||||||
|
JOIN agencyMode ag ON ag.id=o.agency_id
|
||||||
|
LEFT JOIN bs.clientNewBorn cn ON cn.clientFk=c.id
|
||||||
|
LEFT JOIN workerDepartment wd ON wd.workerFk = c.salesPersonFk
|
||||||
|
LEFT JOIN department d ON d.id = wd.departmentFk
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT co.clientFk, COUNT(*) hasObservation
|
||||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
cambiar este tb cambiar este tb
|
|||||||
|
FROM clientObservation co
|
||||||
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
|
|||||||
|
JOIN observationType ot ON ot.id = co.observationTypeFk
|
||||||
|
WHERE ot.code = 'substitution'
|
||||||
|
GROUP BY co.clientFk
|
||||||
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
|
|||||||
|
) substitution ON substitution.clientFk = c.id
|
||||||
|
WHERE r.shipment BETWEEN ? AND ? + INTERVAL ? DAY
|
||||||
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
|
|||||||
|
AND r.created >= ?
|
||||||
|
AND r.warehouseFk = ?
|
||||||
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
|
|||||||
|
AND NOT o.confirmed
|
||||||
|
AND r.itemFk = ?
|
||||||
|
AND r.amount
|
||||||
|
ORDER BY hasToIgnore, isBasket
|
||||||
|
`,
|
||||||
|
[
|
||||||
|
filter.where.warehouseFk,
|
||||||
|
itemFk,
|
||||||
|
vDated, vDated,
|
||||||
|
scopeDays,
|
||||||
|
alertLevels,
|
||||||
|
scopeDays,
|
||||||
|
vDated, vDated, vDated,
|
||||||
|
filter.where.warehouseFk,
|
||||||
|
itemFk
|
||||||
|
]);
|
||||||
|
|
||||||
|
const sql = ParameterizedSQL.join([stmt], ';');
|
||||||
|
const result = await conn.executeStmt(sql, myOptions);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,80 @@
|
||||||
|
const {models} = require('vn-loopback/server/server');
|
||||||
|
|
||||||
|
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() => {
|
||||||
|
tx = await models.Ticket.beginTransaction({});
|
||||||
|
options = {transaction: tx};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async() => {
|
||||||
|
if (tx)
|
||||||
|
await tx.rollback();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return data with NO filters', async() => {
|
||||||
|
const filter = {};
|
||||||
|
const result = await models.Ticket.itemLack(ctx, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return data with filter.id', async() => {
|
||||||
|
const filter = {
|
||||||
|
id: 5
|
||||||
|
};
|
||||||
|
const result = await models.Ticket.itemLack(ctx, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return data with filter.longname', async() => {
|
||||||
|
const filter = {
|
||||||
|
longname: 'Ranged weapon pistol 9mm'
|
||||||
|
};
|
||||||
|
const result = await models.Ticket.itemLack(ctx, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return data with filter.color', async() => {
|
||||||
|
const filter = {
|
||||||
|
colour: 'WHT'
|
||||||
|
};
|
||||||
|
const result = await models.Ticket.itemLack(ctx, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return data with filter.origen', async() => {
|
||||||
|
const filter = {
|
||||||
|
originFk: 1
|
||||||
|
};
|
||||||
|
const result = await models.Ticket.itemLack(ctx, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return data with filter.size', async() => {
|
||||||
|
const filter = {
|
||||||
|
size: '15'
|
||||||
|
};
|
||||||
|
const result = await models.Ticket.itemLack(ctx, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return data with filter.lack', async() => {
|
||||||
|
const filter = {
|
||||||
|
lack: '-15'
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await models.Ticket.itemLack(ctx, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,55 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
|
describe('Item Lack Detail', () => {
|
||||||
|
it('should return false if id is null', async() => {
|
||||||
|
const tx = await models.Ticket.beginTransaction({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const itemFk = null;
|
||||||
|
|
||||||
|
const filter = {where: {warehouseFk: 60}};
|
||||||
|
const result = await models.Ticket.itemLackDetail(itemFk, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(0);
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return data if id exists', async() => {
|
||||||
|
const tx = await models.Ticket.beginTransaction({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const itemFk = 1167;
|
||||||
|
const filter = {where: {warehouseFk: 60}};
|
||||||
|
const result = await models.Ticket.itemLackDetail(itemFk, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(0);
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return error is if not exists', async() => {
|
||||||
|
const tx = await models.Ticket.beginTransaction({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const itemFk = 0;
|
||||||
|
const filter = {where: {warehouseFk: 60}};
|
||||||
|
const result = await models.Ticket.itemLackDetail(itemFk, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(0);
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,47 @@
|
||||||
|
const {models} = require('vn-loopback/server/server');
|
||||||
|
|
||||||
|
describe('Split', () => {
|
||||||
|
let options;
|
||||||
|
let tx;
|
||||||
|
const ctx = beforeAll.getCtx();
|
||||||
|
beforeAll.mockLoopBackContext();
|
||||||
|
|
||||||
|
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() => {
|
||||||
|
const data =
|
||||||
|
{ticketFk: 7, sales: [1]};
|
||||||
|
const result = await models.Ticket.split(ctx, data, options);
|
||||||
|
|
||||||
|
expect(data.ticketFk).toEqual(result.ticket);
|
||||||
|
expect('noSplit').toEqual(result.status);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should split tickets with count 2 and error', async() => {
|
||||||
|
const data =
|
||||||
|
{ticketFk: 11, sales: [7]}
|
||||||
|
;
|
||||||
|
const result = await models.Ticket.split(ctx, data, options);
|
||||||
|
|
||||||
|
expect(data.ticketFk).toEqual(result.ticket);
|
||||||
|
expect('error').toEqual(result.status);
|
||||||
|
expect('Can\'t transfer claimed sales').toEqual(result.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should split tickets with count 2 and success', async() => {
|
||||||
|
const data =
|
||||||
|
{ticketFk: 14, sales: [33]};
|
||||||
|
const result = await models.Ticket.split(ctx, data, options);
|
||||||
|
|
||||||
|
expect(data.ticketFk).toEqual(result.ticket);
|
||||||
|
expect('split').toEqual(result.status);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,73 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('split', {
|
||||||
|
description: 'Split ticket with custom date',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'ticket',
|
||||||
|
type: 'Object',
|
||||||
|
required: true,
|
||||||
|
http: {source: 'body'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'date',
|
||||||
|
type: 'date',
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
type: ['Object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/split`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.split = async(ctx, ticket, options) => {
|
||||||
|
const {ticketFk} = ticket;
|
||||||
|
const models = Self.app.models;
|
||||||
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
let result = [];
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
jsegarra marked this conversation as resolved
Outdated
jgallego
commented
quitar comentarios quitar comentarios
jsegarra
commented
Resuelto Resuelto
|
|||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const count = await models.Sale.count({
|
||||||
|
ticketFk
|
||||||
|
}, 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
|
|||||||
|
if (count === 1)
|
||||||
|
return {ticket: ticketFk, status: 'noSplit'};
|
||||||
|
|
||||||
|
const [, [{vNewTicket}]] = await Self.rawSql(`
|
||||||
|
CALL vn.ticket_clone(?, @vNewTicket);
|
||||||
|
SELECT @vNewTicket vNewTicket;`,
|
||||||
|
[ticketFk], myOptions);
|
||||||
|
|
||||||
|
if (vNewTicket === 0) return result;
|
||||||
|
const sales = await models.Sale.find({
|
||||||
|
where: {id: {inq: ticket.sales}}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
const updateIsPicked = sales.map(({sid}) => Self.rawSql(`
|
||||||
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
|
|||||||
|
UPDATE vn.sale SET isPicked = (id = ?) WHERE ticketFk = ?`,
|
||||||
|
[sid, ticketFk], myOptions));
|
||||||
|
|
||||||
|
await Promise.all(updateIsPicked);
|
||||||
|
await Self.transferSales(ctx, ticketFk, vNewTicket, sales, myOptions);
|
||||||
|
|
||||||
|
await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [ticketFk, 'FIXING'], myOptions);
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
return {ticket: ticketFk, newTicket: vNewTicket, status: 'split'};
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
return {ticket: ticketFk, status: 'error', message: e.message};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -43,8 +43,8 @@ module.exports = Self => {
|
||||||
const {code} = await models.State.findById(params.stateFk, {fields: ['code']}, myOptions);
|
const {code} = await models.State.findById(params.stateFk, {fields: ['code']}, myOptions);
|
||||||
params.code = code;
|
params.code = code;
|
||||||
} else {
|
} else {
|
||||||
const {id} = await models.State.findOne({where: {code: params.code}}, myOptions);
|
const state = await models.State.findOne({where: {id: params.code}}, myOptions);
|
||||||
params.stateFk = id;
|
params.stateFk = state.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!params.userFk) {
|
if (!params.userFk) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ module.exports = Self => {
|
||||||
require('../methods/sale/usesMana')(Self);
|
require('../methods/sale/usesMana')(Self);
|
||||||
require('../methods/sale/clone')(Self);
|
require('../methods/sale/clone')(Self);
|
||||||
require('../methods/sale/getFromSectorCollection')(Self);
|
require('../methods/sale/getFromSectorCollection')(Self);
|
||||||
|
require('../methods/sale/replaceItem')(Self);
|
||||||
|
|
||||||
Self.validatesPresenceOf('concept', {
|
Self.validatesPresenceOf('concept', {
|
||||||
message: `Concept cannot be blank`
|
message: `Concept cannot be blank`
|
||||||
|
|
|
@ -26,6 +26,12 @@
|
||||||
},
|
},
|
||||||
"defaultAttenderFk": {
|
"defaultAttenderFk": {
|
||||||
"type": "number"
|
"type": "number"
|
||||||
|
},
|
||||||
|
"lackAlertPrice": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"lackScopeDays": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
|
|
@ -46,5 +46,8 @@ module.exports = function(Self) {
|
||||||
require('../methods/ticket/docuwareDownload')(Self);
|
require('../methods/ticket/docuwareDownload')(Self);
|
||||||
require('../methods/ticket/myLastModified')(Self);
|
require('../methods/ticket/myLastModified')(Self);
|
||||||
require('../methods/ticket/setWeight')(Self);
|
require('../methods/ticket/setWeight')(Self);
|
||||||
|
require('../methods/ticket/itemLack')(Self);
|
||||||
|
require('../methods/ticket/itemLackDetail')(Self);
|
||||||
|
require('../methods/ticket/split')(Self);
|
||||||
require('../methods/ticket/getTicketProblems')(Self);
|
require('../methods/ticket/getTicketProblems')(Self);
|
||||||
};
|
};
|
||||||
|
|
si esto es el id del artículo, lo ponemos en primer lugar y se llama vSelf