Cupo restante ()
diff --git a/imprimir_rotulos_grandes.php b/imprimir_rotulos_grandes.php
index 69b4013c..e84105df 100644
--- a/imprimir_rotulos_grandes.php
+++ b/imprimir_rotulos_grandes.php
@@ -6,6 +6,7 @@ if (!isset($_SESSION['user_id'])) {
}
require_once 'db/config.php';
+require_once 'includes/callcenter_test_helpers.php';
$pdo = db();
// Fetch all products to have their prefixes ready
@@ -203,39 +204,21 @@ $label_generated_date = date('d/m');
trim($value) !== '')) : [];
}
+function cc_test_parse_quantity_value(mixed $value, int $default = 1): int
+{
+ if (is_int($value)) {
+ return $value > 0 ? $value : $default;
+ }
+
+ if (is_float($value)) {
+ $quantity = (int) round($value);
+ return $quantity > 0 ? $quantity : $default;
+ }
+
+ $value = trim((string) $value);
+ if ($value === '') {
+ return $default;
+ }
+
+ if (strpos($value, '+') !== false) {
+ $sum = 0;
+ foreach (explode('+', $value) as $part) {
+ $part = trim($part);
+ if ($part === '') {
+ continue;
+ }
+ if (is_numeric($part)) {
+ $sum += (int) $part;
+ continue;
+ }
+ if (preg_match('/\d+/', $part, $match)) {
+ $sum += (int) $match[0];
+ }
+ }
+
+ return $sum > 0 ? $sum : $default;
+ }
+
+ if (preg_match('/\d+/', $value, $match)) {
+ $quantity = (int) $match[0];
+ return $quantity > 0 ? $quantity : $default;
+ }
+
+ return $default;
+}
+
+function cc_test_parse_product_detail_rows_from_text(string $text): array
+{
+ $text = trim($text);
+ if ($text === '') {
+ return [];
+ }
+
+ if (!preg_match_all('/(?:Detalle de productos|Detalle confirmado):\s*(.+)$/mi', $text, $matches) || empty($matches[1])) {
+ return [];
+ }
+
+ $lastLine = trim((string) end($matches[1]));
+ if ($lastLine === '') {
+ return [];
+ }
+
+ $parts = preg_split('/\s*,\s*/u', $lastLine);
+ if (!is_array($parts)) {
+ return [];
+ }
+
+ $rows = [];
+ foreach ($parts as $part) {
+ $part = trim((string) $part);
+ if ($part === '') {
+ continue;
+ }
+
+ $name = $part;
+ $quantity = 1;
+
+ if (preg_match('/^(.*?)\s*\(x\s*(\d+)\s*\)$/iu', $part, $match)) {
+ $name = trim((string) $match[1]);
+ $quantity = (int) $match[2];
+ }
+
+ $name = trim($name);
+ if ($name === '') {
+ continue;
+ }
+
+ $rows[] = [
+ 'nombre' => $name,
+ 'cantidad' => $quantity > 0 ? $quantity : 1,
+ ];
+ }
+
+ return $rows;
+}
+
+function cc_test_product_rows_from_tracking(array $tracking): array
+{
+ $rows = [];
+
+ $mainName = trim((string) ($tracking['confirmacion_producto'] ?? ''));
+ $mainQty = cc_test_parse_quantity_value($tracking['confirmacion_cantidad'] ?? '', 1);
+ if ($mainName !== '') {
+ $rows[] = [
+ 'nombre' => $mainName,
+ 'cantidad' => $mainQty,
+ ];
+ }
+
+ $extraName = trim((string) ($tracking['confirmacion_producto_extra'] ?? ''));
+ $extraQty = cc_test_parse_quantity_value($tracking['confirmacion_cantidad_extra'] ?? '', 1);
+ if ($extraName !== '') {
+ $rows[] = [
+ 'nombre' => $extraName,
+ 'cantidad' => $extraQty,
+ ];
+ }
+
+ return $rows;
+}
+
+function cc_test_resolve_pedido_product_rows(PDO $pdo, array $pedido, ?string $trackingLinkColumn = null): array
+{
+ $pedidoId = (int) ($pedido['id'] ?? 0);
+ $allowedTrackingColumns = ['ruta_contraentrega_pedido_id', 'pedido_rotulado_pedido_id'];
+
+ if ($pedidoId > 0 && $trackingLinkColumn !== null && in_array($trackingLinkColumn, $allowedTrackingColumns, true) && cc_test_table_exists($pdo, 'callcenter_test_tracking')) {
+ $sql = 'SELECT confirmacion_producto, confirmacion_cantidad, confirmacion_producto_extra, confirmacion_cantidad_extra FROM callcenter_test_tracking WHERE ' . $trackingLinkColumn . ' = ? ORDER BY id DESC LIMIT 1';
+ $stmt = $pdo->prepare($sql);
+ $stmt->execute([$pedidoId]);
+ $tracking = $stmt->fetch(PDO::FETCH_ASSOC);
+ if (is_array($tracking)) {
+ $rows = cc_test_product_rows_from_tracking($tracking);
+ if (!empty($rows)) {
+ return $rows;
+ }
+ }
+ }
+
+ $rows = cc_test_parse_product_detail_rows_from_text((string) ($pedido['notas'] ?? ''));
+ if (!empty($rows)) {
+ return $rows;
+ }
+
+ $producto = trim((string) ($pedido['producto'] ?? ''));
+ if ($producto === '') {
+ return [];
+ }
+
+ $names = array_values(array_filter(array_map('trim', preg_split('/\s*,\s*/u', $producto) ?: []), static fn ($value) => $value !== ''));
+ if (empty($names)) {
+ return [];
+ }
+
+ $cantidadTotal = cc_test_parse_quantity_value($pedido['cantidad'] ?? 1, 1);
+ $cantidadField = $pedido['cantidad'] ?? '';
+ $qtyParts = [];
+ if (is_string($cantidadField) && strpos(trim($cantidadField), '+') !== false) {
+ $qtyParts = array_values(array_map('trim', explode('+', trim($cantidadField))));
+ }
+
+ $rows = [];
+ $nameCount = count($names);
+ foreach ($names as $index => $name) {
+ if ($nameCount === 1) {
+ $quantity = $cantidadTotal;
+ } elseif (!empty($qtyParts) && isset($qtyParts[$index]) && is_numeric($qtyParts[$index])) {
+ $quantity = (int) $qtyParts[$index];
+ } else {
+ $quantity = 1;
+ }
+
+ $rows[] = [
+ 'nombre' => $name,
+ 'cantidad' => $quantity > 0 ? $quantity : 1,
+ ];
+ }
+
+ return $rows;
+}
+
function cc_test_row_background_style(string $estado): string
{
$color = match (cc_test_normalize_state($estado)) {
diff --git a/pedido_form.php b/pedido_form.php
index 1f986aee..d7c431dd 100644
--- a/pedido_form.php
+++ b/pedido_form.php
@@ -6,6 +6,7 @@ if (!isset($_SESSION['user_id'])) {
}
require_once 'db/config.php';
+require_once 'includes/callcenter_test_helpers.php';
$pdo = db();
$user_id = $_SESSION['user_id'];
@@ -77,34 +78,9 @@ $stmt_products = $pdo->query("SELECT id, nombre FROM products ORDER BY nombre AS
$products = $stmt_products->fetchAll();
// Parse products for editing
-$display_products = [];
-if (!empty($pedido['id'])) {
- // Try to parse from notas first as it has quantities
- if (preg_match_all('/Detalle de productos: (.*)$/m', $pedido['notas'], $matches)) {
- // Take the last match
- $last_match = end($matches[1]);
- $details = explode(', ', $last_match);
- foreach ($details as $detail) {
- if (preg_match('/(.*) \(x(\d+)\)/', $detail, $d_matches)) {
- $display_products[] = [
- 'nombre' => trim($d_matches[1]),
- 'cantidad' => (int)$d_matches[2]
- ];
- }
- }
- }
-
- // Fallback if parsing failed or no details in notas
- if (empty($display_products) && !empty($pedido['producto'])) {
- $names = explode(', ', $pedido['producto']);
- foreach ($names as $name) {
- $display_products[] = [
- 'nombre' => trim($name),
- 'cantidad' => count($names) == 1 ? $pedido['cantidad'] : 1
- ];
- }
- }
-}
+$display_products = !empty($pedido['id'])
+ ? cc_test_resolve_pedido_product_rows($pdo, $pedido, 'pedido_rotulado_pedido_id')
+ : [];
if (empty($display_products)) {
$display_products[] = ['nombre' => '', 'cantidad' => 1];
diff --git a/pedidos_contraentrega.php b/pedidos_contraentrega.php
index 0953b820..863c377d 100644
--- a/pedidos_contraentrega.php
+++ b/pedidos_contraentrega.php
@@ -7,6 +7,7 @@ if (!isset($_SESSION['user_id'])) {
require_once 'db/config.php';
require_once 'includes/contraentrega_cobertura.php';
+require_once 'includes/callcenter_test_helpers.php';
require_once 'includes/tipo_paquete.php';
$pdo = db();
ensureTipoPaqueteEnumDefinition($pdo);
@@ -79,34 +80,9 @@ $stmt_products = $pdo->query("SELECT id, nombre FROM products ORDER BY nombre AS
$products = $stmt_products->fetchAll();
// Parse products for editing
-$display_products = [];
-if (!empty($pedido['id'])) {
- // Try to parse from notas first as it has quantities
- if (preg_match_all('/Detalle de productos: (.*)$/m', $pedido['notas'], $matches)) {
- // Take the last match
- $last_match = end($matches[1]);
- $details = explode(', ', $last_match);
- foreach ($details as $detail) {
- if (preg_match('/(.*) \(x(\d+)\)/', $detail, $d_matches)) {
- $display_products[] = [
- 'nombre' => trim($d_matches[1]),
- 'cantidad' => (int)$d_matches[2]
- ];
- }
- }
- }
-
- // Fallback if parsing failed or no details in notas
- if (empty($display_products) && !empty($pedido['producto'])) {
- $names = explode(', ', $pedido['producto']);
- foreach ($names as $name) {
- $display_products[] = [
- 'nombre' => trim($name),
- 'cantidad' => count($names) == 1 ? $pedido['cantidad'] : 1
- ];
- }
- }
-}
+$display_products = !empty($pedido['id'])
+ ? cc_test_resolve_pedido_product_rows($pdo, $pedido, 'ruta_contraentrega_pedido_id')
+ : [];
if (empty($display_products)) {
$display_products[] = ['nombre' => '', 'cantidad' => 1];
diff --git a/update_callcenter_test_tracking.php b/update_callcenter_test_tracking.php
index 9012940f..dcd0b7bf 100644
--- a/update_callcenter_test_tracking.php
+++ b/update_callcenter_test_tracking.php
@@ -821,6 +821,7 @@ try {
$stmtCurrent = $pdo->prepare('SELECT estado, numero_cuenta_enviado_at, numero_cuenta_sede_id, numero_cuenta_dni, user_id, assigned_at, promo_final_evidencia_path, promo_final_evidencia_subido_at, promo_final_evidencia_subido_por, cancelado_evidencia_path, cancelado_evidencia_subido_at, cancelado_evidencia_subido_por, eliminado_at, eliminado_por, ruta_contraentrega_pedido_id, pedido_rotulado_pedido_id FROM callcenter_test_tracking WHERE source_key = ? LIMIT 1');
$stmtCurrent->execute([$sourceKey]);
$currentTracking = $stmtCurrent->fetch(PDO::FETCH_ASSOC) ?: null;
+ $tieneRutaContraentrega = isset($currentTracking['ruta_contraentrega_pedido_id']) && (int) $currentTracking['ruta_contraentrega_pedido_id'] > 0;
$sourceOrderForAuth = cc_test_fetch_source_order($pdo, $sourceKey);
$sourceStoreKeyForAuth = trim((string) ($sourceOrderForAuth['store_key'] ?? ''));
@@ -1023,7 +1024,7 @@ try {
}
}
- if ($subirALogistica && !in_array($estado, ['CONFIRMADO CONTRAENTREGA', 'CONFIRMADO ENVIO'], true)) {
+ if ($subirALogistica && !in_array($estado, ['CONFIRMADO CONTRAENTREGA', 'CONFIRMADO ENVIO'], true) && !$tieneRutaContraentrega) {
throw new RuntimeException('Para subir el pedido, el estado debe ser CONFIRMADO CONTRAENTREGA o CONFIRMADO ENVIO.');
}
@@ -1275,7 +1276,7 @@ try {
throw new RuntimeException('No encontré el pedido base para enviarlo a logística.');
}
- if ($estado === 'CONFIRMADO CONTRAENTREGA') {
+ if ($estado === 'CONFIRMADO CONTRAENTREGA' || $tieneRutaContraentrega) {
$routePayload = cc_test_prepare_route_order_payload(
$sourceOrder,
$formData,
@@ -1356,7 +1357,7 @@ try {
if ($moverAPromoFinal && $promoFinalEvidencePath !== null) {
$message = 'Pedido movido a Promo Final correctamente.';
}
- if ($subirALogistica && $estado === 'CONFIRMADO CONTRAENTREGA' && $rutaPedidoId !== null) {
+ if ($subirALogistica && ($estado === 'CONFIRMADO CONTRAENTREGA' || $tieneRutaContraentrega) && $rutaPedidoId !== null) {
$message = $rutaAction === 'updated'
? 'Pedido actualizado en Ruta Contraentrega #' . $rutaPedidoId . '.'
: 'Pedido subido a Ruta Contraentrega #' . $rutaPedidoId . '.';