corregidos bugs de: ret, vs delivery, efectivo vs link, charsets, price query
This commit is contained in:
@@ -3,6 +3,22 @@ import { getSettings, upsertSettings, getStoreConfig } from "../db/settingsRepo.
|
||||
// Días de la semana para validación
|
||||
const VALID_DAYS = ["lun", "mar", "mie", "jue", "vie", "sab", "dom"];
|
||||
|
||||
/**
|
||||
* Genera schedule por defecto con horarios uniformes
|
||||
*/
|
||||
function createDefaultSchedule() {
|
||||
const defaultDays = ["lun", "mar", "mie", "jue", "vie", "sab"];
|
||||
const delivery = {};
|
||||
const pickup = {};
|
||||
|
||||
for (const day of defaultDays) {
|
||||
delivery[day] = { start: "09:00", end: "18:00" };
|
||||
pickup[day] = { start: "08:00", end: "20:00" };
|
||||
}
|
||||
|
||||
return { delivery, pickup };
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene la configuración actual del tenant
|
||||
*/
|
||||
@@ -25,10 +41,17 @@ export async function handleGetSettings({ tenantId }) {
|
||||
pickup_days: "lun,mar,mie,jue,vie,sab",
|
||||
pickup_hours_start: "08:00",
|
||||
pickup_hours_end: "20:00",
|
||||
schedule: createDefaultSchedule(),
|
||||
is_default: true,
|
||||
};
|
||||
}
|
||||
|
||||
// Si no tiene schedule, generar desde datos legacy
|
||||
let schedule = settings.schedule;
|
||||
if (!schedule || Object.keys(schedule).length === 0) {
|
||||
schedule = buildScheduleFromLegacy(settings);
|
||||
}
|
||||
|
||||
return {
|
||||
...settings,
|
||||
// Formatear horarios TIME a HH:MM
|
||||
@@ -36,10 +59,121 @@ export async function handleGetSettings({ tenantId }) {
|
||||
delivery_hours_end: settings.delivery_hours_end?.slice(0, 5) || "18:00",
|
||||
pickup_hours_start: settings.pickup_hours_start?.slice(0, 5) || "08:00",
|
||||
pickup_hours_end: settings.pickup_hours_end?.slice(0, 5) || "20:00",
|
||||
schedule,
|
||||
is_default: false,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Construye schedule desde datos legacy
|
||||
*/
|
||||
function buildScheduleFromLegacy(settings) {
|
||||
const schedule = { delivery: {}, pickup: {} };
|
||||
|
||||
// Delivery
|
||||
if (settings.delivery_enabled && settings.delivery_days) {
|
||||
const days = settings.delivery_days.split(",").map(d => d.trim());
|
||||
const start = settings.delivery_hours_start?.slice(0, 5) || "09:00";
|
||||
const end = settings.delivery_hours_end?.slice(0, 5) || "18:00";
|
||||
for (const day of days) {
|
||||
if (VALID_DAYS.includes(day)) {
|
||||
schedule.delivery[day] = { start, end };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pickup
|
||||
if (settings.pickup_enabled && settings.pickup_days) {
|
||||
const days = settings.pickup_days.split(",").map(d => d.trim());
|
||||
const start = settings.pickup_hours_start?.slice(0, 5) || "08:00";
|
||||
const end = settings.pickup_hours_end?.slice(0, 5) || "20:00";
|
||||
for (const day of days) {
|
||||
if (VALID_DAYS.includes(day)) {
|
||||
schedule.pickup[day] = { start, end };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return schedule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Valida la estructura del schedule
|
||||
*/
|
||||
function validateSchedule(schedule) {
|
||||
if (!schedule || typeof schedule !== "object") return;
|
||||
|
||||
const timeRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/;
|
||||
|
||||
for (const type of ["delivery", "pickup"]) {
|
||||
const typeSchedule = schedule[type];
|
||||
if (!typeSchedule || typeof typeSchedule !== "object") continue;
|
||||
|
||||
for (const [day, slot] of Object.entries(typeSchedule)) {
|
||||
if (!VALID_DAYS.includes(day)) {
|
||||
throw new Error(`Invalid day in schedule.${type}: ${day}`);
|
||||
}
|
||||
|
||||
if (slot === null) continue; // null = no disponible
|
||||
|
||||
if (typeof slot !== "object" || !slot.start || !slot.end) {
|
||||
throw new Error(`Invalid slot format for ${type}.${day}`);
|
||||
}
|
||||
|
||||
if (!timeRegex.test(slot.start)) {
|
||||
throw new Error(`Invalid start time for ${type}.${day}: ${slot.start}`);
|
||||
}
|
||||
if (!timeRegex.test(slot.end)) {
|
||||
throw new Error(`Invalid end time for ${type}.${day}: ${slot.end}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sincroniza campos legacy desde schedule
|
||||
*/
|
||||
function syncLegacyFromSchedule(settings) {
|
||||
const schedule = settings.schedule;
|
||||
if (!schedule) return;
|
||||
|
||||
// Sincronizar delivery
|
||||
if (schedule.delivery) {
|
||||
const deliveryDays = Object.keys(schedule.delivery).filter(d => schedule.delivery[d] !== null);
|
||||
if (deliveryDays.length > 0) {
|
||||
// Ordenar días
|
||||
deliveryDays.sort((a, b) => VALID_DAYS.indexOf(a) - VALID_DAYS.indexOf(b));
|
||||
settings.delivery_days = deliveryDays.join(",");
|
||||
|
||||
// Usar primer horario como legacy
|
||||
const firstSlot = schedule.delivery[deliveryDays[0]];
|
||||
if (firstSlot) {
|
||||
settings.delivery_hours_start = firstSlot.start;
|
||||
settings.delivery_hours_end = firstSlot.end;
|
||||
}
|
||||
} else {
|
||||
settings.delivery_days = "";
|
||||
}
|
||||
}
|
||||
|
||||
// Sincronizar pickup
|
||||
if (schedule.pickup) {
|
||||
const pickupDays = Object.keys(schedule.pickup).filter(d => schedule.pickup[d] !== null);
|
||||
if (pickupDays.length > 0) {
|
||||
pickupDays.sort((a, b) => VALID_DAYS.indexOf(a) - VALID_DAYS.indexOf(b));
|
||||
settings.pickup_days = pickupDays.join(",");
|
||||
|
||||
const firstSlot = schedule.pickup[pickupDays[0]];
|
||||
if (firstSlot) {
|
||||
settings.pickup_hours_start = firstSlot.start;
|
||||
settings.pickup_hours_end = firstSlot.end;
|
||||
}
|
||||
} else {
|
||||
settings.pickup_days = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Guarda la configuración del tenant
|
||||
*/
|
||||
@@ -52,41 +186,48 @@ export async function handleSaveSettings({ tenantId, settings }) {
|
||||
throw new Error("bot_name is required");
|
||||
}
|
||||
|
||||
// Validar días
|
||||
if (settings.delivery_days) {
|
||||
const days = settings.delivery_days.split(",").map(d => d.trim().toLowerCase());
|
||||
for (const day of days) {
|
||||
if (!VALID_DAYS.includes(day)) {
|
||||
throw new Error(`Invalid delivery day: ${day}`);
|
||||
// Validar schedule si viene
|
||||
if (settings.schedule) {
|
||||
validateSchedule(settings.schedule);
|
||||
// Sincronizar campos legacy desde schedule
|
||||
syncLegacyFromSchedule(settings);
|
||||
} else {
|
||||
// Legacy: validar días individuales
|
||||
if (settings.delivery_days) {
|
||||
const days = settings.delivery_days.split(",").map(d => d.trim().toLowerCase());
|
||||
for (const day of days) {
|
||||
if (!VALID_DAYS.includes(day)) {
|
||||
throw new Error(`Invalid delivery day: ${day}`);
|
||||
}
|
||||
}
|
||||
settings.delivery_days = days.join(",");
|
||||
}
|
||||
settings.delivery_days = days.join(",");
|
||||
}
|
||||
|
||||
if (settings.pickup_days) {
|
||||
const days = settings.pickup_days.split(",").map(d => d.trim().toLowerCase());
|
||||
for (const day of days) {
|
||||
if (!VALID_DAYS.includes(day)) {
|
||||
throw new Error(`Invalid pickup day: ${day}`);
|
||||
if (settings.pickup_days) {
|
||||
const days = settings.pickup_days.split(",").map(d => d.trim().toLowerCase());
|
||||
for (const day of days) {
|
||||
if (!VALID_DAYS.includes(day)) {
|
||||
throw new Error(`Invalid pickup day: ${day}`);
|
||||
}
|
||||
}
|
||||
settings.pickup_days = days.join(",");
|
||||
}
|
||||
settings.pickup_days = days.join(",");
|
||||
}
|
||||
|
||||
// Validar horarios
|
||||
const timeRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/;
|
||||
|
||||
if (settings.delivery_hours_start && !timeRegex.test(settings.delivery_hours_start)) {
|
||||
throw new Error("Invalid delivery_hours_start format (use HH:MM)");
|
||||
}
|
||||
if (settings.delivery_hours_end && !timeRegex.test(settings.delivery_hours_end)) {
|
||||
throw new Error("Invalid delivery_hours_end format (use HH:MM)");
|
||||
}
|
||||
if (settings.pickup_hours_start && !timeRegex.test(settings.pickup_hours_start)) {
|
||||
throw new Error("Invalid pickup_hours_start format (use HH:MM)");
|
||||
}
|
||||
if (settings.pickup_hours_end && !timeRegex.test(settings.pickup_hours_end)) {
|
||||
throw new Error("Invalid pickup_hours_end format (use HH:MM)");
|
||||
// Validar horarios legacy
|
||||
const timeRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/;
|
||||
|
||||
if (settings.delivery_hours_start && !timeRegex.test(settings.delivery_hours_start)) {
|
||||
throw new Error("Invalid delivery_hours_start format (use HH:MM)");
|
||||
}
|
||||
if (settings.delivery_hours_end && !timeRegex.test(settings.delivery_hours_end)) {
|
||||
throw new Error("Invalid delivery_hours_end format (use HH:MM)");
|
||||
}
|
||||
if (settings.pickup_hours_start && !timeRegex.test(settings.pickup_hours_start)) {
|
||||
throw new Error("Invalid pickup_hours_start format (use HH:MM)");
|
||||
}
|
||||
if (settings.pickup_hours_end && !timeRegex.test(settings.pickup_hours_end)) {
|
||||
throw new Error("Invalid pickup_hours_end format (use HH:MM)");
|
||||
}
|
||||
}
|
||||
|
||||
const result = await upsertSettings({ tenantId, settings });
|
||||
|
||||
Reference in New Issue
Block a user