feat: labores diarias fase 2; el bot repite lo que responde el ERP
Quinto flujo de carga: fecha, labor, lote, trabajadores y cantidad. El catalogo de novedades lo filtra el ERP por fase, asi que el bot no decide cual corresponde. El trabajador vinculado se pre-llena y el supervisor elige. Ademas, collect_and_post descartaba la respuesta del POST y decia "listo" aunque el ERP hubiera rechazado parte. Ahora repite lo que contesta: cuantos entraron, quien ya tenia jornal, que quedo afuera. Y from_phone respeta el tipo del campo: multi_select espera un arreglo aunque el perfil traiga un solo tercero. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
356c157811
commit
8399a86972
+23
-4
@@ -1072,9 +1072,11 @@ class NormalBot
|
||||
if (empty($perfil['es_supervisor'])) {
|
||||
foreach ($fields as $f) {
|
||||
$origen = $f['from_phone'] ?? '';
|
||||
if ($origen !== '' && !empty($perfil[$origen])) {
|
||||
$collected[$f['key']] = (string)$perfil[$origen];
|
||||
}
|
||||
if ($origen === '' || empty($perfil[$origen])) continue;
|
||||
// multi_select espera un arreglo aunque el perfil traiga uno solo
|
||||
$collected[$f['key']] = ($f['type'] ?? '') === 'multi_select'
|
||||
? [(string)$perfil[$origen]]
|
||||
: (string)$perfil[$origen];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1600,7 +1602,24 @@ class NormalBot
|
||||
return self::sendText('⚠️ Error al guardar los datos. Intenta de nuevo.' . $nav, $context['from'], $company);
|
||||
}
|
||||
|
||||
return self::sendText($cap['success_text'] . $nav, $context['from'], $company);
|
||||
// El ERP suele responder algo que el usuario necesita saber: cuántos
|
||||
// lotes entraron, quién ya tenía jornal, qué quedó afuera. Sin esto el
|
||||
// bot decía "listo" sobre registros que no se guardaron.
|
||||
$texto = $cap['success_text'];
|
||||
$resp = json_decode((string)$response, true);
|
||||
if (is_array($resp)) {
|
||||
$detalle = trim((string)($resp['mensaje'] ?? ''));
|
||||
if ($detalle !== '' && ($resp['status'] ?? '1') !== '1') {
|
||||
$texto = '⚠️ ' . $detalle;
|
||||
} elseif ($detalle !== '') {
|
||||
$texto .= "\n" . $detalle;
|
||||
}
|
||||
if (!empty($resp['rechazados'])) {
|
||||
$texto .= "\n\n_" . count($resp['rechazados']) . ' sin procesar_';
|
||||
}
|
||||
}
|
||||
|
||||
return self::sendText($texto . $nav, $context['from'], $company);
|
||||
}
|
||||
|
||||
// ── Submit form (end of multi-step collection) ───────────────────────────
|
||||
|
||||
@@ -250,6 +250,7 @@ $configJson = [
|
||||
['id' => 'registrar_pluviometria','modulo' => 'pluviometria', 'title' => '🌧️ Pluviometría', 'description' => 'Milímetros de lluvia por finca'],
|
||||
['id' => 'registrar_ciclo', 'modulo' => 'ciclos', 'title' => '🔄 Ciclos', 'description' => 'Abrir o cerrar lotes'],
|
||||
['id' => 'registrar_mantenimiento','modulo' => 'mantenimiento', 'title' => '🔧 Mantenimiento', 'description' => 'Avance sobre lotes pendientes'],
|
||||
['id' => 'registrar_labor', 'modulo' => 'labores', 'title' => '💪 Labor diaria', 'description' => 'Tractorista, transporte, horas extra'],
|
||||
],
|
||||
],
|
||||
],
|
||||
@@ -592,6 +593,65 @@ $configJson = [
|
||||
],
|
||||
],
|
||||
|
||||
// Labores diarias sin validaciones: tractorista, transporte, horas
|
||||
// extra. El ERP filtra el catalogo de novedades, el bot no decide cual
|
||||
// corresponde. A quien ya tiene jornal ese dia se le registra con
|
||||
// jornal 0 y el ERP lo avisa en la respuesta.
|
||||
'registrar_labor' => [
|
||||
'type' => 'collect_and_post',
|
||||
'endpoint_key' => 'labores_up',
|
||||
'header' => '💪 Labor diaria',
|
||||
'confirm' => true,
|
||||
'success_text' => '✅ Enviado a Palmas360.',
|
||||
'back' => 'enviar_informacion',
|
||||
'nlu_description' => 'Registrar una labor diaria: tractorista, transporte, horas extra, labores varias',
|
||||
'fields' => [
|
||||
[
|
||||
'key' => 'fecha',
|
||||
'label' => 'Fecha',
|
||||
'type' => 'date_quick',
|
||||
'prompt' => '📅 ¿De qué fecha es la labor?',
|
||||
'other_validate' => 'date',
|
||||
'other_prompt' => 'Escribe la fecha (YYYY-MM-DD):',
|
||||
],
|
||||
[
|
||||
'key' => 'novedad_id',
|
||||
'label' => 'Labor',
|
||||
'type' => 'select',
|
||||
'prompt' => '¿Qué labor se hizo?',
|
||||
'source_endpoint_key' => 'novedades_labor_dn',
|
||||
'value_field' => 'id',
|
||||
'label_field' => 'nombre',
|
||||
],
|
||||
[
|
||||
'key' => 'lote_id',
|
||||
'label' => 'Lote',
|
||||
'type' => 'select',
|
||||
'prompt' => '¿En qué lote?',
|
||||
'source_endpoint_key' => 'lotes_finca_dn',
|
||||
'value_field' => 'id',
|
||||
'label_field' => 'label',
|
||||
],
|
||||
[
|
||||
'key' => 'empleados',
|
||||
'label' => 'Trabajadores',
|
||||
'type' => 'multi_select',
|
||||
'prompt' => '¿Quiénes la hicieron? (puedes marcar varios)',
|
||||
'source_endpoint_key' => 'empleados_labor_dn',
|
||||
'value_field' => 'id',
|
||||
'label_field' => 'nombre',
|
||||
// El trabajador vinculado se pre-llena; el supervisor elige
|
||||
'from_phone' => 'tercero_id',
|
||||
],
|
||||
[
|
||||
'key' => 'cantidad',
|
||||
'label' => 'Cantidad',
|
||||
'type' => 'text',
|
||||
'prompt' => '¿Qué cantidad? (jornales, horas o unidades según la labor)',
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
// Upload
|
||||
'enviar_informacion' => ['type' => 'menu', 'menu' => 'submenu_subir_ciclos', 'nlu_skip' => true, 'back' => 'show_main_menu'],
|
||||
|
||||
@@ -625,6 +685,7 @@ $configJson = [
|
||||
['id' => 'registrar_pluviometria','modulo' => 'pluviometria', 'title' => '🌧️ Pluviometría', 'description' => 'Milímetros de lluvia por finca'],
|
||||
['id' => 'registrar_ciclo', 'modulo' => 'ciclos', 'title' => '🔄 Ciclos', 'description' => 'Abrir o cerrar lotes'],
|
||||
['id' => 'registrar_mantenimiento','modulo' => 'mantenimiento', 'title' => '🔧 Mantenimiento', 'description' => 'Avance sobre lotes pendientes'],
|
||||
['id' => 'registrar_labor', 'modulo' => 'labores', 'title' => '💪 Labor diaria', 'description' => 'Tractorista, transporte, horas extra'],
|
||||
],
|
||||
],
|
||||
],
|
||||
@@ -742,6 +803,11 @@ $endpoints = [
|
||||
['key' => 'lotes_cierre_todos_dn', 'dir' => 'download', 'url' => $BASE . '?peticion=lotes_abiertos_dn&ciclo={ciclo}&finca_id={finca_id}&todos=1'],
|
||||
['key' => 'ciclos_up', 'dir' => 'upload', 'url' => $BASE . '?peticion=ciclos_{ciclo}_up'],
|
||||
// Mantenimiento: lotes con cantidad pendiente de asignar, no apertura/cierre
|
||||
// Labores diarias — fase 2: las que no arrastran inventario ni autorizacion
|
||||
['key' => 'novedades_labor_dn', 'dir' => 'download', 'url' => $BASE . '?peticion=novedades_labor_dn&fase=2'],
|
||||
['key' => 'lotes_finca_dn', 'dir' => 'download', 'url' => $BASE . '?peticion=lotes_x_finca&finca_id={finca_id}'],
|
||||
['key' => 'empleados_labor_dn', 'dir' => 'download', 'url' => $BASE . '?peticion=empleados&estado=1&items=200'],
|
||||
['key' => 'labores_up', 'dir' => 'upload', 'url' => $BASE . '?peticion=labores_up'],
|
||||
['key' => 'lotes_mantenimiento_dn', 'dir' => 'download', 'url' => $BASE . '?peticion=lotes_mantenimiento_dn&grupo={grupo_id}&finca_id={finca_id}'],
|
||||
['key' => 'lotes_mantenimiento_todos_dn', 'dir' => 'download', 'url' => $BASE . '?peticion=lotes_mantenimiento_dn&grupo={grupo_id}&finca_id={finca_id}&todos=1'],
|
||||
// Todos los lotes (PDF) por ciclo
|
||||
|
||||
@@ -562,6 +562,24 @@ $cic = array_column($flows['registrar_ciclo']['fields'], null, 'key');
|
||||
check('mantenimiento no está entre los ciclos',
|
||||
in_array('mantenimiento', array_column($cic['ciclo']['options'], 'id'), true), false);
|
||||
|
||||
echo "\nLabores diarias (POST)\n";
|
||||
|
||||
$lab = $flows['registrar_labor'] ?? [];
|
||||
$lf = array_column($lab['fields'] ?? [], null, 'key');
|
||||
|
||||
check('pide fecha, labor, lote, trabajadores y cantidad',
|
||||
array_keys($lf), ['fecha', 'novedad_id', 'lote_id', 'empleados', 'cantidad']);
|
||||
check('el catálogo lo filtra el ERP por fase',
|
||||
$lf['novedad_id']['source_endpoint_key'] ?? null, 'novedades_labor_dn');
|
||||
check('los trabajadores se eligen de a varios',
|
||||
$lf['empleados']['type'] ?? null, 'multi_select');
|
||||
check('y el vinculado se pre-llena',
|
||||
$lf['empleados']['from_phone'] ?? null, 'tercero_id');
|
||||
check('postea a labores_up', $lab['endpoint_key'] ?? null, 'labores_up');
|
||||
foreach (['novedades_labor_dn', 'lotes_finca_dn', 'empleados_labor_dn', 'labores_up'] as $k) {
|
||||
check("endpoint {$k} registrado", isset($eps[$k]), true);
|
||||
}
|
||||
|
||||
echo "\nAlcance de fincas por número\n";
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user