From 19fd76e910c5e13dedaf5504c3daf671a8e63b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Jim=C3=A9nez?= Date: Sun, 20 Apr 2025 22:10:56 +0200 Subject: [PATCH] falta terminar albaranes --- ci4/app/Config/Routes.php | 2 + ci4/app/Controllers/Albaranes/Albaran.php | 419 ++++++++++++++ .../Logistica/LogisticaController.php | 18 +- ...1500_ModifyAlbaranesAndAlbaranesLineas.php | 98 ++++ ...2025-04-20-111500_AddClienteIdToEnvios.php | 29 + .../2025-04-20-124400_RenameCajasNull.php | 32 ++ ...5-04-20-203000_update_envios_albaranes.php | 90 +++ ...5-04-20-210000_FixDeletedAtToDatetime .php | 28 + ci4/app/Entities/Albaranes/AlbaranEntity.php | 44 ++ .../Entities/Albaranes/AlbaranLineaEntity.php | 40 ++ ci4/app/Entities/Logistica/EnvioEntity.php | 1 + .../Entities/Logistica/EnvioLineaEntity.php | 2 - ci4/app/Language/es/Albaran.php | 29 + ci4/app/Language/es/Logistica.php | 5 + .../Models/Albaranes/AlbaranLineaModel.php | 85 +++ ci4/app/Models/Albaranes/AlbaranModel.php | 203 +++++++ ci4/app/Models/Logistica/EnvioLineaModel.php | 18 +- ci4/app/Models/Logistica/EnvioModel.php | 2 +- .../form/logistica/viewEnvioEditForm.php | 39 +- .../js/safekat/components/albaranComponent.js | 481 ++++++++++++++++ .../js/safekat/pages/logistica/envioEdit.js | 530 ++++-------------- 21 files changed, 1731 insertions(+), 464 deletions(-) create mode 100644 ci4/app/Controllers/Albaranes/Albaran.php create mode 100644 ci4/app/Database/Migrations/2025-04-20-101500_ModifyAlbaranesAndAlbaranesLineas.php create mode 100644 ci4/app/Database/Migrations/2025-04-20-111500_AddClienteIdToEnvios.php create mode 100644 ci4/app/Database/Migrations/2025-04-20-124400_RenameCajasNull.php create mode 100644 ci4/app/Database/Migrations/2025-04-20-203000_update_envios_albaranes.php create mode 100644 ci4/app/Database/Migrations/2025-04-20-210000_FixDeletedAtToDatetime .php create mode 100644 ci4/app/Entities/Albaranes/AlbaranEntity.php create mode 100644 ci4/app/Entities/Albaranes/AlbaranLineaEntity.php create mode 100644 ci4/app/Language/es/Albaran.php create mode 100644 ci4/app/Models/Albaranes/AlbaranLineaModel.php create mode 100644 ci4/app/Models/Albaranes/AlbaranModel.php create mode 100644 httpdocs/assets/js/safekat/components/albaranComponent.js diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index e7f8686b..fd6ed76e 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -511,6 +511,7 @@ $routes->group('albaranes', ['namespace' => 'App\Controllers\Albaranes'], functi $routes->get('datatablesAlbaranLinea', 'Albaran::datatablesLineasAlbaran'); $routes->post('updateAlbaran', 'Albaran::updateAlbaran'); $routes->post('borrarAlbaranLinea', 'Albaran::borrarLinea'); + $routes->post('borrarAlbaran', 'Albaran::borrarAlbaran'); }); $routes->resource('albaranes', ['namespace' => 'App\Controllers\Pedidos', 'controller' => 'Albaran', 'except' => 'show,new,create,update']); @@ -787,6 +788,7 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi $routes->post('deleteLineasEnvio', 'LogisticaController::deleteLineas'); $routes->post('updateLineaEnvio', 'LogisticaController::updateLineaEnvio'); $routes->post('updateComentariosEnvio', 'LogisticaController::saveComments'); + $routes->post('updateCajasEnvio', 'LogisticaController::updateCajasEnvio'); }); /* diff --git a/ci4/app/Controllers/Albaranes/Albaran.php b/ci4/app/Controllers/Albaranes/Albaran.php new file mode 100644 index 00000000..3fc586e9 --- /dev/null +++ b/ci4/app/Controllers/Albaranes/Albaran.php @@ -0,0 +1,419 @@ +request->isAJAX()) { + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + + $model_linea = model('App\Models\Albaranes\AlbaranLineaModel'); + $model_linea->where('albaran_id', $id)->delete(); + + $this->model->where('id', $id)->delete(); + + $data = [ + 'error' => 0, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function addLinea($albaran_id) + { + + if ($this->request->isAJAX()) { + + $model_linea = model('App\Models\Albaranes\AlbaranLineaModel'); + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + + // si es un post, es el iva + if ($this->request->getPost()) { + $reqData = $this->request->getPost(); + $albaran_id = $reqData['albaran_id'] ?? 0; + + $albaran = $this->model->find($albaran_id); + if ($albaran == false) { + $data = [ + 'error' => 'Albaran no encontrado', + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } + $presupuesto_model = model('App\Models\Presupuestos\PresupuestoModel'); + $presupuesto = $presupuesto_model->find($albaran->presupuesto_id); + if ($presupuesto == false) { + $data = [ + 'error' => 'Presupuesto no encontrado', + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } + $iva_reducido = $presupuesto->iva_reducido; + $lineas = $model_linea->where('albaran_id', $albaran_id)->findAll(); + $total = 0; + foreach ($lineas as $linea) { + $total += $linea->total; + } + $iva = $iva_reducido ? $total * 4.0 / 100 : $total * 21.0 / 100; + $data_linea = [ + 'albaran_id' => $albaran_id, + 'titulo' => $iva_reducido ? lang('Pedidos.iva4') : lang('Pedidos.iva21'), + 'cantidad' => 1, + 'precio_unidad' => round($iva, 2), + 'total' => round($iva, 2), + 'user_created_id' => auth()->user()->id, + 'user_updated_id' => auth()->user()->id + ]; + $id_linea = $model_linea->insert($data_linea); + $linea = $model_linea->find($id_linea); + $data = [ + 'error' => 0, + 'data' => $linea, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } else { + $linea = [ + 'albaran_id' => $albaran_id, + 'user_created_id' => auth()->user()->id, + 'user_updated_id' => auth()->user()->id + ]; + $id_linea = $model_linea->insert($linea); + $data = $model_linea->find($id_linea); + + $data = [ + 'error' => 0, + 'data' => $data, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function add() + { + if ($this->request->isAJAX()) { + + $user = auth()->user()->id; + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + + $reqData = $this->request->getPost(); + $pedido_id = $reqData['pedido_id'] ?? 0; + $presupuestos_id = $reqData['presupuestos_id'] ?? 0; + + $return_data = $this->model->generarAlbaranes($pedido_id, $presupuestos_id, $user); + $data = [ + 'data' => $return_data, + $csrfTokenName => $newTokenHash + ]; + + return $this->respond($data); + + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function updateAlbaran() + { + + if ($this->request->isAJAX()) { + + $fieldName = $this->request->getPost('fieldName'); + $fieldValue = $this->request->getPost('fieldValue'); + $id = $this->request->getPost('albaranId'); + + if ($id == null) { + $data = [ + 'success' => false, + 'message' => lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Pedidos.albaran')), $id]), + ]; + return $this->respond($data); + } + $albaranEntity = $this->model->find($id); + + if ($albaranEntity == false) { + $data = [ + 'success' => false, + 'message' => lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Pedidos.albaran')), $id]), + ]; + return $this->respond($data); + } + + $albaranEntity->fill([ + $fieldName => $fieldValue, + 'user_updated_id' => auth()->user()->id, + ]); + $successfulResult = $this->model->skipValidation(true)->update($id, $albaranEntity); + if ($successfulResult) { + $data = [ + 'success' => true, + 'message' => lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.', + ]; + } else { + $data = [ + 'success' => false, + 'message' => lang('Basic.global.updateError', [lang('Basic.global.record')]) . '.', + ]; + } + + return $this->respond($data); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + + public function updateLinea($id = null) + { + + if ($this->request->isAJAX()) { + + $model_linea = model('App\Models\Albaranes\AlbaranLineaModel'); + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + + if ($id == null): + $data = [ + 'error' => 2, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + endif; + $id = filter_var($id, FILTER_SANITIZE_URL); + $albaranEntity = $model_linea->find($id); + + if ($albaranEntity == false): + $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Pedidos.albaran')), $id]); + $data = [ + 'error' => $message, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + endif; + + if ($this->request->getPost()): + + $nullIfEmpty = true; // !(phpversion() >= '8.1'); + + $postData = $this->request->getPost(); + + $sanitizedData = $this->sanitized($postData, $nullIfEmpty); + + // JJO + $sanitizedData['user_updated_id'] = auth()->user()->id; + + $noException = true; + if ($successfulResult = $this->canValidate()): // if ($successfulResult = $this->validate($this->formValidationRules) ) : + + if ($this->canValidate()): + try { + $successfulResult = $model_linea->skipValidation(true)->update($id, $sanitizedData); + } catch (\Exception $e) { + $noException = false; + $this->dealWithException($e); + } + else: + $this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Pedidos.albaran'))]); + $this->session->setFlashdata('formErrors', $model_linea->errors()); + + endif; + + $albaranEntity->fill($sanitizedData); + + endif; + if ($noException && $successfulResult): + $id = $albaranEntity->id ?? $id; + $message = lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.'; + + $data = [ + 'error' => 0, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + + endif; // $noException && $successfulResult + endif; // ($requestMethod === 'post') + + $data = [ + 'error' => 1, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + + public function getAlbaranes() + { + + if ($this->request->isAJAX()) { + + $envio_id = $this->request->getGet('envio_id'); + $albaranes = $this->model->getAlbaranesEnvio($envio_id); + $data = [ + 'status' => true, + 'data' => $albaranes, + ]; + return $this->respond($data); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function generateAlbaran() + { + + if ($this->request->isAJAX()) { + + $reqData = $this->request->getPost(); + $envio_id = $reqData['envio_id'] ?? 0; + $envio_lineas = $reqData['envio_lineas'] ?? []; + $cajas = $reqData['cajas'] ?? 0; + + $response = $this->model->generarAlbaranes($envio_id, $envio_lineas, $cajas); + + return $this->respond($response); + + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function datatablesLineasAlbaran() + { + + $albaranId = $this->request->getGet('albaranId'); + $model = model('App\Models\Albaranes\AlbaranLineaModel'); + $q = $model->getDatatableQuery($albaranId); + + $result = DataTable::of($q) + ->add( + "action", + callback: function ($q) { + return ' +
+ +
+ '; + } + ) + ->edit('pedido', function ($q) { + return '' . $q->pedido . ''; + }) + ->edit('unidades', function ($q) { + return ''; + }) + ->edit('titulo', function ($q) { + return ''; + }) + ->edit('total', function ($q) { + return ''; + }) + ->edit('precio_unidad', function ($q) { + return ''; + }); + + + return $result->toJson(returnAsObject: true); + } + + public function borrarLinea() + { + + if ($this->request->isAJAX()) { + + $model_linea = model('App\Models\Albaranes\AlbaranLineaModel'); + + $reqData = $this->request->getPost(); + $id = $reqData['linea'] ?? 0; + $id = filter_var($id, FILTER_SANITIZE_URL); + $albaranLineaEntity = $model_linea->find($id); + + if ($albaranLineaEntity == false): + $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Pedidos.albaran')), $id]); + $data = [ + 'success' => false, + 'error' => $message, + ]; + return $this->respond($data); + endif; + + $successfulResult = $model_linea->skipValidation(true)->update($id, ['deleted_at' => date('Y-m-d H:i:s')]); + + if ($successfulResult): + $data = [ + 'success' => true, + ]; + else: + $data = [ + 'success' => false, + 'error' => lang('Basic.global.deleteError', [lang('Basic.global.record')]) . '.', + ]; + endif; + return $this->respond($data); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function borrarAlbaran() + { + + if ($this->request->isAJAX()) { + + $id = $this->request->getPost('albaranId'); + $model_linea = model('App\Models\Albaranes\AlbaranLineaModel'); + $model_linea->where('albaran_id', $id)->delete(); + + $this->model->where('id', $id)->delete(); + + $data = [ + 'success' => true + ]; + return $this->respond($data); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + +} diff --git a/ci4/app/Controllers/Logistica/LogisticaController.php b/ci4/app/Controllers/Logistica/LogisticaController.php index cb03b5a4..1e00f72f 100644 --- a/ci4/app/Controllers/Logistica/LogisticaController.php +++ b/ci4/app/Controllers/Logistica/LogisticaController.php @@ -163,7 +163,6 @@ class LogisticaController extends BaseController if (empty($envioEntity)) { return redirect()->to(base_url('logistica/selectEnvios/simple'))->with('error', lang('Logistica.errors.noEnvio')); } - $envioEntity->nextCaja = model('App\Models\Logistica\EnvioLineaModel')->getMaxCaja(); $viewData = [ 'currentModule' => static::$controllerSlug, @@ -177,6 +176,23 @@ class LogisticaController extends BaseController return view(static::$viewPath . 'viewEnvioEditForm', $viewData); } + public function updateCajasEnvio() + { + if ($this->request->isAJAX()) { + $id = $this->request->getPost('id'); + $cajas = $this->request->getPost('cajas'); + $model = model('App\Models\Logistica\EnvioModel'); + $result = $model->update($id, [ + 'cajas' => $cajas, + ]); + return $this->response->setJSON([ + "status" => $result, + ]); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + public function datatable_enviosEdit($idEnvio) { $model = model('App\Models\Logistica\EnvioLineaModel'); diff --git a/ci4/app/Database/Migrations/2025-04-20-101500_ModifyAlbaranesAndAlbaranesLineas.php b/ci4/app/Database/Migrations/2025-04-20-101500_ModifyAlbaranesAndAlbaranesLineas.php new file mode 100644 index 00000000..ed1b8ebd --- /dev/null +++ b/ci4/app/Database/Migrations/2025-04-20-101500_ModifyAlbaranesAndAlbaranesLineas.php @@ -0,0 +1,98 @@ +forge->dropColumn('albaranes', [ + 'pedido_id', + 'presupuesto_id', + 'presupuesto_direccion_id', + 'total' + ]); + + $this->forge->addColumn('albaranes', [ + 'fecha_albaran' => [ + 'type' => 'DATE', + 'null' => true, + 'after' => 'numero_albaran' + ], + 'envio_id' => [ + 'type' => 'INT', + 'constraint' => 10, + 'unsigned' => true, + 'null' => true, + 'after' => 'fecha_albaran' + ] + ]); + + // Añadir foreign key a envios con ON DELETE SET NULL + $this->db->query('ALTER TABLE `albaranes` + ADD CONSTRAINT `fk_albaranes_envio_id` FOREIGN KEY (`envio_id`) + REFERENCES `envios`(`id`) ON DELETE SET NULL ON UPDATE CASCADE'); + + // --- Tabla albaranes_lineas --- + $this->forge->dropColumn('albaranes_lineas', ['cajas', 'ejemplares_por_caja']); + + $this->forge->addColumn('albaranes_lineas', [ + 'iva_reducido' => [ + 'type' => 'TINYINT', + 'constraint' => 1, + 'default' => 0, + 'null' => false, + 'after' => 'precio_unidad' + ] + ]); + } + + public function down() + { + // Deshacer cambios tabla albaranes + $this->forge->dropForeignKey('albaranes', 'fk_albaranes_envio_id'); + $this->forge->dropColumn('albaranes', ['envio_id', 'fecha_albaran']); + + $this->forge->addColumn('albaranes', [ + 'pedido_id' => [ + 'type' => 'INT', + 'constraint' => 10, + 'unsigned' => true, + 'null' => true, + ], + 'presupuesto_id' => [ + 'type' => 'INT', + 'constraint' => 10, + 'unsigned' => true, + 'null' => true, + ], + 'presupuesto_direccion_id' => [ + 'type' => 'INT', + 'constraint' => 10, + 'unsigned' => true, + 'null' => true, + ], + 'total' => [ + 'type' => 'DOUBLE', + 'null' => true, + ], + ]); + + // Deshacer cambios tabla albaranes_lineas + $this->forge->dropColumn('albaranes_lineas', ['iva_reducido']); + + $this->forge->addColumn('albaranes_lineas', [ + 'cajas' => [ + 'type' => 'INT', + 'null' => true, + ], + 'ejemplares_por_caja' => [ + 'type' => 'INT', + 'null' => true, + ], + ]); + } +} diff --git a/ci4/app/Database/Migrations/2025-04-20-111500_AddClienteIdToEnvios.php b/ci4/app/Database/Migrations/2025-04-20-111500_AddClienteIdToEnvios.php new file mode 100644 index 00000000..71faaf82 --- /dev/null +++ b/ci4/app/Database/Migrations/2025-04-20-111500_AddClienteIdToEnvios.php @@ -0,0 +1,29 @@ +forge->addColumn('envios', [ + 'cliente_id' => [ + 'type' => 'INT', + 'constraint' => 11, + 'unsigned' => true, // IMPORTANTE + 'null' => true, + 'after' => 'id', + ], + ]); + + $this->db->query('ALTER TABLE envios ADD CONSTRAINT fk_envios_cliente FOREIGN KEY (cliente_id) REFERENCES clientes(id) ON DELETE SET NULL ON UPDATE CASCADE'); + } + + public function down() + { + $this->db->query('ALTER TABLE envios DROP FOREIGN KEY fk_envios_cliente'); + $this->forge->dropColumn('envios', 'cliente_id'); + } +} diff --git a/ci4/app/Database/Migrations/2025-04-20-124400_RenameCajasNull.php b/ci4/app/Database/Migrations/2025-04-20-124400_RenameCajasNull.php new file mode 100644 index 00000000..c767466f --- /dev/null +++ b/ci4/app/Database/Migrations/2025-04-20-124400_RenameCajasNull.php @@ -0,0 +1,32 @@ +forge->modifyColumn('envios_lineas', [ + 'cajas' => [ + 'type' => 'INT', + 'constraint' => 11, + 'null' => true, + 'default' => null, + ], + ]); + } + + public function down() + { + $this->forge->modifyColumn('envios_lineas', [ + 'cajas' => [ + 'type' => 'INT', + 'constraint' => 11, + 'null' => false, + 'default' => 0, + ], + ]); + } +} diff --git a/ci4/app/Database/Migrations/2025-04-20-203000_update_envios_albaranes.php b/ci4/app/Database/Migrations/2025-04-20-203000_update_envios_albaranes.php new file mode 100644 index 00000000..b77e5e86 --- /dev/null +++ b/ci4/app/Database/Migrations/2025-04-20-203000_update_envios_albaranes.php @@ -0,0 +1,90 @@ +forge->dropColumn('envios_lineas', ['cajas', 'unidades_cajas']); + + // 2. Añadir columna 'cajas' en envios + $this->forge->addColumn('envios', [ + 'cajas' => [ + 'type' => 'INT', + 'constraint' => 11, + 'default' => 0, + 'after' => 'comentarios' + ] + ]); + + // 2. Quitar columna multienvio de envios + $this->forge->dropColumn('envios', 'multienvio'); + + // 3. Añadir columna 'cajas' en albaranes + $this->forge->addColumn('albaranes', [ + 'cajas' => [ + 'type' => 'INT', + 'constraint' => 11, + 'default' => 0, + 'after' => 'envio_id' + ] + ]); + + // 4. Añadir columna 'pedido_linea_id' a albaranes_lineas + $this->forge->addColumn('albaranes_lineas', [ + 'pedido_linea_id' => [ + 'type' => 'INT', + 'constraint' => 11, + 'unsigned' => true, + 'null' => true, + 'after' => 'albaran_id' + ] + ]); + + // 5. Foreign key a pedidos_lineas + $this->db->query(" + ALTER TABLE albaranes_lineas + ADD CONSTRAINT fk_albaranes_lineas_pedido_linea + FOREIGN KEY (pedido_linea_id) REFERENCES pedidos_linea(id) + ON DELETE SET NULL ON UPDATE CASCADE + "); + } + + public function down() + { + // Revertir cajas en envios_lineas + $this->forge->addColumn('envios_lineas', [ + 'cajas' => [ + 'type' => 'INT', + 'constraint' => 11, + 'null' => true, + ], + 'unidades_cajas' => [ + 'type' => 'INT', + 'constraint' => 11, + 'null' => true, + ] + ]); + + $this->forge->addColumn('envios', [ + 'multienvio' => [ + 'type' => 'TINYINT', + 'constraint' => 3, + 'unsigned' => true, + 'default' => 0 + ] + ]); + + // Quitar columnas añadidas + $this->forge->dropColumn('envios', 'cajas'); + $this->forge->dropColumn('albaranes', 'cajas'); + + // Quitar foreign y columna pedido_linea_id + $this->db->query("ALTER TABLE albaranes_lineas DROP FOREIGN KEY fk_albaranes_lineas_pedido_linea"); + $this->forge->dropColumn('albaranes_lineas', 'pedido_linea_id'); + } +} diff --git a/ci4/app/Database/Migrations/2025-04-20-210000_FixDeletedAtToDatetime .php b/ci4/app/Database/Migrations/2025-04-20-210000_FixDeletedAtToDatetime .php new file mode 100644 index 00000000..1ab51870 --- /dev/null +++ b/ci4/app/Database/Migrations/2025-04-20-210000_FixDeletedAtToDatetime .php @@ -0,0 +1,28 @@ +db->query("ALTER TABLE {$tabla} MODIFY COLUMN deleted_at DATETIME NULL"); + } + } + + public function down() + { + // Opcional: puedes restaurar como TIMESTAMP NULL si lo deseas + $tablas = ['albaranes', 'albaranes_lineas', 'envios', 'envios_lineas']; + + foreach ($tablas as $tabla) { + $this->db->query("ALTER TABLE {$tabla} MODIFY COLUMN deleted_at TIMESTAMP NULL"); + } + } +} diff --git a/ci4/app/Entities/Albaranes/AlbaranEntity.php b/ci4/app/Entities/Albaranes/AlbaranEntity.php new file mode 100644 index 00000000..6c2d61e3 --- /dev/null +++ b/ci4/app/Entities/Albaranes/AlbaranEntity.php @@ -0,0 +1,44 @@ + null, + 'envio_id' => null, + 'cliente_id' => null, + 'serie_id' => null, + 'numero_albaran' => null, + 'mostrar_precios' => null, + 'direccion_albaran' => null, + 'att_albaran' => null, + 'user_created_id' => null, + 'user_updated_id' => null, + 'created_at' => null, + 'updated_at' => null, + 'deleted_at' => null, + 'cajas' => null, + ]; + + protected $dates = ['created_at', 'updated_at', 'deleted_at']; + + protected $casts = [ + 'id' => 'integer', + 'envio_id' => '?integer', + 'presupuesto_id' => '?integer', + 'presupuesto_direccion_id' => '?integer', + 'cliente_id' => '?integer', + 'serie_id' => '?integer', + 'numero_albaran' => '?string', + 'mostrar_precios' => '?boolean', + 'total' => 'float', + 'direccion_albaran' => '?string', + 'att_albaran' => '?string', + 'user_created_id' => 'integer', + 'user_updated_id' => 'integer', + ]; + + // Agrega tus métodos personalizados aquí +} diff --git a/ci4/app/Entities/Albaranes/AlbaranLineaEntity.php b/ci4/app/Entities/Albaranes/AlbaranLineaEntity.php new file mode 100644 index 00000000..fc800c64 --- /dev/null +++ b/ci4/app/Entities/Albaranes/AlbaranLineaEntity.php @@ -0,0 +1,40 @@ + null, + 'albaran_id' => null, + 'pedido_linea_id' => null, + 'titulo' => null, + 'isbn' => null, + 'ref_cliente' => null, + 'cantidad' => null, + 'precio_unidad' => null, + 'total' => null, + 'iva_reducido' => null, + 'user_created_id' => null, + 'user_updated_id' => null, + 'created_at' => null, + 'updated_at' => null, + 'deleted_at' => null, + ]; + + protected $casts = [ + 'id' => 'integer', + 'albaran_id' => '?integer', + 'pedido_linea_id' => '?integer', + 'titulo' => 'string', + 'isbn' => '?string', + 'ref_cliente' => '?string', + 'cantidad' => '?integer', + 'precio_unidad' => 'float', + 'total' => 'float', + 'iva_reducido' => '?boolean', + 'user_created_id' => 'integer', + 'user_updated_id' => 'integer', + ]; +} \ No newline at end of file diff --git a/ci4/app/Entities/Logistica/EnvioEntity.php b/ci4/app/Entities/Logistica/EnvioEntity.php index 5ff38b95..e6bef114 100644 --- a/ci4/app/Entities/Logistica/EnvioEntity.php +++ b/ci4/app/Entities/Logistica/EnvioEntity.php @@ -30,5 +30,6 @@ class EnvioEntity extends Entity 'mostrar_iva' => 'boolean', 'created_at' => 'datetime', 'updated_at' => 'datetime', + 'cajas' => 'int', ]; } diff --git a/ci4/app/Entities/Logistica/EnvioLineaEntity.php b/ci4/app/Entities/Logistica/EnvioLineaEntity.php index bc258aad..2ab1a749 100644 --- a/ci4/app/Entities/Logistica/EnvioLineaEntity.php +++ b/ci4/app/Entities/Logistica/EnvioLineaEntity.php @@ -13,8 +13,6 @@ class EnvioLineaEntity extends Entity 'presupuesto_id' => 'int', 'unidades_envio' => 'int', 'unidades_total' => 'int', - 'cajas' => 'int', - 'unidades_cajas' => 'int', 'created_by' => 'int', 'updated_by' => 'int', 'created_at' => 'datetime', diff --git a/ci4/app/Language/es/Albaran.php b/ci4/app/Language/es/Albaran.php new file mode 100644 index 00000000..88131b0f --- /dev/null +++ b/ci4/app/Language/es/Albaran.php @@ -0,0 +1,29 @@ + 'Fecha de creación', + "fechaAlbaran" => 'Fecha de albarán', + 'numEnvio' => 'Número de envío', + 'cliente' => 'Cliente', + 'albaran' => 'Albarán', + 'att' => 'Att', + 'direccion' => 'Dirección', + 'cajas' => 'Cajas', + + 'unidades' => 'Unidades', + 'titulo' => 'Título', + 'ISBN' => 'ISBN', + 'refCliente' => 'Ref. cliente', + 'precioU' => 'Precio/Unidad', + 'subtotal' => 'Subtotal', + 'pedido' => 'Pedido', + + 'mostrarPrecios' => 'Mostrar precios', + 'addIva' => 'Añadir IVA', + 'nuevaLinea' => 'Nueva línea', + 'imprimirAlbaran' => 'Imprimir albarán', + 'borrarAlbaran' => 'Borrar albarán', + 'borrarAlbaranConfirm' => '¿Está seguro de que desea borrar el albarán?', + 'borrar' => 'Borrar', + 'cancelar' => 'Cancelar', + +]; \ No newline at end of file diff --git a/ci4/app/Language/es/Logistica.php b/ci4/app/Language/es/Logistica.php index 059e1d34..c9eaf9c2 100644 --- a/ci4/app/Language/es/Logistica.php +++ b/ci4/app/Language/es/Logistica.php @@ -39,6 +39,8 @@ return [ 'lineasEnvio' => 'Líneas del envío', 'comentariosEnvio' => 'Comentarios del envío', 'guardar' => 'Guardar', + 'totales' => 'Totales', + 'cajas' => 'Cajas', 'pedido' => 'Pedido', 'presupuesto' => 'Presupuesto', @@ -53,6 +55,8 @@ return [ 'addCaja' => 'Añadir caja', 'numCaja' => 'Número de caja', 'selectAll' => 'Seleccionar todo', + 'peso' => 'Peso (kg): ', + 'unidadesTotalesFooter' => 'Unidades:', 'errors' => [ 'noEnvio' => 'No se ha encontrado el envio', @@ -60,4 +64,5 @@ return [ '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', ], + ]; \ No newline at end of file diff --git a/ci4/app/Models/Albaranes/AlbaranLineaModel.php b/ci4/app/Models/Albaranes/AlbaranLineaModel.php new file mode 100644 index 00000000..83f05e34 --- /dev/null +++ b/ci4/app/Models/Albaranes/AlbaranLineaModel.php @@ -0,0 +1,85 @@ +db + + ->table($this->table . " t1") + ->select( + "t1.id AS id, t1.albaran_id AS albaran_id, t1.titulo AS titulo, t1.isbn AS isbn, + t1.ref_cliente AS ref_cliente, t1.cantidad AS cantidad, t1.cajas AS cajas, + t1.ejemplares_por_caja AS ejemplares_por_caja, t1.precio_unidad AS precio_unidad, + t1.total AS total, pedidos.id AS pedido" + ) + ->join("pedidos_linea", "t1.pedido_linea_id = pedidos_linea.id", "left") + ->join("pedidos", "pedidos_linea.pedido_id = pedidos.id", "left"); + + $builder->where("t1.deleted_at IS NULL"); + $builder->where("t1.albaran_id", $albaran_id); + + return $builder; + } + + public function getDatatableQuery($albaran_id = null){ + $builder = $this->db + ->table($this->table . " t1") + ->select( + "t1.id, t1.titulo as titulo, t1.isbn as isbn, t1.ref_cliente as ref_cliente, + t1.cantidad as unidades, t1.precio_unidad as precio_unidad, t1.iva_reducido as iva_reducido, + t1.total as total, pedidos.id AS pedido" + ) + ->join("pedidos_linea", "t1.pedido_linea_id = pedidos_linea.id", "left") + ->join("pedidos", "pedidos_linea.pedido_id = pedidos.id", "left"); + + $builder->where("t1.deleted_at IS NULL"); + $builder->where("t1.albaran_id", $albaran_id); + + return $builder; + } + +} \ No newline at end of file diff --git a/ci4/app/Models/Albaranes/AlbaranModel.php b/ci4/app/Models/Albaranes/AlbaranModel.php new file mode 100644 index 00000000..40e418e5 --- /dev/null +++ b/ci4/app/Models/Albaranes/AlbaranModel.php @@ -0,0 +1,203 @@ +user()->id; + + if (!$envio_id || !$envio_lineas) { + return [ + 'status' => false + ]; + } + + // el albaran es para el mismo cliente, por lo que se obtiene el cliente_id de la primera_linea + $cliente_id = $this->db->table('envios_lineas') + ->select('presupuestos.cliente_id') + ->join('presupuestos', 'presupuestos.id = envios_lineas.presupuesto_id') + ->where('envios_lineas.id', $envio_lineas[0]) + ->get() + ->getRow()->cliente_id; + + // se genera el numero de albaran + $model_series = model('App\Models\Configuracion\SeriesFacturasModel'); + $serie = $model_series->find(11); + $numero_albaran = str_replace('{number}', $serie->next, $serie->formato); + $numero_albaran = str_replace('{year}', date("Y"), $numero_albaran); + $serie->next = $serie->next + 1; + $model_series->save($serie); + + // Se genera el albaran con los datos del envio + $model_envio = model('App\Models\Logistica\EnvioModel'); + $envio = $model_envio->find($envio_id); + $data = [ + 'envio_id' => $envio->id, + 'cliente_id' => $cliente_id, + 'serie_id' => 11, // Serie de albaranes + 'numero_albaran' => $numero_albaran, + 'mostrar_precios' => 0, + 'direccion_albaran' => $envio->direccion, + 'att_albaran' => $envio->att, + 'user_created_id' => $user_id, + 'cajas' => $cajas, + ]; + $id_albaran = $this->insert($data); + if(!$id_albaran) { + return [ + 'status' => false + ]; + } + + // Se generan las lineas del albaran + $model_albaran_linea = model('App\Models\Albaranes\AlbaranLineaModel'); + $albaran_linea = []; + foreach ($envio_lineas as $linea) { + $modelLineaEnvio = model('App\Models\Logistica\EnvioLineaModel'); + $datosLinea = $this->db->table('envios_lineas') + ->select('presupuestos.titulo as titulo, presupuestos.isbn as isbn, presupuestos.referencia_cliente as ref_cliente, + envios_lineas.unidades_envio as cantidad, presupuestos.total_precio_unidad as precio_unidad, presupuestos.iva_reducido as iva_reducido, + ROUND(envios_lineas.unidades_envio * presupuestos.total_precio_unidad, 2) as total, pedidos_linea.id as pedido_linea_id') + ->join('presupuestos', 'presupuestos.id = envios_lineas.presupuesto_id') + ->join('pedidos', 'pedidos.id = envios_lineas.pedido_id') + ->join('pedidos_linea', 'pedidos_linea.pedido_id = pedidos.id') + ->where('envios_lineas.id', $linea) + ->get() + ->getRow(); + $linea = $modelLineaEnvio->find($linea); + if (!$linea) { + continue; + } + $albaran_linea = [ + 'albaran_id' => $id_albaran, + 'titulo' => $datosLinea->titulo, + 'isbn' => $datosLinea->isbn, + 'ref_cliente' => $datosLinea->ref_cliente, + 'cantidad' => $datosLinea->cantidad, + 'precio_unidad' => $datosLinea->precio_unidad, + 'iva_reducido' => $datosLinea->iva_reducido, + 'total' => $datosLinea->total, + 'user_created_id' => $user_id, + 'user_updated_id' => $user_id, + 'pedido_linea_id' => $datosLinea->pedido_linea_id, + + ]; + $model_albaran_linea->insert($albaran_linea); + } + + $albaran_data = $this->db->table('albaranes t1') + ->select(" + t1.id, + t1.att_albaran AS att, + t1.direccion_albaran AS direccion, + t1.envio_id, + t1.numero_albaran AS numero_albaran, + DATE_FORMAT(t1.created_at, '%d/%m/%Y') AS fecha_creacion, + DATE_FORMAT(t1.fecha_albaran, '%d/%m/%Y') AS fecha_albaran, + t1.mostrar_precios AS mostrar_precios, + t1.cajas AS cajas, + ") + ->where('t1.id', $id_albaran) + ->get() + ->getResultObject(); + $modelCliente = model('App\Models\Clientes\ClienteModel'); + $cliente = $modelCliente->find($cliente_id); + $albaran_data[0]->cliente = $cliente->nombre; + + return [ + 'status' => true, + 'albaran' => $albaran_data[0], + ]; + } + + public function getAlbaranesEnvio($envio_id=null){ + if (!$envio_id) { + return []; + } + + $albaran_data = $this->db->table('albaranes t1') + ->select(" + t1.id, + t1.att_albaran AS att, + t1.direccion_albaran AS direccion, + t1.envio_id, + t1.numero_albaran AS numero_albaran, + DATE_FORMAT(t1.created_at, '%d/%m/%Y') AS fecha_creacion, + DATE_FORMAT(t1.fecha_albaran, '%d/%m/%Y') AS fecha_albaran, + t1.mostrar_precios AS mostrar_precios, + t2.nombre AS cliente, + t1.cajas AS cajas + ") + ->join('clientes t2', 't1.cliente_id = t2.id', 'left') + ->where('t1.envio_id', $envio_id) + ->where('t1.deleted_at IS NULL') + ->get() + ->getResultObject(); + return $albaran_data; + } + + /** + * Get resource data for creating PDFs. + * + * @param string $search + * + * @return \CodeIgniter\Database\BaseBuilder + */ + public function getResourceForPdf($albaran_id = -1) + { + $builder = $this->db + + ->table($this->table . " t1") + ->select( + "t1.id AS id, t1.pedido_id AS pedido_id, t1.presupuesto_id AS presupuesto_id, + t1.presupuesto_direccion_id AS presupuesto_direccion_id, t1.cliente_id AS cliente_id, + t1.serie_id AS serie_id, t1.numero_albaran AS numero_albaran, t1.mostrar_precios AS mostrar_precios, + t1.total AS total, t1.direccion_albaran AS direccion_albaran, t1.att_albaran AS att_albaran, + t1.user_created_id AS user_created_id, t1.user_updated_id AS user_updated_id, + t1.created_at AS created_at, t1.updated_at AS updated_at, + t2.nombre AS cliente" + ); + $builder->join("clientes t2", "t1.cliente_id = t2.id", "left"); + + $builder->where("t1.deleted_at IS NULL"); + $builder->where("t1.id", $albaran_id); + + return $builder; + } +} \ No newline at end of file diff --git a/ci4/app/Models/Logistica/EnvioLineaModel.php b/ci4/app/Models/Logistica/EnvioLineaModel.php index e642a5fe..420b4ae6 100644 --- a/ci4/app/Models/Logistica/EnvioLineaModel.php +++ b/ci4/app/Models/Logistica/EnvioLineaModel.php @@ -19,8 +19,6 @@ class EnvioLineaModel extends Model 'pedido_id', 'unidades_envio', 'unidades_total', - 'cajas', - 'unidades_cajas', 'created_at', 'updated_at', 'created_by', @@ -37,7 +35,7 @@ class EnvioLineaModel extends Model $builder = $this->db ->table($this->table . " t1") ->select( - "t1.id, t1.pedido_id as pedido, t3.id as presupuesto,t1.cajas, t1.cajas as cajasRaw, + "t1.id, t1.pedido_id as pedido, t3.id as presupuesto, t3.titulo as titulo, t1.unidades_envio as unidadesEnvio, t1.unidades_envio as unidadesEnvioRaw, t1.unidades_total as unidadesTotal, IFNULL(( @@ -62,17 +60,5 @@ class EnvioLineaModel extends Model return $builder; } - public function getMaxCaja() - { - $builder = $this->db - ->table($this->table . " t1"); - $builder->selectMax('CAST(t1.cajas AS UNSIGNED)', 'max_caja'); - $builder->where('t1.cajas IS NOT NULL'); - $query = $builder->get(); - $row = $query->getRow(); - - $maxCaja = is_numeric($row->max_caja) ? (int) $row->max_caja : 0; - - return $maxCaja + 1; - } + } diff --git a/ci4/app/Models/Logistica/EnvioModel.php b/ci4/app/Models/Logistica/EnvioModel.php index 2dbcf385..b0a60026 100644 --- a/ci4/app/Models/Logistica/EnvioModel.php +++ b/ci4/app/Models/Logistica/EnvioModel.php @@ -31,7 +31,7 @@ class EnvioModel extends Model 'mostrar_iva', 'created_at', 'updated_at', - 'multienvio', + 'cajas', ]; protected $useTimestamps = true; diff --git a/ci4/app/Views/themes/vuexy/form/logistica/viewEnvioEditForm.php b/ci4/app/Views/themes/vuexy/form/logistica/viewEnvioEditForm.php index a8f4d5ce..4214feea 100644 --- a/ci4/app/Views/themes/vuexy/form/logistica/viewEnvioEditForm.php +++ b/ci4/app/Views/themes/vuexy/form/logistica/viewEnvioEditForm.php @@ -190,14 +190,6 @@ -
- -
-
@@ -205,10 +197,6 @@ - - - - @@ -227,10 +215,35 @@ - + + + +
+ + +
+ + + + +
+ + +
+ + + + +
+ + +
diff --git a/httpdocs/assets/js/safekat/components/albaranComponent.js b/httpdocs/assets/js/safekat/components/albaranComponent.js new file mode 100644 index 00000000..3abf586a --- /dev/null +++ b/httpdocs/assets/js/safekat/components/albaranComponent.js @@ -0,0 +1,481 @@ +class AlbaranComponent { + + constructor(item) { + this.item = item; + this.id = item.id; + this.numero = item.numero_albaran; + this.cliente = item.cliente; + this.att = item.att; + this.direccion = item.direccion; + this.envio_id = item.envio_id; + this.selectorTabla = `#tablaAlbaran${this.id}`; + + this.table = null; + } + + mount(selector) { + const dom = this.render(); + $(selector).append(dom); + requestAnimationFrame(() => this.init()); + } + + render() { + const { id, numero } = this; + + const accordion = $('
', { + class: 'accordion accordion-bordered mt-3 accordion-albaran', + id: 'accordioAlbaran' + id, + albaran: id + }); + + const card = $('
', { class: 'card accordion-item active' }); + + const header = $('

', { + class: 'accordion-header', + id: 'headingAlbaran' + id + }); + + const button = $('