From aff79ec3d6ca4681b872d58187353d0f664f285e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Jim=C3=A9nez?= Date: Sun, 16 Feb 2025 18:52:56 +0100 Subject: [PATCH] terminado tickets. faltan respuestas --- ci4/app/Config/Routes.php | 3 + .../Controllers/Soporte/Ticketcontroller.php | 129 ++++++++++++---- ci4/app/Language/es/Tickets.php | 5 +- .../{ticketModel.php => TicketModel.php} | 10 +- ci4/app/Models/UserModel.php | 13 ++ .../vuexy/form/soporte/viewTicketForm.php | 140 +++++++++++------- .../vuexy/form/soporte/viewTicketList.php | 14 +- .../js/safekat/pages/soporte/tickets.js | 78 +++++++--- 8 files changed, 273 insertions(+), 119 deletions(-) rename ci4/app/Models/Soporte/{ticketModel.php => TicketModel.php} (89%) diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index aad9dcaf..359bda01 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -924,7 +924,10 @@ $routes->group('soporte', ['namespace' => 'App\Controllers\Soporte'], function ( $routes->get('', 'Ticketcontroller::index', ['as' => 'TicketIndex']); $routes->get('add', 'Ticketcontroller::add', ['as' => 'NewTicket']); $routes->post('add', 'Ticketcontroller::add', ['as' => 'createTicket']); + $routes->get('edit/(:num)', 'Ticketcontroller::edit/$1', ['as' => 'editTicket']); + $routes->post('edit/(:num)', 'Ticketcontroller::edit/$1', ['as' => 'updateTicket']); $routes->post('ticketlist', 'Ticketcontroller::datatable'); + $routes->get('image/(:segment)', 'Ticketcontroller::image/$1'); }); diff --git a/ci4/app/Controllers/Soporte/Ticketcontroller.php b/ci4/app/Controllers/Soporte/Ticketcontroller.php index 6b12717e..81d8641c 100644 --- a/ci4/app/Controllers/Soporte/Ticketcontroller.php +++ b/ci4/app/Controllers/Soporte/Ticketcontroller.php @@ -2,16 +2,21 @@ namespace App\Controllers\Soporte; -use App\Models\TicketModel; +use App\Models\Soporte\TicketModel; use App\Models\CategoriaModel; use App\Models\EstadoModel; use CodeIgniter\Controller; use App\Entities\Soporte\TicketEntity; use App\Models\Soporte\ticketFileModel; -class Ticketcontroller extends \App\Controllers\GoBaseController + +use App\Models\Collection; + +class Ticketcontroller extends \App\Controllers\BaseResourceController { - protected static $primaryModelName = 'App\Models\Soporte\ticketModel'; + + protected $modelName = TicketModel::class; + protected $format = 'json'; protected static $singularObjectNameCc = 'ticket'; protected static $singularObjectName = 'Ticket'; @@ -34,17 +39,22 @@ class Ticketcontroller extends \App\Controllers\GoBaseController ]; parent::initController($request, $response, $logger); - } public function index() { //checkPermission('tickets.menu'); - $this->viewData['usingClientSideDataTable'] = true; + $viewData = [ + 'currentModule' => static::$controllerSlug, + 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Tickets.tickets')]), + 'usingServerSideDataTable' => true, + 'userType' => auth()->user()->can('tickets.edit')? 1:0, + ]; - $this->viewData['pageSubTitle'] = lang('Basic.global.ManageAllRecords', [lang('Tickets.tickets')]); - parent::index(); + $viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class + + return view(static::$viewPath . 'viewTicketList', $viewData); } @@ -109,7 +119,7 @@ class Ticketcontroller extends \App\Controllers\GoBaseController 'nombre' => $originalName, 'ticket_id' => $id, 'hash' => $fileHash, - 'path' => 'uploads/' . $newFileName + 'path' => 'uploads/tickets/' . $newFileName ]); } } @@ -139,7 +149,7 @@ class Ticketcontroller extends \App\Controllers\GoBaseController $this->viewData['estados'] = $this->model->getEstados(); $this->viewData['secciones'] = $this->model->getSecciones(); - $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('Tarifaextra.tarifaextra') . ' ' . lang('Basic.global.addNewSuffix'); + $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('Tickets.ticket') . ' ' . lang('Basic.global.addNewSuffix'); return $this->displayForm(__METHOD__); @@ -147,32 +157,22 @@ class Ticketcontroller extends \App\Controllers\GoBaseController public function edit($requestedId = null) { - /* - checkPermission('tarifa-extra.edit', $this->indexRoute); - + if ($requestedId == null) : return $this->redirect2listView(); endif; $id = filter_var($requestedId, FILTER_SANITIZE_URL); - $tarifaextraEntity = $this->model->find($id); + $ticket = $this->model->find($id); - if ($tarifaextraEntity == false) : - $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Tarifaextra.tarifaextra')), $id]); + if ($ticket == false) : + $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Tickets.ticket')), $id]); return $this->redirect2listView('errorMessage', $message); endif; if ($this->request->getPost()) : $postData = $this->request->getPost(); - $sanitizedData = $this->sanitized($postData, true); - - // JJO - if (isset($this->model->user_updated_id)) { - $sanitizedData['user_updated_id'] = auth()->user()->id; - } - if ($this->request->getPost('mostrar_en_presupuesto') == null) { - $sanitizedData['mostrar_en_presupuesto'] = false; - } + $sanitizedData = $this->sanitized($postData, false); $noException = true; if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : @@ -184,17 +184,17 @@ class Ticketcontroller extends \App\Controllers\GoBaseController $this->dealWithException($e); } else: - $this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Tarifaextra.tarifaextra'))]); + $this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Tickets.ticket'))]); $this->session->setFlashdata('formErrors', $this->model->errors()); endif; - $tarifaextraEntity->fill($sanitizedData); + $ticket->fill($sanitizedData); $thenRedirect = false; endif; if ($noException && $successfulResult) : - $id = $tarifaextraEntity->id ?? $id; + $id = $ticket->id ?? $id; $message = lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.'; if ($thenRedirect) : @@ -210,15 +210,37 @@ class Ticketcontroller extends \App\Controllers\GoBaseController endif; // $noException && $successfulResult endif; // ($requestMethod === 'post') - $this->viewData['tarifaextraEntity'] = $tarifaextraEntity; + $this->viewData['ticket'] = $ticket; - $this->viewData['formAction'] = route_to('updateTarifaextra', $id); + $this->viewData['formAction'] = route_to('updateTicket', $id); - $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Tarifaextra.tarifaextra') . ' ' . lang('Basic.global.edit3'); + $this->viewData['categorias'] = $this->model->getCategorias(); + $this->viewData['estados'] = $this->model->getEstados(); + $this->viewData['secciones'] = $this->model->getSecciones(); + $defatulSoporteUserId = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('default_soporte_user_id')->value; + $this->viewData['supportUsers'] = array( + array( + 'id' => $defatulSoporteUserId, + 'name' => model('App\Models\UserModel')->getFullName($defatulSoporteUserId) + ), + array( + 'id' => 2, + 'name' => model('App\Models\UserModel')->getFullName(2) + ), + array( + 'id' => 1, + 'name' => model('App\Models\UserModel')->getFullName(1) + ), + ); + + $this->viewData['imagesTicket'] = $this->getImages('ticket', $id); + $this->viewData['imagesRespuesta'] = $this->getImages('respuesta', $id); + + $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Tickets.ticket') . ' ' . lang('Basic.global.edit3'); return $this->displayForm(__METHOD__, $id); - */ + } // end function edit(...) public function datatable() @@ -237,7 +259,7 @@ class Ticketcontroller extends \App\Controllers\GoBaseController $searchValues = get_filter_datatables_columns($reqData); - $resourceData = $this->model->getResource($searchValues, $cliente_id); + $resourceData = $this->model->getResource($searchValues); foreach ($requestedOrder as $order) { $column = $order['column'] ?? 0; $dir = $order['dir'] ?? 'asc'; @@ -258,4 +280,47 @@ class Ticketcontroller extends \App\Controllers\GoBaseController } } + public function image($imageName) + { + $filePath = WRITEPATH . "uploads/tickets/" . $imageName; + + if (!file_exists($filePath)) { + return $this->response->setStatusCode(404, 'Imagen no encontrada'); + } + + $mimeType = mime_content_type($filePath); + + return $this->response + ->setHeader('Content-Type', $mimeType) + ->setBody(file_get_contents($filePath)); + } + + private function getImages($tipo = 'ticket', $id = null) + { + $images = []; + + $model = new ticketFileModel(); + if($tipo == 'ticket'){ + $files = $model->where('ticket_id', $id)->findAll(); + foreach ($files as $file) { + $ext = pathinfo($file['nombre'], PATHINFO_EXTENSION); + array_push($images,array( + "path" => '/soporte/image/' . $file['hash'] .".". $ext, + "name" => $file['nombre'] + )); + } + } + else{ + $files = $model->where('respuesta_id', $id)->findAll(); + foreach ($files as $file) { + $ext = pathinfo($file['nombre'], PATHINFO_EXTENSION); + array_push($images,array( + "path" => '/soporte/image/' . $file['hash'] .".". $ext, + "name" => $file['nombre'] + )); + } + } + return $images; + } + } diff --git a/ci4/app/Language/es/Tickets.php b/ci4/app/Language/es/Tickets.php index 26a17628..9175e6e1 100644 --- a/ci4/app/Language/es/Tickets.php +++ b/ci4/app/Language/es/Tickets.php @@ -28,6 +28,8 @@ return [ 'pedidos' => 'Pedidos', 'facturacion' => 'Facturación', 'logistica' => 'Logística', + 'configuracion' => 'Configuración', + 'general' => 'General', // estados 'abierto' => 'Abierto', @@ -42,6 +44,7 @@ return [ // FIcheros 'adjuntos' => 'Adjuntar imágenes', - 'adjuntos_main_text' => 'Arrastra y suelta las imágenes aquí o haz clic para subirlas', + 'adjuntos_ticket' => 'Imágenes adjuntas', + 'adjuntos_respuesta' => 'Imágenes adjuntos de la respuesta', ]; diff --git a/ci4/app/Models/Soporte/ticketModel.php b/ci4/app/Models/Soporte/TicketModel.php similarity index 89% rename from ci4/app/Models/Soporte/ticketModel.php rename to ci4/app/Models/Soporte/TicketModel.php index 39d7cf9f..7fcd6e9e 100644 --- a/ci4/app/Models/Soporte/ticketModel.php +++ b/ci4/app/Models/Soporte/TicketModel.php @@ -12,6 +12,8 @@ class TicketModel extends \App\Models\BaseModel protected $useTimestamps = true; + protected $returnType = "App\Entities\Soporte\TicketEntity"; + const SORTABLE = [ 0 => "t1.categoria_id", 1 => "t1.seccion_id", @@ -75,14 +77,16 @@ class TicketModel extends \App\Models\BaseModel ->table($this->table . " t1") ->select( "t1.id as id, t1.usuario_id AS usuario_id, CONCAT(t2.first_name, ' ', t2.last_name) AS usuario, - t1.user_soporte_id AS user_soporte_id, CONCAT(t2.first_name, ' ', t2.last_name) AS user_soporte, - t1.categoria_id AS categoria_id, t3.keyword AS categoria, t1.seccion_id AS seccion_id, t1.estado_id AS estado_id, + t1.user_soporte_id AS user_soporte_id, CONCAT(t6.first_name, ' ', t6.last_name) AS user_soporte, + t1.categoria_id AS categoria_id, t3.keyword AS categoria, + t1.seccion_id AS seccion_id, t5.keyword AS seccion, + t1.estado_id AS estado_id, t4.keyword AS estado, t1.prioridad AS prioridad, t1.titulo AS titulo, t1.created_at AS created_at " ); $builder->join("users t2", "t1.usuario_id = t2.id", "left"); - $builder->join("users t2", "t1.user_soporte_id = t2.id", "left"); + $builder->join("users t6", "t1.user_soporte_id = t6.id", "left"); $builder->join("tickets_categorias t3", "t1.categoria_id = t3.id", "left"); $builder->join("tickets_estados t4", "t1.estado_id = t4.id", "left"); $builder->join("tickets_secciones t5", "t1.seccion_id = t5.id", "left"); diff --git a/ci4/app/Models/UserModel.php b/ci4/app/Models/UserModel.php index cd7d2944..34f1767a 100644 --- a/ci4/app/Models/UserModel.php +++ b/ci4/app/Models/UserModel.php @@ -122,6 +122,19 @@ class UserModel extends ShieldUserModel } + public function getFullName($id=0){ + $builder = $this->db + ->table("users" . " t1") + ->select( + "CONCAT(t1.first_name, ' ', t1.last_name) AS name" + ); + + $builder->where('t1.deleted_at', null); + $builder->where('t1.id', $id); + + return $builder->get()->getRow()->name; + } + // Método para comprobar si el email ya está registrado public function isEmailUnique($email) { diff --git a/ci4/app/Views/themes/vuexy/form/soporte/viewTicketForm.php b/ci4/app/Views/themes/vuexy/form/soporte/viewTicketForm.php index ab8fa533..c35984ca 100644 --- a/ci4/app/Views/themes/vuexy/form/soporte/viewTicketForm.php +++ b/ci4/app/Views/themes/vuexy/form/soporte/viewTicketForm.php @@ -1,21 +1,40 @@ +include("themes/_commonPartialsBs/sweetalert") ?> include('themes/_commonPartialsBs/datatables') ?> extend('themes/vuexy/main/defaultlayout') ?> section('content'); ?> + + +
-

+

- + + getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?>
- + id))?"readonly":"" ?> + value="titulo) ?>">
@@ -23,9 +42,11 @@
- id) && !auth()->user()->can('tickets.edit'))?"disabled":"" ?>> - +
@@ -33,18 +54,25 @@
- id) && !auth()->user()->can('tickets.edit'))?"disabled":"" ?>> - +
- + +
@@ -57,15 +85,25 @@
@@ -75,63 +113,51 @@
- +
+

