@@ -662,7 +854,11 @@ require_once 'layout_header.php';
|
- No hay pedidos en esta bandeja por ahora.
+
+ No hay pedidos en esta bandeja para .
+
+ No hay pedidos en esta bandeja por ahora.
+
|
@@ -780,30 +976,22 @@ require_once 'layout_header.php';
-
+
0 ? (int) $orderUserId : null) : null;
$unassigned = $orderUserIdNorm === null;
- $assignedAssessorKey = null;
- if (!$unassigned) {
- foreach ($assessors as $assessorKey => $assessor) {
- if ((int) ($assessor['id'] ?? 0) === (int) $orderUserIdNorm) {
- $assignedAssessorKey = (string) $assessorKey;
- break;
- }
- }
- }
+ $assignedAssessorKey = $order['assessor_key'] ?? null;
- $assignFormClass = 'border rounded-3 p-1 text-start shadow-sm cc-callcenter-assign-form';
+ $assignFormClass = 'border rounded-3 p-1 text-start cc-callcenter-assign-form';
$assignFormStyle = '';
if ($unassigned) {
- $assignFormClass .= ' bg-light';
+ $assignFormClass .= ' is-unassigned';
} elseif ($assignedAssessorKey !== null) {
$assignFormClass .= ' has-accent';
$assignFormStyle = cc_test_assessor_css_vars($assignedAssessorKey, $assessors[$assignedAssessorKey]['color_hex'] ?? null);
} else {
- $assignFormClass .= ' bg-secondary-subtle border-secondary';
+ $assignFormClass .= ' is-neutral';
}
$selectedAssessorKeyForSelect = $unassigned ? '' : ($assignedAssessorKey !== null ? (string) $assignedAssessorKey : '');
diff --git a/db/migrations/092_add_estado_shalom_cache_columns.sql b/db/migrations/092_add_estado_shalom_cache_columns.sql
new file mode 100644
index 00000000..2ca2bcf7
--- /dev/null
+++ b/db/migrations/092_add_estado_shalom_cache_columns.sql
@@ -0,0 +1,4 @@
+-- Cachea el último estado consultado de Shalom para la vista de Pedidos en Tránsito.
+ALTER TABLE `pedidos`
+ ADD COLUMN IF NOT EXISTS `estado_shalom` VARCHAR(120) NULL AFTER `seguimiento`,
+ ADD COLUMN IF NOT EXISTS `estado_shalom_actualizado_at` DATETIME NULL AFTER `estado_shalom`;
diff --git a/download_ruta_contraentrega.php b/download_ruta_contraentrega.php
index 75b77bc7..3f7ae1ad 100644
--- a/download_ruta_contraentrega.php
+++ b/download_ruta_contraentrega.php
@@ -286,7 +286,7 @@ $is_admin = in_array($user_role, ['Administrador', 'admin'], true);
// Exportar solo los pedidos con fecha de entrega "mañana"
$date_condition = "DATE(p.fecha_entrega) = DATE_ADD(CURDATE(), INTERVAL 1 DAY)";
- $sql = "SELECT p.* FROM pedidos p WHERE p.estado IN ('RUTA_CONTRAENTREGA', 'PENDIENTE', 'NO CONTESTO, VOLVER A LLAMAR', 'NO CONTESTO, DEVOLVER LLAMADA', 'CANCELADO', 'REPROGRAMADO', 'ENTREGA EXITOSA', 'RETORNADO')";
+ $sql = "SELECT p.* FROM pedidos p WHERE p.estado IN ('RUTA_CONTRAENTREGA', 'NO CONTESTO, VOLVER A LLAMAR', 'NO CONTESTO, DEVOLVER LLAMADA', 'CANCELADO', 'REPROGRAMADO', 'ENTREGA EXITOSA', 'RETORNADO')";
$params = [];
if ($user_role === 'Asesor') {
diff --git a/gestiones_callcenter.php b/gestiones_callcenter.php
index 43482b28..56b4d30e 100644
--- a/gestiones_callcenter.php
+++ b/gestiones_callcenter.php
@@ -870,10 +870,10 @@ require_once 'layout_header.php';
}
.cc-callcenter-assign-form .cc-callcenter-assessor-badge {
- background-color: rgba(0, 0, 0, .16);
+ background-color: rgba(255, 255, 255, .18);
color: var(--cc-assessor-accent-contrast, #212529);
- border-color: rgba(0, 0, 0, .16) !important;
- box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08);
+ border-color: rgba(255, 255, 255, .42) !important;
+ box-shadow: none;
}
.cc-callcenter-assign-form.is-unassigned .cc-callcenter-assessor-badge {
@@ -884,7 +884,7 @@ require_once 'layout_header.php';
}
.cc-callcenter-assign-form .cc-callcenter-assessor-badge .cc-callcenter-color-dot {
- border: 1px solid rgba(0, 0, 0, .18);
+ border: 1px solid rgba(255, 255, 255, .65);
box-shadow: none;
}
@@ -912,10 +912,11 @@ require_once 'layout_header.php';
.cc-callcenter-assign-row .form-select {
min-width: 10rem;
flex: 1 1 10rem;
- border-color: rgba(0, 0, 0, .18);
- background-color: rgba(0, 0, 0, .12);
+ border-color: rgba(255, 255, 255, .48);
+ background-color: rgba(255, 255, 255, .18);
color: var(--cc-assessor-accent-contrast, #212529);
font-weight: 700;
+ box-shadow: none;
}
.cc-callcenter-assign-form.is-unassigned .cc-callcenter-assign-row .form-select {
@@ -925,18 +926,18 @@ require_once 'layout_header.php';
}
.cc-callcenter-assign-row .form-select:focus {
- border-color: rgba(0, 0, 0, .24);
- box-shadow: 0 0 0 .2rem rgba(0, 0, 0, .12);
+ border-color: rgba(255, 255, 255, .72);
+ box-shadow: 0 0 0 .2rem rgba(255, 255, 255, .18);
}
.cc-callcenter-assign-submit {
flex: 0 0 auto;
white-space: nowrap;
- border-color: rgba(0, 0, 0, .18) !important;
- background-color: rgba(0, 0, 0, .16) !important;
+ border-color: rgba(255, 255, 255, .42) !important;
+ background-color: rgba(255, 255, 255, .18) !important;
color: var(--cc-assessor-accent-contrast, #212529) !important;
font-weight: 700;
- box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08);
+ box-shadow: none;
}
.cc-callcenter-assessor-badge {
@@ -956,11 +957,11 @@ require_once 'layout_header.php';
gap: .3rem;
padding: .2rem .55rem;
white-space: nowrap;
- border-color: rgba(0, 0, 0, .18) !important;
- background-color: rgba(0, 0, 0, .12);
+ border-color: rgba(255, 255, 255, .42) !important;
+ background-color: rgba(255, 255, 255, .18);
color: var(--cc-assessor-accent-contrast, #212529);
font-weight: 700;
- box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08);
+ box-shadow: none;
}
.cc-callcenter-color-trigger:hover:not(:disabled),
@@ -971,7 +972,7 @@ require_once 'layout_header.php';
.cc-callcenter-color-trigger:disabled {
opacity: .72;
- background-color: rgba(0, 0, 0, .10);
+ background-color: rgba(255, 255, 255, .12);
}
.cc-callcenter-assign-form.is-unassigned .cc-callcenter-color-trigger {
@@ -990,7 +991,7 @@ require_once 'layout_header.php';
height: .72rem;
border-radius: 999px;
background: var(--cc-assessor-accent, #adb5bd);
- border: 1px solid rgba(0, 0, 0, .24);
+ border: 1px solid rgba(255, 255, 255, .65);
box-shadow: none;
flex: 0 0 auto;
}
diff --git a/includes/shalom_scraper.js b/includes/shalom_scraper.js
new file mode 100644
index 00000000..4248f2b3
--- /dev/null
+++ b/includes/shalom_scraper.js
@@ -0,0 +1,166 @@
+#!/usr/bin/env node
+const fs = require('fs');
+const path = require('path');
+const puppeteer = require('puppeteer');
+
+function detectChromeExecutable() {
+ const candidates = [];
+ const cacheRoot = '/home/ubuntu/.cache/puppeteer/chrome';
+
+ try {
+ if (fs.existsSync(cacheRoot)) {
+ const versions = fs.readdirSync(cacheRoot).sort().reverse();
+ for (const version of versions) {
+ candidates.push(path.join(cacheRoot, version, 'chrome-linux64', 'chrome'));
+ }
+ }
+ } catch (error) {
+ // Ignoramos y seguimos con rutas fijas.
+ }
+
+ if (process.env.PUPPETEER_EXECUTABLE_PATH) {
+ candidates.unshift(process.env.PUPPETEER_EXECUTABLE_PATH);
+ }
+
+ candidates.push(
+ '/usr/bin/google-chrome-stable',
+ '/usr/bin/google-chrome',
+ '/usr/bin/chromium',
+ '/usr/bin/chromium-browser'
+ );
+
+ return candidates.find((candidate) => candidate && fs.existsSync(candidate)) || null;
+}
+
+function sleep(ms) {
+ return new Promise((resolve) => setTimeout(resolve, ms));
+}
+
+async function main() {
+ const orderNumber = (process.argv[2] || '').trim();
+ const orderCode = (process.argv[3] || '').trim();
+
+ if (!orderNumber || !orderCode) {
+ console.log(JSON.stringify({
+ success: false,
+ error: 'Número de orden y código de orden son requeridos.'
+ }));
+ process.exit(1);
+ }
+
+ const trackingUrl = `https://shalom.com.pe/rastrea/${encodeURIComponent(orderNumber)}/${encodeURIComponent(orderCode)}`;
+ let browser = null;
+
+ try {
+ const executablePath = detectChromeExecutable();
+
+ browser = await puppeteer.launch({
+ headless: 'new',
+ executablePath: executablePath || undefined,
+ args: [
+ '--no-sandbox',
+ '--disable-setuid-sandbox',
+ '--disable-dev-shm-usage'
+ ]
+ });
+
+ const page = await browser.newPage();
+ await page.setViewport({ width: 1280, height: 900 });
+ await page.setUserAgent('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36');
+
+ await page.goto(trackingUrl, {
+ waitUntil: 'networkidle2',
+ timeout: 60000,
+ });
+
+ await sleep(4000);
+
+ const payload = await page.evaluate(() => {
+ const textOf = (selectorList) => {
+ for (const selector of selectorList) {
+ const el = document.querySelector(selector);
+ const text = el && el.textContent ? el.textContent.trim() : '';
+ if (text) return text;
+ }
+ return '';
+ };
+
+ const allParagraphs = Array.from(document.querySelectorAll('p'))
+ .map((p) => (p.textContent || '').trim())
+ .filter(Boolean);
+
+ const status = textOf([
+ '.text-4xl.font-bold.text-red-color-sidebar',
+ '.text-3xl.font-bold.text-red-color-sidebar'
+ ]);
+
+ let description = textOf([
+ 'p.text-md.font-normal.text-silver-title',
+ 'p.text-sm.font-normal.text-silver-title'
+ ]);
+
+ if (!description) {
+ description = allParagraphs.find((text) => {
+ return !/^N° DE ORDEN:/i.test(text)
+ && !/^Desde el/i.test(text)
+ && /destino|recojo|entregado|origen|procesado|tránsito|transito/i.test(text);
+ }) || '';
+ }
+
+ const orderLabel = allParagraphs.find((text) => /^N° DE ORDEN:/i.test(text)) || '';
+ const dateLabel = allParagraphs.find((text) => /^Desde el/i.test(text)) || '';
+ const internalOrderNumber = orderLabel.replace(/^N° DE ORDEN:\s*/i, '').trim();
+ const bodyText = document.body && document.body.innerText ? document.body.innerText.trim() : '';
+
+ return {
+ status,
+ description,
+ orderLabel,
+ dateLabel,
+ internalOrderNumber,
+ requiresLogin: /Inicia sesión para acceder/i.test(bodyText),
+ currentUrl: location.href,
+ currentPath: location.pathname,
+ };
+ });
+
+ if (!payload.status || payload.currentPath === '/rastrea') {
+ console.log(JSON.stringify({
+ success: false,
+ error: 'No se pudo encontrar la guía en el rastreo público de Shalom.',
+ tracking_url: trackingUrl,
+ }));
+ process.exit(2);
+ }
+
+ console.log(JSON.stringify({
+ success: true,
+ source: 'shalom_web',
+ status: payload.status,
+ description: payload.description,
+ internal_order_number: payload.internalOrderNumber || null,
+ external_order_number: orderNumber,
+ order_code: orderCode,
+ date_text: payload.dateLabel || null,
+ tracking_url: trackingUrl,
+ requires_login: !!payload.requiresLogin,
+ }));
+ } catch (error) {
+ console.log(JSON.stringify({
+ success: false,
+ error: error && error.message ? error.message : 'Error al consultar Shalom.',
+ tracking_url: trackingUrl,
+ }));
+ process.exit(3);
+ } finally {
+ if (browser) {
+ try {
+ await browser.close();
+ } catch (error) {
+ // Ignoramos errores al cerrar el navegador.
+ }
+ }
+ }
+}
+
+main();
diff --git a/pedidos_en_transito.php b/pedidos_en_transito.php
index 19629a35..b6f908b4 100644
--- a/pedidos_en_transito.php
+++ b/pedidos_en_transito.php
@@ -34,6 +34,28 @@ function getStatusStyle($status) {
return "background-color: {$bgColor} !important; {$style}";
}
+function getShalomStatusBadgeClass($status) {
+ $normalized = mb_strtoupper(trim((string) $status), 'UTF-8');
+
+ if ($normalized === '') {
+ return 'bg-warning text-dark';
+ }
+
+ if (str_contains($normalized, 'ENTREGADO') || str_contains($normalized, 'COMPLETADO') || str_contains($normalized, 'DESTINO')) {
+ return 'bg-success';
+ }
+
+ if (str_contains($normalized, 'TRANSITO') || str_contains($normalized, 'TRÁNSITO')) {
+ return 'bg-primary';
+ }
+
+ if (str_contains($normalized, 'REGISTRADO') || str_contains($normalized, 'ORIGEN')) {
+ return 'bg-warning text-dark';
+ }
+
+ return 'bg-secondary';
+}
+
$pdo = db();
$user_id = $_SESSION['user_id'];
@@ -97,6 +119,7 @@ $whatsapp_template_db = $stmt_config->fetchColumn();
?>
@@ -165,9 +188,10 @@ include 'layout_header.php';
Limpiar
-
+
+ El sistema guarda el último estado consultado de Shalom y puedes refrescar la columna con este botón cuando lo necesites.
@@ -246,12 +270,15 @@ include 'layout_header.php';
}
$whatsappUrl = "https://api.whatsapp.com/send?phone={$celular}&text={$whatsappMessageEncoded}";
+ $trackingUrl = (!empty($pedido['codigo_rastreo']) && !empty($pedido['codigo_tracking']))
+ ? 'https://shalom.com.pe/rastrea/' . rawurlencode((string) $pedido['codigo_rastreo']) . '/' . rawurlencode((string) $pedido['codigo_tracking'])
+ : 'https://shalom.com.pe/rastrea';
?>
-
- 🚚
+
+ 🚚
- 💬
+ 💬
|
|
@@ -270,7 +297,22 @@ include 'layout_header.php';
Oculto'; ?>
|
-
VERIFICAR |
+
+
+
+
+
+
+ Act.
+
+
+
+ VERIFICAR
+
+ |
|
|
@@ -308,7 +350,6 @@ include 'layout_header.php';
|