feat: flujo de registro de pluviometria (Fase 1, carga de datos)
Segundo flujo de POST: fecha una sola vez y luego los milimetros de cada finca.
collect_for_each gana tres piezas que este flujo necesitaba:
- ask_date pregunta la fecha antes del bucle (Hoy/Ayer/Anteayer/Otra), en vez
de repetirla por item o asumir hoy.
- exclude_values descarta el "Todas las fincas" (id 0) que el catalogo antepone
para los informes y que aca no es una finca real.
- El payload pasa de un array plano a {fecha, fincas:[{id,label,valor}]}, que es
lo que BotEntradaProcesador::pluviosidad() espera; ademas manda telefono y
nombre, que el controller usa para la trazabilidad en bot_entrada.
Nota: el procesador ACTUALIZA la fila de pluviosidad del dia y falla si no
existe. Queda pendiente confirmar con Palmas360 quien las crea.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
0e72aa3d5a
commit
76ee42b96e
+75
-4
@@ -593,6 +593,14 @@ class NormalBot
|
||||
$meta = ConversationContext::getMetadata($ctxId);
|
||||
$items = self::fetchDynamicList($flow['source_endpoint_key'] ?? '', $company, $meta);
|
||||
|
||||
// exclude_values descarta opciones que no son ítems reales, como el
|
||||
// "🌐 Todas las fincas" (id 0) que el catálogo antepone para los informes.
|
||||
$excluir = array_map('strval', $flow['exclude_values'] ?? []);
|
||||
if ($excluir && is_array($items)) {
|
||||
$vf = $flow['value_field'] ?? 'id';
|
||||
$items = array_values(array_filter($items, fn($i) => !in_array((string)($i[$vf] ?? ''), $excluir, true)));
|
||||
}
|
||||
|
||||
if (empty($items)) {
|
||||
ConversationContext::reset($ctxId);
|
||||
return self::sendText(
|
||||
@@ -674,18 +682,70 @@ class NormalBot
|
||||
'header' => $flow['header'] ?? '📋 Ingreso de datos',
|
||||
'endpoint_key'=> $flow['endpoint_key'] ?? '',
|
||||
'success_text'=> $flow['success_text'] ?? '✅ Datos registrados correctamente.',
|
||||
'items_key' => $flow['items_key'] ?? 'fincas',
|
||||
'ask_date' => (bool)($flow['ask_date'] ?? false),
|
||||
'fecha' => null,
|
||||
];
|
||||
ConversationContext::updateMetadata($ctxId, $meta);
|
||||
|
||||
// El dato se registra contra una fecha; se pregunta antes del bucle
|
||||
// para no repetirla en cada ítem.
|
||||
if ($meta['__foreach']['ask_date']) {
|
||||
return self::foreachAskDate($flow, $context['from'], $company);
|
||||
}
|
||||
|
||||
return self::foreachAskNext($meta['__foreach'], $context['from'], $company);
|
||||
}
|
||||
|
||||
/** Hoy / Ayer / Anteayer / Otra — mismo criterio que el campo date_quick. */
|
||||
private static function foreachAskDate(array $flow, string $to, array $company): ?array
|
||||
{
|
||||
$hoy = date('Y-m-d');
|
||||
return self::enqueueInteractive($to, [
|
||||
'type' => 'list',
|
||||
'header' => ['type' => 'text', 'text' => mb_substr($flow['header'] ?? '📋 Registro', 0, 60)],
|
||||
'body' => ['text' => $flow['date_question'] ?? '📅 ¿De qué fecha es el registro?'],
|
||||
'footer' => ['text' => ''],
|
||||
'action' => ['button' => 'Ver fechas', 'sections' => [[
|
||||
'title' => 'Fecha',
|
||||
'rows' => [
|
||||
['id' => $hoy, 'title' => '📅 Hoy', 'description' => $hoy],
|
||||
['id' => date('Y-m-d', strtotime('-1 day')), 'title' => '📅 Ayer', 'description' => date('Y-m-d', strtotime('-1 day'))],
|
||||
['id' => date('Y-m-d', strtotime('-2 days')), 'title' => '📅 Anteayer', 'description' => date('Y-m-d', strtotime('-2 days'))],
|
||||
['id' => '__fe_other', 'title' => '✏️ Otra fecha', 'description' => 'Escribe la fecha'],
|
||||
],
|
||||
]]],
|
||||
], $company);
|
||||
}
|
||||
|
||||
private static function handleForeachInput(array $meta, string $input, array $context, array $company, int $ctxId, array $flows): ?array
|
||||
{
|
||||
$fe = $meta['__foreach'];
|
||||
$items = $fe['items'];
|
||||
$idx = (int)$fe['index'];
|
||||
|
||||
// ── Fecha del registro, antes de recorrer los ítems ──────────────────
|
||||
if (!empty($fe['ask_date']) && ($fe['fecha'] ?? null) === null) {
|
||||
$v = trim($input);
|
||||
|
||||
if ($v === '__fe_other') {
|
||||
$fe['awaiting_date'] = true;
|
||||
$meta['__foreach'] = $fe;
|
||||
ConversationContext::updateMetadata($ctxId, $meta);
|
||||
return self::sendText('✏️ Escribe la fecha (YYYY-MM-DD, ej: ' . date('Y-m-d') . '):', $context['from'], $company);
|
||||
}
|
||||
|
||||
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $v) || !strtotime($v)) {
|
||||
return self::sendText('⚠️ Formato inválido. Escribe la fecha como YYYY-MM-DD (ej: ' . date('Y-m-d') . '):', $context['from'], $company);
|
||||
}
|
||||
|
||||
$fe['fecha'] = $v;
|
||||
unset($fe['awaiting_date']);
|
||||
$meta['__foreach'] = $fe;
|
||||
ConversationContext::updateMetadata($ctxId, $meta);
|
||||
return self::foreachAskNext($fe, $context['from'], $company);
|
||||
}
|
||||
|
||||
// Validate: must be a number
|
||||
if (!is_numeric(str_replace(',', '.', $input))) {
|
||||
$item = $items[$idx];
|
||||
@@ -712,7 +772,9 @@ class NormalBot
|
||||
}
|
||||
|
||||
// All collected — show summary and confirm/cancel buttons
|
||||
$summary = "*📊 Resumen — {$fe['header']}*\n\n";
|
||||
$summary = "*📊 Resumen — {$fe['header']}*\n";
|
||||
if (!empty($fe['fecha'])) $summary .= "📅 {$fe['fecha']}\n";
|
||||
$summary .= "\n";
|
||||
foreach ($fe['collected'] as $row) {
|
||||
$summary .= "• {$row['label']}: *{$row['valor']}*\n";
|
||||
}
|
||||
@@ -748,11 +810,20 @@ class NormalBot
|
||||
$endpointKey = $fe['endpoint_key'] ?? '';
|
||||
$nav = "\n\nEscribe *menú* para volver al inicio, *atrás* para subir un nivel o *salir* para terminar.";
|
||||
|
||||
// Build POST body: array of {id, valor} objects
|
||||
$body = [];
|
||||
// El ERP espera {fecha, <items_key>: [{id, label, valor}]}; telefono y
|
||||
// nombre los lee el controller para dejar trazabilidad en bot_entrada.
|
||||
// (string) explícito: PHP convierte las claves numéricas del array en int
|
||||
// y el JSON saldría con tipos distintos según el id de la finca.
|
||||
$lecturas = [];
|
||||
foreach ($fe['collected'] as $id => $row) {
|
||||
$body[] = ['id' => $id, 'label' => $row['label'], 'valor' => $row['valor']];
|
||||
$lecturas[] = ['id' => (string)$id, 'label' => $row['label'], 'valor' => $row['valor']];
|
||||
}
|
||||
$body = [
|
||||
'fecha' => $fe['fecha'] ?? date('Y-m-d'),
|
||||
'telefono' => $context['from'],
|
||||
'nombre' => $context['name'] ?? '',
|
||||
($fe['items_key'] ?? 'fincas') => $lecturas,
|
||||
];
|
||||
|
||||
unset($meta['__foreach']);
|
||||
ConversationContext::updateMetadata($ctxId, $meta);
|
||||
|
||||
Reference in New Issue
Block a user