diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index 185309ad..5bed71a5 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -721,6 +721,44 @@ $routes->group( ); $routes->resource('buscadorpresupuestos', ['namespace' => 'App\Controllers\Presupuestos', 'controller' => 'Buscador', 'except' => 'show,new,create,update']); +/* Rutas para mensajeria */ +$routes->group('mensajes', ['namespace' => 'App\Controllers\Mensajeria'], function ($routes) { + + /* Interna */ + $routes->group('internos', ['namespace' => 'App\Controllers\Mensajeria'], function ($routes) { + + $routes->get('', 'MensajesDirectos::index', ['as' => 'mensajeriaView']); + $routes->get('chat/(:num)', 'MensajesDirectos::getChatInfo/$1', ['as' => 'getChatInfo']); + /*$routes->match(['get', 'post'], 'add', 'TarifaAcabados::add', ['as' => 'tarifaAcabadoAdd']); + $routes->match(['get', 'post'], 'edit/(:num)', 'TarifaAcabados::edit/$1', ['as' => 'tarifaAcabadoEdit']); + $routes->get('delete/(:num)', 'TarifaAcabados::delete/$1', ['as' => 'tarifaAcabadoDelete']); + $routes->post('datatable', 'TarifaAcabados::datatable', ['as' => 'tarifaAcabadoDT']);*/ + + }); + +}); +$routes->group('chat', ['namespace' => 'App\Controllers\Chat'], function ($routes) { + $routes->get('departments', 'ChatController::get_chat_departments', ['as' => 'getChatDepartments']); + $routes->get('department/presupuesto/(:num)/(:num)', 'ChatController::get_chat_presupuesto/$1/$2', ['as' => 'getChatPresupuesto']); + $routes->get('department/pedido/(:num)/(:num)', 'ChatController::get_chat_pedido/$1/$2', ['as' => 'getChatPedido']); + $routes->get('department/factura/(:num)/(:num)', 'ChatController::get_chat_factura/$1/$2', ['as' => 'getChatFactura']); + + $routes->get('(:num)', 'ChatController::get_chat/$1', ['as' => 'getChat']); + $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']); + $routes->post('message/internal', 'ChatController::store_chat_message_single', ['as' => 'storeChatMessageSingle']); + $routes->get('contacts', 'ChatController::get_chat_internal_contacts', ['as' => 'getChatInternalContacts']); + $routes->get('contacts/(:num)', 'ChatController::get_chat_internal_contact/$1', ['as' => 'getChatInternalContact']); + $routes->get('contact/(:num)/messages', 'ChatController::get_chat_internal_messages/$1', ['as' => 'getChatInternalMessages']); + + + + + + + +}); /* * -------------------------------------------------------------------- diff --git a/ci4/app/Controllers/Chat/ChatController.php b/ci4/app/Controllers/Chat/ChatController.php new file mode 100644 index 00000000..775ae028 --- /dev/null +++ b/ci4/app/Controllers/Chat/ChatController.php @@ -0,0 +1,189 @@ +chatDeparmentModel = model(ChatDeparmentModel::class); + $this->chatDeparmentUserModel = model(ChatDeparmentUserModel::class); + $this->chatModel = model(ChatModel::class); + $this->chatMessageModel = model(ChatMessageModel::class); + $this->userModel = model(UserModel::class); + } + public function index() {} + public function get_chat_departments() + { + + $data = $this->chatDeparmentModel->getChatDepartments(); + return $this->response->setJSON($data); + } + public function get_chat_presupuesto(int $chat_department_id, int $presupuesto_id) + { + + $data = [ + "chat" => null, + "messages" => null, + ]; + $chat = $this->chatModel->getChatPresupuesto($chat_department_id, $presupuesto_id); + if ($chat) { + $data["messages"] = $this->chatMessageModel->get_chat_messages($chat->id); + } + $data["chat"] = $chat; + return $this->response->setJSON($data); + } + public function get_chat_pedido(int $chat_department_id, int $pedido_id) + { + + $data = [ + "chat" => null, + "messages" => null, + ]; + $chat = $this->chatModel->getChatPedido($chat_department_id, $pedido_id); + if ($chat) { + $data["messages"] = $this->chatMessageModel->get_chat_messages($chat->id); + } + $data["chat"] = $chat; + return $this->response->setJSON($data); + } + public function get_chat_factura(int $chat_department_id, int $factura_id) + { + + $data = [ + "chat" => null, + "messages" => null, + ]; + $chat = $this->chatModel->getChatFactura($chat_department_id, $factura_id); + if ($chat) { + $data["messages"] = $this->chatMessageModel->get_chat_messages($chat->id); + } + $data["chat"] = $chat; + return $this->response->setJSON($data); + } + public function get_chat(int $chat_id) + { + + $data = $this->chatModel->getChat($chat_id); + return $this->response->setJSON($data); + } + public function store_chat_message_presupuesto() + { + + $data = $this->request->getPost(); + // $data = $this->chatModel->createChatPresupuesto(); + $existChat = $this->chatModel->existChatPresupuesto($data["chat_department_id"], $data["model_id"]); + if ($existChat == false) { + $chatId = $this->chatModel->createChatPresupuesto($data["chat_department_id"], $data["model_id"]); + } else { + $chat = $this->chatModel->getChatPresupuesto($data["chat_department_id"], $data["model_id"]); + $chatId = $chat->id; + } + $chat_message_id = $this->chatMessageModel->insert(["chat_id" => $chatId, "sender_id" => auth()->user()->id, "message" => $data["message"]]); + $dataResponse = $this->chatMessageModel->find($chat_message_id); + return $this->response->setJSON($dataResponse); + } + public function store_chat_message_pedido() + { + + $data = $this->request->getPost(); + $existChat = $this->chatModel->existChatPedido($data["chat_department_id"], $data["model_id"]); + if ($existChat == false) { + $chatId = $this->chatModel->createChatPedido($data["chat_department_id"], $data["model_id"]); + } else { + $chat = $this->chatModel->getChatPedido($data["chat_department_id"], $data["model_id"]); + $chatId = $chat->id; + } + $chat_message_id = $this->chatMessageModel->insert(["chat_id" => $chatId, "sender_id" => auth()->user()->id, "message" => $data["message"]]); + $dataResponse = $this->chatMessageModel->find($chat_message_id); + return $this->response->setJSON($dataResponse); + } + public function store_chat_message_factura() + { + + $data = $this->request->getPost(); + $existChat = $this->chatModel->existChatFactura($data["chat_department_id"], $data["model_id"]); + if ($existChat == false) { + $chatId = $this->chatModel->createChatFactura($data["chat_department_id"], $data["model_id"]); + } else { + $chat = $this->chatModel->getChatFactura($data["chat_department_id"], $data["model_id"]); + $chatId = $chat->id; + } + $chat_message_id = $this->chatMessageModel->insert(["chat_id" => $chatId, "sender_id" => auth()->user()->id, "message" => $data["message"]]); + $dataResponse = $this->chatMessageModel->find($chat_message_id); + return $this->response->setJSON($dataResponse); + } + public function store_chat_message_single() + { + $data = $this->request->getPost(); + + $existChat = $this->chatMessageModel->get_chat_contact_messages($data["receiver_id"]); + if (count($existChat) > 0) { + $chatId = $existChat[0]->chat_id; + } else { + $chatId = $this->chatModel->createChatSingle(); + } + $chat_message_id = $this->chatMessageModel->insert( + [ + "chat_id" => $chatId, + "sender_id" => auth()->user()->id, + "message" => $data["message"], + "receiver_id" => $data["receiver_id"] + ] + ); + $dataResponse = $this->chatMessageModel->find($chat_message_id); + return $this->response->setJSON($dataResponse); + } + public function get_chat_internal_contacts() + { + $users = $this->userModel->builder() + ->where("cliente_id", null) + ->whereNotIn("id", [auth()->user()->id]) + ->where("deleted_at", null) + ->get()->getResultObject(); + foreach ($users as $user) { + $user->unreadMessages = $this->chatMessageModel->get_chat_unread_messages_count($user->id); + } + return $this->response->setJSON($users); + } + public function get_chat_internal_contact(int $user_id) + { + $users = $this->userModel->builder() + ->where("cliente_id", null) + ->where("deleted_at", null) + ->where("id", $user_id) + ->get()->getFirstRow(); + $this->chatMessageModel->set_chat_messages_as_read($user_id); + return $this->response->setJSON($users); + } + public function get_chat_internal_messages(int $user_id) + { + $conversation = $this->chatMessageModel->get_chat_contact_messages($user_id); + return $this->response->setJSON($conversation); + } +} diff --git a/ci4/app/Controllers/Js_loader.php b/ci4/app/Controllers/Js_loader.php index 7fabccd0..58b9aa02 100755 --- a/ci4/app/Controllers/Js_loader.php +++ b/ci4/app/Controllers/Js_loader.php @@ -117,5 +117,13 @@ class Js_loader extends BaseController $this->response->setHeader('Content-Type', 'text/javascript'); return view('themes/vuexy/form/presupuestos/cliente/previews.js'); } + + function chat_js() + { + $this->response->setHeader('Content-Type', 'text/javascript'); + return view('themes/vuexy/form/mensajes/mensajeria.js'); + } + + } \ No newline at end of file diff --git a/ci4/app/Controllers/Mensajeria/MensajesDirectos.php b/ci4/app/Controllers/Mensajeria/MensajesDirectos.php new file mode 100644 index 00000000..ff1e8686 --- /dev/null +++ b/ci4/app/Controllers/Mensajeria/MensajesDirectos.php @@ -0,0 +1,64 @@ +viewData['pageTitle'] = "Mensajeria interna"; + + // Breadcrumbs + $this->viewData['breadcrumb'] = [ + ['title' => "Home", 'route' => "javascript:void(0);", 'active' => false], + ['title' => lang("App.menu_mensajes"), 'route' => route_to('mensajeriaView'), 'active' => true] + ]; + + parent::initController($request, $response, $logger); + } + + public function index() + { + return view(static::$viewPath . static::$indexRoute); + } + + + public function getChatInfo($conversacionId) + { + // Modelos + $conversacionModel = model('App\Models\Mensajeria\ConversacionModel'); + + // Verificar si es una solicitud AJAX + if ($this->request->isAJAX()) { + // Obtener los datos + $data = [ + 'people' => $conversacionModel->getChatParticipants($conversacionId), + 'messages' => $conversacionModel->getChatMessages($conversacionId) + ]; + + // Devolver respuesta JSON + return $this->respond($data, 200, 'Chat information retrieved successfully'); + } else { + return $this->failForbidden('Only AJAX requests are allowed'); + } + } + + +} diff --git a/ci4/app/Controllers/Test.php b/ci4/app/Controllers/Test.php index eb68eaba..e78799d0 100755 --- a/ci4/app/Controllers/Test.php +++ b/ci4/app/Controllers/Test.php @@ -76,10 +76,10 @@ class Test extends BaseController - private function test_get_tirada_alt($tirada, $merma, $tipo_impresion_id, - $json_data, $cliente_id, $ancho, $alto, - $solapas_cubierta, $solapas_ancho_cubierta, $solapas_sobrecubierta, $solapas_ancho_sobrecubierta, $lomo) - { + private function test_get_tirada_alt($tirada, $merma, $tipo_impresion_id, + $json_data, $cliente_id, $ancho, $alto, + $solapas_cubierta, $solapas_ancho_cubierta, $solapas_sobrecubierta, $solapas_ancho_sobrecubierta, $lomo) + { $values = []; if ($json_data) { diff --git a/ci4/app/Database/Migrations/2024-09-17-151435_ChatDepartments.php b/ci4/app/Database/Migrations/2024-09-17-151435_ChatDepartments.php new file mode 100644 index 00000000..0993133e --- /dev/null +++ b/ci4/app/Database/Migrations/2024-09-17-151435_ChatDepartments.php @@ -0,0 +1,66 @@ + [ + "type" => "INT", + "unsigned" => true, + "auto_increment" => true + ], + "name" => [ + "type" => "VARCHAR", + "constraint" => '45', + "unique" => true, + ], + "display" => [ + "type" => "VARCHAR", + "constraint" => '255', + ], + "description" => [ + "type" => "TEXT", + "null" => true, + ], + "type" => [ + "type" => "ENUM", + 'constraint' => ['general', 'presupuesto', 'pedido'], + 'default' => 'general', + ], + + ]; + public function up() + { + $this->forge->addField($this->COLUMNS); + $currenttime = new RawSql("CURRENT_TIMESTAMP"); + $this->forge->addField([ + "created_at" => [ + "type" => "TIMESTAMP", + "default" => $currenttime, + + ], + "updated_at" => [ + "type" => "TIMESTAMP", + "null" => true, + + ], + "deleted_at" => [ + "type" => "TIMESTAMP", + "null" => true, + + ], + ]); + $this->forge->addPrimaryKey('id'); + $this->forge->createTable("chat_departments", true); + } + + public function down() + { + // + $this->forge->dropTable("chat_departments"); + } +} diff --git a/ci4/app/Database/Migrations/2024-09-17-151440_ChatsTable.php b/ci4/app/Database/Migrations/2024-09-17-151440_ChatsTable.php new file mode 100644 index 00000000..f4b69606 --- /dev/null +++ b/ci4/app/Database/Migrations/2024-09-17-151440_ChatsTable.php @@ -0,0 +1,81 @@ + [ + "type" => "INT", + "unsigned" => true, + "auto_increment" => true + ], + "chat_department_id" => [ + "type" => "INT", + "unsigned" => true, + "null" => true + ], + "pedido_id" => [ + "type" => "INT", + "constraint" => 16, + "unsigned" => true, + "null" => true + ], + "presupuesto_id" => [ + "type" => "INT", + "constraint" => 10, + "unsigned" => true, + "null" => true + ], + "factura_id" => [ + "type" => "INT", + "constraint" => 10, + "unsigned" => true, + "null" => true + ], + + + ]; + public function up() + { + $this->forge->dropTable("chat_conversaciones", true); + $this->forge->dropTable("chat_mensajes", true); + $this->forge->dropTable("chat_participantes", true); + + + $this->forge->addField($this->COLUMNS); + $currenttime = new RawSql("CURRENT_TIMESTAMP"); + $this->forge->addField([ + "created_at" => [ + "type" => "TIMESTAMP", + "default" => $currenttime, + ], + "updated_at" => [ + "type" => "TIMESTAMP", + "null" => true, + ], + "deleted_at" => [ + "type" => "TIMESTAMP", + "null" => true, + + ], + ]); + $this->forge->addPrimaryKey('id'); + $this->forge->addForeignKey('pedido_id', 'pedidos', 'id'); + $this->forge->addForeignKey('chat_department_id', 'chat_departments', 'id'); + $this->forge->addForeignKey('factura_id', 'facturas', 'id'); + $this->forge->addForeignKey('presupuesto_id', 'presupuestos', 'id'); + + + $this->forge->createTable("chats", true); + } + + public function down() + { + // + $this->forge->dropTable("chats", true); + } +} diff --git a/ci4/app/Database/Migrations/2024-09-17-151450_ChatMessages.php b/ci4/app/Database/Migrations/2024-09-17-151450_ChatMessages.php new file mode 100644 index 00000000..289918d5 --- /dev/null +++ b/ci4/app/Database/Migrations/2024-09-17-151450_ChatMessages.php @@ -0,0 +1,75 @@ + [ + "type" => "INT", + "auto_increment" => true, + ], + "chat_id" => [ + "type" => "INT", + "unsigned" => true + ], + + "sender_id" => [ + "type" => "INT", + "unsigned" => true, + "null" => true, + + ], + "receiver_id" => [ + "type" => "INT", + "unsigned" => true, + "null" => true, + ], + "message" => [ + "type" => "TEXT", + ], + "viewed" => [ + "type" => "TEXT", + "type" => "boolean", + "default" => false, + ], + + + ]; + public function up() + { + $this->forge->addField($this->COLUMNS); + + $currenttime = new RawSql("CURRENT_TIMESTAMP"); + $this->forge->addField([ + "created_at" => [ + "type" => "TIMESTAMP", + "default" => $currenttime, + + ], + "updated_at" => [ + "type" => "TIMESTAMP", + "null" => true, + + ], + "deleted_at" => [ + "type" => "TIMESTAMP", + "null" => true, + + ], + ]); + $this->forge->addPrimaryKey('id'); + $this->forge->addForeignKey(['receiver_id'], 'users', ['id']); + $this->forge->addForeignKey(['sender_id'], 'users', ['id']); + $this->forge->addForeignKey(['chat_id'], 'chats', ['id']); + $this->forge->createTable("chat_messages", true); + } + + public function down() + { + $this->forge->dropTable("chat_messages", true); + } +} diff --git a/ci4/app/Database/Migrations/2024-09-17-151500_ChatDepartmentUsers.php b/ci4/app/Database/Migrations/2024-09-17-151500_ChatDepartmentUsers.php new file mode 100644 index 00000000..aa1e9ec3 --- /dev/null +++ b/ci4/app/Database/Migrations/2024-09-17-151500_ChatDepartmentUsers.php @@ -0,0 +1,50 @@ + [ + "type" => "INT", + "unsigned" => true, + ], + "user_id" => [ + "type" => "INT", + "unsigned" => true, + ], + ]; + public function up() + { + $this->forge->addField($this->COLUMNS); + $currenttime = new RawSql("CURRENT_TIMESTAMP"); + $this->forge->addField([ + "created_at" => [ + "type" => "TIMESTAMP", + "default" => $currenttime, + + ], + "updated_at" => [ + "type" => "TIMESTAMP", + "null" => true, + + ], + "deleted_at" => [ + "type" => "TIMESTAMP", + "null" => true, + + ], + ]); + $this->forge->addForeignKey(["user_id"], "users", ["id"]); + $this->forge->addForeignKey(["chat_department_id"], "chat_departments", ["id"]); + $this->forge->createTable("chat_department_users", true); + } + + public function down() + { + $this->forge->dropTable("chat_department_users"); + } +} diff --git a/ci4/app/Database/Seeds/ChatSeeder.php b/ci4/app/Database/Seeds/ChatSeeder.php new file mode 100644 index 00000000..28df32ab --- /dev/null +++ b/ci4/app/Database/Seeds/ChatSeeder.php @@ -0,0 +1,89 @@ + "_produccion", + "display" => "Producción", + "users" => [ + "mbalbaci@safekat.com", + "mari.cano@safekat.com", + "beatriz@safekat.com", + "imnavajas@coit.es", + ], + ], + [ + "name" => "_pod", + "display" => "POD", + "users" => [ + "pod@safekat.com", + "imnavajas@coit.es", + ], + ], + [ + "name" => "_maquetacion", + "display" => "Maquetación", + "users" => [ + "maquetacion@safekat.com", + "imnavajas@coit.es", + ], + ], + // [ + // "name" => "_comercial", + // "display" => "Comercial", + // "users" => [ + // "incidencias@safekat.com", + // ], + // ], + [ + "name" => "_incidencias", + "display" => "Incidencias", + "users" => [ + "incidencias@safekat.com", + ], + ], + [ + "name" => "_logistica", + "display" => "Logística", + "users" => [ + "logistica@safekat.com", + "imnavajas@coit.es", + ], + ], + [ + "name" => "_admin", + "display" => "Administración", + "users" => [ + "contabilidad@safekat.com", + "imnavajas@coit.es", + ], + ], + ]; + $chatDeparmentModel = model(ChatDeparmentModel::class); + $chatDeparmentUsersModel = model(ChatDeparmentUserModel::class); + $userModel = model(UserModel::class); + foreach ($data as $row) { + $chatDeparmentId = $chatDeparmentModel->insert(["name" => $row["name"], "display" => $row["display"]]); + if (count($row["users"]) > 0) { + foreach ($row["users"] as $mail) { + $user = $userModel->like("username", explode("@",$mail)[0])->first(); + + if ($user) { + echo $user->id."\r\n"; + $chatDeparmentUsersModel->insert(['user_id' => $user->id, "chat_department_id" => $chatDeparmentId]); + } + } + } + }; + } +} diff --git a/ci4/app/Entities/Mensajeria/ConversacionEntity.php b/ci4/app/Entities/Mensajeria/ConversacionEntity.php new file mode 100644 index 00000000..4ee45b16 --- /dev/null +++ b/ci4/app/Entities/Mensajeria/ConversacionEntity.php @@ -0,0 +1,28 @@ + null, + 'pedido_libro_id' => null, + 'pedido_maquetacion_id' => null, + 'factura_id' => null, + 'departamento' => null, + 'asunto' => null, + 'created_at' => null, + 'updated_at' => null, + 'deleted_at' => null, + ]; + + protected $casts = [ + "pedido_libro_id" => "?int", + "pedido_maquetacion_id" => "?int", + "factura_id" => "?int" + ]; + + +} diff --git a/ci4/app/Entities/Mensajeria/ParticipanteEntity.php b/ci4/app/Entities/Mensajeria/ParticipanteEntity.php new file mode 100644 index 00000000..6a38ebab --- /dev/null +++ b/ci4/app/Entities/Mensajeria/ParticipanteEntity.php @@ -0,0 +1,26 @@ + null, + 'conversacion_id' => null, + 'usuario_id' => null, + 'cliente_id' => null, + 'email' => null, + 'last_read' => null, + 'created_at' => null, + 'updated_at' => null, + 'deleted_at' => null, + ]; + + protected $casts = [ + "conversacion_id" => "?int", + "usuario_id" => "?int", + "cliente_id" => "?int" + ]; +} diff --git a/ci4/app/Language/es/Chat.php b/ci4/app/Language/es/Chat.php new file mode 100644 index 00000000..3981f2ce --- /dev/null +++ b/ci4/app/Language/es/Chat.php @@ -0,0 +1,5 @@ + "Chat" +]; \ No newline at end of file diff --git a/ci4/app/Models/Chat/ChatDeparmentModel.php b/ci4/app/Models/Chat/ChatDeparmentModel.php new file mode 100644 index 00000000..4558bbd3 --- /dev/null +++ b/ci4/app/Models/Chat/ChatDeparmentModel.php @@ -0,0 +1,101 @@ +db->table('chat_departments') + ->select( + [ + 'chat_departments.id', + 'chat_departments.name', + 'chat_departments.display', + 'chat_department_users.user_id' + ] + ) + ->join( + "chat_department_users", + "chat_department_users.chat_department_id = chat_departments.id", + 'left' + ) + ->join( + "users", + "chat_department_users.user_id = users.id", + 'left' + )->where("chat_departments.type",$type) + ->where("chat_department_users.user_id",auth()->user()->id); + + $results = $query->get()->getResultArray(); + // Create the desired structure + $departments = []; + + foreach ($results as $row) { + $departmentName = $row['name']; + + // If the department is not yet added to the array, initialize it + if (!isset($departments[$departmentName])) { + $departments[$departmentName] = [ + 'id' => $row['id'], + 'name' => $row['name'], + 'display' => $row['display'], + 'users' => [] // Initialize users as an empty array + ]; + } + + // If user_id is not null, add the user to the department's 'users' array + if ($row['user_id']) { + $departments[$departmentName]['users'][] = $userModel->find($row["user_id"]); + } + } + return $departments; + } +} diff --git a/ci4/app/Models/Chat/ChatDeparmentUserModel.php b/ci4/app/Models/Chat/ChatDeparmentUserModel.php new file mode 100644 index 00000000..36fe4836 --- /dev/null +++ b/ci4/app/Models/Chat/ChatDeparmentUserModel.php @@ -0,0 +1,50 @@ +builder()->where("chat_id", $chat_id)->orderBy("created_at", "asc")->get()->getResultObject(); + foreach ($messages as $message) { + $message->pos = auth()->user()->id == $message->sender_id ? "right" : "left"; + if (auth()->user()->id == $message->sender_id) { + $message->user = auth()->user(); + } else { + $message->user = $user->find($message->sender_id); + } + } + return $messages; + } + public function get_chat_contact_messages(int $receiver_id): array + { + $conversationArray = []; + $userModel = model(UserModel::class); + $receiverUser = $userModel->find($receiver_id); + $messagesFromClient = $this->builder() + ->where("sender_id", auth()->user()->id) + ->where("receiver_id", $receiverUser->id) + ->get()->getResultObject(); + $messagesFromReceiver = $this->builder() + ->where("sender_id", $receiver_id) + ->where("receiver_id", auth()->user()->id) + ->get()->getResultObject(); + foreach ($messagesFromClient as $message) { + $message->pos = "right"; + $message->user = auth()->user(); + $conversationArray[] = $message; + } + foreach ($messagesFromReceiver as $message) { + $message->pos = "left"; + $message->user = $receiverUser; + $conversationArray[] = $message; + } + $dates = array(); + foreach ($conversationArray as $key => $row) { + $dates[$key] = strtotime($row->created_at); + } + array_multisort($dates, SORT_ASC, $conversationArray); + return $conversationArray; + } + + public function get_chat_unread_messages_count(int $sender_id): int + { + $messagesFromReceiver = $this->builder() + ->where("sender_id", $sender_id) + ->where("viewed", false) + ->where("receiver_id", auth()->user()->id)->countAllResults(); + return $messagesFromReceiver; + } + public function set_chat_messages_as_read(int $sender_id): int + { + $messagesFromReceiver = $this->builder() + ->set("viewed", true) + ->where("sender_id", $sender_id) + ->where("receiver_id", auth()->user()->id)->update(); + return $messagesFromReceiver; + } +} diff --git a/ci4/app/Models/Chat/ChatModel.php b/ci4/app/Models/Chat/ChatModel.php new file mode 100644 index 00000000..65cf010e --- /dev/null +++ b/ci4/app/Models/Chat/ChatModel.php @@ -0,0 +1,196 @@ +db->table('chats') + ->select( + [ + "chats.*", + "chat_messages.created_at as messageCreatedAt", + "chat_messages.message as messageText", + ] + ) + ->join("chat_messages", "chats.id = chat_messages.chat_id", "left") + ->orderBy("created_at", "desc") + ->where("chats.id", $chat_id) + ->get()->getResultObject(); + } + public function getChatPresupuesto(int $chat_department_id, int $presupuesto_id) + { + return $this->builder()->where("presupuesto_id", $presupuesto_id)->where("chat_department_id", $chat_department_id)->get()->getFirstRow(); + } + public function getChatPedido(int $chat_department_id, int $pedido_id) + { + return $this->builder()->where("pedido_id", $pedido_id)->where("chat_department_id", $chat_department_id)->get()->getFirstRow(); + } + public function getChatFactura(int $chat_department_id, int $factura_id) + { + return $this->builder()->where("factura_id", $factura_id)->where("chat_department_id", $chat_department_id)->get()->getFirstRow(); + } + + public function createChatPresupuesto(int $chat_department_id, int $presupuesto_id): int + { + return $this->insert([ + "presupuesto_id" => $presupuesto_id, + "chat_department_id" => $chat_department_id + ]); + } + public function createChatPedido(int $chat_department_id, int $pedido_id) : int + { + + return $this->insert([ + "pedido_id" => $pedido_id, + "chat_department_id" => $chat_department_id + ]); + } + public function createChatFactura(int $chat_department_id, int $factura_id) : int + { + + return $this->insert([ + "factura_id" => $factura_id, + "chat_department_id" => $chat_department_id + ]); + } + public function createChatSingle() : int + { + return $this->insert(["chat_department_id" => null]); + } + public function existChatPresupuesto(int $chat_department_id, int $presupuesto_id): bool + { + $countChatPresupuesto = $this->builder() + ->where("presupuesto_id", $presupuesto_id) + ->where("chat_department_id", $chat_department_id) + ->countAllResults(); + return $countChatPresupuesto > 0; + } + public function existChatPedido(int $chat_department_id, int $pedido_id): bool + { + $countChatPresupuesto = $this->builder() + ->where("pedido_id", $pedido_id) + ->where("chat_department_id", $chat_department_id) + ->countAllResults(); + return $countChatPresupuesto > 0; + } + public function existChatFactura(int $chat_department_id, int $factura_id): bool + { + $countChatPresupuesto = $this->builder() + ->where("factura_id", $factura_id) + ->where("chat_department_id", $chat_department_id) + ->countAllResults(); + return $countChatPresupuesto > 0; + } + + public function getChatPedidosChat() : array + { + $query = $this->db->table("chats") + ->select([ + "chats.id as chatId", + "chats.pedido_id as pedidoId", + "chats.chat_department_id as chatDepartmentId", + "chat_departments.display as chatDisplay", + "pedidos.id as title" + ]) + ->join("chat_departments","chat_departments.id = chats.chat_department_id","left") + ->join("pedidos","pedidos.id = chats.pedido_id","left") + ->get()->getResultObject(); + return $query; + } + + public function getChatPresupuestosChat() : array + { + $query = $this->db->table("chats") + ->select([ + "chats.id as chatId", + "chats.pedido_id as pedidoId", + "chats.chat_department_id as chatDepartmentId", + "chat_departments.display as chatDisplay", + "presupuestos.titulo as title" + ]) + ->join("chat_departments","chat_departments.id = chats.chat_department_id","left") + ->join("presupuestos","presupuestos.id = chats.pedido_id","left") + ->get()->getResultObject(); + return $query; + } + public function getChatFacturasChat() : array + { + $query = $this->db->table("chats") + ->select([ + "chats.id as chatId", + "chats.pedido_id as pedidoId", + "chats.chat_department_id as chatDepartmentId", + "chat_departments.display as chatDisplay", + "facturas.numero as title" + ]) + ->join("chat_departments","chat_departments.id = chats.chat_department_id","left") + ->join("facturas","facturas.id = chats.pedido_id","left") + ->get()->getResultObject(); + return $query; + } + public function getChatSingleChat() : array + { + $query = $this->db->table("chats") + ->select([ + "chats.id as chatId", + "chats.chat_department_id as chatDepartmentId", + "chat_departments.display as chatDisplay", + "facturas.numero as title" + ]) + ->join("chat_departments","chat_departments.id = chats.chat_department_id","left") + ->join("facturas","facturas.id = chats.pedido_id","left") + ->get()->getResultObject(); + return $query; + } + +} diff --git a/ci4/app/Models/Mensajeria/ConversacionModel.php b/ci4/app/Models/Mensajeria/ConversacionModel.php new file mode 100644 index 00000000..e6863051 --- /dev/null +++ b/ci4/app/Models/Mensajeria/ConversacionModel.php @@ -0,0 +1,201 @@ +db + ->table('pedido_libros') + ->where('id', $this->pedido_libro_id) + ->get() + ->getFirstRow(); + } + + public function pedidoMaquetacion() + { + return $this->db + ->table('pedido_maquetaciones') + ->where('id', $this->pedido_maquetacion_id) + ->get() + ->getFirstRow(); + } + + public function factura() + { + return $this->db + ->table('facturas') + ->where('id', $this->factura_id) + ->get() + ->getFirstRow(); + } + + + public function getConversacion($convesacionId) + { + $builder = $this->db + ->table($this->table . " t1") + //->select("t1.conversacion_id AS id, t2.asunto AS asunto") + ->where("t1.id", $convesacionId) + ->join("chat_participantes t2", "t2.conversacion_id = t1.id", "left") + ->join("chat_mensajes t3", "t3.conversacion_id = t1.id", "left") + ->orderBy('t1.created_at', 'DESC') + ->get() + ->getResultArray(); + + return $builder; + } + + public function getChatParticipants($chatId) + { + return $this->db + ->table($this->table . " t1") + ->select("t2.usuario_id as user_id, t3.first_name AS nombre, t3.last_name AS apellidos") + ->where("t1.id", $chatId) + ->join("chat_participantes t2", "t2.conversacion_id = t1.id", "left") + ->join("users t3", "t3.id = t2.usuario_id", "left") + ->get() + ->getResultArray(); + } + + public function getChatMessages($chatId) + { + return $this->db + ->table($this->table . " t1") + ->select("t2.mensaje AS mensaje, t2.usuario_id as user_id") + ->select("t3.first_name AS nombre, t3.last_name AS apellidos") + ->where("t1.id", intval($chatId)) + ->join("chat_mensajes t2", "t2.conversacion_id = t1.id", "left") + ->join("users t3", "t3.id = t2.usuario_id", "left") + ->get() + ->getResultArray(); + } + + + + + + + + + + + + + + + + + + + + + + + + /** + * Devuelve si la conversacion tiene algún cliente + */ + public function isClient() + { + $isCliente = false; + $participantes = $this->participantes(); // Asegúrate de implementar este método + foreach ($participantes as $p) { + if (($p->user && $p->user->customer_id) || $p->customer_id) { + $isCliente = true; + break; + } + } + + return $isCliente; + } + + /** + * Comprueba si la conversacion del mensaje tiene el cliente + */ + public function haveCliente($userCustomer) + { + $customer_id = $userCustomer->customer_id; + $participants = $this->participantes(); // Asegúrate de implementar este método + + foreach ($participants as $p) { + if ($p->customer_id && $p->customer_id === $customer_id) { + return true; + } + } + + return false; + } + + public function getParticipanteDesdeCliente($cliente_id) + { + return $this->db->table('chat_participantes') + ->where('cliente_id', $cliente_id) + ->where('conversacion_id', $this->id) + ->get() + ->getFirstRow(); + } + + public function marcarLeidoCliente($cliente_id) + { + try { + $participante = $this->getParticipanteDesdeCliente($cliente_id); + if ($participante) { + $this->db->table('chat_participantes') + ->where('id', $participante->id) + ->update(['last_read' => date('Y-m-d H:i:s')]); + } + } catch (\Exception $e) { + // do nothing + } + } + + public function marcarNoLeido($usuario_id) + { + try { + $participante = $this->getParticipanteDesdeUsuario($usuario_id); // Asegúrate de implementar este método + if ($participante) { + $this->db->table('chat_participantes') + ->where('id', $participante->id) + ->update(['last_read' => null]); + } + } catch (\Exception $e) { + // do nothing + } + } + + protected function participantes() + { + return $this->db + ->table('chat_participantes') + ->where('conversacion_id', $this->id) + ->get() + ->getResult(); + } + + protected function getParticipanteDesdeUsuario($usuario_id) + { + return $this->db->table('chat_participantes') + ->where('usuario_id', $usuario_id) + ->where('conversacion_id', $this->id) + ->get() + ->getFirstRow(); + } +} diff --git a/ci4/app/Models/Mensajeria/ParticipanteModel.php b/ci4/app/Models/Mensajeria/ParticipanteModel.php new file mode 100644 index 00000000..7a0e0a9c --- /dev/null +++ b/ci4/app/Models/Mensajeria/ParticipanteModel.php @@ -0,0 +1,52 @@ +db + ->table($this->table . " t1") + ->where("t1.conversacion_id", $conversacionId); + + return $builder; + } + + public function getChatsByUser($userId){ + + $builder = $this->db + ->table($this->table . " t1") + ->select("t1.conversacion_id AS id, t2.asunto AS asunto") + ->where("t1.usuario_id", $userId) + ->join("chat_conversaciones t2", "t2.id = conversacion_id", "left") + ->orderBy('t1.created_at', 'DESC') + ->get() + ->getResultObject(); + + return $builder; + } + + + public function getCustomer() + { + //$customerModel = new Customer(); + //return $customerModel->find($this->attributes['customer_id']); + } +} diff --git a/ci4/app/Models/Presupuestos/PresupuestoModel.php b/ci4/app/Models/Presupuestos/PresupuestoModel.php index 85eb6e8f..0150f6af 100755 --- a/ci4/app/Models/Presupuestos/PresupuestoModel.php +++ b/ci4/app/Models/Presupuestos/PresupuestoModel.php @@ -781,4 +781,7 @@ class PresupuestoModel extends \App\Models\BaseModel return $description_interior . $description_cubierta . $description_sobrecubierta . $acabado; } + + + } diff --git a/ci4/app/Views/themes/vuexy/components/chat_factura.php b/ci4/app/Views/themes/vuexy/components/chat_factura.php new file mode 100644 index 00000000..b06bcdaf --- /dev/null +++ b/ci4/app/Views/themes/vuexy/components/chat_factura.php @@ -0,0 +1,151 @@ +
+
+

+ +

+
+
+
+
+
+ + +
+ +
+ +
+ + + +
+
+
+
+
+ +
+ P +
+
+
Departamento Producción
+ Consulta sobre el presupuesto + P001 +
+
+ +
+
+
+
    + + +
+
+ + +
+
+ + +
+
+
+
+
+
+ +
+
+section('css') ?> + +endSection() ?> + + + +section("additionalExternalJs") ?> + + + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/components/chat_general.php b/ci4/app/Views/themes/vuexy/components/chat_general.php new file mode 100644 index 00000000..b28a8b3e --- /dev/null +++ b/ci4/app/Views/themes/vuexy/components/chat_general.php @@ -0,0 +1,152 @@ +
+
+

+ +

+
+
+
+
+
+ + +
+ +
+ +
+ + + +
+
+
+
+
+ +
+ P +
+
+
Departamento Producción
+ Consulta sobre el presupuesto + P001 +
+
+ +
+
+
+
    + + +
+
+ + +
+ + +
+
+
+
+
+
+ +
+
+ section('css') ?> + + endSection() ?> + + + + section("additionalExternalJs") ?> + + + + endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/components/chat_pedido.php b/ci4/app/Views/themes/vuexy/components/chat_pedido.php new file mode 100644 index 00000000..6375ea59 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/components/chat_pedido.php @@ -0,0 +1,152 @@ +
+
+

+ +

+
+
+
+ +
+
+ + +
+ +
+ +
+ + + +
+
+
+
+
+ +
+ P +
+
+
+ +
+
+ +
+
+
+
    + + +
+
+ + +
+
+ + +
+
+
+
+
+
+
+
+
+ + +section('css') ?> + +endSection() ?> + + + +section("additionalExternalJs") ?> + + + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/components/chat_presupuesto.php b/ci4/app/Views/themes/vuexy/components/chat_presupuesto.php new file mode 100644 index 00000000..851c9a12 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/components/chat_presupuesto.php @@ -0,0 +1,153 @@ +
+
+

+ +

+
+
+
+
+
+ + +
+ +
+ +
+ + + +
+
+
+
+
+ +
+ P +
+
+
Departamento Producción
+ Consulta sobre el presupuesto + P001 +
+
+ +
+
+
+
    + + +
+
+ + +
+
+ + +
+
+
+
+
+
+
+
+ +section('css') ?> + +endSection() ?> + + + +section("additionalExternalJs") ?> + + + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php index cfecf659..671486db 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php @@ -28,6 +28,7 @@ estado !='borrador' && (strpos($facturaEntity->numero, "REC ") === 0) ) : ?> + $facturaEntity->id]) ?>
estado =='borrador') : ?> diff --git a/ci4/app/Views/themes/vuexy/form/mensajes/mensajeria.js b/ci4/app/Views/themes/vuexy/form/mensajes/mensajeria.js new file mode 100644 index 00000000..4e7667b8 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/mensajes/mensajeria.js @@ -0,0 +1,138 @@ +/** + * App Chat + */ + +// Seleccionar elementos del DOM +const chatContactsBody = $('.app-chat-contacts .sidebar-body'), + chatContactListItems = $('.chat-contact-list-item:not(.chat-contact-list-item-title)'), + chatHistoryBody = $('.chat-history-body'), + chatSidebarLeftUserAbout = $('.chat-sidebar-left-user-about'), + messageInput = $('.message-input'), + searchInput = $('.chat-search-input'), + sendMsgBtn = $('.send-msg-btn'); // Seleccionar el botón de envío de mensaje + +// Inicializar PerfectScrollbar +if (chatContactsBody.length) { + new PerfectScrollbar(chatContactsBody[0], { + wheelPropagation: false, + suppressScrollX: true + }); +} + +if (chatHistoryBody.length) { + new PerfectScrollbar(chatHistoryBody[0], { + wheelPropagation: false, + suppressScrollX: true + }); +} + +// Función para desplazar el scroll al final +function scrollToBottom() { + if (chatHistoryBody.length) { + chatHistoryBody.scrollTop(chatHistoryBody[0].scrollHeight); + } +} + +scrollToBottom(); + +// Seleccionar chat o contacto +chatContactListItems.on('click', function () { + chatContactListItems.removeClass('active'); + $(this).addClass('active'); +}); + +// Filtrar chats +if (searchInput.length) { + searchInput.on('keyup', function () { + const searchValue = $(this).val().toLowerCase(), + chatListItem0 = $('.chat-list-item-0'), + contactListItem0 = $('.contact-list-item-0'), + searchChatListItems = $('#chat-list li:not(.chat-contact-list-item-title)'), + searchContactListItems = $('#contact-list li:not(.chat-contact-list-item-title)'); + + // Buscar en chats + const chatListItemsCount = searchChatContacts(searchChatListItems, searchValue); + // Mostrar u ocultar mensaje de "No se encontraron resultados" en chats + if (chatListItem0.length) { + chatListItem0.toggleClass('d-none', chatListItemsCount === 0); + } + + // Buscar en contactos + const contactListItemsCount = searchChatContacts(searchContactListItems, searchValue); + // Mostrar u ocultar mensaje de "No se encontraron resultados" en contactos + if (contactListItem0.length) { + contactListItem0.toggleClass('d-none', contactListItemsCount === 0); + } + }); +} + +// Función para buscar en chats y contactos +function searchChatContacts(searchListItems, searchValue) { + let searchListItemsCount = 0; + searchListItems.each(function () { + const searchListItemText = $(this).text().toLowerCase(); + const matchesSearch = searchListItemText.indexOf(searchValue) !== -1; + + $(this).toggleClass('d-flex', matchesSearch); + $(this).toggleClass('d-none', !matchesSearch); + + if (matchesSearch) { + searchListItemsCount++; + } + }); + + return searchListItemsCount; +} + +// Enviar mensaje +if (sendMsgBtn.length) { + // sendMsgBtn.on('click', function (e) { + // e.preventDefault(); + // if (messageInput.val()) { + // const renderMsg = $('
').addClass('chat-message-text mt-2').html(`

