From f7b9c23f69c9181551b216a8c8175a638b905b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Jim=C3=A9nez?= Date: Thu, 24 Apr 2025 00:32:53 +0200 Subject: [PATCH] parece terminado los envios --- ci4/app/Config/Routes.php | 1 + .../Logistica/LogisticaController.php | 29 +- ci4/app/Language/es/Logistica.php | 3 +- ci4/app/Models/Logistica/EnvioLineaModel.php | 11 +- ci4/app/Services/LogisticaService.php | 363 +++++++++++------- ci4/app/Services/PresupuestoService.php | 2 +- .../form/logistica/viewEnvioEditForm.php | 2 +- .../js/safekat/pages/logistica/envio.js | 74 +++- .../js/safekat/pages/logistica/envioEdit.js | 177 ++++++--- 9 files changed, 426 insertions(+), 236 deletions(-) diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index 9056eff7..06be3baa 100755 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -806,6 +806,7 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi $routes->post('updateCodigoSeguimiento', 'LogisticaController::updateCodigoSeguimiento'); $routes->post('updateProveedorEnvio', 'LogisticaController::updateProveedorEnvio'); $routes->post('finalizarEnvio', 'LogisticaController::finalizarEnvio'); + $routes->post('generateEnvio', 'LogisticaController::generarEnvio'); }); /* diff --git a/ci4/app/Controllers/Logistica/LogisticaController.php b/ci4/app/Controllers/Logistica/LogisticaController.php index 09cd0ef9..19444426 100755 --- a/ci4/app/Controllers/Logistica/LogisticaController.php +++ b/ci4/app/Controllers/Logistica/LogisticaController.php @@ -83,6 +83,20 @@ class LogisticaController extends BaseController return $this->response->setJSON($result); } + + public function generarEnvio() + { + if ($this->request->isAJAX()) { + + $pedido_id = $this->request->getPost('pedido_id'); + $direccion = $this->request->getPost('direccion'); + $result = LogisticaService::generateEnvio($pedido_id, $direccion); + return $this->response->setJSON($result); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + public function selectAddEnvioLinea() { @@ -209,20 +223,6 @@ class LogisticaController extends BaseController $id = $this->request->getPost('id') ?? null; $finalizar_ots = $this->request->getPost('finalizar_ots') ?? false; - $result = LogisticaService::finalizarEnvio($id); - return $this->response->setJSON($result); - } else { - return $this->failUnauthorized('Invalid request', 403); - } - } - - public function finalizarEnvioYOts() - { - if ($this->request->isAJAX()) { - - $id = $this->request->getPost('id') ?? null; - $finalizar_ots = $this->request->getPost('finalizar_ots') ?? false; - $result = LogisticaService::finalizarEnvio($id, $finalizar_ots); return $this->response->setJSON($result); } else { @@ -230,6 +230,7 @@ class LogisticaController extends BaseController } } + public function datatable_enviosEdit($idEnvio) { $model = model('App\Models\Logistica\EnvioLineaModel'); diff --git a/ci4/app/Language/es/Logistica.php b/ci4/app/Language/es/Logistica.php index f6fff6b0..6f1d35a8 100755 --- a/ci4/app/Language/es/Logistica.php +++ b/ci4/app/Language/es/Logistica.php @@ -65,11 +65,12 @@ return [ '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', + 'notFound' => 'No se encuentra el pedido o ISBN, el pedido no está en producción o 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', + 'finalizadoOTs' => 'El envío se ha finalizado correctamente.\nSe han creado las OTs siguientes OTs: {ots}', ], ]; \ No newline at end of file diff --git a/ci4/app/Models/Logistica/EnvioLineaModel.php b/ci4/app/Models/Logistica/EnvioLineaModel.php index 2c64da3c..26938014 100644 --- a/ci4/app/Models/Logistica/EnvioLineaModel.php +++ b/ci4/app/Models/Logistica/EnvioLineaModel.php @@ -40,19 +40,16 @@ class EnvioLineaModel extends Model t1.unidades_total as unidadesTotal, IFNULL(( SELECT SUM(t_sub.unidades_envio) - FROM " . $this->table . " t_sub + FROM envios_lineas t_sub JOIN envios e ON e.id = t_sub.envio_id - JOIN presupuesto_direcciones d ON d.presupuesto_id = t_sub.presupuesto_id WHERE e.finalizado = 1 AND t_sub.pedido_id = t1.pedido_id - AND e.direccion = d.direccion COLLATE utf8mb3_general_ci + AND e.direccion = t2.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) + OR (t_sub.envio_id = t1.envio_id AND e.finalizado = 1) ) - ), 0) as unidadesEnviadas, + ), 0) AS unidadesEnviadas, IFNULL(( SELECT ROUND(SUM(peso) / 1000, 1) FROM presupuesto_linea diff --git a/ci4/app/Services/LogisticaService.php b/ci4/app/Services/LogisticaService.php index 7b29dc01..de7440f7 100644 --- a/ci4/app/Services/LogisticaService.php +++ b/ci4/app/Services/LogisticaService.php @@ -10,6 +10,7 @@ class LogisticaService public static function findPedidoOrISBN($search) { $multienvio = false; + $direcciones = []; $modelPedido = model('App\Models\Pedidos\PedidoModel'); @@ -32,13 +33,14 @@ class LogisticaService $builder->groupStart() ->where('pedidos.id', $search) - ->whereIn('pedidos.estado', ['finalizado']) + ->whereIn('pedidos.estado', ['finalizado', 'produccion']) ->orWhere("REPLACE(presupuestos.isbn, '-', '')", $searchClean) ->groupEnd(); $builder->groupBy('pedidos_linea.id'); $builder->having('IFNULL(SUM(envios_lineas.unidades_envio), 0) < cantidad_linea', null, false); + $result = $builder->get()->getResult(); if (empty($result)) { @@ -60,6 +62,21 @@ class LogisticaService return $response; } else if ($numDirecciones > 1) { $multienvio = true; + $dirs = $PresupuestoDireccionesModel->select('direccion')->where('presupuesto_id', $result[0]->presupuesto_id) + ->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', $result[0]->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, $direccion->direccion); + } + } } $response = [ @@ -67,8 +84,18 @@ class LogisticaService 'data' => $result[0], ]; + if ($multienvio) { + $response_envio = [ + 'status' => true, + 'multienvio' => true, + 'direcciones' => $direcciones, + 'pedido_id' => $result[0]->pedido_id, + ]; + return $response_envio; + } - $response_envio = LogisticaService::generateEnvio($result[0]->pedido_id, $multienvio); + + $response_envio = LogisticaService::generateEnvio($result[0]->pedido_id); if ($response_envio['status'] == false) { $response = [ 'status' => false, @@ -84,84 +111,113 @@ class LogisticaService } + public static function findLineaEnvioPorEnvio(int $envio_id) { $db = \Config\Database::connect(); - $subCliente = $db->table('envios') - ->select('cliente_id') - ->where('id', $envio_id) - ->getCompiledSelect(); - $builder = $db->table('envios e_main'); + // 1. Obtener dirección del envío actual + $envio = $db->table('envios')->select('direccion')->where('id', $envio_id)->get()->getRow(); + if (!$envio) { + return []; + } - $builder->select(" - CONCAT('[', p.id, '] - ', pr.titulo) AS name, - pl.id AS id, - pl.cantidad, - ( - 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 e.direccion = e_main.direccion - AND pr.cliente_id = ($subCliente) - ) AS unidades_enviadas, - ( - pl.cantidad - ( - SELECT IFNULL(SUM(el2.unidades_envio), 0) - FROM envios_lineas el2 - JOIN envios e2 ON e2.id = el2.envio_id - WHERE el2.pedido_id = p.id - AND e2.direccion = e_main.direccion - AND pr.cliente_id = ($subCliente) - ) - ) AS unidades_pendientes - "); + $direccionNormalizada = str_replace(' ', '', strtolower(trim($envio->direccion))); + $direccionSQL = $db->escape($direccionNormalizada); - $builder->join('pedidos_linea pl', '1=1'); // para incluir líneas sin envío aún - $builder->join('pedidos p', 'p.id = pl.pedido_id'); - $builder->join('presupuestos pr', 'pr.id = pl.presupuesto_id'); - $builder->where('e_main.id', $envio_id); - $builder->where('p.estado', 'finalizado'); - $builder->where("pr.cliente_id = ($subCliente)", null, false); + // 2. Obtener los presupuesto_id asociados a esa dirección + $presupuestosConEsaDireccion = $db->table('presupuesto_direcciones') + ->select('presupuesto_id') + ->where("REPLACE(LOWER(TRIM(direccion)), ' ', '') = $direccionSQL", null, false) + ->get() + ->getResultArray(); - $builder->having('unidades_pendientes >', 0); + $presupuestoIds = array_column($presupuestosConEsaDireccion, 'presupuesto_id'); + if (empty($presupuestoIds)) { + return []; + } + + // 3. Subconsulta principal con unidades pendientes + $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 REPLACE(LOWER(TRIM(e.direccion)), ' ', '') = $direccionSQL + AND (e.finalizado = 1 OR e.id = $envio_id) + ) 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') + ->whereIn('pr.id', $presupuestoIds) + ->whereIn('p.estado', ['finalizado', 'produccion']) + ->where("REPLACE(LOWER(TRIM(pd.direccion)), ' ', '') = $direccionSQL", null, false) + ->groupBy('pl.id'); + + // 4. Envolver y filtrar por unidades pendientes reales + $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 addLineaEnvio($envio_id = null, $pedido_id = null, $direccion = null) { - $modelPedido = model('App\Models\Pedidos\PedidoModel'); + $db = \Config\Database::connect(); - $builder = $modelPedido->builder(); + $direccionNormalizada = strtolower(trim($direccion)); - $builder->select(" - pedidos.id as pedido_id, - pedidos_linea.id as linea_id, - pedidos_linea.cantidad as total_unidades, - ( - SELECT IFNULL(SUM(el.unidades_envio), 0) - FROM envios_lineas el - JOIN envios e ON e.id = el.envio_id - WHERE el.pedido_id = pedidos.id - AND e.finalizado = 1 - AND TRIM(e.direccion) = '" . addslashes(trim($direccion)) . "' - ) as unidades_enviadas, - pedidos_linea.cantidad - IFNULL(SUM(envios_lineas.unidades_envio), 0) as unidades_envio, - presupuestos.id as presupuesto_id - "); - - $builder->join('pedidos_linea', 'pedidos_linea.pedido_id = pedidos.id', 'left'); - $builder->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id', 'left'); - $builder->join('envios_lineas', 'envios_lineas.pedido_id = pedidos_linea.pedido_id', 'left'); - - $builder->groupBy('pedidos_linea.id'); - $builder->having('IFNULL(SUM(envios_lineas.unidades_envio), 0) < pedidos_linea.cantidad', null, false); - $builder->where('pedidos.estado', 'finalizado'); - $builder->where('pedidos.id', $pedido_id); + // 1. Obtener presupuesto_id y cantidad desde presupuesto_direcciones + $builder = $db->table('pedidos_linea pl') + ->select(" + p.id AS pedido_id, + pl.id AS linea_id, + pr.id AS presupuesto_id, + pd.cantidad AS total_unidades, + + ( + 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 TRIM(LOWER(e.direccion)) = '$direccionNormalizada' + AND (e.finalizado = 1 OR e.id = $envio_id) + ) AS unidades_enviadas, + + ( + pd.cantidad - ( + SELECT IFNULL(SUM(el2.unidades_envio), 0) + FROM envios_lineas el2 + JOIN envios e2 ON e2.id = el2.envio_id + WHERE el2.pedido_id = p.id + AND el2.presupuesto_id = pr.id + AND TRIM(LOWER(e2.direccion)) = '$direccionNormalizada' + AND (e2.finalizado = 1 OR e2.id = $envio_id) + ) + ) AS unidades_envio + ") + ->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') + ->where('p.id', $pedido_id) + ->whereIn('p.estado', ['finalizado', 'produccion']) + ->where("TRIM(LOWER(pd.direccion)) = '$direccionNormalizada'", null, false) + ->groupBy('pl.id'); $result = $builder->get()->getResultObject(); @@ -170,122 +226,132 @@ class LogisticaService 'status' => false, 'message' => lang('Logistica.errors.notFound'), ]; - } else { + } + + $r = $result[0]; + + // 2. Insertar solo si hay unidades a enviar + if ($r->unidades_envio > 0) { $EnvioLineasModel = model('App\Models\Logistica\EnvioLineaModel'); $EnvioLineasModel->save([ 'envio_id' => $envio_id, - 'pedido_id' => $result[0]->pedido_id, - 'unidades_envio' => $result[0]->unidades_envio, - 'unidades_total' => $result[0]->total_unidades, + 'pedido_id' => $r->pedido_id, + 'presupuesto_id' => $r->presupuesto_id, + 'unidades_envio' => $r->unidades_envio, + 'unidades_total' => $r->total_unidades, 'cajas' => null, 'unidades_cajas' => 1, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), 'created_by' => auth()->user()->id, 'updated_by' => auth()->user()->id, - 'presupuesto_id' => $result[0]->presupuesto_id, ]); } return [ 'status' => true, 'data' => [ - 'unidades_envio' => $result[0]->unidades_envio, - 'unidades_enviadas' => $result[0]->unidades_enviadas, - 'total_unidades' => $result[0]->total_unidades, + 'unidades_envio' => $r->unidades_envio, + 'unidades_enviadas' => $r->unidades_enviadas, + 'total_unidades' => $r->total_unidades, ] ]; } - private static function generateEnvio($pedido_id, $multienvio = false) + public static function generateEnvio($pedido_id, $direccion = null) { - $presupuestoDireccionesModel = model('App\Models\Presupuestos\PresupuestoDireccionesModel'); + $direccionNormalizada = strtolower(trim($direccion)); - if (!$multienvio) { - // solo hay una dirección, se obtiene de los albaranes + // Consulta con cálculo exacto de unidades pendientes por dirección + $datosEnvio = $presupuestoDireccionesModel + ->select(" + presupuestos.id as presupuesto_id, + presupuesto_direcciones.att, + presupuesto_direcciones.direccion, + presupuesto_direcciones.provincia as ciudad, + presupuesto_direcciones.cp, + presupuesto_direcciones.telefono, + presupuesto_direcciones.email, + presupuesto_direcciones.pais_id, + presupuesto_direcciones.cantidad as cantidad_total, + presupuestos.cliente_id as cliente_id, - $datosEnvio = $presupuestoDireccionesModel - ->select(' - presupuestos.id as presupuesto_id, - presupuesto_direcciones.att, - presupuesto_direcciones.direccion, - presupuesto_direcciones.provincia as ciudad, - presupuesto_direcciones.cp, - presupuesto_direcciones.telefono, - presupuesto_direcciones.email, - presupuesto_direcciones.pais_id, - presupuesto_direcciones.cantidad - IFNULL(SUM(envios_lineas.unidades_envio), 0) as cantidad, - presupuesto_direcciones.cantidad as cantidad_total, - presupuestos.cliente_id as cliente_id - ') - ->join('pedidos_linea', 'pedidos_linea.presupuesto_id = presupuesto_direcciones.presupuesto_id') - ->join('pedidos', 'pedidos.id = pedidos_linea.pedido_id') - ->join('presupuestos', 'pedidos_linea.presupuesto_id = presupuestos.id') - ->join('envios_lineas', 'envios_lineas.pedido_id = pedidos.id', 'left') - ->join('envios', 'envios.id = envios_lineas.envio_id', 'left') - ->where('pedidos.id', $pedido_id) - ->groupBy('presupuesto_direcciones.id') // Necesario por el uso de SUM - ->first(); + ( + presupuesto_direcciones.cantidad - IFNULL(( + SELECT SUM(el.unidades_envio) + FROM envios_lineas el + 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.finalizado = 1 + ), 0) + ) as cantidad + ") + ->join('pedidos_linea', 'pedidos_linea.presupuesto_id = presupuesto_direcciones.presupuesto_id') + ->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) + ->groupBy('presupuesto_direcciones.id') + ->first(); - - // se genera un nuevo envio con estos datos - $EnvioModel = model('App\Models\Logistica\EnvioModel'); - $EnvioModel->set('cliente_id', $datosEnvio->cliente_id); - $EnvioModel->set('att', $datosEnvio->att); - $EnvioModel->set('direccion', $datosEnvio->direccion); - $EnvioModel->set('ciudad', $datosEnvio->ciudad); - $EnvioModel->set('cp', $datosEnvio->cp); - $EnvioModel->set('telefono', $datosEnvio->telefono); - $EnvioModel->set('email', $datosEnvio->email); - $EnvioModel->set('pais_id', $datosEnvio->pais_id); - $EnvioModel->set('cantidad', $datosEnvio->cantidad); - $EnvioModel->set('cajas', 1); - $EnvioModel->set('multienvio', $multienvio ? 1 : 0); - $EnvioModel->set('created_at', date('Y-m-d H:i:s')); - $EnvioModel->set('updated_at', date('Y-m-d H:i:s')); - $EnvioModel->insert(); - $idEnvio = $EnvioModel->insertID(); - - // se genera la linea de envio - $EnvioLineasModel = model('App\Models\Logistica\EnvioLineaModel'); - $EnvioLineasModel->save([ - 'envio_id' => $idEnvio, - 'pedido_id' => $pedido_id, - 'unidades_envio' => $datosEnvio->cantidad, - 'unidades_total' => $datosEnvio->cantidad_total, - 'cajas' => 1, - 'unidades_cajas' => 1, - 'created_at' => date('Y-m-d H:i:s'), - 'updated_at' => date('Y-m-d H:i:s'), - 'created_by' => auth()->user()->id, - 'updated_by' => auth()->user()->id, - 'presupuesto_id' => (int) $datosEnvio->presupuesto_id - ]); - - - - return [ - 'status' => true, - 'data' => [ - 'id_envio' => $idEnvio, - 'multienvio' => false, - ], - ]; - - } - - if (empty($datosEnvio)) { + // Validación si no hay datos o no quedan unidades + if (empty($datosEnvio) || $datosEnvio->cantidad <= 0) { return [ 'status' => false, - 'message' => lang('Logistica.errors.noAddresses'), + 'message' => lang('Logistica.errors.noAddresses') . ' o no hay unidades pendientes.', ]; } + + // Crear envío + $EnvioModel = model('App\Models\Logistica\EnvioModel'); + $EnvioModel->set([ + 'cliente_id' => $datosEnvio->cliente_id, + 'att' => $datosEnvio->att, + 'direccion' => $datosEnvio->direccion, + 'ciudad' => $datosEnvio->ciudad, + 'cp' => $datosEnvio->cp, + 'telefono' => $datosEnvio->telefono, + 'email' => $datosEnvio->email, + 'pais_id' => $datosEnvio->pais_id, + 'cantidad' => $datosEnvio->cantidad, + 'cajas' => 1, + 'created_at' => date('Y-m-d H:i:s'), + 'updated_at' => date('Y-m-d H:i:s'), + ]); + $EnvioModel->insert(); + $idEnvio = $EnvioModel->insertID(); + + // Crear línea de envío + $EnvioLineasModel = model('App\Models\Logistica\EnvioLineaModel'); + $EnvioLineasModel->save([ + 'envio_id' => $idEnvio, + 'pedido_id' => $pedido_id, + 'unidades_envio' => $datosEnvio->cantidad, + 'unidades_total' => $datosEnvio->cantidad_total, + 'cajas' => 1, + 'unidades_cajas' => 1, + 'created_at' => date('Y-m-d H:i:s'), + 'updated_at' => date('Y-m-d H:i:s'), + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id, + 'presupuesto_id' => (int) $datosEnvio->presupuesto_id + ]); + + return [ + 'status' => true, + 'data' => [ + 'id_envio' => $idEnvio, + ], + ]; } + public static function finalizarEnvio($envio_id, $finalizar_ot = false) { // hay que comprobar que para todas las lineas de envio de este envio @@ -337,7 +403,7 @@ class LogisticaService $cantidad_enviada = $cantidad_enviada[0]->unidades_enviadas; } - if ($cantidad_enviada + $linea->unidades_envio == $linea->unidades_total) { + if ($cantidad_enviada + $linea->unidades_envio == $pedido->total_tirada) { $otModel = model('App\Models\OrdenTrabajo\OrdenTrabajoModel'); $ot = $otModel->where('pedido_id', $linea->pedido_id) ->first(); @@ -365,6 +431,9 @@ class LogisticaService ]; if ($finalizar_ot) { + $data_return['message'] = lang('Logistica.success.finalizadoOTs', [ + 'ots' => implode(', ', $ots) + ]); $data_return['ots'] = $ots; } return $data_return; diff --git a/ci4/app/Services/PresupuestoService.php b/ci4/app/Services/PresupuestoService.php index 74c73088..37ba5e64 100755 --- a/ci4/app/Services/PresupuestoService.php +++ b/ci4/app/Services/PresupuestoService.php @@ -144,7 +144,7 @@ class PresupuestoService extends BaseService $maquina->velocidad ); $tiempo = round($tiempo, 2); - [$precio_hora, $margen_precio_hora] = $clientePreciosModel->get_precio_hora($cliente_id, $config, $tiempo); + [$precio_hora, $margen_precio_hora] = $clientePreciosModel->get_precio_hora($cliente_id, $config, round($tiempo, 2)); if (is_null($precio_hora)) { diff --git a/ci4/app/Views/themes/vuexy/form/logistica/viewEnvioEditForm.php b/ci4/app/Views/themes/vuexy/form/logistica/viewEnvioEditForm.php index 508b40df..e012b79d 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

+

finalizado == 0)?'':'FINALIZADO' ?>

diff --git a/httpdocs/assets/js/safekat/pages/logistica/envio.js b/httpdocs/assets/js/safekat/pages/logistica/envio.js index 0a9d1c27..4caed7e6 100644 --- a/httpdocs/assets/js/safekat/pages/logistica/envio.js +++ b/httpdocs/assets/js/safekat/pages/logistica/envio.js @@ -1,33 +1,36 @@ import Ajax from '../../components/ajax.js'; -$(()=>{ +$(() => { - $('#buscadorPedidos').on('keydown', function(e) { + $('#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, + '/logistica/buscar/' + search, {}, {}, - function(response) { - if(!response.status){ + function (response) { + if (!response.status) { popErrorAlert(response.message); } - if(response.data){ + 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') + function (xhr, status, error) { + if (status == 'error' && typeof (error) == 'string') popErrorAlert(error); else popErrorAlert(error.responseJSON.message); } ).get(); - + } }); @@ -55,7 +58,7 @@ $(()=>{ { "data": "cp" }, { "data": "email" }, { "data": "telefono" }, - { + { "data": "finalizado", "className": "text-center", }, @@ -78,5 +81,52 @@ $(()=>{ $(document).on('click', '.btn-edit', function (e) { 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 diff --git a/httpdocs/assets/js/safekat/pages/logistica/envioEdit.js b/httpdocs/assets/js/safekat/pages/logistica/envioEdit.js index 04357abb..5e85f9bd 100644 --- a/httpdocs/assets/js/safekat/pages/logistica/envioEdit.js +++ b/httpdocs/assets/js/safekat/pages/logistica/envioEdit.js @@ -29,14 +29,14 @@ class EnvioEdit { this.btnbtnSelectAll = $("#btnSelectAll"); this.cajas = $("#cajas"); this.codigoSeguimiento = $("#codigoSeguimiento"); - if($("#empresaMensajeriaInput").length) { + if (!$("#empresaMensajeriaInput").length) { this.proveedor = new ClassSelect($("#empresaMensajeria"), '/compras/proveedores/getProveedores', "", true, { 'tipo_id': 2 }); } } init() { - if($("#empresaMensajeriaInput").length) { + if (!$("#empresaMensajeriaInput").length) { this.proveedor.init(); } @@ -62,14 +62,14 @@ class EnvioEdit { footerCallback: function (row, data, start, end, display) { let totalUnidades = 0; let totalPeso = 0; - + data.forEach(row => { const unidades = parseFloat(row.unidadesEnvioRaw) || 0; const pesoUnidad = parseFloat(row.pesoUnidad) || 0; totalUnidades += unidades; totalPeso += unidades * pesoUnidad; }); - + // Mostrar en spans personalizados del $('#footer-unidades-envio').text(totalUnidades); $('#footer-peso').text(totalPeso.toFixed(2)); @@ -126,7 +126,7 @@ class EnvioEdit { buttonsStyling: false }); $(e.currentTarget).val(0); - } + } }).fail(() => { Swal.fire({ title: 'Error', @@ -218,7 +218,7 @@ class EnvioEdit { this.codigoSeguimiento.on('change', (e) => { const value = $(e.currentTarget).val(); - + $.post('/logistica/updateCodigoSeguimiento', { id: $('#id').val(), codigo_seguimiento: value @@ -254,17 +254,32 @@ class EnvioEdit { ); }); - this.proveedor.onChange((e) => { + if (!$("#empresaMensajeriaInput").length) { + this.proveedor.onChange((e) => { - const value = this.proveedor.getVal(); - $.post('/logistica/updateProveedorEnvio', { - id: $('#id').val(), - proveedor_id: value - }, function (response) { - if (!response.status) { + 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: response.message, + text: 'No se pudo actualizar el proveedor.', icon: 'error', confirmButtonColor: '#3085d6', confirmButtonText: 'Ok', @@ -275,47 +290,15 @@ class EnvioEdit { }); 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); - } - ); - }); + ); + }); + } - $('.btn-finalizar').on('click', (e) => { - let data = { - id : $('#id').val(); - }; - let url = '/logistica/finalizarEnvio'; - if(e.currentTarget.id() != "finalizarEnvio"){ - let url = '/logistica/finalizarEnvioYOts'; - data.finalizar_ots = true; - } - 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 - }); + $('#finalizarEnvio').on('click', (e) => { + + if (!this._checkDatosFinalizar()) return; - } -//////////////////// + Swal.fire({ title: 'Finalizar envío', text: '¿Está seguro de que desea finalizar el envío?', @@ -343,6 +326,75 @@ class EnvioEdit { confirmButton: 'btn btn-primary me-1', }, buttonsStyling: false + }).then(() => { + window.location.reload(); + }); + } 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 + }); + }); + } + }); + }); + + $('#finalizarEnvioYOTs').on('click', (e) => { + + if (!this._checkDatosFinalizar()) + return; + + Swal.fire({ + title: 'Finalizar envío y las OTs', + text: '¿Está seguro de que desea finalizar el envío y las OTs de las líneas de 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(), + finalizar_ots: true + }, 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 + }).then(() => { + window.location.reload(); }); } else { Swal.fire({ @@ -377,6 +429,25 @@ class EnvioEdit { this._getAlbaranes(); } + _checkDatosFinalizar() { + + 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 false; + } + return true; + } + _getAlbaranes() { $.get('/albaranes/albaranesEnvio', { envio_id: $('#id').val(),