-
+
+
+
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 @@ +
${messageInput.val()}
`); + // const lastChatMessageWrapper = $('li:last-child .chat-message-wrapper'); + // if (lastChatMessageWrapper.length) { + // lastChatMessageWrapper.append(renderMsg); + // } + // messageInput.val(''); + // scrollToBottom(); + // } + // }); +} + +// // Seleccionar los elementoscon 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 = ` +//
+ ${row.display} +
++ ${contact.username} +
+${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;