From 5ac1e3d4c1aea8e7be46ae12ab66d20cd39ba63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Jim=C3=A9nez?= Date: Tue, 22 Apr 2025 22:20:03 +0200 Subject: [PATCH] finalizar envio ok --- ci4/app/Config/Routes.php | 5 +- ci4/app/Config/Routes/ComprasRoutes.php | 1 + ci4/app/Controllers/Compras/Proveedores.php | 22 +++ .../Logistica/LogisticaController.php | 91 ++++++++-- ci4/app/Language/es/Logistica.php | 17 +- ci4/app/Models/Logistica/EnvioLineaModel.php | 12 +- ci4/app/Services/LogisticaService.php | 68 ++++++++ .../form/logistica/viewEnvioEditForm.php | 165 ++++++++++++------ .../form/logistica/viewPanelLogistica.php | 53 ++---- .../js/safekat/pages/logistica/envioEdit.js | 163 ++++++++++++++++- 10 files changed, 481 insertions(+), 116 deletions(-) diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index 96e0e1dc..9056eff7 100755 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -791,7 +791,7 @@ $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('selectEnvios/(:any)', 'LogisticaController::selectorEnvios/$1', ['as' => 'selectEnvios']); + $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'); @@ -803,6 +803,9 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi $routes->post('updateLineaEnvio', 'LogisticaController::updateLineaEnvio'); $routes->post('updateComentariosEnvio', 'LogisticaController::saveComments'); $routes->post('updateCajasEnvio', 'LogisticaController::updateCajasEnvio'); + $routes->post('updateCodigoSeguimiento', 'LogisticaController::updateCodigoSeguimiento'); + $routes->post('updateProveedorEnvio', 'LogisticaController::updateProveedorEnvio'); + $routes->post('finalizarEnvio', 'LogisticaController::finalizarEnvio'); }); /* diff --git a/ci4/app/Config/Routes/ComprasRoutes.php b/ci4/app/Config/Routes/ComprasRoutes.php index eea2da0c..7075f1b4 100755 --- a/ci4/app/Config/Routes/ComprasRoutes.php +++ b/ci4/app/Config/Routes/ComprasRoutes.php @@ -19,6 +19,7 @@ $routes->group('compras', ['namespace' => 'App\Controllers\Compras'], function ( $routes->get('delete/(:num)', 'Proveedores::delete/$1', ['as' => 'deleteProveedores']); $routes->post('allmenuitems', 'Proveedores::allItemsSelect', ['as' => 'select2ItemsOfProveedores']); $routes->post('menuitems', 'Proveedores::menuItems', ['as' => 'menuItemsOfProveedores']); + $routes->get('getProveedores', 'Proveedores::getForSelect'); }); }); diff --git a/ci4/app/Controllers/Compras/Proveedores.php b/ci4/app/Controllers/Compras/Proveedores.php index cca3fe73..61161a78 100755 --- a/ci4/app/Controllers/Compras/Proveedores.php +++ b/ci4/app/Controllers/Compras/Proveedores.php @@ -383,4 +383,26 @@ class Proveedores extends \App\Controllers\BaseResourceController { } } + public function getForSelect(){ + + if ($this->request->isAJAX()) { + $tipo_id = $this->request->getGet("tipo_id"); + $query = $this->model->builder()->select( + [ + "id", + "nombre as name" + ] + )->where('tipo_id', $tipo_id)->where('deleted_at', null)->orderBy("nombre", "asc"); + if ($this->request->getGet("q")) { + $query->groupStart() + ->orLike("lg_proveedores.nombre", $this->request->getGet("q")) + ->groupEnd(); + } + + return $this->response->setJSON($query->get()->getResultObject()); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + } diff --git a/ci4/app/Controllers/Logistica/LogisticaController.php b/ci4/app/Controllers/Logistica/LogisticaController.php index 1e00f72f..f00efa16 100755 --- a/ci4/app/Controllers/Logistica/LogisticaController.php +++ b/ci4/app/Controllers/Logistica/LogisticaController.php @@ -29,7 +29,7 @@ class LogisticaController extends BaseController // Breadcrumbs $this->viewData['breadcrumb'] = [ - ['title' => lang("App.menu_logistica"), 'route' => "javascript:void(0);", 'active' => false], + ['title' => lang("App.menu_logistica"), 'route' => route_to("LogisticaPanel"), 'active' => false], ]; @@ -56,13 +56,12 @@ class LogisticaController extends BaseController return view(static::$viewPath . 'viewPanelLogistica', $viewData); } - public function selectorEnvios($tipoEnvio = null) + public function gestionEnvios() { $viewData = [ 'currentModule' => static::$controllerSlug, - 'boxTitle' => lang('Logistica.envioSimpleMultiple'), + 'boxTitle' => lang('Logistica.gestionEnvios'), 'usingServerSideDataTable' => true, - 'tipoEnvio' => $tipoEnvio, ]; $viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class @@ -164,6 +163,16 @@ class LogisticaController extends BaseController return redirect()->to(base_url('logistica/selectEnvios/simple'))->with('error', lang('Logistica.errors.noEnvio')); } + $modelProveedor = model('App\Models\Compras\ProveedorModel'); + $proveedor = $modelProveedor->select('id, nombre') + ->where('deleted_at', null) + ->where('id', $envioEntity->proveedor_id) + ->orderBy('nombre', 'asc') + ->first(); + if(!empty($proveedor)){ + $envioEntity->proveedor_nombre = $proveedor->nombre; + } + $viewData = [ 'currentModule' => static::$controllerSlug, 'boxTitle' => '' . ' ' . lang('Logistica.envio') . ' [' . $envioEntity->id . ']: ' . $envioEntity->direccion, @@ -193,6 +202,19 @@ class LogisticaController extends BaseController } } + public function finalizarEnvio() + { + if ($this->request->isAJAX()) { + + $id = $this->request->getPost('id'); + + $result = LogisticaService::finalizarEnvio($id); + return $this->response->setJSON($result); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + public function datatable_enviosEdit($idEnvio) { $model = model('App\Models\Logistica\EnvioLineaModel'); @@ -217,23 +239,16 @@ class LogisticaController extends BaseController function ($row, $meta) { return '' . $row->presupuesto . ''; } - ) - ->edit( - "cajas", - function ($row, $meta) { - return ''; - } )->edit( "unidadesEnvio", function ($row, $meta) { + if($row->finalizado == 1){ + return $row->unidadesEnvio; + } return ''; } - ) - ->edit('cajasRaw', function ($row) { - return is_null($row->cajas) ? '__SIN__ASIGNAR__' : $row->cajas; - }); + ); return $result->toJson(returnAsObject: true); } @@ -296,6 +311,52 @@ class LogisticaController extends BaseController ]); } + public function updateCodigoSeguimiento() + { + $id = $this->request->getPost('id'); + $fieldValue = $this->request->getPost('codigo_seguimiento'); + + if (!$id) { + return $this->response->setJSON([ + 'status' => false, + 'message' => 'Datos inválidos' + ]); + } + + $model = model('App\Models\Logistica\EnvioModel'); + $updated = $model->update($id, [ + "codigo_seguimiento" => $fieldValue==""? null: $fieldValue, + ]); + + return $this->response->setJSON([ + 'status' => $updated, + 'message' => $updated ? 'Actualizado' : 'Error al actualizar' + ]); + } + + public function updateProveedorEnvio() + { + $id = $this->request->getPost('id'); + $fieldValue = $this->request->getPost('proveedor_id'); + + if (!$id) { + return $this->response->setJSON([ + 'status' => false, + 'message' => 'Datos inválidos' + ]); + } + + $model = model('App\Models\Logistica\EnvioModel'); + $updated = $model->update($id, [ + "proveedor_id" => $fieldValue==""? null: $fieldValue, + ]); + + return $this->response->setJSON([ + 'status' => $updated, + 'message' => $updated ? 'Actualizado' : 'Error al actualizar' + ]); + } + public function saveComments() { $id = $this->request->getPost('id'); diff --git a/ci4/app/Language/es/Logistica.php b/ci4/app/Language/es/Logistica.php index c9eaf9c2..f6fff6b0 100755 --- a/ci4/app/Language/es/Logistica.php +++ b/ci4/app/Language/es/Logistica.php @@ -2,13 +2,11 @@ return [ 'logistica' => 'Logística', 'panel' => 'Panel', - 'envioSimple' => 'Envío simple', - 'envioMultiple' => 'Envío múltiple', - 'envioConjunto' => 'Envío conjunto', + 'gestionEnvios' => 'Gestión de Envíos de pedidos', 'etiquetasTitulos' => 'Etiquetas de títulos', 'etiquetasEnvio' => 'Etiquetas de envío', - 'envioFerros' => 'Envío de ferros', - 'cerrarOTauto' => 'Cerrar OT automáticamente', + 'envioFerros' => 'Gestión de Envíos de ferros/prototipos', + 'albaranes' => 'Albaranes', 'envioSimpleMultiple' => 'Envío simple/múltiple', 'nuevoEnvio' => 'Nuevo envío', 'buscadorPedidosTitle' => 'Código Pedido o ISBN', @@ -58,11 +56,20 @@ return [ 'peso' => 'Peso (kg): ', 'unidadesTotalesFooter' => 'Unidades:', + 'codigoSeguimiento' => 'Código de seguimiento', + 'empresaMensajería' => 'Empresa de mensajería', + 'finalizarEnvio' => 'Finalizar envío', + 'finalizarEnvioYOTs' => 'Finalizar envío y OTS', + 'errors' => [ 'noEnvio' => 'No se ha encontrado el envio', + 'noEnvioLineas' => 'No se han encontrado líneas de envío', 'noDataToFind' => 'No se ha introducido ningún dato para buscar', 'notFound' => 'No se encuentra el pedido o ISBN, el pedido aún no se ha finalizado o no tiene envíos pendientes', 'noAddresses' => 'El pedido no tiene direcciones de envío', ], + 'success' => [ + 'finalizado' => 'El envío se ha finalizado correctamente', + ], ]; \ No newline at end of file diff --git a/ci4/app/Models/Logistica/EnvioLineaModel.php b/ci4/app/Models/Logistica/EnvioLineaModel.php index 420b4ae6..2c64da3c 100644 --- a/ci4/app/Models/Logistica/EnvioLineaModel.php +++ b/ci4/app/Models/Logistica/EnvioLineaModel.php @@ -46,13 +46,21 @@ class EnvioLineaModel extends Model WHERE e.finalizado = 1 AND t_sub.pedido_id = t1.pedido_id AND e.direccion = d.direccion COLLATE utf8mb3_general_ci + AND ( + t_sub.envio_id <> t1.envio_id + OR (t_sub.envio_id = t1.envio_id AND ( + SELECT finalizado FROM envios WHERE id = t1.envio_id + ) = 1) + ) ), 0) as unidadesEnviadas, IFNULL(( SELECT ROUND(SUM(peso) / 1000, 1) FROM presupuesto_linea WHERE presupuesto_id = t3.id - ), 0) AS pesoUnidad" + ), 0) AS pesoUnidad, + t2.finalizado as finalizado," ); + $builder->join("envios t2", "t1.envio_id = t2.id", "left"); $builder->join("presupuestos t3", "t1.presupuesto_id = t3.id", "left"); $builder->where("t1.envio_id", $envio_id); @@ -60,5 +68,5 @@ class EnvioLineaModel extends Model return $builder; } - + } diff --git a/ci4/app/Services/LogisticaService.php b/ci4/app/Services/LogisticaService.php index 3cbab564..625751a1 100644 --- a/ci4/app/Services/LogisticaService.php +++ b/ci4/app/Services/LogisticaService.php @@ -1,6 +1,7 @@ lang('Logistica.errors.noAddresses'), ]; } + } + + public static function finalizarEnvio($envio_id) + { + // hay que comprobar que para todas las lineas de envio de este envio + // se ha enviado toda la cantidad teniendo en cuenta otros envios + $EnvioModel = model('App\Models\Logistica\EnvioModel'); + $EnvioLineasModel = model('App\Models\Logistica\EnvioLineaModel'); + + $envio = $EnvioModel->find($envio_id); + if (empty($envio)) { + return [ + 'status' => false, + 'message' => lang('Logistica.errors.noEnvio'), + ]; + } + $lineasEnvio = $EnvioLineasModel->where('envio_id', $envio_id) + ->findAll(); + if (empty($lineasEnvio)) { + return [ + 'status' => false, + 'message' => lang('Logistica.errors.noEnvioLineas'), + ]; + } + + foreach ($lineasEnvio as $linea) { + + $pedido = model('App\Models\Pedidos\PedidoModel')->find($linea->pedido_id); + if (empty($pedido)) { + return [ + 'status' => false, + 'message' => lang('Logistica.errors.notFound'), + ]; + } + $cantidad_enviada = $EnvioLineasModel->select('SUM(envios_lineas.unidades_envio) as unidades_enviadas') + ->where('envios_lineas.pedido_id', $linea->pedido_id) + ->where('envios_lineas.envio_id !=', $envio_id) + ->where('envios.finalizado', 1) + ->join('envios', 'envios.id = envios_lineas.envio_id') + ->get()->getResult(); + + if (count($cantidad_enviada) == 0 || + empty($cantidad_enviada[0]->unidades_enviadas) || + $cantidad_enviada[0]->unidades_enviadas == null) { + $cantidad_enviada = 0; + } else { + $cantidad_enviada = $cantidad_enviada[0]->unidades_enviadas; + } + + if ($cantidad_enviada + $linea->unidades_envio == $linea->unidades_total) { + $otModel = model('App\Models\OrdenTrabajo\OrdenTrabajoModel'); + $ot = $otModel->where('pedido_id', $linea->pedido_id) + ->first(); + $ps = (new ProductionService())->init($ot->id); + $ps->updateOrdenTrabajoDate([ + "name" => "envio_at", + "envio_at" => date('Y-m-d H:i:s') + ]); + } + } + + $EnvioModel->update($envio_id, ['finalizado'=> 1]); + + return [ + 'status' => true, + 'message' => lang('Logistica.success.finalizado'), + ]; } } diff --git a/ci4/app/Views/themes/vuexy/form/logistica/viewEnvioEditForm.php b/ci4/app/Views/themes/vuexy/form/logistica/viewEnvioEditForm.php index d9016dc6..1695789b 100644 --- a/ci4/app/Views/themes/vuexy/form/logistica/viewEnvioEditForm.php +++ b/ci4/app/Views/themes/vuexy/form/logistica/viewEnvioEditForm.php @@ -9,7 +9,7 @@
-

