[ 'menu' => 'show_main_menu', 'informes' => 'descargar_informes', 'info' => 'recibir_info', 'inicio' => 'show_main_menu', 'volver' => 'show_main_menu', ], 'menus' => [ 'show_main_menu' => [ 'type' => 'list', 'header' => 'Menú Principal', 'body' => 'Selecciona una opción:', 'footer' => 'Palmas360', 'button' => 'Ver opciones', 'sections' => [ [ 'title' => 'Opciones', 'rows' => [ ['id' => 'recibir_info', 'title' => 'Recibir Información', 'description' => 'Obtén información útil'], ['id' => 'descargar_informes', 'title' => 'Descargar Informes', 'description' => 'Accede a tus informes'], ['id' => 'menu_mixto', 'title' => 'Menú Mixto', 'description' => 'Combina ambas opciones'], ], ], ], ], 'submenu_informes' => [ 'type' => 'list', 'header' => 'Informes', 'body' => 'Selecciona el tipo de informe:', 'footer' => 'Palmas360', 'button' => 'Ver informes', 'sections' => [ [ 'title' => 'Tipo de Informe', 'rows' => [ ['id' => 'submenu_ciclos', 'title' => 'Ciclos', 'description' => 'Informes de ciclos'], ['id' => 'submenu_produccion', 'title' => 'Producción', 'description' => 'Informes de producción'], ['id' => 'submenu_mantenimiento_fecha', 'title' => 'Ciclos Mtto. Fecha', 'description' => 'Ciclos de mantenimiento a la fecha'], ], ], ], ], 'submenu_ciclos' => [ 'type' => 'list', 'header' => 'Ciclos', 'body' => 'Selecciona tipo de ciclo:', 'footer' => 'Palmas360', 'button' => 'Ver ciclos', 'sections' => [ [ 'title' => 'Ciclos', 'rows' => [ ['id' => 'submenu_ciclos_cosecha', 'title' => 'Ciclos Cosecha', 'description' => 'Ciclos de cosecha'], ['id' => 'submenu_ciclos_sanidad', 'title' => 'Ciclos Sanidad', 'description' => 'Ciclos de sanidad'], ['id' => 'submenu_ciclo_cosecha', 'title' => 'Ciclo de Cosecha','description' => 'Día o histórico de cosecha'], ], ], ], ], 'submenu_ciclo_cosecha' => [ 'type' => 'button', 'body' => 'Selecciona una opción:', 'buttons' => [ ['id' => 'ciclo_cosecha_dia', 'title' => 'Día Ciclo Cosecha'], ['id' => 'ciclo_cosecha_historico', 'title' => 'Histórico 30 Días'], ], ], 'menu_mixto' => [ 'type' => 'button', 'body' => '¿Qué deseas hacer?', 'buttons' => [ ['id' => 'recibir_info', 'title' => 'Recibir Información'], ['id' => 'descargar_informes', 'title' => 'Descargar Informes'], ], ], ], 'flows' => [ 'show_main_menu' => ['type' => 'menu', 'menu' => 'show_menu_cat2'], 'recibir_info' => ['type' => 'function', 'function' => 'forward_to_ai'], 'descargar_informes' => ['type' => 'menu', 'menu' => 'submenu_informes'], 'menu_mixto' => ['type' => 'menu', 'menu' => 'menu_mixto'], 'submenu_ciclos' => ['type' => 'menu', 'menu' => 'submenu_ciclos'], 'submenu_produccion' => ['type' => 'function', 'function' => 'api_report', 'params' => ['endpoint_key' => 'produccion_dn', 'filename' => 'reporte_produccion.xlsx', 'caption' => 'Reporte de producción']], 'submenu_mantenimiento_fecha' => ['type' => 'function', 'function' => 'api_report', 'params' => ['endpoint_key' => 'mantenimiento_dn', 'filename' => 'reporte_mantenimiento.xlsx', 'caption' => 'Ciclos de mantenimiento a la fecha']], 'submenu_ciclos_cosecha' => ['type' => 'function', 'function' => 'api_report', 'params' => ['endpoint_key' => 'cosecha_dn', 'filename' => 'reporte_ciclos_cosecha.xlsx', 'caption' => 'Ciclos de cosecha']], 'submenu_ciclos_sanidad' => ['type' => 'function', 'function' => 'api_report', 'params' => ['endpoint_key' => 'sanidad_dn', 'filename' => 'reporte_ciclos_sanidad.xlsx', 'caption' => 'Ciclos de sanidad']], 'submenu_ciclo_cosecha' => ['type' => 'menu', 'menu' => 'submenu_ciclo_cosecha'], 'ciclo_cosecha_dia' => ['type' => 'function', 'function' => 'api_report', 'params' => ['endpoint_key' => 'cosecha_dn', 'filename' => 'ciclo_cosecha_hoy.xlsx', 'caption' => 'Ciclo de cosecha del día de hoy', 'date_mode' => 'today']], 'ciclo_cosecha_historico' => ['type' => 'function', 'function' => 'api_report', 'params' => ['endpoint_key' => 'cosecha_dn', 'filename' => 'ciclo_cosecha_30dias.xlsx', 'caption' => 'Histórico ciclos de cosecha últimos 30 días', 'date_mode' => 'last_30']], ], 'per_type' => [ '3' => [ 'greeting_flow' => 'show_main_menu', 'fallback_flow' => 'show_main_menu', 'greeting' => null, 'fallback' => null, ], '1' => [ 'greeting_flow' => 'show_menu_cat1', 'fallback_flow' => 'show_menu_cat1', 'greeting' => null, 'fallback' => null, 'commands' => [ 'menu' => 'show_menu_cat1', ], 'menus' => [ 'show_menu_cat1' => [ 'type' => 'list', 'header' => 'Bienvenido', 'body' => '¿Qué deseas hacer?', 'footer' => 'Palmas360', 'button' => 'Ver opciones', 'sections' => [ [ 'title' => 'Opciones', 'rows' => [ ['id' => 'recibir_info_cat1', 'title' => 'Recibir Información', 'description' => 'Información útil para ti'], ], ], ], ], ], 'flows' => [ 'show_menu_cat1' => ['type' => 'menu', 'menu' => 'show_menu_cat1'], 'recibir_info_cat1' => ['type' => 'function', 'function' => 'forward_to_ai'], 'show_main_menu' => ['type' => 'menu', 'menu' => 'show_menu_cat1'], ], ], '2' => [ 'greeting_flow' => 'show_menu_cat2', 'fallback_flow' => 'show_menu_cat2', 'greeting' => null, 'fallback' => null, 'commands' => [ 'menu' => 'show_menu_cat2', ], 'menus' => [ 'show_menu_cat2' => [ 'type' => 'list', 'header' => 'Menú', 'body' => 'Selecciona una opción:', 'footer' => 'Palmas360', 'button' => 'Ver opciones', 'sections' => [ [ 'title' => 'Opciones', 'rows' => [ ['id' => 'descargar_informes', 'title' => 'Descargar Informes', 'description' => 'Accede a tus informes'], ], ], ], ], ], 'flows' => [ 'show_menu_cat2' => ['type' => 'menu', 'menu' => 'show_menu_cat2'], 'show_main_menu' => ['type' => 'menu', 'menu' => 'show_menu_cat2'], ], ], ], ]; // Claves de flows y menus definidas en este script (las únicas que se actualizan) $baseFlowKeys = array_keys($menuConfig['flows']); $baseMenuKeys = array_keys($menuConfig['menus']); $companies = CompanyRepository::findAll(true); $count = 0; foreach ($companies as $company) { $existing = []; if (!empty($company['config_json'])) { $decoded = json_decode($company['config_json'], true); if (is_array($decoded)) { $existing = $decoded; } } // Partir del config existente para preservar TODO lo custom (nlu, whisper_*, gemini_*, etc.) $merged = $existing; // Actualizar SOLO los flows base definidos aquí; los flows custom se preservan foreach ($menuConfig['flows'] as $key => $flow) { $merged['flows'][$key] = $flow; } // Actualizar SOLO los menus base; los menus custom se preservan foreach ($menuConfig['menus'] as $key => $menu) { $merged['menus'][$key] = $menu; } // Actualizar commands, per_type y otros campos estructurales del template foreach (['commands', 'per_type'] as $structKey) { if (isset($menuConfig[$structKey])) { $merged[$structKey] = $menuConfig[$structKey]; } } // Aplicar defaults solo si no existen if (!isset($merged['greeting'])) { $merged['greeting'] = '¡Bienvenido! Escribe *menu* para ver las opciones disponibles.'; } if (!isset($merged['fallback'])) { $merged['fallback'] = 'No entendí. Escribe *menu* para ver las opciones disponibles.'; } CompanyRepository::save([ 'id' => (int)$company['id'], 'config_json' => json_encode($merged, JSON_UNESCAPED_UNICODE), ]); $name = $company['display_name'] ?: $company['name']; $customFlows = count(array_diff(array_keys($merged['flows'] ?? []), $baseFlowKeys)); $customMenus = count(array_diff(array_keys($merged['menus'] ?? []), $baseMenuKeys)); echo "✔ {$name} actualizada (preservados: {$customFlows} flows custom, {$customMenus} menus custom)\n"; $count++; } echo "\n✅ {$count} empresas actualizadas con los nuevos menús.\n";