- - + +
- - + - - +
+ id) && auth()->user()->can('tickets.edit'))): ?> + " + /> + + "btn btn-secondary"]) ?> - - - +
diff --git a/ci4/app/Views/themes/vuexy/form/soporte/viewTicketList.php b/ci4/app/Views/themes/vuexy/form/soporte/viewTicketList.php index 7fe03d7a..a1d546f5 100644 --- a/ci4/app/Views/themes/vuexy/form/soporte/viewTicketList.php +++ b/ci4/app/Views/themes/vuexy/form/soporte/viewTicketList.php @@ -13,7 +13,7 @@
- @@ -21,10 +21,10 @@ - + - - + + @@ -49,6 +49,11 @@ section('additionalExternalJs') ?> + + + +endSection() ?> diff --git a/httpdocs/assets/js/safekat/pages/soporte/tickets.js b/httpdocs/assets/js/safekat/pages/soporte/tickets.js index b6567306..82fd6b32 100644 --- a/httpdocs/assets/js/safekat/pages/soporte/tickets.js +++ b/httpdocs/assets/js/safekat/pages/soporte/tickets.js @@ -1,20 +1,6 @@ import Table from '../../components/table.js'; import Ajax from '../../components/ajax.js'; -/*$(function () { - - - -/* - document.querySelectorAll('[data-bs-toggle="lightbox"]').forEach(anchor => { - anchor.addEventListener('click', function (event) { - event.preventDefault(); - const imgSrc = this.getAttribute('href'); - document.getElementById('lightboxImage').src = imgSrc; - new bootstrap.Modal(document.getElementById('lightboxModal')).show(); - }); - }); -});*/ class Ticket { @@ -37,6 +23,12 @@ class Ticket { init() { if(this.action == "edit") { + + $('.gallery-img').on('click', function() { + let imageUrl = $(this).data('src'); // Obtiene la URL de la imagen + $('#modalImage').attr('src', imageUrl); // Cambia la imagen en el modal + $('#imageModal').modal('show'); // Muestra el modal + }); } else if (this.action == "list") { @@ -51,16 +43,44 @@ class Ticket { const actions = ['view']; const columns = [ { 'data': 'id' }, - { 'data': 'categoria_id' }, - { 'data': 'seccion_id' }, - { 'data': 'estado_id' }, - { 'data': 'prioridad' }, + { 'data': 'categoria_id', + render: function (data, type, row) { + return window.language.Tickets[row.categoria]; + } + }, + { 'data': 'seccion_id' , + render: function (data, type, row) { + return window.language.Tickets[row.seccion]; + } + }, + { 'data': 'estado_id' , + render: function (data, type, row) { + return window.language.Tickets[row.estado]; + } + }, + { 'data': 'prioridad' , + render: function (data, type, row) { + return window.language.Tickets[data]; + }, + visible: false, + }, { 'data': 'titulo' }, - { 'data': 'usuario_id' }, - { 'data': 'user_soporte_id' }, + { 'data': 'usuario_id' , + render: function (data, type, row) { + return row.usuario; + }, + visible: false, + }, + { 'data': 'user_soporte_id', + render: function (data, type, row) { + return row.user_soporte; + }, + visible: false, + }, { 'data': 'created_at' }, ]; + this.table = new Table( $('#tableOfTickets'), 'tickets', @@ -68,15 +88,29 @@ class Ticket { columns, ); + this.table.init({ actions: actions, buttonsExport: true, }); + this.table.table.on('init.dt', function () { + self.table.table.page.len(50).draw(); + if(window.userType==1){ - this.tableTarifas.table.on('init.dt', function () { - self.tableTarifas.table.page.len(50).draw(); + self.table.table.column(4).visible(true); + self.table.table.column(6).visible(true); + self.table.table.column(7).visible(true); + + self.table.table.column(4).header().style.display = 'table-cell'; + self.table.table.column(6).header().style.display = 'table-cell'; + self.table.table.column(7).header().style.display = 'table-cell'; + } }); + + this.table.setEditCallback(function(id){ + window.location.href = '/soporte/edit/' + id; + }) } }