+

FINALIZADO

@@ -112,41 +112,43 @@
-
-
-

- -

+ finalizado == 0): ?> +
+
+

+ +

-
+
-
-
-

+
+
+

+
+ +
+
+ + +
+
+ +
+
+
- -
-
- - -
-
- -
-
-
-
+
@@ -168,13 +170,15 @@
-
- -
+ finalizado == 0): ?> +
+ +
+
-
-
+
-
-

- -

+
+

+ +

-
-
+
+
+
+
-
+ +
+
+

+ +

+ +
+
+ + finalizado == 0) ? "" : "readonly" ?> + value="codigo_seguimiento) ?>"> +
+
+ + finalizado == 0): ?> + + + + +
+ finalizado == 0): ?> +
+ +
+
+ +
+ +
+
+
+
- -
diff --git a/ci4/app/Views/themes/vuexy/form/logistica/viewPanelLogistica.php b/ci4/app/Views/themes/vuexy/form/logistica/viewPanelLogistica.php index 4ba6b66c..76698bb6 100755 --- a/ci4/app/Views/themes/vuexy/form/logistica/viewPanelLogistica.php +++ b/ci4/app/Views/themes/vuexy/form/logistica/viewPanelLogistica.php @@ -12,48 +12,24 @@
-
-
- +
+
+ " alt="Envíos"> +
-
- +
+ " alt="Envío de Ferros/Prototipos"> +
-
- +
+ " alt="Etiquetas de títulos"> +
-
-
-
- -
-
- -
-
- -
-
-
-
- +
+ " alt="Albaranes"> +
+
@@ -63,6 +39,7 @@ endSection(); ?> section('css') ?> + endSection() ?> diff --git a/httpdocs/assets/js/safekat/pages/logistica/envioEdit.js b/httpdocs/assets/js/safekat/pages/logistica/envioEdit.js index 2fbff388..7965b4c2 100644 --- a/httpdocs/assets/js/safekat/pages/logistica/envioEdit.js +++ b/httpdocs/assets/js/safekat/pages/logistica/envioEdit.js @@ -28,9 +28,18 @@ class EnvioEdit { this.btnGenerarAlbaran = $("#btnGenerarAlbaran"); this.btnbtnSelectAll = $("#btnSelectAll"); this.cajas = $("#cajas"); + this.codigoSeguimiento = $("#codigoSeguimiento"); + if($("#empresaMensajeriaInput").length) { + this.proveedor = new ClassSelect($("#empresaMensajeria"), '/compras/proveedores/getProveedores', "", true, { 'tipo_id': 2 }); + } } init() { + + if($("#empresaMensajeriaInput").length) { + this.proveedor.init(); + } + this.table = $('#tableLineasEnvio').DataTable({ processing: true, serverSide: true, @@ -205,8 +214,158 @@ class EnvioEdit { const checkboxes = this.table.$('input[type="checkbox"]'); const allChecked = checkboxes.length === checkboxes.filter(':checked').length; checkboxes.prop('checked', !allChecked); - } - ); + }); + + this.codigoSeguimiento.on('change', (e) => { + const value = $(e.currentTarget).val(); + + $.post('/logistica/updateCodigoSeguimiento', { + id: $('#id').val(), + codigo_seguimiento: value + }, function (response) { + if (!response.status) { + Swal.fire({ + title: 'Error', + text: response.message, + icon: 'error', + confirmButtonColor: '#3085d6', + confirmButtonText: 'Ok', + customClass: { + confirmButton: 'btn btn-primary me-1', + }, + buttonsStyling: false + }); + $(e.currentTarget).val(value.substring(0, 100)); + } + }).fail(() => { + Swal.fire({ + title: 'Error', + text: 'No se pudo actualizar el código de seguimiento.', + icon: 'error', + confirmButtonColor: '#3085d6', + confirmButtonText: 'Ok', + customClass: { + confirmButton: 'btn btn-primary me-1', + }, + buttonsStyling: false + }); + $(e.currentTarget).val(value.substring(0, 100)); + } + ); + }); + + this.proveedor.onChange((e) => { + + const value = this.proveedor.getVal(); + $.post('/logistica/updateProveedorEnvio', { + id: $('#id').val(), + proveedor_id: value + }, function (response) { + if (!response.status) { + Swal.fire({ + title: 'Error', + text: response.message, + icon: 'error', + confirmButtonColor: '#3085d6', + confirmButtonText: 'Ok', + customClass: { + confirmButton: 'btn btn-primary me-1', + }, + buttonsStyling: false + }); + this.proveedor.setVal(0); + } + }).fail(() => { + Swal.fire({ + title: 'Error', + text: 'No se pudo actualizar el proveedor.', + icon: 'error', + confirmButtonColor: '#3085d6', + confirmButtonText: 'Ok', + customClass: { + confirmButton: 'btn btn-primary me-1', + }, + buttonsStyling: false + }); + this.proveedor.setVal(0); + } + ); + }); + + $('#finalizarEnvio').on('click', () => { + + if(this.codigoSeguimiento.val().length <= 0 || this.proveedor.getVal() <= 0) { + Swal.fire({ + title: 'Atención!', + text: 'Debe seleccionar un proveedor y un código de seguimiento antes de finalizar el envío.', + icon: 'info', + confirmButtonColor: '#3085d6', + confirmButtonText: 'Ok', + customClass: { + confirmButton: 'btn btn-primary me-1', + }, + buttonsStyling: false + }); + return; + } + + Swal.fire({ + title: 'Finalizar envío', + text: '¿Está seguro de que desea finalizar el envío?', + icon: 'warning', + showCancelButton: true, + confirmButtonText: 'Sí', + cancelButtonText: 'Cancelar', + customClass: { + confirmButton: 'btn btn-danger me-1', + cancelButton: 'btn btn-secondary' + }, + buttonsStyling: false + }).then((result) => { + if (result.isConfirmed) { + $.post('/logistica/finalizarEnvio', { + id: $('#id').val() + }, function (response) { + if (response.status) { + Swal.fire({ + text: response.message, + icon: 'success', + confirmButtonColor: '#3085d6', + confirmButtonText: 'Ok', + customClass: { + confirmButton: 'btn btn-primary me-1', + }, + buttonsStyling: false + }); + } else { + Swal.fire({ + title: 'Error', + text: response.message, + icon: 'error', + confirmButtonColor: '#3085d6', + confirmButtonText: 'Ok', + customClass: { + confirmButton: 'btn btn-primary me-1', + }, + buttonsStyling: false + }); + } + }).fail(() => { + Swal.fire({ + title: 'Error', + text: 'No se pudo finalizar el envío.', + icon: 'error', + confirmButtonColor: '#3085d6', + confirmButtonText: 'Ok', + customClass: { + confirmButton: 'btn btn-primary me-1', + }, + buttonsStyling: false + }); + }); + } + }); + }); this._getAlbaranes(); }