diff --git a/ci4/app/Config/Email.php b/ci4/app/Config/Email.php index 43b3edb0..9447a491 100755 --- a/ci4/app/Config/Email.php +++ b/ci4/app/Config/Email.php @@ -6,7 +6,7 @@ use CodeIgniter\Config\BaseConfig; class Email extends BaseConfig { - public string $fromEmail = 'safekat@imnavajas.es'; + public string $fromEmail = 'soporte_erp@safekat.es'; public string $fromName = 'Safekat ERP'; public string $recipients = ''; @@ -28,27 +28,27 @@ class Email extends BaseConfig /** * SMTP Server Hostname */ - public string $SMTPHost = 'imnavajas.es'; + public string $SMTPHost = 'smtp.ionos.es'; /** * SMTP Username */ - public string $SMTPUser = 'safekat@imnavajas.es'; + public string $SMTPUser = 'soporte_erp@safekat.es'; /** * SMTP Password */ - public string $SMTPPass = 'Etkd9~448'; + public string $SMTPPass = 'H%5&qDkDkWnfLTGN'; /** * SMTP Port */ - public int $SMTPPort = 25; + public int $SMTPPort = 465; /** * SMTP Timeout (in seconds) */ - public int $SMTPTimeout = 5; + public int $SMTPTimeout = 15; /** * Enable persistent SMTP connections diff --git a/ci4/app/Config/RBAC/permissionMatrix.php b/ci4/app/Config/RBAC/permissionMatrix.php index ce466841..c9f0a2ee 100644 --- a/ci4/app/Config/RBAC/permissionMatrix.php +++ b/ci4/app/Config/RBAC/permissionMatrix.php @@ -89,6 +89,9 @@ const SK_PERMISSION_MATRIX = [ "roles-permisos.edit", "roles-permisos.delete", "roles-permisos.menu", + "tickets.create", + "tickets.edit", + "tickets.menu", ], "cliente-admin" => [ "presupuesto-cliente.create", @@ -218,6 +221,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", @@ -262,5 +269,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/Config/RBAC/permissions.php b/ci4/app/Config/RBAC/permissions.php index 4c640b77..35e8235f 100644 --- a/ci4/app/Config/RBAC/permissions.php +++ b/ci4/app/Config/RBAC/permissions.php @@ -93,4 +93,7 @@ const SK_PERMISSIONS = [ 'roles-permisos.edit' => 'Can edit', 'roles-permisos.delete' => 'Can delete', 'roles-permisos.menu' => 'Menu shall be visualize', + 'tickets.create' => 'Can create', + 'tickets.edit' => 'Can edit', + 'tickets.menu' => 'Menu shall be visualize', ]; diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index 3b03dfa2..2d01a49f 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -886,8 +886,8 @@ $routes->group('chat', ['namespace' => 'App\Controllers\Chat'], function ($route $routes->get('department/factura/(:num)/(:num)', 'ChatController::get_chat_factura/$1/$2', ['as' => 'getChatFactura']); $routes->get('department/(:num)/users', 'ChatController::get_chat_department_users/$1', ['as' => 'getChatDepartmentUsers']); - $routes->get('(:num)', 'ChatController::get_chat/$1', ['as' => 'getChat']); + $routes->post('message/error/presupuesto', 'ChatController::store_chat_error_message', ['as' => 'storeChatErrorMessage']); $routes->post('message/presupuesto', 'ChatController::store_chat_message_presupuesto', ['as' => 'storeChatMessagePresupuesto']); $routes->post('message/pedido', 'ChatController::store_chat_message_pedido', ['as' => 'storeChatMessagePedido']); $routes->post('message/factura', 'ChatController::store_chat_message_factura', ['as' => 'storeChatMessageFactura']); @@ -909,6 +909,27 @@ $routes->group('chat', ['namespace' => 'App\Controllers\Chat'], function ($route }); +$routes->group('messages', ['namespace' => 'App\Controllers\Chat'], function ($routes) { + $routes->get('datatable', 'ChatController::datatable_messages', ['as' => 'getDatatableMessages']); + $routes->get('datatable/presupuesto', 'ChatController::datatable_presupuesto_messages', ['as' => 'getDatatablePresupuestoMessages']); + $routes->get('datatable/pedido', 'ChatController::datatable_pedido_messages', ['as' => 'getDatatablePedidoMessages']); + $routes->get('datatable/factura', 'ChatController::datatable_factura_messages', ['as' => 'getDatatableFacturaMessages']); + + $routes->post('direct', 'ChatController::store_new_direct_message', ['as' => 'storeNewDirectMessage']); + $routes->post('direct/client', 'ChatController::store_new_direct_message_client', ['as' => 'storeNewDirectMessageClient']); +}); + + +$routes->group('soporte', ['namespace' => 'App\Controllers\Soporte'], function ($routes) { + $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'); +}); + $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], function ($routes) { $routes->group('ordentrabajo', ['namespace' => 'App\Controllers\Produccion'], function ($routes) { diff --git a/ci4/app/Config/Services.php b/ci4/app/Config/Services.php index 8d209990..33330fa1 100755 --- a/ci4/app/Config/Services.php +++ b/ci4/app/Config/Services.php @@ -4,6 +4,7 @@ namespace Config; use App\Services\FTPService; use App\Services\MaquinaService; +use App\Services\MessageService; use App\Services\PapelImpresionService; use CodeIgniter\Config\BaseService; use App\Services\ProductionService; @@ -48,4 +49,8 @@ class Services extends BaseService { return new MaquinaService(); } + public static function messages() + { + return new MessageService(); + } } diff --git a/ci4/app/Controllers/Chat/ChatController.php b/ci4/app/Controllers/Chat/ChatController.php index 854f562b..0be4e8ed 100644 --- a/ci4/app/Controllers/Chat/ChatController.php +++ b/ci4/app/Controllers/Chat/ChatController.php @@ -766,4 +766,11 @@ class ChatController extends BaseController $this->chatModel->setAsUnviewedChatUserNotifications($chat_id, auth()->user()->id); return $this->response->setJSON(["message" => "ok", "status" => true]); } + public function store_chat_error_message() + { + $bodyData = $this->request->getPost(); + $messageService = service('messages'); + $r = $messageService->createErrorMessagePresupuesto("Error",$bodyData['presupuesto_id']); + return $this->response->setJSON(["message" => "ok","data" => $r]); + } } diff --git a/ci4/app/Controllers/Configuracion/Papelesgenericos.php b/ci4/app/Controllers/Configuracion/Papelesgenericos.php index 82392fca..37e2ca7c 100755 --- a/ci4/app/Controllers/Configuracion/Papelesgenericos.php +++ b/ci4/app/Controllers/Configuracion/Papelesgenericos.php @@ -156,6 +156,9 @@ class Papelesgenericos extends \App\Controllers\BaseResourceController if ($this->request->getPost('show_in_client') == null) { $sanitizedData['show_in_client'] = false; } + if ($this->request->getPost('activo') == null) { + $sanitizedData['activo'] = false; + } if ($this->request->getPost('show_in_client_special') == null) { $sanitizedData['show_in_client_special'] = false; } @@ -163,6 +166,9 @@ class Papelesgenericos extends \App\Controllers\BaseResourceController if ($sanitizedData['show_in_client_special']) { $sanitizedData['show_in_client'] = true; } + if ($sanitizedData['activo']) { + $sanitizedData['activo'] = true; + } $noException = true; if ($successfulResult = $this->canValidate()): // if ($successfulResult = $this->validate($this->formValidationRules) ) : diff --git a/ci4/app/Controllers/Presupuestos/Presupuestocliente.php b/ci4/app/Controllers/Presupuestos/Presupuestocliente.php index 919d141a..fdb162cd 100755 --- a/ci4/app/Controllers/Presupuestos/Presupuestocliente.php +++ b/ci4/app/Controllers/Presupuestos/Presupuestocliente.php @@ -18,6 +18,7 @@ use App\Models\Presupuestos\PresupuestoModel; use App\Models\Presupuestos\PresupuestoPreimpresionesModel; use App\Models\Presupuestos\PresupuestoServiciosExtraModel; use App\Models\Presupuestos\ErrorPresupuesto; +use App\Services\MessageService; use App\Services\PresupuestoClienteService; use App\Services\PresupuestoService; use Exception; @@ -42,7 +43,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController protected $indexRoute = 'listaPresupuestos'; - + protected MessageService $messageService; public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger) { @@ -61,6 +62,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController ['title' => lang("App.menu_presupuestos"), 'route' => "javascript:void(0);", 'active' => false], ['title' => "Listado", 'route' => site_url('presupuestocliente/list'), 'active' => true] ]; + $this->messageService = service('messages'); parent::initController($request, $response, $logger); $this->model = new PresupuestoModel(); diff --git a/ci4/app/Controllers/Sistema/Intranet.php b/ci4/app/Controllers/Sistema/Intranet.php index 99d3b206..73aa48f2 100644 --- a/ci4/app/Controllers/Sistema/Intranet.php +++ b/ci4/app/Controllers/Sistema/Intranet.php @@ -32,4 +32,29 @@ class Intranet extends Controller } + function tickets($resource_name) + { + helper('file'); + + $resource_path = WRITEPATH . 'uploads/tickets/' . $resource_name; + + if (file_exists($resource_path)) { + // Get the mime type of the file + $mime_type = mime_content_type($resource_path); + + // Get an instance of the Response class + $response = service('response'); + + // Set the content type + $response->setContentType($mime_type); + + // Set the output + $response->setBody(file_get_contents($resource_path)); + + // Send the response to the browser + $response->send(); + } + + } + } \ No newline at end of file diff --git a/ci4/app/Controllers/Soporte/Ticketcontroller.php b/ci4/app/Controllers/Soporte/Ticketcontroller.php new file mode 100644 index 00000000..a50c7889 --- /dev/null +++ b/ci4/app/Controllers/Soporte/Ticketcontroller.php @@ -0,0 +1,429 @@ +viewData['pageTitle'] = lang('Tickets.moduleTitle'); + + // Breadcrumbs + $this->viewData['breadcrumb'] = [ + ['title' => lang("App.menu_soporte"), 'route' => "javascript:void(0);", 'active' => false], + ['title' => lang("App.menu_soporte_ticket_list"), 'route' => route_to('TicketIndex'), 'active' => true] + ]; + + parent::initController($request, $response, $logger); + } + + public function index() + { + //checkPermission('tickets.menu'); + + $viewData = [ + 'currentModule' => static::$controllerSlug, + 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Tickets.tickets')]), + 'usingServerSideDataTable' => true, + '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); + } + + private function sendMail($subject, $body, $recipient) + { + $settings_model = new SettingsModel(); + $config = $settings_model->first()->toArray(); + $gateway = $config['email_gateway']; + $body = html_entity_decode($body); + + if ($gateway == 'smtp') { + try { + //https://codeigniter.com/user_guide/libraries/email.html + $email = \Config\Services::email(); + $config['protocol'] = $config['email_gateway']; + $config['SMTPHost'] = $config['email_smtp']; + $config['SMTPUser'] = $config['email_address']; + $config['SMTPPass'] = $config['email_pass']; + $config['SMTPPort'] = intval($config['email_port']); + $config['SMTPCrypto'] = $config['email_cert'] == 'none' ? '' : $config['email_cert']; + $config['SMTPTimeout'] = 15; + $config['mailType'] = 'html'; + $config['wordWrap'] = true; + + $email->initialize($config); + + $email->setFrom($config['email_address'], $config['email_name']); + $email->setTo($recipient); + + $email->setSubject($subject); + $email->setMessage($body); + + if (!$email->send()) { + return false; + } else { + return true; + } + } catch (\Exception $ex) { + return false; + } + } + return false; + } + + public function add() + { + + //checkPermission('tickets.create', $this->indexRoute); + + if ($this->request->getPost()): + + $nullIfEmpty = false; // !(phpversion() >= '8.1'); + + $postData = $this->request->getPost(); + + // get user id + $postData['usuario_id'] = auth()->user()->id; + $postData['user_soporte_id'] = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('default_soporte_user_id')->value; + + $sanitizedData = $this->sanitized($postData, $nullIfEmpty); + + $noException = true; + if ($successfulResult = $this->canValidate()): // if ($successfulResult = $this->validate($this->formValidationRules) ) : + + + if ($this->canValidate()): + try { + $successfulResult = $this->model->skipValidation(true)->save($sanitizedData); + } catch (\Exception $e) { + $noException = false; + $this->dealWithException($e); + } + else: + $this->viewData['errorMessage'] = lang('Basic.global.formErr1', [lang('Basic.global.record')]); + $this->session->setFlashdata('formErrors', $this->model->errors()); + endif; + + $thenRedirect = true; // Change this to false if you want your user to stay on the form after submission + endif; + if ($noException && $successfulResult): + + $id = $this->model->db->insertID(); + + $this->saveImages($id, $this->request->getFiles()); + + $message = lang('Basic.global.saveSuccess', [lang('Basic.global.record')]) . '.'; + + $userModel = new \App\Models\UserModel(); + + $this->sendMail(lang('Tickets.newTicket'), lang('Tickets.newTicketBody') . base_url(route_to('editTicket', $id)), $userModel->find($sanitizedData['user_soporte_id'])->email); + + if ($thenRedirect): + if (!empty($this->indexRoute)): + return redirect()->to(route_to($this->indexRoute))->with('successMessage', $message); + else: + return $this->redirect2listView('successMessage', $message); + endif; + else: + $this->session->setFlashData('sweet-success', $message); + endif; + + endif; // $noException && $successfulResult + + endif; // ($requestMethod === 'post') + + $this->viewData['ticket'] = isset($sanitizedData) ? new TicketEntity($sanitizedData) : new TicketEntity(); + + $this->viewData['formAction'] = route_to('NewTicket'); + + $this->viewData['categorias'] = $this->model->getCategorias(); + $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'); + + + return $this->displayForm(__METHOD__); + } // end function add() + + public function edit($requestedId = null) + { + $modelRespuesta = new \App\Models\Soporte\TicketRespuestaModel(); + + if ($requestedId == null): + return $this->redirect2listView(); + endif; + $id = filter_var($requestedId, FILTER_SANITIZE_URL); + $ticket = $this->model->find($id); + + if ($ticket == false): + $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Tickets.ticket')), $id]); + 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()): + + $oldUserSupport = $ticket->user_soporte_id; + $oldState = $ticket->estado_id; + + $postData = $this->request->getPost(); + $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, + ]); + } + + // envio de correos + $userModel = new \App\Models\UserModel(); + if ($oldUserSupport != $sanitizedData['user_soporte_id']) { + $this->sendMail(lang('Tickets.asgignToChanged'), lang('Tickets.asgignToChangedBody') . base_url(route_to('editTicket', $id)), $userModel->find($sanitizedData['user_soporte_id'])->email); + } + + if ($oldState != $sanitizedData['estado_id']) { + $this->sendMail(lang('Tickets.stateChange'), lang('Tickets.stateChangeBody') . base_url(route_to('editTicket', $id)), $userModel->find($ticket->usuario_id)->email); + } + + } + + } catch (\Exception $e) { + $noException = false; + $this->dealWithException($e); + } + else: + $this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Tickets.ticket'))]); + $this->session->setFlashdata('formErrors', $this->model->errors()); + + endif; + + $ticket->fill($sanitizedData); + + $thenRedirect = false; + endif; + if ($noException && $successfulResult): + $id = $ticket->id ?? $id; + $message = lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.'; + + if ($thenRedirect): + if (!empty($this->indexRoute)): + return redirect()->to(route_to($this->indexRoute))->with('successMessage', $message); + else: + return $this->redirect2listView('successMessage', $message); + endif; + else: + 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(); + $this->viewData['supportUsers'] = $this->getSupportUsers(); + + $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() + { + if ($this->request->isAJAX()) { + $reqData = $this->request->getPost(); + if (!isset($reqData['draw']) || !isset($reqData['columns'])) { + $errstr = 'No data available in response to this specific request.'; + $response = $this->respond(Collection::datatable([], 0, 0, $errstr), 400, $errstr); + return $response; + } + $start = $reqData['start'] ?? 0; + $length = $reqData['length'] ?? 5; + + $requestedOrder = $reqData['order'] ?? []; + + $searchValues = get_filter_datatables_columns($reqData); + + 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'; + $orderColumn = $this->model::SORTABLE[$column] ?? null; + if ($orderColumn) { + $resourceData->orderBy($orderColumn, $dir); + } + } + $resourceData = $resourceData->limit($length, $start)->get()->getResultObject(); + + return $this->respond(Collection::datatable( + $resourceData, + $this->model->getResource($searchValues)->countAllResults(), + $this->model->getResource($searchValues)->countAllResults() + )); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + 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 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') { + $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; + } + + 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/Controllers/Tarifas/Tarifaextra.php b/ci4/app/Controllers/Tarifas/Tarifaextra.php index 28ea2f1b..049c07d6 100755 --- a/ci4/app/Controllers/Tarifas/Tarifaextra.php +++ b/ci4/app/Controllers/Tarifas/Tarifaextra.php @@ -65,7 +65,9 @@ class Tarifaextra extends \App\Controllers\GoBaseController if ($this->request->getPost('mostrar_en_presupuesto') == null) { $sanitizedData['mostrar_en_presupuesto'] = false; } - + if ($this->request->getPost('mostrar_en_presupuesto_cliente') == null) { + $sanitizedData['mostrar_en_presupuesto_cliente'] = false; + } $noException = true; if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : @@ -142,7 +144,9 @@ class Tarifaextra extends \App\Controllers\GoBaseController if ($this->request->getPost('mostrar_en_presupuesto') == null) { $sanitizedData['mostrar_en_presupuesto'] = false; } - + if ($this->request->getPost('mostrar_en_presupuesto_cliente') == null) { + $sanitizedData['mostrar_en_presupuesto_cliente'] = false; + } $noException = true; if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : if ($this->canValidate()) : diff --git a/ci4/app/Controllers/Tarifas/Tarifapreimpresion.php b/ci4/app/Controllers/Tarifas/Tarifapreimpresion.php index 6d26178e..474d60f1 100755 --- a/ci4/app/Controllers/Tarifas/Tarifapreimpresion.php +++ b/ci4/app/Controllers/Tarifas/Tarifapreimpresion.php @@ -63,7 +63,9 @@ class Tarifapreimpresion extends \App\Controllers\GoBaseController if ($this->request->getPost('mostrar_en_presupuesto') == null) { $sanitizedData['mostrar_en_presupuesto'] = false; } - + if ($this->request->getPost('mostrar_en_presupuesto_cliente') == null) { + $sanitizedData['mostrar_en_presupuesto_cliente'] = false; + } $noException = true; if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : @@ -144,7 +146,9 @@ class Tarifapreimpresion extends \App\Controllers\GoBaseController if ($this->request->getPost('mostrar_en_presupuesto') == null) { $sanitizedData['mostrar_en_presupuesto'] = false; } - + if ($this->request->getPost('mostrar_en_presupuesto_cliente') == null) { + $sanitizedData['mostrar_en_presupuesto_cliente'] = false; + } $noException = true; if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : if ($this->canValidate()) : 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 new file mode 100644 index 00000000..c0bbab1f --- /dev/null +++ b/ci4/app/Database/Migrations/2025-02-14-114500_create_tickets_system.php @@ -0,0 +1,99 @@ +forge->addField([ + 'id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true], + 'keyword' => ['type' => 'VARCHAR', 'constraint' => 100, 'unique' => true], + ]); + $this->forge->addPrimaryKey('id'); + $this->forge->createTable('tickets_categorias'); + + // Tabla de secciones + $this->forge->addField([ + 'id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true], + 'keyword' => ['type' => 'VARCHAR', 'constraint' => 100, 'unique' => true], + ]); + $this->forge->addPrimaryKey('id'); + $this->forge->createTable('tickets_secciones'); + + // Tabla de Estados + $this->forge->addField([ + 'id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true], + 'keyword' => ['type' => 'VARCHAR', 'constraint' => 100, 'unique' => true], + ]); + $this->forge->addPrimaryKey('id'); + $this->forge->createTable('tickets_estados'); + + // Tabla de Tickets + $this->forge->addField([ + 'id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true], + 'usuario_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true], + 'user_soporte_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true], + 'categoria_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true], + 'seccion_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true], + 'estado_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'default' => 1], + 'prioridad' => ['type' => 'ENUM', 'constraint' => ['alta', 'media', 'baja'], 'default' => 'media'], + 'titulo' => ['type' => 'VARCHAR', 'constraint' => 255], + 'descripcion' => ['type' => 'TEXT'], + 'created_at' => ['type' => 'DATETIME', 'null' => true], + 'updated_at' => ['type' => 'DATETIME', 'null' => true], + ]); + $this->forge->addPrimaryKey('id'); + $this->forge->addForeignKey('usuario_id', 'users', 'id', 'NO ACTION', 'NO ACTION'); + $this->forge->addForeignKey('user_soporte_id', 'users', 'id', 'NO ACTION', 'NO ACTION'); + $this->forge->addForeignKey('categoria_id', 'tickets_categorias', 'id', 'NO ACTION', 'NO ACTION'); + $this->forge->addForeignKey('seccion_id', 'tickets_secciones', 'id', 'NO ACTION', 'NO ACTION'); + $this->forge->addForeignKey('estado_id', 'tickets_estados', 'id', 'NO ACTION', 'NO ACTION'); + $this->forge->createTable('tickets'); + + // Tabla de Respuestas + $this->forge->addField([ + 'id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true], + 'ticket_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true], + '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'); + $this->forge->addForeignKey('usuario_id', 'users', 'id', 'NO ACTION', 'NO ACTION'); + $this->forge->createTable('tickets_respuestas'); + + // Tabla de Adjuntos + $this->forge->addField([ + 'id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true], + 'ticket_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'null' => true], + 'respuesta_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'null' => true], + 'nombre' => ['type' => 'VARCHAR', 'constraint' => 255], + 'hash' => ['type' => 'VARCHAR', 'constraint' => 255], + 'path' => ['type' => 'VARCHAR', 'constraint' => 255], + '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', 'NO ACTION'); + $this->forge->addForeignKey('respuesta_id', 'tickets_respuestas', 'id', 'NO ACTION', 'NO ACTION'); + $this->forge->createTable('tickets_adjuntos'); + } + + public function down() + { + $this->forge->dropTable('tickets_adjuntos'); + $this->forge->dropTable('tickets_respuestas'); + $this->forge->dropTable('tickets'); + $this->forge->dropTable('tickets_categorias'); + $this->forge->dropTable('tickets_estados'); + $this->forge->dropTable('tickets_secciones'); + + $this->db->table('config_variables_app')->where('name', 'default_soporte_user_id')->delete(); + } +} diff --git a/ci4/app/Database/Migrations/2025-02-16-194726_AlterTableTarifasCheckPresupuestoClienteMigration.php b/ci4/app/Database/Migrations/2025-02-16-194726_AlterTableTarifasCheckPresupuestoClienteMigration.php new file mode 100644 index 00000000..1d4f8510 --- /dev/null +++ b/ci4/app/Database/Migrations/2025-02-16-194726_AlterTableTarifasCheckPresupuestoClienteMigration.php @@ -0,0 +1,29 @@ + [ + 'type' => 'BOOLEAN', + 'default' => false, + ] + ]; + $this->forge->addColumn('lg_tarifa_acabado',$field); + $this->forge->addColumn('lg_tarifa_manipulado',$field); + $this->forge->addColumn('tarifa_encuadernacion',$field); + + } + + public function down() + { + $this->forge->dropColumn('lg_tarifa_acabado','mostrar_en_presupuesto_cliente'); + $this->forge->dropColumn('lg_tarifa_manipulado','mostrar_en_presupuesto_cliente'); + $this->forge->dropColumn('tarifa_encuadernacion','mostrar_en_presupuesto_cliente'); + } +} diff --git a/ci4/app/Database/Migrations/2025-02-16-224244_AlterAddColumnActivoPapelGenerico.php b/ci4/app/Database/Migrations/2025-02-16-224244_AlterAddColumnActivoPapelGenerico.php new file mode 100644 index 00000000..ae73c86b --- /dev/null +++ b/ci4/app/Database/Migrations/2025-02-16-224244_AlterAddColumnActivoPapelGenerico.php @@ -0,0 +1,26 @@ + [ + 'type' => 'BOOLEAN', + 'default' => true, + ] + ]; + $this->forge->addColumn('lg_papel_generico',$field); + + } + + public function down() + { + $this->forge->dropColumn('lg_papel_generico','activo'); + } +} + diff --git a/ci4/app/Database/Migrations/2025-02-20-080000_AlterTableTarifasExtraPreimpresionCheckPresupuestoClienteMigration.php b/ci4/app/Database/Migrations/2025-02-20-080000_AlterTableTarifasExtraPreimpresionCheckPresupuestoClienteMigration.php new file mode 100644 index 00000000..ee5e2428 --- /dev/null +++ b/ci4/app/Database/Migrations/2025-02-20-080000_AlterTableTarifasExtraPreimpresionCheckPresupuestoClienteMigration.php @@ -0,0 +1,30 @@ + [ + 'type' => 'BOOLEAN', + 'default' => false, + ] + ]; + $this->forge->addColumn('tarifa_extra',$field); + $this->forge->addColumn('lg_tarifa_preimpresion',$field); + + + } + + public function down() + { + $this->forge->dropColumn('tarifa_extra','mostrar_en_presupuesto_cliente'); + $this->forge->dropColumn('lg_tarifa_preimpresion','mostrar_en_presupuesto_cliente'); + + + } +} diff --git a/ci4/app/Database/Seeds/TicketsSeeder.php b/ci4/app/Database/Seeds/TicketsSeeder.php new file mode 100644 index 00000000..f7d0ea93 --- /dev/null +++ b/ci4/app/Database/Seeds/TicketsSeeder.php @@ -0,0 +1,76 @@ + 'errores', + ], + [ + 'keyword' => 'consultas', + ], + [ + 'keyword' => 'sugerencias', + ], + ]; + $this->db->table('tickets_categorias')->insertBatch($data); + + // secciones + $data = [ + [ + 'keyword' => 'presupuestos', + ], + [ + 'keyword' => 'pedidos', + ], + [ + 'keyword' => 'facturacion', + ], + [ + 'keyword' => 'logistica', + ], + [ + 'keyword' => 'configuracion', + ], + [ + 'keyword' => 'general', + ], + ]; + $this->db->table('tickets_secciones')->insertBatch($data); + + // estados + $data = [ + [ + 'keyword' => 'abierto', + ], + [ + 'keyword' => 'en_proceso', + ], + [ + 'keyword' => 'resuelto', + ], + [ + 'keyword' => 'archivado', + ], + ]; + $this->db->table('tickets_estados')->insertBatch($data); + + // config variables + $data = [ + [ + 'name' => 'default_soporte_user_id', + 'value' => '10', + 'description' => 'ID del usuario por defecto para asignar tickets', + ], + ]; + $this->db->table('config_variables_app')->insertBatch($data); + } +} \ No newline at end of file diff --git a/ci4/app/Entities/Configuracion/PapelGenerico.php b/ci4/app/Entities/Configuracion/PapelGenerico.php index a6bc5faa..344d1832 100755 --- a/ci4/app/Entities/Configuracion/PapelGenerico.php +++ b/ci4/app/Entities/Configuracion/PapelGenerico.php @@ -13,11 +13,13 @@ class PapelGenerico extends \CodeIgniter\Entity\Entity "show_in_client" => false, "show_in_client_special" => false, "is_deleted" => 0, + "activo" => false, "created_at" => null, "updated_at" => null, ]; protected $casts = [ "show_in_client" => "boolean", + "activo" => "boolean", "show_in_client_special" => "boolean", "is_deleted" => "int", ]; diff --git a/ci4/app/Entities/Soporte/TicketEntity.php b/ci4/app/Entities/Soporte/TicketEntity.php new file mode 100644 index 00000000..192e8d51 --- /dev/null +++ b/ci4/app/Entities/Soporte/TicketEntity.php @@ -0,0 +1,52 @@ + null, + 'usuario_id' => null, + 'tecnico_id' => null, + 'categoria_id'=> null, + 'estado_id' => null, + 'prioridad' => 'media', + 'titulo' => '', + 'descripcion' => '', + 'created_at' => null, + 'updated_at' => null, + ]; + + protected $dates = ['created_at', 'updated_at']; + + public function setTitulo(string $titulo) + { + $this->attributes['titulo'] = ucfirst($titulo); // Capitaliza el título + return $this; + } + + public function setDescripcion(string $descripcion) + { + $this->attributes['descripcion'] = ucfirst($descripcion); + return $this; + } + + public function getPrioridad(): string + { + return ucfirst($this->attributes['prioridad']); + } + + public function asignarTecnico(int $tecnicoId) + { + $this->attributes['tecnico_id'] = $tecnicoId; + return $this; + } + + public function cambiarEstado(int $estadoId) + { + $this->attributes['estado_id'] = $estadoId; + return $this; + } +} 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/Entities/Tarifas/Acabados/TarifaAcabadoEntity.php b/ci4/app/Entities/Tarifas/Acabados/TarifaAcabadoEntity.php index 37554c8d..0e384c7f 100644 --- a/ci4/app/Entities/Tarifas/Acabados/TarifaAcabadoEntity.php +++ b/ci4/app/Entities/Tarifas/Acabados/TarifaAcabadoEntity.php @@ -13,6 +13,7 @@ class TarifaAcabadoEntity extends \CodeIgniter\Entity\Entity "precio_min" => 0, "importe_fijo" => 0, "mostrar_en_presupuesto" => 1, + "mostrar_en_presupuesto_cliente" => 0, "acabado_cubierta" => 0, "acabado_sobrecubierta" => 0, "user_created_id" => 0, diff --git a/ci4/app/Entities/Tarifas/TarifaEncuadernacionEntity.php b/ci4/app/Entities/Tarifas/TarifaEncuadernacionEntity.php index 1aa85454..b8d01575 100755 --- a/ci4/app/Entities/Tarifas/TarifaEncuadernacionEntity.php +++ b/ci4/app/Entities/Tarifas/TarifaEncuadernacionEntity.php @@ -11,6 +11,7 @@ class TarifaEncuadernacionEntity extends \CodeIgniter\Entity\Entity "nombre" => null, "code" => null, "mostrar_en_presupuesto" => 1, + "mostrar_en_presupuesto_cliente" => 0, "tipo_encuadernacion" => 0, "servicio_encuadernacion" => 0, "por_horas" => 0, @@ -23,6 +24,7 @@ class TarifaEncuadernacionEntity extends \CodeIgniter\Entity\Entity ]; protected $casts = [ "mostrar_en_presupuesto" => "int", + "mostrar_en_presupuesto_cliente" => "bool", "code" => "string", "tipo_encuadernacion" => "int", "servicio_encuadernacion" => "int", diff --git a/ci4/app/Entities/Tarifas/TarifaManipuladoEntity.php b/ci4/app/Entities/Tarifas/TarifaManipuladoEntity.php index d9f3c2f7..d976de71 100755 --- a/ci4/app/Entities/Tarifas/TarifaManipuladoEntity.php +++ b/ci4/app/Entities/Tarifas/TarifaManipuladoEntity.php @@ -14,6 +14,7 @@ class TarifaManipuladoEntity extends \CodeIgniter\Entity\Entity "precio_min" => 0, "importe_fijo" => 0, "mostrar_en_presupuesto" => 1, + "mostrar_en_presupuesto_cliente" => 0, "user_created_id" => 0, "user_updated_id" => 0, "is_deleted" => 0, @@ -27,6 +28,7 @@ class TarifaManipuladoEntity extends \CodeIgniter\Entity\Entity "code" => "string", "comment" => "string", "mostrar_en_presupuesto" => "int", + "mostrar_en_presupuesto_cliente" => "bool", "user_created_id" => "int", "user_updated_id" => "int", "is_deleted" => "int", diff --git a/ci4/app/Entities/Tarifas/TarifaextraEntity.php b/ci4/app/Entities/Tarifas/TarifaextraEntity.php index db2b0594..7134684d 100755 --- a/ci4/app/Entities/Tarifas/TarifaextraEntity.php +++ b/ci4/app/Entities/Tarifas/TarifaextraEntity.php @@ -13,6 +13,7 @@ class TarifaextraEntity extends \CodeIgniter\Entity\Entity "precio" => null, "margen" => 0, "mostrar_en_presupuesto" => 1, + "mostrar_en_presupuesto_cliente" => false, "user_created_id" => 1, "user_update_id" => 1, "is_deleted" => 0, @@ -26,6 +27,7 @@ class TarifaextraEntity extends \CodeIgniter\Entity\Entity "comment" => "string", "margen" => "float", "mostrar_en_presupuesto" => "int", + "mostrar_en_presupuesto_cliente" => "bool", "user_created_id" => "int", "user_update_id" => "int", "is_deleted" => "int", diff --git a/ci4/app/Entities/Tarifas/TarifapreimpresionEntity.php b/ci4/app/Entities/Tarifas/TarifapreimpresionEntity.php index b1873597..86bd7f14 100755 --- a/ci4/app/Entities/Tarifas/TarifapreimpresionEntity.php +++ b/ci4/app/Entities/Tarifas/TarifapreimpresionEntity.php @@ -13,6 +13,7 @@ class TarifapreimpresionEntity extends \CodeIgniter\Entity\Entity "precio" => null, "margen" => 0, "mostrar_en_presupuesto" => 1, + "mostrar_en_presupuesto_cliente" => false, "user_created_id" => 1, "user_update_id" => 1, "is_deleted" => 0, @@ -26,6 +27,7 @@ class TarifapreimpresionEntity extends \CodeIgniter\Entity\Entity "code" => "string", "comment" => "string", "mostrar_en_presupuesto" => "int", + "mostrar_en_presupuesto_cliente" => "bool", "user_created_id" => "int", "user_update_id" => "int", "is_deleted" => "int", diff --git a/ci4/app/Language/es/App.php b/ci4/app/Language/es/App.php index 44552d73..a24597ea 100755 --- a/ci4/app/Language/es/App.php +++ b/ci4/app/Language/es/App.php @@ -818,5 +818,9 @@ return [ "menu_oauth" => "Autenticaciones", "menu_template" => "Plantillas", + "menu_soporte" => "Soporte", + "menu_soporte_new_ticket" => "Crear ticket", + "menu_soporte_ticket_list" => "Mis tickets", + ]; \ No newline at end of file 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/PapelGenerico.php b/ci4/app/Language/es/PapelGenerico.php index c38d8c1c..5df63224 100755 --- a/ci4/app/Language/es/PapelGenerico.php +++ b/ci4/app/Language/es/PapelGenerico.php @@ -8,6 +8,7 @@ return [ 'createdAt' => 'Creado el', 'deletedAt' => 'Deleted At', 'id' => 'ID', + 'activo' => 'Activo', 'isDeleted' => 'Is Deleted', 'moduleTitle' => 'Papel Genérico', 'nombre' => 'Nombre', diff --git a/ci4/app/Language/es/RolesPermisos.php b/ci4/app/Language/es/RolesPermisos.php index 84e56b7f..ccc4176a 100644 --- a/ci4/app/Language/es/RolesPermisos.php +++ b/ci4/app/Language/es/RolesPermisos.php @@ -55,7 +55,7 @@ return [ 'ajustesSection' => 'Ajustes', 'actividadSection' => 'Accesos', - + "ticketsSection" => "Tickets", 'validation' => [ 'id' => [ diff --git a/ci4/app/Language/es/Tarifaacabado.php b/ci4/app/Language/es/Tarifaacabado.php index 5bdd61e9..1b5af0c8 100755 --- a/ci4/app/Language/es/Tarifaacabado.php +++ b/ci4/app/Language/es/Tarifaacabado.php @@ -13,6 +13,7 @@ return [ 'precioMin' => 'Precio Mínimo', 'importeFijo' => 'Importe Fijo', 'mostrar_en_presupuesto' => 'Mostrar en presupuesto', + 'mostrar_en_presupuesto_cliente' => 'Mostrar en presupuesto (cliente)', "acabado_cubierta" => "Acabado cubierta", "acabado_sobrecubierta" => "Acabado sobrecubierta", 'tarifaacabado' => 'Tarifa Acabado', diff --git a/ci4/app/Language/es/Tarifaencuadernacion.php b/ci4/app/Language/es/Tarifaencuadernacion.php index fbc59ef5..a4e15cde 100755 --- a/ci4/app/Language/es/Tarifaencuadernacion.php +++ b/ci4/app/Language/es/Tarifaencuadernacion.php @@ -23,6 +23,7 @@ return [ 'tiradaMax' => 'Tirada Max', 'tiradaMin' => 'Tirada Min', 'mostrar_en_presupuesto' => 'Mostrar en presupuesto', + 'mostrar_en_presupuesto_cliente' => 'Mostrar en presupuesto (cliente)', 'tipo_encuadernacion' => 'Tipo encuardernación', 'servicio_encuadernacion' => 'Servicio encuardernación', 'updatedAt' => 'Actualizado en', diff --git a/ci4/app/Language/es/Tarifaextra.php b/ci4/app/Language/es/Tarifaextra.php index ea711c63..f1263281 100755 --- a/ci4/app/Language/es/Tarifaextra.php +++ b/ci4/app/Language/es/Tarifaextra.php @@ -14,6 +14,7 @@ return [ 'precioMin' => 'Precio Mínimo', 'importeFijo' => 'Importe Fijo', 'mostrar_en_presupuesto' => 'Mostrar en presupuesto', + 'mostrar_en_presupuesto_cliente' => 'Mostrar en presupuesto (Cliente)', 'margen' => 'Margen', 'tarifaextra' => 'Tarifa Servicios Extra', 'tarifaextraList' => 'Lista Tarifas Servicios Extra', diff --git a/ci4/app/Language/es/Tarifamanipulado.php b/ci4/app/Language/es/Tarifamanipulado.php index 80afab6a..0bd0c413 100755 --- a/ci4/app/Language/es/Tarifamanipulado.php +++ b/ci4/app/Language/es/Tarifamanipulado.php @@ -18,6 +18,7 @@ return [ 'precioMin' => 'Precio T. Máx', 'importeFijo' => 'Importe Fijo', 'mostrar_en_presupuesto' => 'Mostrar en presupuesto', + 'mostrar_en_presupuesto_cliente' => 'Mostrar en presupuesto (cliente)', 'tarifamanipulado' => 'Tarifa Manipulado', 'tarifamanipuladoList' => 'Lista Tarifas Manipulado', 'tarifasmanipulado' => 'Tarifas Manipulado', diff --git a/ci4/app/Language/es/Tarifapreimpresion.php b/ci4/app/Language/es/Tarifapreimpresion.php index f98cd490..a1c885dd 100755 --- a/ci4/app/Language/es/Tarifapreimpresion.php +++ b/ci4/app/Language/es/Tarifapreimpresion.php @@ -14,6 +14,7 @@ return [ 'precioMin' => 'Precio Mínimo', 'importeFijo' => 'Importe Fijo', 'mostrar_en_presupuesto' => 'Mostrar en presupuesto', + 'mostrar_en_presupuesto_cliente' => 'Mostrar en presupuesto (Cliente)', 'margen' => 'Margen', 'tarifapreimpresion' => 'Tarifa Preimpresión', 'tarifapreimpresionList' => 'Lista Tarifas Preimpresión', diff --git a/ci4/app/Language/es/Tickets.php b/ci4/app/Language/es/Tickets.php new file mode 100644 index 00000000..020d304f --- /dev/null +++ b/ci4/app/Language/es/Tickets.php @@ -0,0 +1,70 @@ + 'Ticket', + 'tickets' => 'Tickets', + 'moduleTitle' => 'Tickets', + + "asunto" => "Asunto", + "tipo" => "Tipo", + "seccion" => "Sección", + "estado" => "Estado", + "prioridad" => "Prioridad", + "descripcion" => "Descripción", + "asignarTo" => "Asignado a", + "usuario" => "Creado por", + "createTicket" => "Crear Ticket", + "fechaCreacion" => "Fecha de creación", + "respuesta" => "Respuesta", + + // categorías + 'errores' => 'Errores', + 'consultas' => 'Consultas', + 'sugerencias' => 'Sugerencias', + + // secciones + 'presupuestos' => 'Presupuestos', + 'pedidos' => 'Pedidos', + 'facturacion' => 'Facturación', + 'logistica' => 'Logística', + 'configuracion' => 'Configuración', + 'general' => 'General', + + // estados + 'abierto' => 'Abierto', + 'en_proceso' => 'En proceso', + 'resuelto' => 'Resuelto', + 'archivado' => 'Archivado', + + //Prioridades + 'alta' => 'Alta', + 'media' => 'Media', + 'baja' => 'Baja', + + // FIcheros + 'adjuntos' => 'Adjuntar imágenes', + 'adjuntos_ticket' => 'Imágenes adjuntas', + + // Mail + 'newTicket' => 'Nuevo Ticket en ERP Safekat', + 'stateChange' => 'Cambio de estado en ticket en ERP Safekat', + 'asgignToChanged' => 'Asignado ticket en ERP Safekat', + 'newTicketBody' => '
Se ha creado un nuevo ticket en el sistema de soporte de Safekat ERP.
Puede verlo en el siguiente enlace:
El estado de un ticket en el sistema de soporte de Safekat ERP ha cambiado.
Puede verlo en el siguiente enlace:
Se le ha asignado un ticket en el sistema de soporte de Safekat ERP.
Puede verlo en el siguiente enlace:
| ID | += lang('Tickets.tipo') ?> | += lang('Tickets.seccion') ?> | += lang('Tickets.estado') ?> | + += lang('Tickets.prioridad') ?> | + += lang('Tickets.asunto') ?> | + += lang('Tickets.usuario') ?> | += lang('Tickets.asignarTo') ?> | + += lang('Tickets.fechaCreacion') ?> | += lang('Basic.global.Action') ?> | +
|---|
Directory access is forbidden.
- - - diff --git a/httpdocs/assets/js/safekat/components/alerts/sweetAlert.js b/httpdocs/assets/js/safekat/components/alerts/sweetAlert.js index 97f9bd66..449f9a7c 100644 --- a/httpdocs/assets/js/safekat/components/alerts/sweetAlert.js +++ b/httpdocs/assets/js/safekat/components/alerts/sweetAlert.js @@ -1,37 +1,37 @@ -export const alertConfirmationDelete = (title,type="primary") => { - return Swal.fire({ - title: '¿Está seguro?', - text: "Esta acción es irreversible.", - icon: 'warning', - showCancelButton: true, - confirmButtonColor: '#3085d6', - cancelButtonColor: '#d33', - confirmButtonText: 'Sí', - cancelButtonText: 'Cancelar', - customClass: { - confirmButton: 'btn btn-danger me-1', - cancelButton: 'btn btn-label-secondary' - }, - buttonsStyling: false - }) -} - -export const alertSuccessMessage = (title,type="primary") => { - return Swal.fire({ - showCancelButton: false, - showConfirmButton : false, - title: title, - text: title, - icon: "success", - timer : 2000 +export const alertConfirmationDelete = (title, type = "primary") => { + return Swal.fire({ + title: '¿Está seguro?', + text: "Esta acción es irreversible.", + icon: 'warning', + showCancelButton: true, + confirmButtonColor: '#3085d6', + cancelButtonColor: '#d33', + confirmButtonText: 'Sí', + cancelButtonText: 'Cancelar', + customClass: { + confirmButton: 'btn btn-danger me-1', + cancelButton: 'btn btn-label-secondary' + }, + buttonsStyling: false }) } -export const alertWarningMessage = (title,message,type="primary") => { - return Swal.fire({ +export const alertSuccessMessage = (title, type = "primary") => { + return Swal.fire({ + showCancelButton: false, + showConfirmButton: false, + title: title, + text: title, + icon: "success", + timer: 2000 + }) +} + +export const alertWarningMessage = (title, message, type = "primary") => { + return Swal.fire({ title: title, text: message, icon: "warning", @@ -40,4 +40,28 @@ export const alertWarningMessage = (title,message,type="primary") => { }, buttonsStyling: false }) +} + +export const toastPresupuestoSummary = (value, target = 'body') => { + return Swal.mixin({ + toast: true, + position: 'bottom-end', + html: ` +Total presupuesto
+ ${value} +