[ 'label' => 'Flower', 'spreadsheet_id' => '1SSmQuR9quxeQbMKNMDkRe8-n1gU7WuEfsFaJ3WKFO-c', 'sheet_gid' => null, 'startRow' => 5552, ], // Segunda tienda (nuevo link que pasaste). 'otra_tienda' => [ 'label' => 'TUANI', 'spreadsheet_id' => '1QYKeBJIIqYm6yW6Ka-5gKdxhUHwXOAc0No7RjnimxTw', 'sheet_gid' => 1523126328, 'startRow' => 5552, ], ]; } function drive_test_get_store_config(string $storeKey): array { $storeKey = trim(mb_strtolower($storeKey)); $stores = drive_test_available_stores(); if (!isset($stores[$storeKey])) { return $stores['flower']; } return $stores[$storeKey] + ['key' => $storeKey]; } function drive_test_resolve_sheet_a1_range($service, string $spreadsheetId, ?int $sheetGid, string $rangeA1): string { if ($sheetGid === null) { return $rangeA1; } static $cache = []; $cacheKey = $spreadsheetId . '|' . (string) $sheetGid . '|' . $rangeA1; if (isset($cache[$cacheKey])) { return $cache[$cacheKey]; } try { $meta = $service->spreadsheets->get($spreadsheetId, ['fields' => 'sheets(properties(sheetId,title))']); foreach (($meta->getSheets() ?? []) as $sheet) { $props = $sheet->getProperties(); if (!$props) { continue; } if ((int) $props->getSheetId() === (int) $sheetGid) { $title = trim((string) ($props->getTitle() ?? '')); if ($title !== '') { // Sheet names with spaces/special chars must be quoted. $escaped = str_replace("'", "''", $title); $cache[$cacheKey] = "'{$escaped}'!{$rangeA1}"; return $cache[$cacheKey]; } } } } catch (Throwable $exception) { // Fallback to default range. } $cache[$cacheKey] = $rangeA1; return $rangeA1; } function drive_test_get_cell(array $row, array $indexes, array $aliases, string $default = ''): string { foreach ($aliases as $alias) { $normalized = drive_test_normalize_header($alias); if (array_key_exists($normalized, $indexes)) { return trim((string) ($row[$indexes[$normalized]] ?? $default)); } } return $default; } function drive_test_fetch_orders(int $limit = 10, int $startRow = 5552, string $storeKey = 'flower'): array { $storeConfig = drive_test_get_store_config($storeKey); $credentialsPath = __DIR__ . '/../google_credentials.json'; $spreadsheetId = (string) ($storeConfig['spreadsheet_id'] ?? ''); $sheetGid = array_key_exists('sheet_gid', $storeConfig) ? ($storeConfig['sheet_gid'] === null ? null : (int) $storeConfig['sheet_gid']) : null; $rangeA1 = 'A:Z'; if ($spreadsheetId === '') { throw new RuntimeException('Configuración de Drive para la tienda no válida.'); } if (!file_exists($credentialsPath)) { throw new RuntimeException('No se encontró el archivo de credenciales de Google.'); } $client = new Google\Client(); $client->setAuthConfig($credentialsPath); $client->addScope(Google\Service\Sheets::SPREADSHEETS_READONLY); $service = new Google\Service\Sheets($client); $range = drive_test_resolve_sheet_a1_range($service, $spreadsheetId, $sheetGid, $rangeA1); $response = $service->spreadsheets_values->get($spreadsheetId, $range); $values = $response->getValues(); if (empty($values)) { return [ 'headers' => [], 'orders' => [], 'total_rows' => 0, ]; } $headers = $values[0] ?? []; $headerIndexes = []; foreach ($headers as $index => $header) { $normalized = drive_test_normalize_header((string) $header); if ($normalized === '') { $normalized = $index === 0 ? 'CODIGO' : 'COL_' . $index; } $headerIndexes[$normalized] = $index; } $dataRows = array_slice($values, 1); $startIndex = max(0, $startRow - 2); if ($startIndex > 0 && $startIndex < count($dataRows)) { $dataRows = array_slice($dataRows, $startIndex); } $previewRows = $limit > 0 ? array_reverse(array_slice($dataRows, -$limit)) : array_reverse($dataRows); $orders = []; foreach ($previewRows as $row) { $codigo = trim((string) ($row[0] ?? '')); $importId = drive_test_get_cell($row, $headerIndexes, ['ID']); $nombre = drive_test_get_cell($row, $headerIndexes, ['NOMBRE']); $celular = preg_replace('/\D+/', '', drive_test_get_cell($row, $headerIndexes, ['CELULAR'])); $producto = drive_test_get_cell($row, $headerIndexes, ['PRODUCTO']); $cantidad = drive_test_get_cell($row, $headerIndexes, ['CANTIDAD']); $precio = drive_test_get_cell($row, $headerIndexes, ['PRECIO']); $pais = drive_test_get_cell($row, $headerIndexes, ['PAIS']); $coordenadas = drive_test_get_cell($row, $headerIndexes, ['COORDENADAS']); $ciudad = drive_test_get_cell($row, $headerIndexes, ['CIUDAD']); $metodo = drive_test_get_cell($row, $headerIndexes, ['METODO']); $sede = drive_test_get_cell($row, $headerIndexes, ['SEDE / ID', 'SEDE/ID']); $dni = drive_test_get_cell($row, $headerIndexes, ['N° DNI', 'N° DNI ', 'NRO DNI', 'DNI']); $observaciones = drive_test_get_cell($row, $headerIndexes, ['OBSERVACIONES', 'OBSERVACIONES ']); $direccion = drive_test_get_cell($row, $headerIndexes, ['DIRECION', 'DIRECCION']); $referencia = drive_test_get_cell($row, $headerIndexes, ['REFERENCIA']); $distrito = drive_test_get_cell($row, $headerIndexes, ['DISTRITO']); // Importante: para 'flower' mantenemos EXACTAMENTE el algoritmo anterior // para no romper el historial/tracking ya existente. $sourceKeyBase = implode('|', [$codigo, $importId, $nombre, $celular, $producto]); if (($storeConfig['key'] ?? 'flower') === 'flower') { $sourceKey = sha1($sourceKeyBase); } else { $sourceKey = sha1(($storeConfig['key'] ?? $storeKey) . '|' . $sourceKeyBase); } $orders[] = [ 'source_key' => $sourceKey, 'codigo' => $codigo, 'import_id' => $importId, 'nombre' => $nombre, 'direccion' => $direccion, 'referencia' => $referencia, 'agencia' => '', 'sede_agencia' => '', 'distrito' => $distrito, 'celular' => $celular, 'producto' => $producto, 'cantidad' => $cantidad, 'precio' => $precio, 'pais' => $pais, 'coordenadas' => $coordenadas, 'ciudad' => $ciudad, 'metodo' => $metodo, 'sede' => $sede, 'dni' => $dni, 'observaciones' => $observaciones, ]; } return [ 'headers' => $headers, 'orders' => $orders, 'total_rows' => count($dataRows), ]; } function drive_test_fetch_tracking(PDO $pdo, array $sourceKeys): array { if (empty($sourceKeys)) { return []; } cc_test_ensure_tracking_table($pdo); $placeholders = implode(',', array_fill(0, count($sourceKeys), '?')); $stmt = $pdo->prepare("SELECT source_key, estado, nota_seguimiento, user_id, direccion, referencia, agencia, sede_agencia, sede, ciudad, distrito, dni, observaciones, producto, cantidad, precio, confirmacion_producto, confirmacion_cantidad, confirmacion_precio, confirmacion_producto_extra, confirmacion_cantidad_extra, confirmacion_precio_extra, proxima_llamada_at, fecha_entrega_programada, numero_cuenta_enviado_at, ultima_gestion_at, updated_at FROM callcenter_test_tracking WHERE source_key IN ($placeholders)"); $stmt->execute($sourceKeys); $tracking = []; foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { $tracking[$row['source_key']] = $row; } return $tracking; } function drive_test_merge_tracking(array $orders, array $tracking): array { $editableFields = ['direccion', 'referencia', 'agencia', 'sede_agencia', 'sede', 'ciudad', 'distrito', 'dni', 'observaciones', 'producto', 'cantidad', 'precio', 'confirmacion_producto', 'confirmacion_cantidad', 'confirmacion_precio', 'confirmacion_producto_extra', 'confirmacion_cantidad_extra', 'confirmacion_precio_extra']; foreach ($orders as &$order) { $current = $tracking[$order['source_key']] ?? null; $order['estado'] = $current['estado'] ?? 'POR LLAMAR'; $order['nota_seguimiento'] = $current['nota_seguimiento'] ?? ''; $userId = array_key_exists('user_id', (array) $current) ? $current['user_id'] : null; $order['user_id'] = $userId !== null ? ((int) $userId > 0 ? (int) $userId : null) : null; $order['seguimiento_actualizado'] = $current['updated_at'] ?? null; $order['proxima_llamada_at'] = $current['proxima_llamada_at'] ?? null; $order['fecha_entrega_programada'] = $current['fecha_entrega_programada'] ?? null; $order['numero_cuenta_enviado_at'] = $current['numero_cuenta_enviado_at'] ?? null; $order['ultima_gestion_at'] = $current['ultima_gestion_at'] ?? ($current['updated_at'] ?? null); foreach ($editableFields as $field) { $order[$field . '_drive'] = $order[$field] ?? ''; $trackedValue = $current[$field] ?? null; $order[$field . '_editado'] = $trackedValue; if ($trackedValue !== null && trim((string) $trackedValue) !== '') { $order[$field] = $trackedValue; } } $digits = preg_replace('/\D+/', '', $order['celular'] ?? ''); $order['whatsapp_url'] = $digits !== '' ? 'https://wa.me/' . $digits : ''; $order['telefono_url'] = $digits !== '' ? 'tel:' . $digits : ''; } unset($order); return $orders; }