From 5c68334e9a0fe8b89fb0924a4829ab062f13cae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Jim=C3=A9nez?= Date: Thu, 24 Apr 2025 23:44:07 +0200 Subject: [PATCH] =?UTF-8?q?cambiado=20ael=20a=C3=B1adir=20envios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ci4/app/Config/Routes.php | 3 +- .../Logistica/LogisticaController.php | 40 ++++++ ci4/app/Language/es/Logistica.php | 1 + ci4/app/Services/LogisticaService.php | 81 +++++++++++- ci4/app/Services/ProductionService.php | 4 +- .../logistica/viewLogisticaSelectEnvios.php | 37 ++++-- .../vuexy/main/menus/logistica_menu.php | 23 +--- .../js/safekat/pages/logistica/envio.js | 120 +++++++----------- 8 files changed, 200 insertions(+), 109 deletions(-) diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index a9e395e1..d94ce4c8 100755 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -793,7 +793,6 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi $routes->get('print/label/test', 'LogisticaController::print_test_label'); $routes->get('panel', 'LogisticaController::panel', ['as' => 'LogisticaPanel']); $routes->get('envios', 'LogisticaController::gestionEnvios', ['as' => 'gestionEnvios']); - $routes->get('buscar/(:any)', 'LogisticaController::searchPedidoOrISBN/$1', ['as' => 'buscarPedidoOrISBN']); $routes->get('datatableEnvios', 'LogisticaController::datatable_envios'); $routes->get('datatableLineasEnvios/(:num)', 'LogisticaController::datatable_enviosEdit/$1'); $routes->get('envio/(:num)', 'LogisticaController::editEnvio/$1'); @@ -808,6 +807,8 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi $routes->post('updateProveedorEnvio', 'LogisticaController::updateProveedorEnvio'); $routes->post('finalizarEnvio', 'LogisticaController::finalizarEnvio'); $routes->post('generateEnvio', 'LogisticaController::generarEnvio'); + $routes->get('selectPedidosForEnvio', 'LogisticaController::findPedidosNewEnvio'); + $routes->get('selectDireccionForEnvio', 'LogisticaController::selectDireccionForEnvio'); }); /* diff --git a/ci4/app/Controllers/Logistica/LogisticaController.php b/ci4/app/Controllers/Logistica/LogisticaController.php index d9b41e7b..8dbd4630 100755 --- a/ci4/app/Controllers/Logistica/LogisticaController.php +++ b/ci4/app/Controllers/Logistica/LogisticaController.php @@ -69,6 +69,46 @@ class LogisticaController extends BaseController return view(static::$viewPath . 'viewLogisticaSelectEnvios', $viewData); } + + public function findPedidosNewEnvio() + { + + if ($this->request->isAJAX()) { + $query = LogisticaService::findPedidosNewEnvio(); + if ($this->request->getGet("q")) { + $query->groupStart() + ->orLike("id", $this->request->getGet("q")) + ->orLike("name", $this->request->getGet("q")) + ->groupEnd(); + } + + + $result = $query->orderBy("name", "asc")->get()->getResultObject(); + + return $this->response->setJSON($result); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function selectDireccionForEnvio(){ + + if ($this->request->isAJAX()) { + $pedido_id = $this->request->getGet('pedido_id'); + if($pedido_id == null || $pedido_id == 0){ + return []; + } + $searchVal = $this->request->getGet("q") ?? ""; + $result = LogisticaService::findDireccionesNewEnvio($pedido_id, $searchVal); + + return $this->response->setJSON($result); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + + public function searchPedidoOrISBN($search = "", $envio_id = null) { diff --git a/ci4/app/Language/es/Logistica.php b/ci4/app/Language/es/Logistica.php index 6f1d35a8..db614f9a 100755 --- a/ci4/app/Language/es/Logistica.php +++ b/ci4/app/Language/es/Logistica.php @@ -11,6 +11,7 @@ return [ 'nuevoEnvio' => 'Nuevo envío', 'buscadorPedidosTitle' => 'Código Pedido o ISBN', 'buscadorPedidosTitle2' => 'Código Pedido o título', + 'selectDirecciones' => 'Dirección de envio', 'listadoEnvios' => 'Listado de envíos', 'idEnvio' => 'ID Envío', 'numeroPedidos' => 'Nº Pedidos', diff --git a/ci4/app/Services/LogisticaService.php b/ci4/app/Services/LogisticaService.php index e1196579..9124a3d7 100644 --- a/ci4/app/Services/LogisticaService.php +++ b/ci4/app/Services/LogisticaService.php @@ -158,8 +158,11 @@ class LogisticaService ->join('pedidos p', 'p.id = pl.pedido_id') ->join('presupuestos pr', 'pr.id = pl.presupuesto_id') ->join('presupuesto_direcciones pd', 'pd.presupuesto_id = pr.id') + ->join('ordenes_trabajo ot', 'ot.pedido_id = p.id') + ->join('orden_trabajo_dates ot_dates', 'ot_dates.orden_trabajo_id = ot.id') ->whereIn('pr.id', $presupuestoIds) ->whereIn('p.estado', ['finalizado', 'produccion']) + ->where('ot_dates.embalaje_at IS NOT NULL') ->where("NOT EXISTS ( SELECT 1 FROM envios_lineas el @@ -180,11 +183,84 @@ class LogisticaService return $builder; } + public static function findPedidosNewEnvio() + { + $db = \Config\Database::connect(); + // 3. Subconsulta principal + $subBuilder = $db->table('pedidos_linea pl') + ->select(" + pl.id AS id, + CONCAT('[', p.id, '] - ', pr.titulo) AS name, + ( + SELECT IFNULL(SUM(el.unidades_envio), 0) + FROM envios_lineas el + JOIN envios e ON e.id = el.envio_id + WHERE el.pedido_id = p.id + AND el.presupuesto_id = pr.id + AND e.finalizado = 1 + ) AS unidades_enviadas, + pd.cantidad AS cantidad + ") + ->join('pedidos p', 'p.id = pl.pedido_id') + ->join('presupuestos pr', 'pr.id = pl.presupuesto_id') + ->join('presupuesto_direcciones pd', 'pd.presupuesto_id = pr.id') + ->join('ordenes_trabajo ot', 'ot.pedido_id = p.id') + ->join('orden_trabajo_dates ot_dates', 'ot_dates.orden_trabajo_id = ot.id') + ->whereIn('p.estado', ['finalizado', 'produccion']) + ->where('ot_dates.embalaje_at IS NOT NULL') + ->groupBy('pl.id'); + // 4. Envolver y filtrar por unidades pendientes + $builder = $db->table("({$subBuilder->getCompiledSelect(false)}) AS sub"); + $builder->select('id, name'); + $builder->where('cantidad > unidades_enviadas'); + $builder->orderBy('name', 'ASC'); + return $builder; + } + public static function findDireccionesNewEnvio($pedido_id, $searchVal = "") + { + $direcciones = []; + $counter = 1; + + $PresupuestoDireccionesModel = model('App\Models\Presupuestos\PresupuestoDireccionesModel'); + $dirs = $PresupuestoDireccionesModel->select('direccion') + ->join('presupuestos pr', 'pr.id=presupuesto_direcciones.presupuesto_id') + ->join('pedidos_linea pl', 'pl.presupuesto_id = pr.id') + ->join('pedidos p', 'pl.pedido_id=p.id') + ->where('p.id', $pedido_id); + if ($searchVal != "") { + $dirs = $dirs->groupStart() + ->Like("id", $searchVal) + ->groupEnd(); + } + $dirs = $dirs->orderBy('direccion', 'asc')->findAll(); + foreach ($dirs as $key => $direccion) { + $modelEnvioLineasModel = model('App\Models\Logistica\EnvioLineaModel'); + $unidades_en_direccion = $modelEnvioLineasModel->select('SUM(envios_lineas.unidades_envio) as unidades_enviadas, + envios_lineas.unidades_total') + ->join('envios', 'envios.id = envios_lineas.envio_id') + ->where('pedido_id', $pedido_id) + ->where('envios.direccion', $direccion->direccion) + ->where('envios.finalizado', 1) + ->groupBy('pedido_id')->get()->getResult(); + if (count($unidades_en_direccion) == 0 || $unidades_en_direccion[0]->unidades_enviadas < $unidades_en_direccion[0]->unidades_total) { + array_push( + $direcciones, + (object) [ + "id" => $counter, + 'name' => $direccion->direccion + ] + ); + $counter++; + } + } + return $direcciones; + + } public static function addLineaEnvio($envio_id = null, $pedido_id = null, $direccion = null) { @@ -276,7 +352,6 @@ class LogisticaService $presupuestoDireccionesModel = model('App\Models\Presupuestos\PresupuestoDireccionesModel'); $direccionNormalizada = strtolower(trim($direccion)); - // Consulta con cálculo exacto de unidades pendientes por dirección $datosEnvio = $presupuestoDireccionesModel ->select(" presupuestos.id as presupuesto_id, @@ -297,7 +372,7 @@ class LogisticaService JOIN envios e ON e.id = el.envio_id WHERE el.pedido_id = pedidos.id AND el.presupuesto_id = presupuestos.id - AND TRIM(LOWER(e.direccion)) = '$direccionNormalizada' + AND e.direccion LIKE " . $presupuestoDireccionesModel->db->escape("%$direccion%") . " AND e.finalizado = 1 ), 0) ) as cantidad @@ -306,7 +381,7 @@ class LogisticaService ->join('pedidos', 'pedidos.id = pedidos_linea.pedido_id') ->join('presupuestos', 'pedidos_linea.presupuesto_id = presupuestos.id') ->where('pedidos.id', $pedido_id) - ->where("TRIM(LOWER(presupuesto_direcciones.direccion)) = '$direccionNormalizada'", null, false) + ->like('presupuesto_direcciones.direccion', $direccion) ->groupBy('presupuesto_direcciones.id') ->first(); diff --git a/ci4/app/Services/ProductionService.php b/ci4/app/Services/ProductionService.php index e59c4c8c..70e159b3 100755 --- a/ci4/app/Services/ProductionService.php +++ b/ci4/app/Services/ProductionService.php @@ -259,13 +259,13 @@ class ProductionService extends BaseService { $fecha_encuadernado = Time::now()->addDays(2)->format("Y-m-d"); $fecha_entrega_real = Time::now()->addDays(5)->format("Y-m-d"); - $fecha_embalaje_at = Time::now()->addDays(4)->format("Y-m-d"); + //$fecha_embalaje_at = Time::now()->addDays(4)->format("Y-m-d"); $data = [ "orden_trabajo_id" => $this->ot->id, "fecha_encuadernado_at" => $fecha_encuadernado, "fecha_entrega_real_at" => $fecha_entrega_real, "fecha_impresion_at" => Time::now()->format("Y-m-d"), - "embalaje_at" => $fecha_embalaje_at, + //"embalaje_at" => $fecha_embalaje_at, "fecha_entrega_externo" => $this->pedido->fecha_entrega_externo, ]; $otDateId = $this->otDate->insert($data); diff --git a/ci4/app/Views/themes/vuexy/form/logistica/viewLogisticaSelectEnvios.php b/ci4/app/Views/themes/vuexy/form/logistica/viewLogisticaSelectEnvios.php index aecb0c00..c8fd78c3 100644 --- a/ci4/app/Views/themes/vuexy/form/logistica/viewLogisticaSelectEnvios.php +++ b/ci4/app/Views/themes/vuexy/form/logistica/viewLogisticaSelectEnvios.php @@ -1,5 +1,6 @@ include("themes/_commonPartialsBs/sweetalert") ?> include('themes/_commonPartialsBs/datatables') ?> +include("themes/_commonPartialsBs/select2bs5") ?> extend('themes/vuexy/main/defaultlayout') ?> section('content'); ?> @@ -22,15 +23,35 @@
- -
+
- +
+
+
+
+ + +
+
+ +
+
+ +
@@ -87,10 +108,10 @@ section('css') ?> - + endSection() ?> section('additionalExternalJs') ?> - - + + endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/main/menus/logistica_menu.php b/ci4/app/Views/themes/vuexy/main/menus/logistica_menu.php index 510bdb6e..58376d7a 100755 --- a/ci4/app/Views/themes/vuexy/main/menus/logistica_menu.php +++ b/ci4/app/Views/themes/vuexy/main/menus/logistica_menu.php @@ -7,29 +7,10 @@ if (auth()->user()->inGroup('beta')) { ?> \ No newline at end of file diff --git a/httpdocs/assets/js/safekat/pages/logistica/envio.js b/httpdocs/assets/js/safekat/pages/logistica/envio.js index 4caed7e6..0dd45488 100644 --- a/httpdocs/assets/js/safekat/pages/logistica/envio.js +++ b/httpdocs/assets/js/safekat/pages/logistica/envio.js @@ -1,38 +1,55 @@ import Ajax from '../../components/ajax.js'; +import ClassSelect from '../../components/select2.js'; $(() => { - $('#buscadorPedidos').on('keydown', function (e) { - if (e.key === 'Enter' || e.keyCode === 13) { - e.preventDefault(); // Evita el submit si está dentro de un form - let search = $(this).val().trim(); - new Ajax( - '/logistica/buscar/' + search, - {}, - {}, - function (response) { - if (!response.status) { - popErrorAlert(response.message); - } - if (response.multienvio) { - mostrarSwalDirecciones(response); - } - else if (response.data) { - window.open(`${window.location.origin}/logistica/envio/${response.data.id_envio}`); - } - - }, - function (xhr, status, error) { - if (status == 'error' && typeof (error) == 'string') - popErrorAlert(error); - else - popErrorAlert(error.responseJSON.message); - } - ).get(); - - } + const selectPedidos = new ClassSelect($('#buscadorPedidos'), '/logistica/selectPedidosForEnvio', ""); + selectPedidos.init(); + const selectDirecciones = new ClassSelect($('#selectDirecciones'), '/logistica/selectDireccionForEnvio', "", true, { + pedido_id: () => selectPedidos.getVal() }); + selectDirecciones.init(); + + + selectPedidos.item.on('select2:open', () => { + $('.select-direcciones').addClass('d-none'); + $('.add-envio').addClass('d-none'); + }) + selectPedidos.item.on('change', () => { + selectDirecciones.empty(); + $('.select-direcciones').removeClass('d-none'); + }) + selectDirecciones.item.on('select2:open', () => { + $('.add-envio').addClass('d-none'); + }) + + selectDirecciones.item.on('change', () => { + $('.add-envio').removeClass('d-none'); + }) + + + $('#btnAddEnvio').on('click', () => { + const pedido_id = selectPedidos.getVal(); + const direccionSeleccionada = selectDirecciones.getText(); + $.post('/logistica/generateEnvio', { + pedido_id: pedido_id, + direccion: direccionSeleccionada + }, function (response) { + if (response.status) { + window.open(`${window.location.origin}/logistica/envio/${response.data.id_envio}`); + selectDirecciones.empty(); + selectPedidos.empty(); + $('.select-direcciones').addClass('d-none'); + $('.add-envio').addClass('d-none'); + } else { + popErrorAlert(response.message); + } + }).fail(function (xhr, status, error) { + popErrorAlert(error); + }); + }) + const tableEnvios = $('#tableOfEnvios').DataTable({ processing: true, @@ -82,51 +99,6 @@ $(() => { window.location.href = '/logistica/envio/' + $(this).attr('data-id'); }); - function mostrarSwalDirecciones(response) { - // Crear el select como HTML - let options = response.direcciones.map((dir, index) => - `` - ).join(""); - Swal.fire({ - title: 'Múltiples direcciones', - html: ` -

El pedido tiene múltiples direcciones. Debe seleccionar una dirección:

- - `, - confirmButtonText: 'Aceptar', - cancelButtonText: 'Cancelar', - customClass: { - confirmButton: 'swal2-confirm btn btn-primary', - cancelButton: 'swal2-cancel btn btn-secondary' // Estilo gris - }, - preConfirm: () => { - const select = document.getElementById('swal-select-direccion'); - if (!select.value) { - Swal.showValidationMessage('Debe seleccionar una dirección'); - return false; - } - return response.direcciones[select.value]; // Devuelve la dirección seleccionada - } - }).then((result) => { - if (result.isConfirmed) { - const direccionSeleccionada = result.value; - $.post('/logistica/generateEnvio', { - pedido_id: response.pedido_id, - direccion: direccionSeleccionada - }, function (response) { - if (response.status) { - window.open(`${window.location.origin}/logistica/envio/${response.data.id_envio}`); - } else { - popErrorAlert(response.message); - } - }).fail(function (xhr, status, error) { - popErrorAlert(error); - }); - } - }); - } }); \ No newline at end of file