${messageInput.val()}

`); + // const lastChatMessageWrapper = $('li:last-child .chat-message-wrapper'); + // if (lastChatMessageWrapper.length) { + // lastChatMessageWrapper.append(renderMsg); + // } + // messageInput.val(''); + // scrollToBottom(); + // } + // }); +} + +// // Seleccionar los elementos

con la clase .chat-contact-status +// $('.chat-contact-status').on('click', function () { +// // Obtener el id de la conversación desde el atributo id del elemento

+// var conversationId = $(this).attr('id'); + +// console.log(conversationId) + +// // Realizar la llamada AJAX +// $.ajax({ +// url: 'internos/chat/' + conversationId, // Cambia esta URL por la ruta correcta a tu API +// type: 'GET', +// dataType: 'json', +// success: function (data) { +// // Manejar la respuesta exitosa de la llamada AJAX +// console.log('Datos recibidos:', data); +// // Aquí puedes actualizar el DOM o realizar otras acciones con los datos recibidos +// if (Array.isArray(data.people) && data.people.length > 0) { +// // Limpiar el contenedor donde se mostrarán los participantes +// $('#participants-container').empty(); +// data.people.forEach(person => { +// // Crear el HTML para cada participante y agregarlo al contenedor +// var participantHtml = ` +//

