diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index 352a871e..5f952ada 100755 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -818,6 +818,7 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi $routes->get('panel', 'LogisticaController::panel', ['as' => 'LogisticaPanel']); $routes->get('envios', 'LogisticaController::gestionEnvios', ['as' => 'gestionEnvios']); $routes->get('enviosFerros', 'LogisticaController::gestionEnviosFerros', ['as' => 'gestionEnviosFerros']); + $routes->get('etiquetasLogistica', 'LogisticaController::etiquetasLogistica', ['as' => 'etiquetasLogistica']); $routes->get('datatableEnvios', 'LogisticaController::datatable_envios'); $routes->get('datatableLineasEnvios/(:num)', 'LogisticaController::datatable_enviosEdit/$1'); $routes->get('envio/(:num)', 'LogisticaController::editEnvio/$1'); @@ -841,6 +842,13 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi }); +$routes->group('etiquetasTitulos', ['namespace' => 'App\Controllers\Logistica'], function ($routes) { + + $routes->get('otList', 'EtiquetasTitulosController::findOTs'); + $routes->get('addList', 'EtiquetasTitulosController::findAddresses'); + $routes->post('newEtiquetaTitulos', 'EtiquetasTitulosController::addEtiqueta'); +}); + /* * -------------------------------------------------------------------- * Translation diff --git a/ci4/app/Controllers/Logistica/EtiquetasTitulosController.php b/ci4/app/Controllers/Logistica/EtiquetasTitulosController.php new file mode 100644 index 00000000..15fc86ab --- /dev/null +++ b/ci4/app/Controllers/Logistica/EtiquetasTitulosController.php @@ -0,0 +1,112 @@ +impresoraEtiquetaService = service('impresora_etiqueta'); + $this->locale = session()->get('lang'); + + $this->viewData['pageTitle'] = lang('Logistica.logistica'); + + // Breadcrumbs + $this->viewData['breadcrumb'] = [ + ['title' => lang("App.menu_logistica"), 'route' => route_to("LogisticaPanel"), 'active' => false], + ]; + + + parent::initController($request, $response, $logger); + } + + public function findOTs() + { + if ($this->request->isAJAX()) { + + $query = EtiquetasTitulosService::getOtsWithTitulos(); + + if ($this->request->getGet("q")) { + $query->groupStart() + ->orLike("ot.id", $this->request->getGet("q")) + ->orLike("pr.titulo)", $this->request->getGet("q")) + ->groupEnd(); + } + + + $result = $query->orderBy("id", "DESC")->get()->getResultObject(); + + return $this->response->setJSON($result); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function findAddresses() + { + if ($this->request->isAJAX()) { + + $ot_id = $this->request->getGet("ot_id"); + + $query = EtiquetasTitulosService::getDireccionesOT($ot_id); + + if ($this->request->getGet("q")) { + $query->groupStart() + ->orLike("pd.direccion", $this->request->getGet("q")) + ->groupEnd(); + } + + + $result = $query->orderBy("pd.direccion", "ASC")->get()->getResultObject(); + + return $this->response->setJSON($result); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function addEtiqueta() + { + if ($this->request->isAJAX()) { + + $data = []; + $data['user_id'] = auth()->user()->id; + $data['ot_id'] = $this->request->getPost('ot_id') ?? null; + $data['direccion'] = $this->request->getPost('direccion') ?? null; + $data['unidades_caja'] = $this->request->getPost('unidades_caja') ?? null; + + if( + $this->request->getPost('ot_id') == null || + $this->request->getPost('direccion') == null || + $this->request->getPost('unidades_caja') == null + ){ + return [ + 'status' => false, + 'message' => lang('Logistica.errorMissingData') + ]; + } + + $result = EtiquetasTitulosService::addEtiqueta($data); + + return $this->response->setJSON($result); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } +} \ No newline at end of file diff --git a/ci4/app/Controllers/Logistica/LogisticaController.php b/ci4/app/Controllers/Logistica/LogisticaController.php index d8dade10..586bb83d 100755 --- a/ci4/app/Controllers/Logistica/LogisticaController.php +++ b/ci4/app/Controllers/Logistica/LogisticaController.php @@ -85,6 +85,19 @@ class LogisticaController extends BaseController return view(static::$viewPath . 'viewLogisticaSelectEnvios', $viewData); } + public function etiquetasLogistica() + { + $viewData = [ + 'currentModule' => static::$controllerSlug, + 'boxTitle' => lang('Logistica.etiquetasTitulos'), + 'usingServerSideDataTable' => true, + ]; + + $viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class + + return view(static::$viewPath . 'viewImpresionEtiquetas', $viewData); + } + public function listAlbaranes(){ $viewData = [ 'currentModule' => static::$controllerSlug, diff --git a/ci4/app/Database/Migrations/2025-05-03-094500_CreateEtiquetasTitulos.php b/ci4/app/Database/Migrations/2025-05-03-094500_CreateEtiquetasTitulos.php new file mode 100644 index 00000000..18baa8a8 --- /dev/null +++ b/ci4/app/Database/Migrations/2025-05-03-094500_CreateEtiquetasTitulos.php @@ -0,0 +1,60 @@ +forge->addField([ + 'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true], + 'comentarios' => ['type' => 'TEXT', 'null' => true], + 'direccion' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => false], + 'att' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => false], + 'cliente_id' => ['type' => 'INT', 'unsigned' => true, 'null' => true], + 'created_at' => ['type' => 'DATETIME', 'null' => true], + 'updated_at' => ['type' => 'DATETIME', 'null' => true], + 'deleted_at' => ['type' => 'DATETIME', 'null' => true], + 'user_created_at' => ['type' => 'INT', 'unsigned' => true, 'null' => true], + 'user_updated_at' => ['type' => 'INT', 'unsigned' => true, 'null' => true], + 'user_deleted_at' => ['type' => 'INT', 'unsigned' => true, 'null' => true], + ]); + $this->forge->addKey('id', true); + $this->forge->addForeignKey('user_created_at', 'users', 'id', 'SET NULL', 'CASCADE'); + $this->forge->addForeignKey('user_updated_at', 'users', 'id', 'SET NULL', 'CASCADE'); + $this->forge->addForeignKey('user_deleted_at', 'users', 'id', 'SET NULL', 'CASCADE'); + $this->forge->addForeignKey('cliente_id', 'clientes', 'id', 'SET NULL', 'CASCADE'); + $this->forge->createTable('etiquetas_titulos'); + + // Tabla: etiquetas_titulos_lineas + $this->forge->addField([ + 'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true], + 'etiqueta_titulos_id' => ['type' => 'INT', 'unsigned' => true], + 'ot_id' => ['type' => 'INT', 'unsigned' => true], + 'unidades' => ['type' => 'INT', 'unsigned' => true], + 'numero_caja' => ['type' => 'INT', 'unsigned' => true], + 'created_at' => ['type' => 'DATETIME', 'null' => true], + 'updated_at' => ['type' => 'DATETIME', 'null' => true], + 'deleted_at' => ['type' => 'DATETIME', 'null' => true], + 'user_created_at' => ['type' => 'INT', 'unsigned' => true, 'null' => true], + 'user_updated_at' => ['type' => 'INT', 'unsigned' => true, 'null' => true], + 'user_deleted_at' => ['type' => 'INT', 'unsigned' => true, 'null' => true], + ]); + $this->forge->addKey('id', true); + $this->forge->addForeignKey('etiqueta_titulos_id', 'etiquetas_titulos', 'id', 'CASCADE', 'CASCADE'); + $this->forge->addForeignKey('ot_id', 'ordenes_trabajo', 'id', 'CASCADE', 'CASCADE'); + $this->forge->addForeignKey('user_created_at', 'users', 'id', 'SET NULL', 'CASCADE'); + $this->forge->addForeignKey('user_updated_at', 'users', 'id', 'SET NULL', 'CASCADE'); + $this->forge->addForeignKey('user_deleted_at', 'users', 'id', 'SET NULL', 'CASCADE'); + $this->forge->createTable('etiquetas_titulos_lineas'); + } + + public function down() + { + $this->forge->dropTable('etiquetas_titulos_lineas', true); + $this->forge->dropTable('etiquetas_titulos', true); + } +} diff --git a/ci4/app/Entities/Etiquetas/EtiquetaTitulo.php b/ci4/app/Entities/Etiquetas/EtiquetaTitulo.php new file mode 100644 index 00000000..35168ebf --- /dev/null +++ b/ci4/app/Entities/Etiquetas/EtiquetaTitulo.php @@ -0,0 +1,17 @@ +where('etiqueta_titulos_id', $this->id)->findAll(); + } +} diff --git a/ci4/app/Entities/Etiquetas/EtiquetaTituloLinea.php b/ci4/app/Entities/Etiquetas/EtiquetaTituloLinea.php new file mode 100644 index 00000000..74ee95a6 --- /dev/null +++ b/ci4/app/Entities/Etiquetas/EtiquetaTituloLinea.php @@ -0,0 +1,10 @@ + 'Finalizar envío', 'finalizarEnvioYOTs' => 'Finalizar envío y OTS', + + 'id' => 'ID', + 'numeroCajas' => 'Nº Cajas', + 'listadoEtiquetas' => 'Listado de etiquetas', + 'nuevaEtiqueta' => 'Nueva etiqueta', + + '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 no está en producción o finalizado o no tiene envíos pendientes', 'noAddresses' => 'El pedido no tiene direcciones de envío', + 'errorMissingData' => 'Faltan datos para crear la etiqueta', + 'errorInsertarEtiqueta' => 'Error al insertar la etiqueta', ], 'success' => [ 'finalizado' => 'El envío se ha finalizado correctamente', diff --git a/ci4/app/Models/Etiquetas/EtiquetasTitulosLineasModel.php b/ci4/app/Models/Etiquetas/EtiquetasTitulosLineasModel.php new file mode 100644 index 00000000..01ee3db4 --- /dev/null +++ b/ci4/app/Models/Etiquetas/EtiquetasTitulosLineasModel.php @@ -0,0 +1,35 @@ +table('ordenes_trabajo ot') + ->select(" + ot.id AS id, + CONCAT('[', ot.id, '] - ', pr.titulo) AS name") + ->join('pedidos p', 'p.id = ot.pedido_id') + ->join('pedidos_linea pl', 'p.id = pl.pedido_id') + ->join('presupuestos pr', 'pr.id = pl.presupuesto_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'); + + return $builder; + } + + public static function getDireccionesOT($ot_id){ + + $db = \Config\Database::connect(); + + // 3. Subconsulta principal + $builder = $db->table('presupuesto_direcciones pd') + ->select(" + pd.id AS id, + pd.direccion AS name") + ->join('presupuestos pr', 'pr.id = pd.presupuesto_id') + ->join('pedidos_linea pl', 'pr.id = pl.presupuesto_id') + ->join('pedidos p', 'p.id = pl.pedido_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') + ->where('ot.id', $ot_id); + + return $builder; + } + + public static function addEtiqueta($data) + { + $db = \Config\Database::connect(); + + $builder = $db->table('presupuesto_direcciones pd'); + $builder->select('pd.att, pd.direccion, pd.cantidad, pr.cliente_id'); + $builder->join('presupuestos pr', 'pr.id = pd.presupuesto_id'); + $builder->join('pedidos_linea pl', 'pr.id = pl.presupuesto_id'); + $builder->join('pedidos p', 'p.id = pl.pedido_id'); + $builder->join('ordenes_trabajo ot', 'ot.pedido_id = p.id'); + $builder->where('ot.id', $data['ot_id']); + $builder->where('pd.direccion', $data['direccion']); + + $result = $builder->get()->getRow(); + $data['att'] = $result->att; + $data['direccion'] = $result->direccion; + $data['cantidad'] = $result->cantidad; + $data['cliente_id'] = $result->cliente_id; + + $modelEtiquetasTitulos = model('App\Models\Etiquetas\EtiquetasTitulosModel'); + $modelEtiquetasTitulos->insert([ + 'direccion' => $data['direccion'], + 'att' => $data['att'], + 'cliente_id' => $data['cliente_id'], + 'user_created_at' => $data['user_id'], + ]); + $etiquetaId = $modelEtiquetasTitulos->getInsertID(); + + if($etiquetaId == null){ + return [ + 'status' => false, + 'message' => lang('Logistica.errorInsertarEtiqueta'), + ]; + } + + $cantidad_restante = intval($data['cantidad']); + $numero_caja = 1; + while($cantidad_restante > 0){ + $modelEtiquetasTitulosLineas = model('App\Models\Etiquetas\EtiquetasTitulosLineasModel'); + $modelEtiquetasTitulosLineas->insert([ + 'etiqueta_titulos_id' => $etiquetaId, + 'ot_id' => $data['ot_id'], + 'unidades' => $cantidad_restante - intval($data['unidades_caja']) < 0 ? $cantidad_restante : intval($data['unidades_caja']), + 'numero_caja' => $numero_caja, + 'user_created_at' => $data['user_id'], + ]); + $cantidad_restante -= $data['unidades_caja']; + $numero_caja++; + } + + + return [ + 'status' => true, + 'etiqueta' => $etiquetaId, + ]; + } +} \ No newline at end of file diff --git a/ci4/app/Services/LogisticaService.php b/ci4/app/Services/LogisticaService.php index d2251313..cb4fb1b5 100644 --- a/ci4/app/Services/LogisticaService.php +++ b/ci4/app/Services/LogisticaService.php @@ -78,6 +78,7 @@ class LogisticaService return $builder; } + public static function findForNewEnvio() { $db = \Config\Database::connect(); @@ -576,11 +577,11 @@ class LogisticaService $data = [ "printer" => $printer->name, "header" => [ - "_FORMAT" => "E:PEDIDO.ZPL", - "_QUANTITY" => 1, - "_PRINBTERNAME" => $printer->name, - "_JOBNAME" => "LBL101" - ], + "_FORMAT" => "E:PEDIDO.ZPL", + "_QUANTITY" => 1, + "_PRINBTERNAME" => $printer->name, + "_JOBNAME" => "LBL101" + ], ]; foreach ($lineas as $linea) { diff --git a/ci4/app/Views/themes/vuexy/form/logistica/viewImpresionEtiquetas.php b/ci4/app/Views/themes/vuexy/form/logistica/viewImpresionEtiquetas.php new file mode 100644 index 00000000..8966d68f --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/logistica/viewImpresionEtiquetas.php @@ -0,0 +1,119 @@ += $this->include("themes/_commonPartialsBs/sweetalert") ?> += $this->include('themes/_commonPartialsBs/datatables') ?> += $this->include("themes/_commonPartialsBs/select2bs5") ?> += $this->extend('themes/vuexy/main/defaultlayout') ?> + += $this->section('content'); ?> +
| = lang('Logistica.id') ?? 'ID Envío' ?> | += lang('Logistica.numeroOts') ?? 'Nº OTs' ?> | += lang('Logistica.numeroCajas') ?? 'Nº Cajas' ?> | += lang('Logistica.att') ?? 'Att' ?> | += lang('Logistica.direccion') ?? 'Dirección' ?> | += lang('Logistica.acciones') ?? 'Acciones' ?> | +
|---|---|---|---|---|---|
| + | + | + | + | + | + |