corregidos bugs de: ret, vs delivery, efectivo vs link, charsets, price query
This commit is contained in:
@@ -333,13 +333,103 @@ async function handleRecommendIntent({ tenantId, text, nlu, currentOrder, audit
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detecta si el usuario pregunta por el total del carrito actual
|
||||
*/
|
||||
function isCartTotalQuery(nlu) {
|
||||
const query = nlu?.entities?.product_query || "";
|
||||
const q = query.trim().toLowerCase();
|
||||
|
||||
// Patrones que indican consulta sobre el carrito actual
|
||||
const cartKeywords = [
|
||||
"todo", "el total", "total", "mi pedido", "el pedido", "precio total",
|
||||
"lo que tengo", "lo que llevo", "lo que estoy pidiendo", "lo que pedí",
|
||||
"en el carrito", "del carrito", "mi carrito", "el carrito",
|
||||
"lo que voy", "hasta ahora", "hasta el momento",
|
||||
];
|
||||
|
||||
// Si la query contiene alguna de estas frases, es consulta del carrito
|
||||
if (cartKeywords.some(kw => q.includes(kw))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Patrones regex adicionales
|
||||
const patterns = [
|
||||
/^cu[aá]nto (es|sale|cuesta|est[aá])/i,
|
||||
/^precio/i,
|
||||
];
|
||||
return patterns.some(p => p.test(q));
|
||||
}
|
||||
|
||||
/**
|
||||
* Maneja price_query
|
||||
*/
|
||||
async function handlePriceQuery({ tenantId, nlu, currentOrder, audit }) {
|
||||
// Si pregunta por el total del carrito
|
||||
if (isCartTotalQuery(nlu) || !nlu?.entities?.product_query) {
|
||||
const cartItems = currentOrder?.cart || [];
|
||||
if (cartItems.length === 0) {
|
||||
return {
|
||||
plan: {
|
||||
reply: "Tu carrito está vacío. ¿Qué te gustaría agregar?",
|
||||
next_state: ConversationState.CART,
|
||||
intent: "price_query",
|
||||
missing_fields: [],
|
||||
order_action: "none",
|
||||
},
|
||||
decision: { actions: [], order: currentOrder, audit },
|
||||
};
|
||||
}
|
||||
|
||||
// Calcular y mostrar el total
|
||||
let total = 0;
|
||||
const lines = cartItems.map(item => {
|
||||
const itemTotal = (item.price || 0) * (item.qty || 0);
|
||||
total += itemTotal;
|
||||
const unitStr = item.unit === "unit" ? "" : " kg";
|
||||
return `• ${item.name}: ${item.qty}${unitStr} x $${item.price} = $${itemTotal.toLocaleString("es-AR")}`;
|
||||
});
|
||||
|
||||
const reply = `Tu pedido actual:\n\n${lines.join("\n")}\n\n💰 Total: $${total.toLocaleString("es-AR")}\n\n¿Algo más?`;
|
||||
return {
|
||||
plan: {
|
||||
reply,
|
||||
next_state: ConversationState.CART,
|
||||
intent: "price_query",
|
||||
missing_fields: [],
|
||||
order_action: "none",
|
||||
},
|
||||
decision: { actions: [], order: currentOrder, audit },
|
||||
};
|
||||
}
|
||||
|
||||
const productQueries = extractProductQueries(nlu);
|
||||
|
||||
if (productQueries.length === 0) {
|
||||
// Si no hay query pero hay carrito, mostrar el carrito
|
||||
const cartItems = currentOrder?.cart || [];
|
||||
if (cartItems.length > 0) {
|
||||
let total = 0;
|
||||
const lines = cartItems.map(item => {
|
||||
const itemTotal = (item.price || 0) * (item.qty || 0);
|
||||
total += itemTotal;
|
||||
const unitStr = item.unit === "unit" ? "" : " kg";
|
||||
return `• ${item.name}: ${item.qty}${unitStr} x $${item.price} = $${itemTotal.toLocaleString("es-AR")}`;
|
||||
});
|
||||
|
||||
const reply = `Tu pedido actual:\n\n${lines.join("\n")}\n\n💰 Total: $${total.toLocaleString("es-AR")}\n\n¿Querés saber el precio de algún producto específico?`;
|
||||
return {
|
||||
plan: {
|
||||
reply,
|
||||
next_state: ConversationState.CART,
|
||||
intent: "price_query",
|
||||
missing_fields: [],
|
||||
order_action: "none",
|
||||
},
|
||||
decision: { actions: [], order: currentOrder, audit },
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
plan: {
|
||||
reply: "¿De qué producto querés saber el precio?",
|
||||
|
||||
@@ -354,7 +354,7 @@ function processStrongMatch({ updatedOrder, pendingItem, best, audit }) {
|
||||
const displayUnit = normalizeUnit(best.sell_unit) || inferDefaultUnit({ name: best.name, categories: best.categories });
|
||||
const hasQty = pendingItem.requested_qty != null && pendingItem.requested_qty > 0;
|
||||
const needsQuantity = displayUnit !== "unit" && !hasQty;
|
||||
|
||||
|
||||
const autoSelectedOrder = updatePendingItem(updatedOrder, pendingItem.id, {
|
||||
selected_woo_id: best.woo_product_id,
|
||||
selected_name: best.name,
|
||||
|
||||
@@ -25,25 +25,17 @@ function isDeliveryInfoQuestion(text) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatea los días de entrega para mostrar
|
||||
* Detecta si el usuario pregunta por horarios de retiro
|
||||
*/
|
||||
function formatDeliveryDays(daysStr) {
|
||||
if (!daysStr) return null;
|
||||
|
||||
const dayMap = {
|
||||
"lun": "Lunes", "mar": "Martes", "mie": "Miércoles", "mié": "Miércoles",
|
||||
"jue": "Jueves", "vie": "Viernes", "sab": "Sábado", "sáb": "Sábado", "dom": "Domingo",
|
||||
};
|
||||
|
||||
const days = daysStr.split(",").map(d => d.trim().toLowerCase());
|
||||
const formatted = days.map(d => dayMap[d] || d).filter(Boolean);
|
||||
|
||||
if (formatted.length === 0) return null;
|
||||
if (formatted.length === 1) return formatted[0];
|
||||
|
||||
// "Lunes, Martes, Miércoles y Jueves"
|
||||
const last = formatted.pop();
|
||||
return `${formatted.join(", ")} y ${last}`;
|
||||
function isPickupInfoQuestion(text) {
|
||||
const t = String(text || "").toLowerCase();
|
||||
const patterns = [
|
||||
/horario.*(retir|buscar|pasar)/i,
|
||||
/cu[aá]ndo.*(retir|buscar|pasar)/i,
|
||||
/a\s+qu[eé]\s+hora.*(retir|buscar)/i,
|
||||
/d[ií]as?.*(retir|buscar)/i,
|
||||
];
|
||||
return patterns.some(p => p.test(t));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,19 +63,17 @@ export async function handleWaitingState({ tenantId, text, nlu, order, audit, st
|
||||
|
||||
// Preguntas sobre horarios/días de entrega
|
||||
if (isDeliveryInfoQuestion(text)) {
|
||||
const deliveryDays = formatDeliveryDays(storeConfig.delivery_days);
|
||||
const startHour = storeConfig.delivery_hours_start?.slice(0, 5);
|
||||
const endHour = storeConfig.delivery_hours_end?.slice(0, 5);
|
||||
// Usar deliveryHours que ya viene formateado desde getStoreConfig
|
||||
// (agrupa días con mismos horarios: "Lunes a Viernes de 9:00 a 14:00, Sábado de 9:00 a 13:00")
|
||||
const deliveryHours = storeConfig.deliveryHours;
|
||||
|
||||
let reply = "";
|
||||
if (deliveryDays) {
|
||||
reply = `Hacemos entregas los días ${deliveryDays}`;
|
||||
if (startHour && endHour) {
|
||||
reply += ` de ${startHour} a ${endHour}`;
|
||||
}
|
||||
reply += ". ";
|
||||
if (deliveryHours && deliveryHours !== "No disponible") {
|
||||
reply = `Hacemos entregas: ${deliveryHours}. `;
|
||||
} else if (storeConfig.deliveryEnabled === false) {
|
||||
reply = "Por el momento no ofrecemos delivery. ";
|
||||
} else {
|
||||
reply = "Todavía no tengo configurado los días de entrega. ";
|
||||
reply = "Todavía no tengo configurados los horarios de entrega. ";
|
||||
}
|
||||
|
||||
reply += "Tu pedido ya está en proceso, avisame cualquier cosa.";
|
||||
@@ -100,6 +90,33 @@ export async function handleWaitingState({ tenantId, text, nlu, order, audit, st
|
||||
};
|
||||
}
|
||||
|
||||
// Preguntas sobre horarios de retiro
|
||||
if (isPickupInfoQuestion(text)) {
|
||||
const pickupHours = storeConfig.pickupHours;
|
||||
|
||||
let reply = "";
|
||||
if (pickupHours && pickupHours !== "No disponible") {
|
||||
reply = `Podés retirar: ${pickupHours}. `;
|
||||
} else if (storeConfig.pickupEnabled === false) {
|
||||
reply = "Por el momento no ofrecemos retiro en tienda. ";
|
||||
} else {
|
||||
reply = "Todavía no tengo configurados los horarios de retiro. ";
|
||||
}
|
||||
|
||||
reply += "Tu pedido ya está en proceso, avisame cualquier cosa.";
|
||||
|
||||
return {
|
||||
plan: {
|
||||
reply,
|
||||
next_state: ConversationState.WAITING_WEBHOOKS,
|
||||
intent: "pickup_info",
|
||||
missing_fields: [],
|
||||
order_action: "none",
|
||||
},
|
||||
decision: { actions: [], order: currentOrder, audit },
|
||||
};
|
||||
}
|
||||
|
||||
// Default
|
||||
const reply = currentOrder.payment_type === "link"
|
||||
? "Tu pedido está en proceso. Avisame si necesitás algo más o esperá la confirmación de pago."
|
||||
|
||||
Reference in New Issue
Block a user