borrado de articulos del carrito

This commit is contained in:
Lucas Tettamanti
2026-01-25 23:43:00 -03:00
parent bd63d92c50
commit debad78781
4 changed files with 448 additions and 50 deletions

View File

@@ -154,6 +154,97 @@ export function addPendingItem(order, pendingItem) {
};
}
/**
* Remueve items del carrito que coincidan con el query
* Usa fuzzy matching para encontrar el producto
*/
export function removeCartItem(order, productQuery) {
if (!order?.cart?.length || !productQuery) return { order, removed: null };
const query = String(productQuery).toLowerCase().trim();
const words = query.split(/\s+/).filter(w => w.length > 2);
// Buscar el item que mejor matchee
let bestIdx = -1;
let bestScore = 0;
for (let i = 0; i < order.cart.length; i++) {
const item = order.cart[i];
const name = String(item.name || "").toLowerCase();
// Score basado en coincidencia de palabras
let score = 0;
for (const word of words) {
if (name.includes(word)) score += 1;
}
// Bonus si el query entero está en el nombre
if (name.includes(query)) score += 2;
if (score > bestScore) {
bestScore = score;
bestIdx = i;
}
}
if (bestIdx >= 0 && bestScore > 0) {
const removed = order.cart[bestIdx];
const newCart = [...order.cart];
newCart.splice(bestIdx, 1);
return {
order: { ...order, cart: newCart },
removed,
};
}
return { order, removed: null };
}
/**
* Actualiza la cantidad de un item en el carrito
*/
export function updateCartItemQuantity(order, productQuery, newQty, newUnit = null) {
if (!order?.cart?.length || !productQuery) return { order, updated: null };
const query = String(productQuery).toLowerCase().trim();
const words = query.split(/\s+/).filter(w => w.length > 2);
// Buscar el item que mejor matchee
let bestIdx = -1;
let bestScore = 0;
for (let i = 0; i < order.cart.length; i++) {
const item = order.cart[i];
const name = String(item.name || "").toLowerCase();
let score = 0;
for (const word of words) {
if (name.includes(word)) score += 1;
}
if (name.includes(query)) score += 2;
if (score > bestScore) {
bestScore = score;
bestIdx = i;
}
}
if (bestIdx >= 0 && bestScore > 0) {
const updated = { ...order.cart[bestIdx] };
const newCart = [...order.cart];
newCart[bestIdx] = {
...updated,
qty: newQty,
unit: newUnit || updated.unit,
};
return {
order: { ...order, cart: newCart },
updated: newCart[bestIdx],
};
}
return { order, updated: null };
}
/**
* Convierte orden vieja (order_basket, pending_items, etc.) a nuevo formato
*/
@@ -217,18 +308,35 @@ export function migrateOldContext(ctx) {
/**
* Formatea el carrito para mostrar al usuario
* Incluye items del carrito + items pendientes (incompletos)
*/
export function formatCartForDisplay(order, locale = "es-AR") {
if (!order?.cart?.length) {
return "Tu carrito está vacío.";
const lines = [];
// Items confirmados en el carrito
for (const item of (order?.cart || [])) {
if (item.qty != null) {
const qtyStr = item.unit === "kg" ? `${item.qty}kg` :
item.unit === "g" ? `${item.qty}g` :
item.unit === "unit" ? `${item.qty}` : `${item.qty}`;
lines.push(`- ${qtyStr} de ${item.name || `Producto #${item.woo_id}`}`);
} else {
lines.push(`- ${item.name || `Producto #${item.woo_id}`} (falta cantidad)`);
}
}
const lines = order.cart.map(item => {
const qtyStr = item.unit === "kg" ? `${item.qty}kg` :
item.unit === "g" ? `${item.qty}g` :
`${item.qty}`;
return `- ${qtyStr} de ${item.name || `Producto #${item.woo_id}`}`;
});
// Items pendientes (mostrar como provisionales)
for (const p of (order?.pending || [])) {
if (p.status === PendingStatus.NEEDS_TYPE) {
lines.push(`- "${p.query}" (pendiente de elegir)`);
} else if (p.status === PendingStatus.NEEDS_QUANTITY && p.selected_name) {
lines.push(`- ${p.selected_name} (falta cantidad)`);
}
}
if (lines.length === 0) {
return "Tu carrito está vacío.";
}
return "Tenés anotado:\n" + lines.join("\n");
}
@@ -236,7 +344,7 @@ export function formatCartForDisplay(order, locale = "es-AR") {
/**
* Formatea opciones de un pending item para mostrar al usuario
*/
export function formatOptionsForDisplay(pendingItem, pageSize = 9) {
export function formatOptionsForDisplay(pendingItem, pageSize = 12) {
if (!pendingItem?.candidates?.length) {
return { question: `No encontré "${pendingItem?.query}". ¿Podrías ser más específico?`, options: [] };
}