Autosave: 20260725-185550

This commit is contained in:
Flatlogic Bot 2026-07-25 18:54:23 +00:00
parent 7a6edd7faf
commit de25048671
2 changed files with 242 additions and 0 deletions

View File

@ -32,6 +32,10 @@ function drive_test_available_stores(): array
'startRow' => 6804,
'enforce_db_start_row' => true,
'incremental_sync' => true,
'status_sync_start_row' => 7207,
'status_sync_column' => 'V',
'advisor_sync_start_row' => 7207,
'advisor_sync_column' => 'X',
],
// Bandeja compartida de carritos recuperables: misma estructura, pero desde la fila 2000.
'tuani_recuperables' => [
@ -131,6 +135,198 @@ function drive_test_get_store_config(string $storeKey): array
return $stores[$storeKey] + ['key' => $storeKey];
}
function drive_test_status_sync_start_row(string $storeKey): ?int
{
$storeConfig = drive_test_get_store_config($storeKey);
if (!array_key_exists('status_sync_start_row', $storeConfig)) {
return null;
}
$startRow = (int) $storeConfig['status_sync_start_row'];
return $startRow > 0 ? $startRow : null;
}
function drive_test_status_sync_start_date(string $storeKey): ?DateTimeImmutable
{
$storeConfig = drive_test_get_store_config($storeKey);
$rawDate = trim((string) ($storeConfig['status_sync_start_date'] ?? ''));
if ($rawDate === '') {
return null;
}
try {
return new DateTimeImmutable($rawDate);
} catch (Throwable $exception) {
return null;
}
}
function drive_test_status_sync_column(string $storeKey): string
{
$storeConfig = drive_test_get_store_config($storeKey);
$column = strtoupper(trim((string) ($storeConfig['status_sync_column'] ?? 'V')));
return preg_match('/^[A-Z]+$/', $column) ? $column : 'V';
}
function drive_test_advisor_sync_start_row(string $storeKey): ?int
{
$storeConfig = drive_test_get_store_config($storeKey);
if (!array_key_exists('advisor_sync_start_row', $storeConfig)) {
return null;
}
$startRow = (int) $storeConfig['advisor_sync_start_row'];
return $startRow > 0 ? $startRow : null;
}
function drive_test_advisor_sync_column(string $storeKey): string
{
$storeConfig = drive_test_get_store_config($storeKey);
$column = strtoupper(trim((string) ($storeConfig['advisor_sync_column'] ?? 'R')));
return preg_match('/^[A-Z]+$/', $column) ? $column : 'R';
}
function drive_test_status_sync_reference_datetime(array $sourceOrder): ?DateTimeImmutable
{
$candidates = [
trim((string) ($sourceOrder['first_seen_at'] ?? '')),
trim((string) ($sourceOrder['drive_imported_at'] ?? '')),
trim((string) ($sourceOrder['updated_at'] ?? '')),
];
foreach ($candidates as $candidate) {
if ($candidate === '') {
continue;
}
try {
return new DateTimeImmutable($candidate);
} catch (Throwable $exception) {
continue;
}
}
return null;
}
function drive_test_should_sync_status_to_sheet(array $sourceOrder): bool
{
$storeKey = trim((string) ($sourceOrder['store_key'] ?? ''));
if ($storeKey === '') {
return false;
}
$sourceRow = (int) ($sourceOrder['source_row'] ?? 0);
if ($sourceRow <= 0) {
return false;
}
$cutoffRow = drive_test_status_sync_start_row($storeKey);
if ($cutoffRow !== null) {
return $sourceRow >= $cutoffRow;
}
$cutoff = drive_test_status_sync_start_date($storeKey);
if ($cutoff === null) {
return false;
}
$referenceDate = drive_test_status_sync_reference_datetime($sourceOrder);
if ($referenceDate === null) {
return false;
}
return $referenceDate->format('Y-m-d') >= $cutoff->format('Y-m-d');
}
function drive_test_sync_status_to_sheet(array $sourceOrder, string $estado, ?string $advisorName = null): array
{
$storeKey = trim((string) ($sourceOrder['store_key'] ?? ''));
if ($storeKey === '') {
return [
'success' => false,
'skipped' => true,
'reason' => 'missing_store_key',
];
}
if (!drive_test_should_sync_status_to_sheet($sourceOrder)) {
return [
'success' => true,
'skipped' => true,
'reason' => 'before_cutoff',
];
}
$sourceRow = (int) ($sourceOrder['source_row'] ?? 0);
if ($sourceRow <= 0) {
return [
'success' => false,
'skipped' => true,
'reason' => 'missing_source_row',
];
}
$storeConfig = drive_test_get_store_config($storeKey);
$spreadsheetId = trim((string) ($storeConfig['spreadsheet_id'] ?? ''));
if ($spreadsheetId === '') {
throw new RuntimeException('Configuración de Drive para la tienda no válida.');
}
$credentialsPath = __DIR__ . '/../google_credentials.json';
if (!file_exists($credentialsPath)) {
throw new RuntimeException('No se encontró el archivo de credenciales de Google.');
}
$statusColumn = drive_test_status_sync_column($storeKey);
$sheetGid = array_key_exists('sheet_gid', $storeConfig) ? ($storeConfig['sheet_gid'] === null ? null : (int) $storeConfig['sheet_gid']) : null;
$client = new Google\Client();
$client->setAuthConfig($credentialsPath);
$client->addScope(Google\Service\Sheets::SPREADSHEETS);
$service = new Google\Service\Sheets($client);
$statusRange = drive_test_resolve_sheet_a1_range($service, $spreadsheetId, $sheetGid, $statusColumn . $sourceRow);
$estadoNormalizado = cc_test_normalize_state(trim($estado));
$updates = [
new Google\Service\Sheets\ValueRange([
'range' => $statusRange,
'values' => [[ $estadoNormalizado ]],
]),
];
$advisorName = drive_test_compact_text($advisorName);
$advisorRange = null;
$advisorStartRow = drive_test_advisor_sync_start_row($storeKey);
if ($advisorName !== '' && $advisorStartRow !== null && $sourceRow >= $advisorStartRow) {
$advisorColumn = drive_test_advisor_sync_column($storeKey);
$advisorRange = drive_test_resolve_sheet_a1_range($service, $spreadsheetId, $sheetGid, $advisorColumn . $sourceRow);
$updates[] = new Google\Service\Sheets\ValueRange([
'range' => $advisorRange,
'values' => [[ $advisorName ]],
]);
}
$body = new Google\Service\Sheets\BatchUpdateValuesRequest([
'data' => $updates,
'valueInputOption' => 'RAW',
]);
$service->spreadsheets_values->batchUpdate($spreadsheetId, $body);
return [
'success' => true,
'skipped' => false,
'store_key' => $storeKey,
'source_row' => $sourceRow,
'range' => $statusRange,
'advisor_range' => $advisorRange,
'estado' => $estadoNormalizado,
'advisor_name' => $advisorRange !== null ? $advisorName : null,
];
}
function drive_test_resolve_sheet_a1_range($service, string $spreadsheetId, ?int $sheetGid, string $rangeA1): string
{
if ($sheetGid === null) {

View File

@ -2,6 +2,7 @@
session_start();
require_once 'db/config.php';
require_once 'includes/callcenter_test_helpers.php';
require_once 'includes/drive_test_orders.php';
require_once 'includes/contraentrega_cobertura.php';
header('Content-Type: application/json; charset=utf-8');
@ -65,6 +66,33 @@ function cc_test_normalize_optional_image_upload(string $key): ?array
return $file;
}
function cc_test_resolve_user_display_name(PDO $pdo, ?int $userId): string
{
if ($userId === null || $userId <= 0) {
return '';
}
try {
$stmt = $pdo->prepare('SELECT nombre_asesor, username FROM users WHERE id = ? LIMIT 1');
$stmt->execute([$userId]);
if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$nombreAsesor = trim((string) ($row['nombre_asesor'] ?? ''));
if ($nombreAsesor !== '') {
return $nombreAsesor;
}
$username = trim((string) ($row['username'] ?? ''));
if ($username !== '') {
return $username;
}
}
} catch (Throwable $exception) {
// Use the fallback below if the user lookup fails.
}
return 'Asesor #' . $userId;
}
function cc_test_store_tracking_evidence_image(array $file, string $prefix, string $sourceKey, int $userId): array
{
$tmpName = (string) ($file['tmp_name'] ?? '');
@ -116,6 +144,7 @@ function cc_test_fetch_source_order(PDO $pdo, string $sourceKey): ?array
'SELECT
source_key,
store_key,
source_row,
codigo,
import_id,
drive_imported_at,
@ -968,6 +997,7 @@ try {
$userIdToSet = $isAdmin
? ($currentTracking ? ((int) ($currentTracking['user_id'] ?? 0) > 0 ? (int) $currentTracking['user_id'] : null) : null)
: (int) $_SESSION['user_id'];
$advisorNameForDrive = cc_test_resolve_user_display_name($pdo, $userIdToSet);
$proximaRaw = trim((string) ($_POST['proxima_llamada_at'] ?? ''));
$proximaLlamada = null;
@ -1335,6 +1365,21 @@ try {
$pdo->commit();
$driveSyncResult = null;
if ($sourceOrderForAuth) {
try {
$driveSyncResult = drive_test_sync_status_to_sheet($sourceOrderForAuth, $estado, $advisorNameForDrive);
} catch (Throwable $driveException) {
error_log('update_callcenter_test_tracking.php drive sync: ' . $driveException->getMessage());
$driveSyncResult = [
'success' => false,
'skipped' => false,
'reason' => 'sync_error',
'error' => 'No se pudo sincronizar el estado con Drive.',
];
}
}
$message = 'Gestión actualizada correctamente.';
if ($moverAPromoFinal && $promoFinalEvidencePath !== null) {
$message = 'Pedido movido a Promo Final correctamente.';
@ -1367,6 +1412,7 @@ try {
'ruta_contraentrega_subido_at' => $rutaSubidoAt,
'pedido_rotulado_pedido_id' => $pedidoRotuladoId,
'pedido_rotulado_subido_at' => $pedidoRotuladoSubidoAt,
'drive_sync' => $driveSyncResult,
]);
} catch (Throwable $exception) {
if (isset($pdo) && $pdo instanceof PDO && $pdo->inTransaction()) {