diff --git a/ci4/app/Config/RBAC/permissionMatrix.php b/ci4/app/Config/RBAC/permissionMatrix.php index 7506cfec..ed0b4fe3 100644 --- a/ci4/app/Config/RBAC/permissionMatrix.php +++ b/ci4/app/Config/RBAC/permissionMatrix.php @@ -202,6 +202,10 @@ const SK_PERMISSION_MATRIX = [ "tarifa-encuadernacion.edit", "tarifa-encuadernacion.delete", "tarifa-encuadernacion.menu", + "tarifa-extra.create", + "tarifa-extra.edit", + "tarifa-extra.delete", + "tarifa-extra.menu", "tarifa-envio.create", "tarifa-envio.edit", "tarifa-envio.delete", @@ -246,5 +250,8 @@ const SK_PERMISSION_MATRIX = [ "roles-permisos.edit", "roles-permisos.delete", "roles-permisos.menu", + "tickets.create", + "tickets.edit", + "tickets.menu", ], ]; diff --git a/ci4/app/Controllers/Soporte/Ticketcontroller.php b/ci4/app/Controllers/Soporte/Ticketcontroller.php index ec1539ad..3f5c8757 100644 --- a/ci4/app/Controllers/Soporte/Ticketcontroller.php +++ b/ci4/app/Controllers/Soporte/Ticketcontroller.php @@ -16,7 +16,7 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController { protected $modelName = TicketModel::class; - protected $format = 'json'; + protected $format = 'json'; protected static $singularObjectNameCc = 'ticket'; protected static $singularObjectName = 'Ticket'; @@ -25,13 +25,13 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController protected static $viewPath = 'themes/vuexy/form/soporte/'; - protected $indexRoute = 'viewTicketList'; + protected $indexRoute = 'ticketList'; public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger) { $this->viewData['pageTitle'] = lang('Tickets.moduleTitle'); - + // Breadcrumbs $this->viewData['breadcrumb'] = [ ['title' => lang("App.menu_soporte"), 'route' => "javascript:void(0);", 'active' => false], @@ -49,20 +49,19 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController 'currentModule' => static::$controllerSlug, 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Tickets.tickets')]), 'usingServerSideDataTable' => true, - 'userType' => auth()->user()->can('tickets.edit')? 1:0, + 'userType' => auth()->user()->can('tickets.edit') ? 1 : 0, ]; $viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class return view(static::$viewPath . 'viewTicketList', $viewData); - } public function add() { //checkPermission('tickets.create', $this->indexRoute); - + if ($this->request->getPost()) : $nullIfEmpty = false; // !(phpversion() >= '8.1'); @@ -97,33 +96,7 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController $id = $this->model->db->insertID(); - $uploadPath = WRITEPATH . 'uploads/tickets/'; - - $fileModel = new ticketFileModel(); - $files = $this->request->getFiles(); - if ($files && isset($files['files'])) { - foreach ($files['files'] as $file) { - if ($file->isValid() && !$file->hasMoved()) { - $originalName = $file->getClientName(); - $fileExt = $file->getExtension(); - - // Generar hash SHA-256 basado en el contenido del archivo - $fileHash = hash_file("sha256", $file->getTempName()); - $newFileName = $fileHash . '.' . $fileExt; - - // Mover el archivo con el nombre basado en el hash - $file->move($uploadPath, $newFileName); - - // Guardar en la base de datos - $fileModel->insert([ - 'nombre' => $originalName, - 'ticket_id' => $id, - 'hash' => $fileHash, - 'path' => 'uploads/tickets/' . $newFileName - ]); - } - } - } + $this->saveImages($id, $this->request->getFiles()); $message = lang('Basic.global.saveSuccess', [lang('Basic.global.record')]) . '.'; @@ -149,6 +122,8 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController $this->viewData['estados'] = $this->model->getEstados(); $this->viewData['secciones'] = $this->model->getSecciones(); + $this->viewData['supportUsers'] = $this->getSupportUsers(); + $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('Tickets.ticket') . ' ' . lang('Basic.global.addNewSuffix'); @@ -157,7 +132,8 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController public function edit($requestedId = null) { - + $modelRespuesta = new \App\Models\Soporte\TicketRespuestaModel(); + if ($requestedId == null) : return $this->redirect2listView(); endif; @@ -169,16 +145,42 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController return $this->redirect2listView('errorMessage', $message); endif; + if(!auth()->user()->can('Tickets.edit') && auth()->user()->id != $ticket->usuario_id){ + return redirect()->to(route_to('TicketIndex'))->with('errorMessage', lang('Basic.global.noPermission')); + } + if ($this->request->getPost()) : $postData = $this->request->getPost(); - $sanitizedData = $this->sanitized($postData, false); + $sanitizedData = $this->sanitized($postData, false); $noException = true; if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : if ($this->canValidate()) : try { $successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData); + + $this->saveImages($id, $this->request->getFiles()); + + if(auth()->user()->can('Tickets.edit')){ + + $respuesta = $modelRespuesta->where('ticket_id', $id)->first(); + if($respuesta == null){ + $modelRespuesta->insert([ + 'ticket_id' => $id, + 'usuario_id' => auth()->user()->id, + 'mensaje' => $sanitizedData['respuesta_mensaje'] + ]); + }else{ + $modelRespuesta->update($respuesta->id, [ + 'mensaje' => $sanitizedData['respuesta_mensaje'], + 'usuario_id' => auth()->user()->id, + ]); + } + + + } + } catch (\Exception $e) { $noException = false; $this->dealWithException($e); @@ -204,34 +206,22 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController return $this->redirect2listView('successMessage', $message); endif; else: - $this->session->setFlashData('sweet-success', $message); + return redirect()->to(route_to("editTicket", $id))->with('successMessage', $message); + //$this->session->setFlashData('sweet-success', $message); endif; endif; // $noException && $successfulResult endif; // ($requestMethod === 'post') $this->viewData['ticket'] = $ticket; + $this->viewData['respuesta'] = $modelRespuesta->where('ticket_id', $id)->first(); $this->viewData['formAction'] = route_to('updateTicket', $id); $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['supportUsers'] = $this->getSupportUsers(); $this->viewData['imagesTicket'] = $this->getImages('ticket', $id); $this->viewData['imagesRespuesta'] = $this->getImages('respuesta', $id); @@ -240,7 +230,6 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController return $this->displayForm(__METHOD__, $id); - } // end function edit(...) public function datatable() @@ -259,7 +248,13 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController $searchValues = get_filter_datatables_columns($reqData); - $resourceData = $this->model->getResource($searchValues); + if(auth()->user()->can('tickets.edit')){ + $user_id = null; + }else{ + $user_id = auth()->user()->id; + } + + $resourceData = $this->model->getResource($searchValues, $user_id); foreach ($requestedOrder as $order) { $column = $order['column'] ?? 0; $dir = $order['dir'] ?? 'asc'; @@ -269,7 +264,7 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController } } $resourceData = $resourceData->limit($length, $start)->get()->getResultObject(); - + return $this->respond(Collection::datatable( $resourceData, $this->model->getResource($searchValues)->countAllResults(), @@ -295,27 +290,57 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController ->setBody(file_get_contents($filePath)); } + private function saveImages($ticket_id, $files = []) + { + $uploadPath = WRITEPATH . 'uploads/tickets/'; + + $fileModel = new ticketFileModel(); + + if ($files && isset($files['files'])) { + foreach ($files['files'] as $file) { + if ($file->isValid() && !$file->hasMoved()) { + $originalName = $file->getClientName(); + $fileExt = $file->getExtension(); + + // Generar hash SHA-256 basado en el contenido del archivo + $fileHash = hash_file("sha256", $file->getTempName()); + $newFileName = $fileHash . '.' . $fileExt; + + // Mover el archivo con el nombre basado en el hash + $file->move($uploadPath, $newFileName); + + // Guardar en la base de datos + $fileModel->insert([ + 'nombre' => $originalName, + 'ticket_id' => $ticket_id, + 'hash' => $fileHash, + 'path' => 'uploads/tickets/' . $newFileName + ]); + } + } + } + } + private function getImages($tipo = 'ticket', $id = null) { $images = []; $model = new ticketFileModel(); - if($tipo == 'ticket'){ + 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, + array_push($images, array( + "path" => '/soporte/image/' . $file['hash'] . "." . $ext, "name" => $file['nombre'] )); } - } - else{ + } 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, + array_push($images, array( + "path" => '/soporte/image/' . $file['hash'] . "." . $ext, "name" => $file['nombre'] )); } @@ -323,4 +348,24 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController return $images; } + private function getSupportUsers() + { + $defatulSoporteUserId = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('default_soporte_user_id')->value; + $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) + ), + ); + + return $supportUsers; + } } diff --git a/ci4/app/Database/Migrations/2025-02-14-114500_create_tickets_system.php b/ci4/app/Database/Migrations/2025-02-14-114500_create_tickets_system.php index 716bf956..2b3242fa 100644 --- a/ci4/app/Database/Migrations/2025-02-14-114500_create_tickets_system.php +++ b/ci4/app/Database/Migrations/2025-02-14-114500_create_tickets_system.php @@ -61,6 +61,7 @@ class CreateTicketsSystem extends Migration 'usuario_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true], 'mensaje' => ['type' => 'TEXT'], 'created_at' => ['type' => 'DATETIME', 'null' => true], + 'updated_at' => ['type' => 'DATETIME', 'null' => true], ]); $this->forge->addPrimaryKey('id'); $this->forge->addForeignKey('ticket_id', 'tickets', 'id', '', 'NO ACTION'); diff --git a/ci4/app/Entities/Soporte/TicketRespuestaEntity.php b/ci4/app/Entities/Soporte/TicketRespuestaEntity.php new file mode 100644 index 00000000..d7a082a3 --- /dev/null +++ b/ci4/app/Entities/Soporte/TicketRespuestaEntity.php @@ -0,0 +1,20 @@ + null, + 'ticket_id' => null, + 'usuario_id' => null, + 'mensaje' => null, + 'created_at' => null, + 'updated_at' => null, + ]; + + protected $dates = ['created_at', 'updated_at']; + +} diff --git a/ci4/app/Language/es/Basic.php b/ci4/app/Language/es/Basic.php index be74f2d1..3f1c5bf5 100755 --- a/ci4/app/Language/es/Basic.php +++ b/ci4/app/Language/es/Basic.php @@ -88,6 +88,7 @@ return [ 'line' => 'la línea', 'error_tittle' => 'Error', ], + 'noPermission' => 'No tiene permiso para acceder a esta página.', 'ok' => 'Ok', 'wait' => 'Espere', 'yes' => 'Si', diff --git a/ci4/app/Language/es/Tickets.php b/ci4/app/Language/es/Tickets.php index 9175e6e1..59bb9747 100644 --- a/ci4/app/Language/es/Tickets.php +++ b/ci4/app/Language/es/Tickets.php @@ -17,6 +17,7 @@ return [ "usuario" => "Creado por", "createTicket" => "Crear Ticket", "fechaCreacion" => "Fecha de creación", + "respuesta" => "Respuesta", // categorías 'errores' => 'Errores', @@ -45,6 +46,5 @@ return [ // FIcheros 'adjuntos' => 'Adjuntar imágenes', '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 index 7fcd6e9e..99114ee1 100644 --- a/ci4/app/Models/Soporte/TicketModel.php +++ b/ci4/app/Models/Soporte/TicketModel.php @@ -71,7 +71,7 @@ class TicketModel extends \App\Models\BaseModel return $this->find($id); } - public function getResource($search = [], ) + public function getResource($search = [], $user_id = null) { $builder = $this->db ->table($this->table . " t1") @@ -91,6 +91,9 @@ class TicketModel extends \App\Models\BaseModel $builder->join("tickets_estados t4", "t1.estado_id = t4.id", "left"); $builder->join("tickets_secciones t5", "t1.seccion_id = t5.id", "left"); + if ($user_id !== null) + $builder->where("t1.usuario_id", $user_id); + if (empty($search)) return $builder; else { diff --git a/ci4/app/Models/Soporte/TicketRespuestaModel.php b/ci4/app/Models/Soporte/TicketRespuestaModel.php new file mode 100644 index 00000000..5d616c85 --- /dev/null +++ b/ci4/app/Models/Soporte/TicketRespuestaModel.php @@ -0,0 +1,17 @@ + id))?"readonly":"" ?> + = ($formAction !== route_to('NewTicket', $ticket->id)) ? "readonly" : "" ?> value="= old('titulo', $ticket->titulo) ?>"> @@ -43,7 +43,7 @@
Directory access is forbidden.
- - -