+// ${person.user_id} +//
`; +// $('#participants-container').append(participantHtml); +// }); +// } +// }, +// error: function (jqXHR, textStatus, errorThrown) { +// // Manejar errores en la llamada AJAX +// console.error('Error en la llamada AJAX:', textStatus, errorThrown); +// } +// }); +// }) +// ; \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/mensajes/mensajesView.php b/ci4/app/Views/themes/vuexy/form/mensajes/mensajesView.php new file mode 100644 index 00000000..594efa39 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/mensajes/mensajesView.php @@ -0,0 +1,10 @@ +include("themes/_commonPartialsBs/select2bs5") ?> +include("themes/_commonPartialsBs/datatables") ?> +extend('themes/vuexy/main/defaultlayout') ?> + +section('content'); ?> + +
+ null]) ?> +
+endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidoForm.php b/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidoForm.php index fc16989d..4c0be90a 100644 --- a/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidoForm.php +++ b/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidoForm.php @@ -1,53 +1,62 @@ include("themes/_commonPartialsBs/datatables") ?> include("themes/_commonPartialsBs/select2bs5") ?> include("themes/_commonPartialsBs/sweetalert") ?> -extend('themes/vuexy/main/defaultlayout') ?> +extend('themes/vuexy/main/defaultlayout') ?> section("content") ?>
-
-
-

-
-
- +
+
+

+
+ + +
getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?> user()->inGroup('cliente-admin') || auth()->user()->inGroup('cliente-editor'))) : ?> - + + $pedidoEntity->id]) ?>
"btn btn-secondary float-start"]) ?>
- +
-
-
+
+ +
+ + endSection() ?> -section('css') ?> - "> - "> - -endSection() ?> +section('css') ?> +"> +"> + +endSection() ?> section('additionalExternalJs') ?> - - - - - - - - - -endSection() ?> - + + + + + + + + + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_mensajeria.php b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_mensajeria.php new file mode 100644 index 00000000..0e57e675 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_mensajeria.php @@ -0,0 +1,152 @@ +
+
+
+ + +
+ +
+ +
+ + + +
+
+
+
+
+ +
+ P +
+
+
Departamento Producción
+ Consulta sobre el presupuesto P001 +
+
+ +
+
+
+
    + + +
+
+ + +
+
+ + +
+
+
+
+ +section('css') ?> + +endSection() ?> + + + +section("additionalExternalJs") ?> + + + +endSection() ?> + + + diff --git a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/viewCosidotapablandaForm.php b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/viewCosidotapablandaForm.php index c0596ac0..638cc728 100644 --- a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/viewCosidotapablandaForm.php +++ b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/viewCosidotapablandaForm.php @@ -34,8 +34,9 @@ + $presupuestoId]) ?> - + @@ -367,6 +368,7 @@ $('#bc-save').on( "click", function() { section('css') ?> "> + endSection() ?> @@ -390,5 +392,6 @@ $('#bc-save').on( "click", function() { + endSection() ?> diff --git a/ci4/app/Views/themes/vuexy/main/menus/mensajes_menu.php b/ci4/app/Views/themes/vuexy/main/menus/mensajes_menu.php index 051999dc..44913967 100644 --- a/ci4/app/Views/themes/vuexy/main/menus/mensajes_menu.php +++ b/ci4/app/Views/themes/vuexy/main/menus/mensajes_menu.php @@ -6,7 +6,7 @@ if (auth()->user()->inGroup('beta')) { ?>
  • + +
    + ${row.display.charAt(0)} +
    +
    +
    ${row.display}
    +

    + ${row.display} +

    +
    +
    +
  • + ` + return chat + } + _getChatMessage(chatDeparmentId) { + this.chatDeparmentId = chatDeparmentId + let ajax = new Ajax( + `/chat/department/${this.chatType}/${this.chatDeparmentId}/${this.modelId}`, + null, + null, + this._getChatMessageSuccess.bind(this), + this._getChatMessageError.bind(this), + + + ); + ajax.get(); + } + _getChatMessageSuccess(data) { + this.chatHistory.empty() + this._setBtnDeparment() + if (data.messages) { + data.messages.map((m) => { + this._addChatMessage(m) + }) + } + } + _getChatMessageError(err) { + console.log(err) + + } + _addChatMessage(chatMessage, pos = "left") { + let chatItem = ` +
  • +
    +
    + +
    +

    ${chatMessage?.message}

    +
    +
    +
    + + ${chatMessage?.user?.first_name + " " + chatMessage?.user?.last_name} +
    + + ${chatMessage.created_at} +
    + +
    +
    +
    + ${chatMessage?.user?.first_name.charAt(0) + chatMessage?.user?.last_name.charAt(0)} +
    +
    +
    +
  • + ` + this.chatHistory.append(chatItem) + return chatItem + } + _sendMessage() { + let messageText = this.messageInput.val() + const body = { + message: messageText, + chat_department_id: this.chatDeparmentId, + user: this.userId, + model_id: this.modelId + } + if (messageText) { + let ajax = new Ajax( + `/chat/message/${this.chatType}`, + body, + null, + this._sendMessageSuccess.bind(this), + this._sendMessageError.bind(this), + + ); + ajax.post(); + } + } + _sendMessageSuccess(data) { + this.messageInput.val("") + this._getChatMessage(this.chatDeparmentId) + } + _sendMessageError(err) { + console.error(err) + } + _handleListContacts() { + this.sideBar.find("#contact-list").removeClass("d-none") + this.sendBtnMessageInternal.on("click",this._sendMessageInternal.bind(this)) + let ajax = new Ajax( + "/chat/contacts", + null, + null, + this._handleListContactsSuccess.bind(this), + this._handleListContactsError.bind(this) + + ) + ajax.get() + + } + _handleListContactsSuccess(contacts) { + if (contacts) { + contacts.map((c) => { + this._addContactToList(c) + }); + } else { + this.sideBar.find("#contact-list").removeClass("d-none") + } + this.sideBar.find(".contact-chat").on("click", (e) => { + let userId = $(e.currentTarget).data("id") + this.receiverId = userId + this._handleGetSingleContact(userId) + this._setBtnInternal() + this.chatHistory.empty() + }) + } + _handleListContactsError(err) { + console.error(err) + } + _handleGetSingleContact(userId) { + let ajax = new Ajax( + `/chat/contacts/${userId}`, + null, + null, + this._handleGetSingleContactSuccess.bind(this), + this._handleGetSingleContactError.bind(this), + ) + ajax.get() + } + + _handleGetSingleContactSuccess(contact) { + this.domItem.find(".chat-history-header div.chat-contact-info h6").text([contact.first_name, contact.last_name].join(" ")) + this.domItem.find(".chat-history-header div.chat-contact-info small.user-status").text(contact.username) + let ajax = new Ajax( + `/chat/contact/${contact.id}/messages`, + null, + null, + this._handleGetSingleContactMessagesSuccess.bind(this), + this._handleGetSingleContactMessagesError.bind(this) + ) + ajax.get() + } + _handleGetSingleContactMessagesSuccess(data) { + if (data) { + data.map((m) => { + this._addChatMessage(m) + }) + } + } + _handleGetSingleContactMessagesError(err) { } + + _handleGetSingleContactError(err) { + + } + _sendMessageInternal() { + let messageText = this.messageInput.val() + const body = { + message: messageText, + receiver_id: this.receiverId, + } + if (messageText) { + let ajax = new Ajax( + `/chat/message/internal`, + body, + null, + this._sendMessageInternalSuccess.bind(this), + this._sendMessageInternalError.bind(this), + + ); + ajax.post(); + } + } + _sendMessageInternalSuccess(message) { + this.messageInput.val("") + this._handleGetSingleContact(this.receiverId) + } + _sendMessageInternalError(err) { + console.error(err) + } + _addContactToList(contact) { + + let contactItem = + ` +
  • + +
    + + ${contact?.first_name?.charAt(0) ?? "?" + + contact?.last_name?.charAt(0) ?? "?"} + +
    +
    +
    ${contact?.first_name ?? "" + " " + + contact?.last_name ?? ""}
    +

    + ${contact.username} +

    +
    + ${contact.unreadMessages ? `${contact.unreadMessages}` : ""} +
    +
  • + ` + + if (contact.first_name || contact.last_name) { + this.sideBar.find("#contact-list").append(contactItem) + } + } + + + + + + +} +export default Chat + + +// // Seleccionar elementos del DOM +// const chatContactsBody = document.querySelector('.app-chat-contacts .sidebar-body'), +// chatContactListItems = [].slice.call( +// document.querySelectorAll('.chat-contact-list-item:not(.chat-contact-list-item-title)') +// ), +// chatHistoryBody = document.querySelector('.chat-history-body'), +// chatSidebarLeftUserAbout = document.querySelector('.chat-sidebar-left-user-about'), +// messageInput = document.querySelector('.message-input'), +// searchInput = document.querySelector('.chat-search-input'), +// sendMsgBtn = document.querySelector('.send-msg-btn'); // Seleccionar el botón de envío de mensaje + +// // Inicializar PerfectScrollbar +// if (chatContactsBody) { +// new PerfectScrollbar(chatContactsBody, { +// wheelPropagation: false, +// suppressScrollX: true +// }); +// } + +// if (chatHistoryBody) { +// new PerfectScrollbar(chatHistoryBody, { +// wheelPropagation: false, +// suppressScrollX: true +// }); +// } + +// // Función para desplazar el scroll al final +// function scrollToBottom() { +// if (chatHistoryBody) { +// chatHistoryBody.scrollTo(0, chatHistoryBody.scrollHeight); +// } +// } +// scrollToBottom(); + +// // Seleccionar chat o contacto + + +// // Filtrar chats +// if (searchInput) { +// searchInput.addEventListener('keyup', e => { +// const searchValue = e.currentTarget.value.toLowerCase(), +// chatListItem0 = document.querySelector('.chat-list-item-0'), +// contactListItem0 = document.querySelector('.contact-list-item-0'), +// searchChatListItems = [].slice.call( +// document.querySelectorAll('#chat-list li:not(.chat-contact-list-item-title)') +// ), +// searchContactListItems = [].slice.call( +// document.querySelectorAll('#contact-list li:not(.chat-contact-list-item-title)') +// ); + +// // Buscar en chats +// const chatListItemsCount = searchChatContacts(searchChatListItems, searchValue); +// // Mostrar u ocultar mensaje de "No se encontraron resultados" en chats +// if (chatListItem0) { +// chatListItem0.classList.toggle('d-none', chatListItemsCount !== 0); +// } + +// // Buscar en contactos +// const contactListItemsCount = searchChatContacts(searchContactListItems, searchValue); +// // Mostrar u ocultar mensaje de "No se encontraron resultados" en contactos +// if (contactListItem0) { +// contactListItem0.classList.toggle('d-none', contactListItemsCount !== 0); +// } +// }); +// } + +// // Función para buscar en chats y contactos +// function searchChatContacts(searchListItems, searchValue) { +// let searchListItemsCount = 0; +// searchListItems.forEach(searchListItem => { +// const searchListItemText = searchListItem.textContent.toLowerCase(); +// const matchesSearch = searchListItemText.indexOf(searchValue) !== -1; + +// searchListItem.classList.toggle('d-flex', matchesSearch); +// searchListItem.classList.toggle('d-none', !matchesSearch); + +// if (matchesSearch) { +// searchListItemsCount++; +// } +// }); + +// return searchListItemsCount; +// } + +// // // Enviar mensaje +// // if (sendMsgBtn) { +// // sendMsgBtn.addEventListener('click', e => { +// // e.preventDefault(); +// // if (messageInput.value) { +// // const renderMsg = document.createElement('div'); +// // renderMsg.className = 'chat-message-text mt-2'; +// // renderMsg.innerHTML = `

    ${messageInput.value}

    `; +// // const lastChatMessageWrapper = document.querySelector('li:last-child .chat-message-wrapper'); +// // if (lastChatMessageWrapper) { +// // lastChatMessageWrapper.appendChild(renderMsg); +// // } +// // messageInput.value = ''; +// // scrollToBottom(); +// // } +// // }); +// // } diff --git a/httpdocs/assets/js/safekat/pages/chatFactura.js b/httpdocs/assets/js/safekat/pages/chatFactura.js new file mode 100644 index 00000000..b7fa104a --- /dev/null +++ b/httpdocs/assets/js/safekat/pages/chatFactura.js @@ -0,0 +1,6 @@ +import Chat from '../components/chat.js' + +let chat = new Chat($("#chat-factura")) +chat.init() +chat.initFactura() +chat._handleListContacts() \ No newline at end of file diff --git a/httpdocs/assets/js/safekat/pages/chatGeneral.js b/httpdocs/assets/js/safekat/pages/chatGeneral.js new file mode 100644 index 00000000..22a63347 --- /dev/null +++ b/httpdocs/assets/js/safekat/pages/chatGeneral.js @@ -0,0 +1,5 @@ +import Chat from '../components/chat.js' + +let chat = new Chat($("#chat-general")) +chat.init() +chat._handleListContacts() \ No newline at end of file diff --git a/httpdocs/assets/js/safekat/pages/chatPedido.js b/httpdocs/assets/js/safekat/pages/chatPedido.js new file mode 100644 index 00000000..ad0225ab --- /dev/null +++ b/httpdocs/assets/js/safekat/pages/chatPedido.js @@ -0,0 +1,6 @@ +import Chat from '../components/chat.js' + +let chat = new Chat($("#chat-pedido")) +chat.init() +chat.initPedido() +chat._handleListContacts() \ No newline at end of file diff --git a/httpdocs/assets/js/safekat/pages/chatPresupuesto.js b/httpdocs/assets/js/safekat/pages/chatPresupuesto.js new file mode 100644 index 00000000..4a09c66d --- /dev/null +++ b/httpdocs/assets/js/safekat/pages/chatPresupuesto.js @@ -0,0 +1,6 @@ +import Chat from '../components/chat.js' + +let chat = new Chat($("#chat-presupuesto")) +chat.init() +chat.initPresupuesto() +chat._handleListContacts() \ No newline at end of file diff --git a/httpdocs/themes/vuexy/img/avatars/user.png b/httpdocs/themes/vuexy/img/avatars/user.png new file mode 100644 index 00000000..2b8b6583 Binary files /dev/null and b/httpdocs/themes/vuexy/img/avatars/user.png differ diff --git a/httpdocs/themes/vuexy/vendor/css/pages/app-chat.css b/httpdocs/themes/vuexy/vendor/css/pages/app-chat.css index 5fa07556..a5b4d535 100755 --- a/httpdocs/themes/vuexy/vendor/css/pages/app-chat.css +++ b/httpdocs/themes/vuexy/vendor/css/pages/app-chat.css @@ -2,6 +2,9 @@ position: relative; height: calc(100vh - 11.5rem) !important; } +a.send-msg-btn { + color: white +} @media (min-width: 1200px) { .layout-horizontal .app-chat { height: calc(100vh - 11.5rem - 2.2rem) !important; @@ -57,6 +60,7 @@ height: calc(calc(100vh - 11.5rem) - 5rem - 2.2rem); } } + .app-chat .app-chat-contacts .sidebar-body .chat-contact-list li.chat-contact-list-item { display: flex; justify-content: space-between;