diff --git a/ci4/app/Config/Email.php b/ci4/app/Config/Email.php index 9447a491..09d27f0b 100755 --- a/ci4/app/Config/Email.php +++ b/ci4/app/Config/Email.php @@ -28,7 +28,7 @@ class Email extends BaseConfig /** * SMTP Server Hostname */ - public string $SMTPHost = 'smtp.ionos.es'; + public string $SMTPHost = 'localhost'; /** * SMTP Username @@ -38,7 +38,7 @@ class Email extends BaseConfig /** * SMTP Password */ - public string $SMTPPass = 'H%5&qDkDkWnfLTGN'; + public string $SMTPPass = ''; /** * SMTP Port diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index 45716364..3e1e9adb 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -133,6 +133,9 @@ $routes->group('configuracion', ['namespace' => 'App\Controllers\Configuracion'] $routes->get('edit/(:num)', 'MaquinaTarea::viewForm/$1', ['as' => 'maquinaTareaViewForm']); $routes->get('datatable', 'MaquinaTarea::datatable', ['as' => 'maquinaTareaDatatable']); }); + $routes->group("messages", ["namespace" => 'App\Controllers\Chat'], function ($routes) { + $routes->get('', 'ChatController::config_view', ['as' => 'configMessagesIndex']); + }); }); @@ -903,18 +906,30 @@ $routes->group('chat', ['namespace' => 'App\Controllers\Chat'], function ($route $routes->post('direct/messages/unread/(:num)', 'ChatController::update_chat_direct_message_unread/$1', ['as' => 'updateChatDirectMessageUnread']); - $routes->get('departments', 'ChatController::get_chat_departments', ['as' => 'getChatDepartments']); + $routes->post('department', 'ChatController::store_chat_department', ['as' => 'storeChatDepartment']); + $routes->delete('department/(:num)', 'ChatController::delete_chat_department/$1', ['as' => 'deleteChatDepartment']); + $routes->post('department/update/(:num)', 'ChatController::update_chat_department/$1', ['as' => 'updateChatDepartment']); + $routes->get('departments/(:alpha)/(:num)', 'ChatController::get_chat_departments/$1/$2', ['as' => 'getChatDepartments']); $routes->get('departments/select', 'ChatController::get_chat_department_select', ['as' => 'getChatDepartmentSelect']); $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('department/(:num)/users', 'ChatController::get_chat_department_users/$1', ['as' => 'getChatDepartmentUsers']); + $routes->get('department/users/presupuesto/(:num)/(:num)', 'ChatController::get_chat_department_presupuesto_users/$1/$2', ['as' => 'getPresupuestoChatDepartmentUsers']); + $routes->get('department/datatable', 'ChatController::chat_department_datatable', ['as' => 'chatDepartmentDatatable']); + $routes->get('department/edit/(:num)', 'ChatController::chat_department_edit/$1', ['as' => 'chatDepartmentEditView']); + $routes->get('department/users/datatable/(:num)', 'ChatController::chat_department_user_datatable/$1', ['as' => 'chatDepartmentUsersDatatable']); + $routes->get('department/users/pedido/(:num)/(:num)', 'ChatController::get_chat_department_pedido_users/$1/$2', ['as' => 'getPedidoChatDepartmentUsers']); + $routes->get('department/users/factura/(:num)/(:num)', 'ChatController::get_chat_department_factura_users/$1/$2', ['as' => 'getFacturaChatDepartmentUsers']); + $routes->get('department/users/select/add/(:num)', 'ChatController::select_users_not_in_chat_department/$1', ['as' => 'selectUsersNotInChatDepartment']); + $routes->post('department/user', 'ChatController::subscribe_to_chat_deparment/$1', ['as' => 'subscribeToChatDepartment']); + $routes->post('department/subscribe/admin/user', 'ChatController::subscribe_admin_to_department', ['as' => 'subscribeAdminToChatDepartment']); + $routes->delete('department/user/(:num)', 'ChatController::delete_user_from_department/$1', ['as' => 'deleteUserFromDepartment']); + $routes->delete('department/admin/user/(:num)/(:num)', 'ChatController::delete_user_admin_from_department/$1/$2', ['as' => 'deleteUserAdminFromDepartment']); + $routes->get('(:num)', 'ChatController::get_chat/$1', ['as' => 'getChat']); $routes->post('message/error/presupuesto', 'ChatController::store_chat_error_message', ['as' => 'storeChatErrorMessage']); - $routes->post('message/presupuesto', 'ChatController::store_chat_message_presupuesto', ['as' => 'storeChatMessagePresupuesto']); - $routes->post('message/pedido', 'ChatController::store_chat_message_pedido', ['as' => 'storeChatMessagePedido']); - $routes->post('message/factura', 'ChatController::store_chat_message_factura', ['as' => 'storeChatMessageFactura']); + $routes->post('message/(:alpha)', 'ChatController::store_message/$1', ['as' => 'storeChatMessage']); $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']); @@ -923,15 +938,11 @@ $routes->group('chat', ['namespace' => 'App\Controllers\Chat'], function ($route $routes->get('users/internal', 'ChatController::get_chat_users_internal', ['as' => 'getChatUsersInternal']); $routes->get('users/all', 'ChatController::get_chat_users_all', ['as' => 'getChatUsersAll']); - $routes->post('hebra/presupuesto', 'ChatController::store_hebra_presupuesto', ['as' => 'storeHebraPresupuesto']); - $routes->post('hebra/pedido', 'ChatController::store_hebra_pedido', ['as' => 'storeHebraPedido']); - $routes->post('hebra/factura', 'ChatController::store_hebra_factura', ['as' => 'storeHebraFactura']); + $routes->post('hebra/(:alpha)', 'ChatController::store_hebra/$1', ['as' => 'storeHebra']); $routes->post('hebra/(:num)', 'ChatController::update_hebra/$1', ['as' => 'updateHebra']); - $routes->get('hebra/presupuesto/(:num)', "ChatController::get_hebra_presupuesto/$1", ["as" => "getHebraPresupuesto"]); - $routes->get('hebra/pedido/(:num)', "ChatController::get_hebra_pedido/$1", ["as" => "getHebraPedido"]); - $routes->get('hebra/factura/(:num)', "ChatController::get_hebra_factura/$1", ["as" => "getHebraFactura"]); + $routes->get('hebra/(:alpha)/(:num)', "ChatController::get_hebra/$1/$2", ["as" => "getHebra"]); - $routes->get('users/notifications-unviewed/(:num)','ChatController::get_notifications_not_viewed_from_chat/$1'); + $routes->get('users/message/notifications-unviewed/(:num)','ChatController::get_notifications_not_viewed_from_message/$1'); }); diff --git a/ci4/app/Config/Services.php b/ci4/app/Config/Services.php index 33330fa1..02632cdf 100755 --- a/ci4/app/Config/Services.php +++ b/ci4/app/Config/Services.php @@ -2,6 +2,7 @@ namespace Config; +use App\Services\ChatService; use App\Services\FTPService; use App\Services\MaquinaService; use App\Services\MessageService; @@ -9,6 +10,7 @@ use App\Services\PapelImpresionService; use CodeIgniter\Config\BaseService; use App\Services\ProductionService; use App\Services\TarifaMaquinaService; +use CodeIgniter\Email\Email; /** * Services Configuration file. @@ -35,6 +37,7 @@ class Services extends BaseService * return new \CodeIgniter\Example(); * } */ + public static function production(){ return new ProductionService(); } @@ -53,4 +56,8 @@ class Services extends BaseService { return new MessageService(); } + public static function chat() + { + return new ChatService(); + } } diff --git a/ci4/app/Config/Validation.php b/ci4/app/Config/Validation.php index 1c8614bf..982ce5c9 100755 --- a/ci4/app/Config/Validation.php +++ b/ci4/app/Config/Validation.php @@ -162,4 +162,15 @@ class Validation extends BaseConfig ], ]; + public array $chat_department = + [ + "display" => [ + "rules" => "required|string", + "label" => "tarifa acabado", + ], + "description" => [ + "rules" => "permit_empty", + "label" => "maquina", + ], + ]; } diff --git a/ci4/app/Controllers/Chat/ChatController.php b/ci4/app/Controllers/Chat/ChatController.php index 872235f4..b54ec909 100644 --- a/ci4/app/Controllers/Chat/ChatController.php +++ b/ci4/app/Controllers/Chat/ChatController.php @@ -14,6 +14,7 @@ use App\Models\Facturas\FacturaModel; use App\Models\Pedidos\PedidoModel; use App\Models\Presupuestos\PresupuestoModel; use App\Models\Usuarios\UserModel; +use App\Services\ChatService; use App\Services\MessageService; use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\HTTP\RequestInterface; @@ -21,6 +22,7 @@ use CodeIgniter\Log\Logger; use Psr\Log\LoggerInterface; use Hermawan\DataTables\DataTable; use CodeIgniter\I18n\Time; +use CodeIgniter\Validation\Validation; class ChatController extends BaseController { @@ -32,6 +34,8 @@ class ChatController extends BaseController protected ClienteModel $clienteModel; protected ChatUser $chatUserModel; protected ChatNotification $chatNotificationModel; + protected Validation $validation; + protected ChatService $chatService; protected array $viewData; protected static $viewPath = 'themes/vuexy/form/mensajes/'; @@ -52,12 +56,16 @@ class ChatController extends BaseController $this->clienteModel = model(ClienteModel::class); $this->chatUserModel = model(ChatUser::class); $this->chatNotificationModel = model(ChatNotification::class); + $this->validation = service("validation"); + $this->chatService = service("chat"); + } public function index() {} - public function get_chat_departments() + public function get_chat_departments(string $model,int $modelId) { - $data = $this->chatDeparmentModel->getChatDepartments(); + $data = $this->chatService->getChatDepartments($model,$modelId); + return $this->response->setJSON($data); } public function get_chat_department_select() @@ -69,6 +77,7 @@ class ChatController extends BaseController { $data = [ + "department" => $this->chatDeparmentModel->find($chat_department_id), "chat" => null, "messages" => null, "count" => 0, @@ -77,6 +86,8 @@ class ChatController extends BaseController if ($chat) { $data["messages"] = $this->chatMessageModel->get_chat_messages($chat->id); $this->chatMessageModel->set_chat_department_messages_as_read($chat->id); + $this->chatModel->setAsViewedChatUserNotifications($chat->id, auth()->user()->id); + $data["count"] = count($data["messages"]); } $data["chat"] = $chat; @@ -86,6 +97,7 @@ class ChatController extends BaseController { $data = [ + "department" => $this->chatDeparmentModel->find($chat_department_id), "chat" => null, "messages" => null, "count" => 0, @@ -94,6 +106,8 @@ class ChatController extends BaseController if ($chat) { $data["messages"] = $this->chatMessageModel->get_chat_messages($chat->id); $this->chatMessageModel->set_chat_department_messages_as_read($chat->id); + $this->chatModel->setAsViewedChatUserNotifications($chat->id, auth()->user()->id); + $data["count"] = count($data["messages"]); } $data["chat"] = $chat; @@ -103,6 +117,7 @@ class ChatController extends BaseController { $data = [ + "department" => $this->chatDeparmentModel->find($chat_department_id), "chat" => null, "messages" => null, "count" => 0, @@ -111,6 +126,7 @@ class ChatController extends BaseController if ($chat) { $data["messages"] = $this->chatMessageModel->get_chat_messages($chat->id); $this->chatMessageModel->set_chat_department_messages_as_read($chat->id); + $this->chatModel->setAsViewedChatUserNotifications($chat->id, auth()->user()->id); $data["count"] = count($data["messages"]); } $data["chat"] = $chat; @@ -192,70 +208,15 @@ class ChatController extends BaseController $data = $this->chatModel->getChat($chat_id); return $this->response->setJSON($data); } - public function store_chat_message_presupuesto() + public function store_message($model) { $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); - $chatDepartmentUsers = $this->chatDeparmentModel->getChatDepartmentUsers($data["chat_department_id"]); - foreach ($chatDepartmentUsers as $user) { - if ($user->id != auth()->user()->id) { - $this->chatNotificationModel->insert(["chat_message_id" => $chat_message_id, "user_id" => $user->id]); - } - } - return $this->response->setJSON($dataResponse); - } - public function store_chat_message_pedido() - { + $chatMessageEntity = $this->chatService->storeChatMessage($data["chat_department_id"],$model,$data["model_id"],$data); + return $this->response->setJSON($chatMessageEntity); - $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); - $chatDepartmentUsers = $this->chatDeparmentModel->getChatDepartmentUsers($data["chat_department_id"]); - foreach ($chatDepartmentUsers as $user) { - if ($user->id != auth()->user()->id) { - $this->chatNotificationModel->insert(["chat_message_id" => $chat_message_id, "user_id" => $user->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); - $chatDepartmentUsers = $this->chatDeparmentModel->getChatDepartmentUsers($data["chat_department_id"]); - foreach ($chatDepartmentUsers as $user) { - if ($user->id != auth()->user()->id) { - $this->chatNotificationModel->insert(["chat_message_id" => $chat_message_id, "user_id" => $user->id]); - } - } - return $this->response->setJSON($dataResponse); - } public function store_chat_message_single() { $data = $this->request->getPost(); @@ -316,50 +277,23 @@ class ChatController extends BaseController public function get_chat_cliente() { $cliente_id = auth()->user()->cliente_id; - $response = []; - if ($cliente_id) { - $data = $this->clienteModel->getClienteDataPresupuestoPedidoFactura($cliente_id); - $response["totalMessages"] = 0; - $response["chatFacturas"] = $this->chatModel->getClienteChatFacturas($data["facturas"]); - $mensajes_directos = $this->chatModel->getChatDirectMessageNotifications(); - - foreach ($response["chatFacturas"] as $key => $value) { - $response["totalMessages"] += $value->unreadMessages; - } - $response["chatPresupuestos"] = $this->chatModel->getClienteChatPresupuestos($data["presupuestos"]); - foreach ($response["chatPresupuestos"] as $key => $value) { - $response["totalMessages"] += $value->unreadMessages; - } - foreach ($mensajes_directos as $value) { - $response["internals"][] = $value; - $response["totalMessages"] += $value->unreadMessages; - } - $response["chatPedidos"] = $this->chatModel->getClienteChatPedidos($data["pedidos"]); - foreach ($response["chatPedidos"] as $key => $value) { - $response["totalMessages"] += $value->unreadMessages; - } - $response["data"] = $data; - } else { - $response["internals"] = $this->chatModel->getChatDepartmentNotifications(); - $internal_notifications = $this->chatModel->getChatInternalNotifications(); - $mensajes_directos = $this->chatModel->getChatDirectMessageNotifications(); - foreach ($internal_notifications as $value) { - $response["internals"][] = $value; - } - foreach ($mensajes_directos as $value) { - $response["internals"][] = $value; - } - $response["totalMessages"] = 0; - foreach ($response["internals"] as $key => $value) { - $response["totalMessages"] += $value->unreadMessages; - } - } + $response = $this->chatService->getAuthUserNotifications(); return $this->response->setJSON($response); } - public function get_chat_department_users(int $chat_department_id) + public function get_chat_department_presupuesto_users(int $chat_department_id, int $presupuesto_id) { - $data = $this->chatDeparmentModel->getChatDepartmentUsers($chat_department_id); + $data = $this->chatDeparmentModel->find($chat_department_id)->withUsers($presupuesto_id, 'presupuesto'); + return $this->response->setJSON($data); + } + public function get_chat_department_pedido_users(int $chat_department_id, $pedido_id) + { + $data = $this->chatDeparmentModel->find($chat_department_id)->withUsers($pedido_id, 'pedido'); + return $this->response->setJSON($data); + } + public function get_chat_department_factura_users(int $chat_department_id, $factura_id) + { + $data = $this->chatDeparmentModel->find($chat_department_id)->withUsers($factura_id, 'factura'); return $this->response->setJSON($data); } public function get_chat_users_internal() @@ -466,80 +400,14 @@ class ChatController extends BaseController return $this->response->setJSON($query->get()->getResultObject()); } - public function store_hebra_presupuesto() + public function store_hebra(string $model) { $auth_user = auth()->user(); $bodyData = $this->request->getPost(); - $chat_id = $this->chatModel->insert([ - "presupuesto_id" => $bodyData["modelId"], - "title" => $bodyData["title"] - ]); - $chatMessageId = $this->chatMessageModel->insert([ - "chat_id" => $chat_id, - "message" => $bodyData["message"], - "sender_id" => $auth_user->id - ]); - if (isset($bodyData["users"])) { - $bodyData["users"][] = $auth_user->id; - $chatUserData = array_map(fn($x) => ["user_id" => $x, "chat_id" => $chat_id], $bodyData["users"]); - $this->chatUserModel->insertBatch($chatUserData); - foreach ($bodyData["users"] as $userId) { - $this->chatNotificationModel->insert( - ["chat_message_id" => $chatMessageId, "user_id" => $userId] - ); - } - } - return $this->response->setJSON(["message" => "Hebra creada correctamente", "status" => true]); + $status = $this->chatService->storeHebra($model,$bodyData['modelId'],$bodyData); + return $this->response->setJSON(["message" => "Hebra creada correctamente", "status" => $status]); } - public function store_hebra_pedido() - { - $bodyData = $this->request->getPost(); - $chat_id = $this->chatModel->insert([ - "pedido_id" => $bodyData["modelId"], - "title" => $bodyData["title"] - - ]); - $chatMessageId = $this->chatMessageModel->insert([ - "chat_id" => $chat_id, - "message" => $bodyData["message"], - "sender_id" => auth()->user()->id - ]); - if (isset($bodyData["users"])) { - $chatUserData = array_map(fn($x) => ["user_id" => $x, "chat_id" => $chat_id], $bodyData["users"]); - $this->chatUserModel->insertBatch($chatUserData); - foreach ($bodyData["users"] as $userId) { - $this->chatNotificationModel->insert( - ["chat_message_id" => $chatMessageId, "user_id" => $userId] - ); - } - } - return $this->response->setJSON(["message" => "Hebra creada correctamente", "status" => true]); - } - - public function store_hebra_factura() - { - $bodyData = $this->request->getPost(); - $chat_id = $this->chatModel->insert([ - "factura_id" => $bodyData["modelId"], - "title" => $bodyData["title"] - ]); - $chatMessageId = $this->chatMessageModel->insert([ - "chat_id" => $chat_id, - "message" => $bodyData["message"], - "sender_id" => auth()->user()->id - ]); - if (isset($bodyData["users"])) { - $chatUserData = array_map(fn($x) => ["user_id" => $x, "chat_id" => $chat_id], $bodyData["users"]); - $this->chatUserModel->insertBatch($chatUserData); - foreach ($bodyData["users"] as $userId) { - $this->chatNotificationModel->insert( - ["chat_message_id" => $chatMessageId, "user_id" => $userId] - ); - } - } - return $this->response->setJSON(["message" => "Hebra creada correctamente", "status" => true]); - } public function update_hebra($chat_id) { $bodyData = $this->request->getPost(); @@ -550,11 +418,7 @@ class ChatController extends BaseController ]); $actualUsers = $this->chatUserModel->builder()->select("user_id")->where("chat_id", $chat_id)->get()->getResultArray(); $actualUsersArray = array_map(fn($x) => $x["user_id"], $actualUsers); - foreach ($actualUsersArray as $key => $user_id) { - $this->chatNotificationModel->insert( - ["chat_message_id" => $chatMessageId, "user_id" => $user_id] - ); - } + if (isset($bodyData["users"])) { foreach ($bodyData["users"] as $userId) { if (in_array($userId, $actualUsersArray) == false) { @@ -568,55 +432,13 @@ class ChatController extends BaseController } return $this->response->setJSON(["message" => "Hebra actualizada correctamente", "status" => true]); } - public function get_hebra_presupuesto($presupuesto_id) + public function get_hebra(string $model,int $modelId) { - $data = $this->chatModel->getPresupuestoHebras($presupuesto_id); - $notifications = $this->chatModel->builder()->select([ - "chat_notifications.id" - ]) - ->join("chat_messages", "chat_messages.chat_id = chats.id", "left") - ->join("chat_notifications", "chat_notifications.chat_message_id = chat_messages.id", "left") - ->where("chats.presupuesto_id", $presupuesto_id) - ->where("chat_notifications.user_id", auth()->user()->id) - ->get()->getResultArray(); - foreach ($notifications as $notification) { - $this->chatNotificationModel->update($notification["id"], ["viewed" => true]); - } - return $this->response->setJSON($data); - } - public function get_hebra_pedido($pedido_id) - { - $data = $this->chatModel->getPedidoHebras($pedido_id); - $notifications = $this->chatModel->builder()->select([ - "chat_notifications.id" - ]) - ->join("chat_messages", "chat_messages.chat_id = chats.id", "left") - ->join("chat_notifications", "chat_notifications.chat_message_id = chat_messages.id", "left") - ->where("chats.pedido_id", $pedido_id) - ->where("chat_notifications.user_id", auth()->user()->id) - ->get()->getResultArray(); - foreach ($notifications as $notification) { - $this->chatNotificationModel->update($notification["id"], ["viewed" => true]); - } - return $this->response->setJSON($data); - } - public function get_hebra_factura($factura_id) - { - $data = $this->chatModel->getFacturaHebras($factura_id); - $notifications = $this->chatModel->builder()->select([ - "chat_notifications.id" - ]) - ->join("chat_messages", "chat_messages.chat_id = chats.id", "left") - ->join("chat_notifications", "chat_notifications.chat_message_id = chat_messages.id", "left") - ->where("chats.factura_id", $factura_id) - ->where("chat_notifications.user_id", auth()->user()->id) - ->get()->getResultArray(); - foreach ($notifications as $notification) { - $this->chatNotificationModel->update($notification["id"], ["viewed" => true]); - } + $data = $this->chatService->getHebras($model,$modelId); return $this->response->setJSON($data); } + public function datatable_messages() { $auth_user_id = auth()->user()->id; @@ -646,9 +468,9 @@ class ChatController extends BaseController return DataTable::of($query) ->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "") ->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "") - ->add("creator", fn($q) => $this->chatModel->getChatFirstUser($q->id)->userFullName) - ->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->id, $auth_user_id)) - ->add("action", fn($q) => ["type" => "presupuesto", "modelId" => $q->id, "isAdmin" => $isAdmin, "lang" => [ + ->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId)) + ->edit("creator",fn($q) => $q->userId == $auth_user_id ? ''.lang("App.me").'' : $q->creator) + ->add("action", fn($q) => ["type" => "presupuesto", "modelId" => $q->id, "isAdmin" => $isAdmin,"chatMessageId" => $q->chatMessageId, "lang" => [ "view_chat" => lang('Chat.view_chat'), "view_by_alt_message" => lang('Chat.view_by_alt_message') ]]) @@ -662,9 +484,9 @@ class ChatController extends BaseController return DataTable::of($query) ->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "") ->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "") - ->add("creator", fn($q) => $this->chatModel->getChatFirstUser($q->id)->userFullName) - ->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->id, $auth_user_id)) - ->add("action", fn($q) => ["type" => "pedido", "modelId" => $q->id, "isAdmin" => $isAdmin, "lang" => [ + ->edit("creator",fn($q) => $q->userId == $auth_user_id ? ''.lang("App.me").'' : $q->creator) + ->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId)) + ->add("action", fn($q) => ["type" => "pedido", "modelId" => $q->id, "isAdmin" => $isAdmin,"chatMessageId" => $q->chatMessageId, "lang" => [ "view_chat" => lang('Chat.view_chat'), "view_by_alt_message" => lang('Chat.view_by_alt_message') ]]) @@ -679,19 +501,28 @@ class ChatController extends BaseController return DataTable::of($query) ->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "") ->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "") - ->add("creator", fn($q) => $this->chatModel->getChatFirstUser($q->id)->userFullName) - ->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->id, $auth_user_id)) - ->add("action", fn($q) => ["type" => "factura", "modelId" => $q->id, "isAdmin" => $isAdmin, "lang" => [ + ->edit("creator",fn($q) => $q->userId == $auth_user_id ? ''.lang("App.me").'' : $q->creator) + ->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId)) + ->add("action", fn($q) => ["type" => "factura", "modelId" => $q->id, "isAdmin" => $isAdmin,"chatMessageId" => $q->chatMessageId, "lang" => [ "view_chat" => lang('Chat.view_chat'), "view_by_alt_message" => lang('Chat.view_by_alt_message') ]]) ->toJson(true); } - public function get_notifications_not_viewed_from_chat(int $chat_id) + public function get_notifications_not_viewed_from_message(int $chat_message_id) { - $data = $this->chatModel->getUsersNotificationNotViewedFromChat($chat_id); - return $this->response->setJSON(["data" => $data, "chat_id" => $chat_id]); + $unviewedNotifications = $this->chatModel->getUsersNotificationNotViewedFromChat($chat_message_id); + // $viewedNotifications = $this->chatModel->getUsersNotificationViewedFromChat($chat_message_id); + + return $this->response->setJSON( + [ + "data" => [ + "notifications" => $unviewedNotifications, + ], + "chat_message_id" => $chat_message_id + ] + ); } public function store_new_direct_message() { @@ -800,4 +631,144 @@ class ChatController extends BaseController $r = $messageService->createErrorMessagePresupuesto("Error", $bodyData['presupuesto_id']); return $this->response->setJSON(["message" => "ok", "data" => $r]); } + public function delete_user_from_department($chat_department_id) + { + $data = $this->request->getRawInput(); + $user_id = auth()->user()->id; + $adminExist = $this->chatDeparmentUserModel->where('chat_department_id', $chat_department_id) + ->where('user_id', $user_id) + ->where('pedido_id', null) + ->where('factura_id', null) + ->where('presupuesto_id', null)->countAllResults(); + if ($adminExist) { + return $this->response->setJSON(["message" => lang('Chat.exit_admin_chat_wrong'), "status" => false]); + } + $chatDepartmentUserEntity = $this->chatDeparmentUserModel->where('chat_department_id', $chat_department_id)->where('user_id', $user_id)->where($data['model_fk'], $data['model_id_fk']); + if ($chatDepartmentUserEntity->countAllResults() > 0) { + $deleted = $this->chatDeparmentUserModel->where('chat_department_id', $chat_department_id)->where('user_id', $user_id)->delete(purge: true); + return $this->response->setJSON(["message" => lang('Chat.exit_chat_ok'), "status" => true]); + } else { + return $this->response->setJSON(["message" => lang('Chat.exit_chat_wrong'), "status" => false]); + } + } + public function delete_user_admin_from_department($chat_department_id, $user_id) + { + $this->chatDeparmentUserModel->where('chat_department_id', $chat_department_id)->where('user_id', $user_id)->delete(); + return $this->response->setJSON(["message" => lang('Chat.user_deleted_ok'), "status" => true]); + } + public function subscribe_to_chat_deparment() + { + $data = $this->request->getPost(); + $user_id = auth()->user()->id; + $adminExist = $this->chatDeparmentUserModel->where('chat_department_id', $data['chat_department_id']) + ->where('user_id', $user_id) + ->where('pedido_id', null) + ->where('factura_id', null) + ->where('presupuesto_id', null)->countAllResults(); + if ($adminExist) { + return $this->response->setJSON(["message" => lang('Chat.subscribe_chat_wrong'), "status" => false]); + } + $chatDepartmentUserEntity = $this->chatDeparmentUserModel->where('chat_department_id', $data['chat_department_id'])->where('user_id', $user_id)->where($data['model_fk'], $data['model_id_fk']); + if ($chatDepartmentUserEntity->countAllResults() > 0) { + return $this->response->setJSON(["message" => lang('Chat.subscribe_chat_wrong'), "status" => false]); + } else { + $this->chatDeparmentUserModel->insert(["chat_department_id" => $data["chat_department_id"], "user_id" => $user_id, $data['model_fk'] => $data['model_id_fk']]); + return $this->response->setJSON(["message" => lang('Chat.subscribe_chat_ok'), "status" => true]); + } + } + public function subscribe_admin_to_department() + { + $data = $this->request->getPost(); + if ($data['user_id']) { + + $this->chatDeparmentUserModel + ->insert( + [ + "chat_department_id" => $data["chat_department_id"], + "user_id" => $data["user_id"], + ] + ); + return $this->response->setJSON(["message" => lang('Chat.subscribe_admin_chat_ok'), "status" => true]); + } else { + return $this->response->setStatusCode(422)->setJSON(["message" => lang('Chat.subscribe_admin_chat_wrong'), "status" => false]); + } + } + public function config_view() + { + $this->viewData['breadcrumb'] = [ + ['title' => lang("App.menu_configuration"), 'route' => 'javascript:void(0);', 'active' => false], + ['title' => lang("App.menu_config_messages"), 'route' => route_to("configMessagesIndex"), 'active' => true] + ]; + + return view('themes/vuexy/form/configuracion/messages/configView', $this->viewData); + } + public function chat_department_edit($chat_department_id) + { + $chatDepartment = $this->chatDeparmentModel->find($chat_department_id); + $this->viewData['breadcrumb'] = [ + ['title' => lang("App.menu_configuration"), 'route' => 'javascript:void(0);', 'active' => false], + ['title' => lang("App.menu_config_messages"), 'route' => route_to("configMessagesIndex"), 'active' => false], + ['title' => $chatDepartment->display, 'route' => route_to("chatDepartmentEditView", $chat_department_id), 'active' => true] + + ]; + $this->viewData["chat_department"] = $chatDepartment; + return view('themes/vuexy/form/configuracion/messages/editChatDepartmentForm', $this->viewData); + } + public function chat_department_datatable() + { + $q = $this->chatDeparmentModel->datatableQuery(); + return DataTable::of($q) + ->add('action', fn($r) => $r->id) + ->toJson(true); + } + public function chat_department_user_datatable(int $chat_department_id) + { + $q = $this->chatDeparmentUserModel->datatableQuery($chat_department_id); + $datatable = DataTable::of($q); + if (auth()->user()->inGroup('admin')) { + $datatable->add('action', fn($r) => $r->userId); + } + return $datatable->toJson(true); + } + public function select_users_not_in_chat_department(int $chat_department_id) + { + $paramQuery = $this->request->getGet("q"); + $data = $this->chatDeparmentUserModel->querySelectUsersNotInDepartment($chat_department_id, $paramQuery); + return $this->response->setJSON($data); + } + public function store_chat_department() + { + $data = $this->request->getPost(); + $validated = $this->validation->run($data, 'chat_department'); + if ($validated) { + $dataValidated = $this->validation->getValidated(); + $dataValidated['name'] = newUUID(); + $this->chatDeparmentModel->insert($dataValidated); + return $this->response->setJSON(["message" => lang('App.global_alert_save_success'), "status" => true, "data" => $dataValidated]); + } else { + return $this->response->setStatusCode(422)->setJSON(["message" => lang('App.global_alert_save_success'), "status" => false, "errors" => $this->validation->getErrors()]); + } + return $this->response->setJSON(["message" => lang('App.global_alert_save_success'), "status" => true]); + } + public function update_chat_department(int $chat_department_id) + { + $data = $this->request->getPost(); + $validated = $this->validation->run($data, 'chat_department'); + if ($validated) { + $dataValidated = $this->validation->getValidated(); + $this->chatDeparmentModel->update($chat_department_id, $dataValidated); + return $this->response->setJSON(["message" => lang('App.global_alert_save_success'), "status" => true, "data" => $dataValidated]); + } else { + return $this->response->setStatusCode(422)->setJSON(["message" => lang('App.global_alert_save_success'), "status" => false, "errors" => $this->validation->getErrors()]); + } + } + public function delete_chat_department($chat_department_id) + { + if (auth()->user()->inGroup('admin')) { + $this->chatDeparmentModel->delete($chat_department_id); + return $this->response->setJSON(["message" => lang('App.user_alert_delete'), "status" => true]); + } else { + return $this->response->setStatusCode(403)->setJSON(["message" => lang('App.user_alert_forbidden'), "status" => false]); + } + } } diff --git a/ci4/app/Database/Migrations/2025-03-17-080000_AddForeignChatDepartmentUsers.php b/ci4/app/Database/Migrations/2025-03-17-080000_AddForeignChatDepartmentUsers.php new file mode 100644 index 00000000..a92c42e7 --- /dev/null +++ b/ci4/app/Database/Migrations/2025-03-17-080000_AddForeignChatDepartmentUsers.php @@ -0,0 +1,45 @@ + [ + "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->addColumn("chat_department_users",$this->COLUMNS); + $this->forge->addForeignKey('pedido_id', 'pedidos', 'id'); + $this->forge->addForeignKey('factura_id', 'facturas', 'id'); + $this->forge->addForeignKey('presupuesto_id', 'presupuestos', 'id'); + } + + public function down() + { + $this->forge->dropForeignKey("chat_department_users","pedido_id"); + $this->forge->dropForeignKey("chat_department_users","factura_id"); + $this->forge->dropForeignKey("chat_department_users","presupuesto_id"); + $this->forge->dropColumn("chat_department_users",["pedido_id","factura_id","presupuesto_id"]); + } +} diff --git a/ci4/app/Entities/Chat/ChatDepartmentEntity.php b/ci4/app/Entities/Chat/ChatDepartmentEntity.php new file mode 100644 index 00000000..5017c310 --- /dev/null +++ b/ci4/app/Entities/Chat/ChatDepartmentEntity.php @@ -0,0 +1,79 @@ + null, + "name" => null, + "display" => null, + "description" => null, + "type" => null, + ]; + + + protected $casts = [ + "name" => "string", + "display" => "string", + "description" => "?string", + "type" => "string", + ]; + + /** + * Chat department users that are in department as administrador. These users belongs to department in all chats in any model associated and + * will receive notifications always + * + * @return array + */ + public function chatDepartmentAdminUsers(){ + $m = model(ChatDeparmentUserModel::class); + $chatDepartmentUsers = $m->where('chat_department_id',$this->attributes['id']) + ->where('pedido_id',null) + ->where('factura_id',null) + ->where('presupuesto_id',null)->findAll(); + return $chatDepartmentUsers; + } + /** + * Chat department users that has been associated to the department by sending a + * message and users that are not as admin of the department that has written a message. + * + * @param integer $modelFkId Id from model associated + * @param string $model Name of the model associated `['presupuesto','pedido','factura']` + * @return array + */ + public function chatDepartmentExternalUsers(int $modelFkId,string $model = "presupuesto") : array + { + $m = model(ChatDeparmentUserModel::class); + $m->where('chat_department_id',$this->attributes['id']); + + switch ($model) { + case 'presupuesto': + $m->where('presupuesto_id',$modelFkId); + break; + case 'pedido': + $m->where('pedido_id',$modelFkId); + break; + case 'factura': + $m->where('pedido_id',$modelFkId); + break; + default: + break; + } + return $m->findAll() ?? []; + + } + public function withUsers(int $modelFkId,string $model = "presupuesto") : self + { + $externalUsers = $this->chatDepartmentExternalUsers($modelFkId,$model); + $this->attributes["adminUsers"] = array_map(fn(ChatDepartmentUserEntity $du) => $du->user()->withAvatar() , $this->chatDepartmentAdminUsers()); + $this->attributes["externalUsers"] = array_map(fn(ChatDepartmentUserEntity $du) => $du->user()->withAvatar() , $externalUsers); + return $this; + } + +} diff --git a/ci4/app/Entities/Chat/ChatDepartmentUserEntity.php b/ci4/app/Entities/Chat/ChatDepartmentUserEntity.php new file mode 100644 index 00000000..c261f568 --- /dev/null +++ b/ci4/app/Entities/Chat/ChatDepartmentUserEntity.php @@ -0,0 +1,60 @@ + null, + "user_id" => null, + "pedido_id" => null, + "factura_id" => null, + "presupuesto_id" => null, + ]; + + + protected $casts = [ + "chat_department_id" => "integer", + "user_id" => "integer", + "pedido_id" => "?integer", + "factura_id" => "?integer", + "presupuesto_id" => "?integer", + ]; + + public function user() : ?UserEntity + { + $m = model(UserModel::class); + return $m->find($this->attributes['user_id']); + } + public function department() : ?ChatDepartmentEntity + { + $m = model(ChatDeparmentModel::class); + return $m->find($this->attributes['chat_department_id']); + } + public function presupuesto() : ?PresupuestoEntity + { + $m = model(PresupuestoModel::class); + return $m->find($this->attributes['presupuesto_id']); + } + public function pedido() : ?PedidoEntity + { + $m = model(PedidoModel::class); + return $m->find($this->attributes['pedido_id']); + } + public function factura() : ?FacturaEntity + { + $m = model(FacturaEntity::class); + return $m->find($this->attributes['factura_id']); + } + +} diff --git a/ci4/app/Entities/Chat/ChatEntity.php b/ci4/app/Entities/Chat/ChatEntity.php new file mode 100644 index 00000000..1669f3cd --- /dev/null +++ b/ci4/app/Entities/Chat/ChatEntity.php @@ -0,0 +1,148 @@ + null, + "chat_department_id" => null, + "pedido_id" => null, + "presupuesto_id" => null, + "factura_id" => null, + "title" => null + ]; + + + protected $casts = [ + "chat_department_id" => "?integer", + "pedido_id" => "?integer", + "presupuesto_id" => "?integer", + "factura_id" => "?integer", + "title" => "string" + ]; + + public function withMessages(): self + { + $auth_user = auth()->user(); + $messages = $this->messages(); + foreach ($messages as $key => $message) { + if ($message->sender_id == $auth_user->id) { + $message->pos = 'right'; + } else { + $message->pos = 'left'; + } + } + $this->attributes["messages"] = $messages; + return $this; + } + public function department(): ?ChatDepartmentEntity + { + $m = model(ChatDeparmentModel::class); + return $m->find($this->attributes['chat_department_id']); + } + public function presupuesto(): ?PresupuestoEntity + { + $m = model(PresupuestoModel::class); + return $m->find($this->attributes['presupuesto_id']); + } + public function pedido(): ?PedidoEntity + { + $m = model(PedidoModel::class); + return $m->find($this->attributes['pedido_id']); + } + public function factura(): ?FacturaEntity + { + $m = model(FacturaEntity::class); + return $m->find($this->attributes['factura_id']); + } + public function messages(): ?array + { + $m = model(ChatMessageModel::class); + + $messages = $m->where('chat_id', $this->attributes["id"])->findAll(); + return array_map(fn(ChatMessageEntity $m) => $m->withUser(), $messages); + } + public function withHebra(): self + { + $this->attributes["messages"] = array_map(fn(ChatMessageEntity $m) => $m->withUser(), $this->messages()); + $this->attributes["internalUsers"] = array_map(fn(ChatUserEntity $u) => $u->user(), $this->internalUsers()); + return $this; + } + /** + * Undocumented function + * + * @return array + */ + public function internalUsers(): array + { + $m = model(ChatUser::class); + return $m->where('chat_id', $this->attributes["id"])->findAll() ?? []; + } + public function getModel(): ?Model + { + $model = null; + $models = [ + "presupuesto_id" => model(PresupuestoModel::class), + "pedido_id" => model(PedidoModel::class), + "factura_id" => model(FacturaModel::class) + ]; + $fks = [ + "presupuesto_id" => $this->attributes["presupuesto_id"], + "pedido_id" => $this->attributes["pedido_id"], + "factura_id" => $this->attributes["factura_id"], + ]; + foreach ($fks as $key => $fk) { + if ($fk) { + $model = $models[$key]; + break; + } + } + return $model; + } + public function relatedFk(): array + { + $relatedFk = null; + $relatedFkValue = null; + $fks = [ + "presupuesto" => $this->attributes["presupuesto_id"], + "pedido" => $this->attributes["pedido_id"], + "factura" => $this->attributes["factura_id"], + ]; + foreach ($fks as $key => $fk) { + if ($fk) { + $relatedFk = $key; + $relatedFkValue = $fk; + break; + } + } + return [ + "relatedModel" => $relatedFk, + "relatedFkValue" => $relatedFkValue + ]; + } + public function withModel() : self + { + if($this->getModel()){ + $this->attributes["modelData"] = $this->getModel()->find($this->relatedFk()['relatedFkValue']); + }else{ + $this->attributes["modelData"] = null; + } + return $this; + } +} diff --git a/ci4/app/Entities/Chat/ChatMessageEntity.php b/ci4/app/Entities/Chat/ChatMessageEntity.php new file mode 100644 index 00000000..2771a9c4 --- /dev/null +++ b/ci4/app/Entities/Chat/ChatMessageEntity.php @@ -0,0 +1,65 @@ + null, + "message" => null, + "chat_id" => null, + "sender_id" => null, + "receiver_id" => null, + "viewed" => null, + ]; + + + protected $casts = [ + "message" => "string", + "chat_id" => "integer", + "sender_id" => "?integer", + "receiver_id" => "?integer", + "viewed" => "boolean", + ]; + protected $dates = []; + + public function chat() : ?ChatEntity + { + $m = model(ChatModel::class); + return $m->find($this->attributes['chat_id']); + + } + /** + * Notifications related with this chat entity. + * + * @return array + */ + public function notifications() : array + { + $m = model(ChatNotification::class); + return $m->asArray()->where('chat_id',$this->attributes['chat_id'])->findAll() ?? []; + } + public function sentBy() : ?UserEntity + { + $m = model(UserModel::class); + return $m->find($this->attributes["sender_id"])->withAvatar(); + + } + public function withUser() : self + { + $this->attributes["user"] = $this->sentBy(); + return $this; + } + public function getCreatedAt() + { + return Time::createFromFormat("Y-m-d H:i:s",$this->attributes['created_at'])->format('d/m/Y H:i'); + + } +} diff --git a/ci4/app/Entities/Chat/ChatNotificationEntity.php b/ci4/app/Entities/Chat/ChatNotificationEntity.php new file mode 100644 index 00000000..07828a1c --- /dev/null +++ b/ci4/app/Entities/Chat/ChatNotificationEntity.php @@ -0,0 +1,42 @@ + null, + "chat_message_id" => null, + "user_id" => null, + "viewed" => null, + ]; + + + protected $casts = [ + "chat_message_id" => "integer", + "user_id" => "integer", + "viewed" => "boolean", + ]; + + public function message() : ?ChatMessageEntity + { + $m = model(ChatMessageModel::class); + return $m->find($this->attributes['chat_message_id']); + } + public function user() : ?UserEntity + { + $m = model(UserModel::class); + return $m->find($this->attributes['user_id']); + } + public function chat() : ?ChatEntity + { + return $this->message()->chat(); + } + +} diff --git a/ci4/app/Entities/Chat/ChatUserEntity.php b/ci4/app/Entities/Chat/ChatUserEntity.php new file mode 100644 index 00000000..9f485cb5 --- /dev/null +++ b/ci4/app/Entities/Chat/ChatUserEntity.php @@ -0,0 +1,36 @@ + null, + "user_id" => null, + "chat_id" => null, + ]; + + + protected $casts = [ + "user_id" => "integer", + "chat_id" => "integer", + ]; + + public function chat() : ?ChatEntity + { + $m = model(ChatModel::class); + return $m->find($this->attributes['chat_id']); + + } + public function user() : ?UserEntity + { + $m = model(UserModel::class); + return $m->find($this->attributes['user_id'])->withAvatar(); + } + +} diff --git a/ci4/app/Entities/Usuarios/UserEntity.php b/ci4/app/Entities/Usuarios/UserEntity.php index 34206cad..a6410e2f 100755 --- a/ci4/app/Entities/Usuarios/UserEntity.php +++ b/ci4/app/Entities/Usuarios/UserEntity.php @@ -1,6 +1,8 @@ getFullName(); } + public function withAvatar() : self + { + $users = auth()->getProvider(); + $this->attributes["avatar"] = md5($users->findById($this->attributes['id'])->getEmail()); + return $this; + } + /** + * Return an array of ChatNotificationEntities that belongs to the user + * + * @return array + */ + public function chatNotifications() : array + { + $m = model(ChatNotification::class); + return $m->where('user_id',$this->attributes['id'])->findAll() ?? []; + } } diff --git a/ci4/app/Helpers/general_helper.php b/ci4/app/Helpers/general_helper.php index e0578134..0736e7aa 100644 --- a/ci4/app/Helpers/general_helper.php +++ b/ci4/app/Helpers/general_helper.php @@ -97,7 +97,10 @@ function getCurrentLanguageFlag(){ } } - +function getGravatarURL(int $size = 30) +{ + return "https://gravatar.com/avatar/".md5(auth()->user()->getEmail())."?s=".$size; +} function getAllClassFolder($folder = null){ try { helper('filesystem'); diff --git a/ci4/app/Language/en/Chat.php b/ci4/app/Language/en/Chat.php new file mode 100644 index 00000000..42eb23b1 --- /dev/null +++ b/ci4/app/Language/en/Chat.php @@ -0,0 +1,61 @@ + "Messages", + "messages" => "Messages", + "message" => "Message", + "messages_internal" => "Internal messages", + "message_internal" => "Internal message", + "messages_client" => "Client messages", + "message_client" => "Client message", + "modal" => [ + "new_hebra" => "New thread", + "title" => "Title", + "new_message" => "New message", + "new_receivers" => "New participants", + "btn_send" => "Send", + "btn_send_update" => "Send" + ], + "datatable_messages" => [ + "created_at" => "Created at", + "updated_at" => "Updated at", + "title" => "Title", + "creator" => "Created by", + "viewed" => "Viewed", + + ], + "datatable_departments" => [ + "name" => "Name", + "description" => "Description", + ], + "datatable_department_users" => [ + "name" => "Name", + "user" => "User", + ], + "new_message_ok" => "Message sent successfully", + "participants" => "Participants", + "choose_department" => "Choose a deparment", + "new_participant" => "Add new participants", + "write_message_placeholder" => "Type your message here ...", + "add_notification" => "Notification", + "check_as_unviewed" => "Check as not viewed", + "add_notification_message" => "Add users present in this chat a notification", + "chat_title_presupuesto" => 'Presupuesto[{title,string,0}][{id}]', + "no_messages_notification" => 'There is no messages', + "view_chat" => 'See chat', + "view_by_alt_message" => 'Show users that has or not viewed the messages', + "exit_chat" => 'Exit chat', + "subscribe_chat" => 'Subscribe to chat', + "exit_chat_ok" => "You have exit chat successfully. Notifications on this chat will no longer be received", + "exit_chat_wrong" => "You can't exit the chat because you don't belong to it.", + "subscribe_chat_ok" => "You've subscribed to chat successfully. Now on you'll receive notifications.", + "subscribe_chat_wrong" => "You already belong to this chat.", + "message_configuration" => "Messages configuration", + "new_chat_department" => "New chat department", + "user_deleted_ok" => "User deleted succesfully", + "subscribe_admin_chat_ok" => "User added successfully", + "subscribe_admin_chat_wrong" => "You must select a user", + + + +]; diff --git a/ci4/app/Language/es/App.php b/ci4/app/Language/es/App.php index 5fad7c09..0704f891 100755 --- a/ci4/app/Language/es/App.php +++ b/ci4/app/Language/es/App.php @@ -226,6 +226,8 @@ return [ "user_alert_add" => "¡Agregado exitosamente!", "user_alert_edit" => "¡Editado con éxito!", "user_alert_delete" => "¡Eliminado con éxito!", + "user_alert_forbidden" => "No tienes permiso para realizar esta acción", + // USER - form "user_add_title" => "Nuevo Usuario", @@ -686,6 +688,7 @@ return [ "menu_configuration" => "Configuración", "menu_variables" => "Variables sistema", + "menu_config_messages" => "Mensajería", "menu_error_presupuesto" => "Errores presupuesto", "menu_calendario" => "Calendario", "menu_paises" => "Paises", @@ -824,6 +827,6 @@ return [ "menu_soporte" => "Soporte", "menu_soporte_new_ticket" => "Crear ticket", "menu_soporte_ticket_list" => "Mis tickets", - + "me" => "Yo", ]; \ No newline at end of file diff --git a/ci4/app/Language/es/Chat.php b/ci4/app/Language/es/Chat.php index e9f32692..10458366 100644 --- a/ci4/app/Language/es/Chat.php +++ b/ci4/app/Language/es/Chat.php @@ -20,10 +20,19 @@ return [ "created_at" => "Fecha creación", "updated_at" => "Fecha actualización", "title" => "Título", + "message" => "Mensaje", "creator" => "Creador", "viewed" => "Leído", ], + "datatable_departments" => [ + "name" => "Nombre", + "description" => "Descripción", + ], + "datatable_department_users" => [ + "name" => "Nombre", + "user" => "Usuario", + ], "new_message_ok" => "Mensaje enviado correctamente", "participants" => "Participantes", "choose_department" => "Elige un departamento", @@ -35,5 +44,24 @@ return [ "chat_title_presupuesto" => 'Presupuesto[{title,string,0}][{id}]', "no_messages_notification" => 'No hay mensajes que revisar por el momento', "view_chat" => 'Ver chat', - "view_by_alt_message" => 'Muestra los usuarios que han leído o no los mensajes' + "view_by_alt_message" => 'Muestra los usuarios que han leído o no los mensajes', + "exit_chat" => 'Salir conversación', + "subscribe_chat" => 'Subscribirse al chat', + "exit_chat_ok" => "Ha salido de la conversación correctamente. No recibirá más notificaciones a no ser que sea añadido de nuevo.", + "exit_chat_wrong" => "No puede salir de la conversación porque no pertenece a ella.", + "exit_admin_chat_wrong" => "Perteneces como personal a este chat y no puedes salirte. Contacta administrador para ello.", + "subscribe_chat_ok" => "Te has subscrito al chat correctamente. Ahora recibirás notificaciones cuando lleguen mensajes.", + "subscribe_chat_wrong" => "Ya perteneces a este chat.", + "message_configuration" => "Configuración mensajería", + "new_chat_department" => "Nuevo departamento", + "user_deleted_ok" => "Usuario eliminado con éxito", + "department_users" => "Usuarios departamento", + "subscribe_admin_chat_ok" => "Usuario añadido correctamente.", + "subscribe_admin_chat_wrong" => "Tienes que seleccionar un usuario.", + "help_select_chat_department_user" => "Solamente son listados los usuarios que pertenecen al personal. Los clientes no son listados, para añadirlos a la conversación se realiza desde la sección de mensajería de las diferentes secciones(presupuesto,pedido,factura ...)", + "store_department" => "Crear departamento", + "mail" => [ + "mail_subject" => "Nuevo mensaje" + ] + ]; \ No newline at end of file diff --git a/ci4/app/Models/Chat/ChatDeparmentModel.php b/ci4/app/Models/Chat/ChatDeparmentModel.php index f729ec04..c5d81c87 100644 --- a/ci4/app/Models/Chat/ChatDeparmentModel.php +++ b/ci4/app/Models/Chat/ChatDeparmentModel.php @@ -2,6 +2,7 @@ namespace App\Models\Chat; +use App\Entities\Chat\ChatDepartmentEntity; use App\Models\Usuarios\UserModel; use CodeIgniter\Model; @@ -10,7 +11,7 @@ class ChatDeparmentModel extends Model protected $table = 'chat_departments'; protected $primaryKey = 'id'; protected $useAutoIncrement = true; - protected $returnType = 'object'; + protected $returnType = ChatDepartmentEntity::class; protected $useSoftDeletes = true; protected $protectFields = true; protected $allowedFields = [ @@ -89,7 +90,7 @@ class ChatDeparmentModel extends Model $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'], @@ -105,9 +106,10 @@ class ChatDeparmentModel extends Model } return $departments; } - public function getChatDepartmentUsers(int $chat_deparment_id) + + public function getChatDeparmentUserQuery(int $chat_deparment_id) { - $result = $this->builder() + $query = $this ->select( [ "users.*" @@ -122,27 +124,78 @@ class ChatDeparmentModel extends Model "users", "chat_department_users.user_id = users.id", 'left' - )->where("chat_departments.id", $chat_deparment_id) + ) + ->where("chat_department_users.chat_department_id", $chat_deparment_id) ->where("chat_department_users.deleted_at",null) - ->where("users.deleted_at",null) + ->where("users.deleted_at",null); + return $query; + } + public function getChatDepartmentUsers(int $chat_deparment_id) + { + $result = $this->getChatDeparmentUserQuery($chat_deparment_id) + ->where('chat_department_users.presupuesto_id',null) + ->where('chat_department_users.pedido_id',null) + ->where('chat_department_users.factura_id',null) + ->get(); + + return $result->getResultObject() ?: []; + } + public function getChatDeparmentPresupuestoUsers(int $chat_deparment_id, int $presupuesto_id) + { + $result = $this->getChatDeparmentUserQuery($chat_deparment_id) + ->where('chat_department_users.presupuesto_id', $presupuesto_id) ->get()->getResultObject(); return $result; } - public function getDisplay(int $chat_deparment_id) : string + public function getChatDeparmentPedidoUsers(int $chat_deparment_id, int $pedido_id) + { + $result = $this->getChatDeparmentUserQuery($chat_deparment_id) + ->where('chat_department_users.pedido_id', $pedido_id) + ->get()->getResultObject(); + return $result; + } + public function getChatDeparmentFacturaUsers(int $chat_deparment_id, int $factura_id) + { + $result = $this->getChatDeparmentUserQuery($chat_deparment_id) + ->where('chat_department_users.factura_id', $factura_id) + ->get()->getResultObject(); + return $result; + } + public function getDisplay(int $chat_deparment_id): string { return $this->find($chat_deparment_id)->display; } - public function getChatDepartmentSelect(string $query = null) + public function getChatDepartmentSelect(?string $query) { $q = $this->builder()->select([ "id", "display as name", "description" ]); - if($query){ - $q->orLike("display",$query) - ->orLike("name",$query); + if ($query) { + $q->orLike("display", $query) + ->orLike("name", $query); } return $q; } + public function datatableQuery() + { + return $this->select(['id','display','description'])->where('deleted_at',null); + } + + public function getModelChatDepartments(string $modelFk,int $modelId) : array + { + $query = $this->builder()->select([ + 'chat_departments.id', + 'chat_departments.name', + 'chat_departments.display', + 'COUNT(chat_messages.id) as countMessages' + ]) + ->join('chats','chats.chat_department_id = chat_departments.id','left') + ->join('chat_messages','chat_messages.chat_id = chats.id','left') + ->where($modelFk,$modelId) + ->groupBy('chat_departments.name'); + return $query->get()->getResultArray() ?? []; + + } } diff --git a/ci4/app/Models/Chat/ChatDeparmentUserModel.php b/ci4/app/Models/Chat/ChatDeparmentUserModel.php index 9dbde312..1afdca85 100644 --- a/ci4/app/Models/Chat/ChatDeparmentUserModel.php +++ b/ci4/app/Models/Chat/ChatDeparmentUserModel.php @@ -2,7 +2,8 @@ namespace App\Models\Chat; - +use App\Entities\Chat\ChatDepartmentUserEntity; +use App\Models\Usuarios\UserModel; use CodeIgniter\Model; class ChatDeparmentUserModel extends Model @@ -10,12 +11,15 @@ class ChatDeparmentUserModel extends Model protected $table = 'chat_department_users'; protected $primaryKey = 'id'; protected $useAutoIncrement = true; - protected $returnType = 'array'; + protected $returnType = ChatDepartmentUserEntity::class; protected $useSoftDeletes = true; protected $protectFields = true; protected $allowedFields = [ "chat_department_id", - "user_id" + "user_id", + "pedido_id", + "factura_id", + "presupuesto_id" ]; protected bool $allowEmptyInserts = false; @@ -47,14 +51,58 @@ class ChatDeparmentUserModel extends Model protected $afterFind = []; protected $beforeDelete = []; protected $afterDelete = []; + public function getChatDepartmentUser(int $user_id) { - return $this->db->table($this->table." t1") - ->select("chat_departments.*") - ->join("chat_departments","t1.chat_department_id = chat_departments.id","left") - ->where("t1.user_id",$user_id) - ->where("t1.deleted_at",null) - ->get()->getResultObject(); - + return $this->db->table($this->table . " t1") + ->select("chat_departments.*") + ->join("chat_departments", "t1.chat_department_id = chat_departments.id", "left") + ->where("t1.user_id", $user_id) + ->where("t1.deleted_at", null) + ->get()->getResultObject(); + } + public function datatableQuery(int $chat_department_id) + { + return $this->builder()->select( + [ + 'users.id as userId', + 'CONCAT(users.first_name," ",users.last_name) as userFullName', + 'users.username' + ] + ) + ->join('users', 'users.id = chat_department_users.user_id', 'left') + ->join('chat_departments', 'chat_departments.id = chat_department_users.chat_department_id', 'left') + ->where('chat_departments.id', $chat_department_id) + ->where('chat_department_users.pedido_id', null) + ->where('chat_department_users.presupuesto_id', null) + ->where('chat_department_users.factura_id', null) + ->where('chat_department_users.deleted_at', null); + } + public function querySelectUsersNotInDepartment(int $chat_department_id, ?string $q): array + { + $query = $this->builder()->select([ + 'users.id as userId', + ]) + ->join('users', 'users.id = chat_department_users.user_id', 'left') + ->join('chat_departments', 'chat_departments.id = chat_department_users.chat_department_id', 'left') + ->where('chat_departments.id', $chat_department_id) + ->where('chat_department_users.deleted_at', null); + + $usersInDepartment = array_map(fn($q) => $q->userId, $query->get()->getResultObject()); + $userModel = model(UserModel::class); + $queryUser = $userModel->builder()->select([ + 'id', + 'CONCAT(first_name," ",last_name) as name', + 'username as description', + ]) + ->where('cliente_id',null) + ->where('deleted_at', null); + if ($usersInDepartment) { + $queryUser->whereNotIn("id", $usersInDepartment); + } + if ($q) { + $queryUser->like('CONCAT(first_name," ",last_name)', $q); + } + return $queryUser->get()->getResultArray(); } } diff --git a/ci4/app/Models/Chat/ChatMessageModel.php b/ci4/app/Models/Chat/ChatMessageModel.php index e0ee9a20..5fb01241 100644 --- a/ci4/app/Models/Chat/ChatMessageModel.php +++ b/ci4/app/Models/Chat/ChatMessageModel.php @@ -2,6 +2,7 @@ namespace App\Models\Chat; +use App\Entities\Chat\ChatMessageEntity; use App\Models\ChatNotification; use App\Models\Usuarios\UserModel; use CodeIgniter\Model; @@ -12,7 +13,7 @@ class ChatMessageModel extends Model protected $table = 'chat_messages'; protected $primaryKey = 'id'; protected $useAutoIncrement = true; - protected $returnType = 'object'; + protected $returnType = ChatMessageEntity::class; protected $useSoftDeletes = true; protected $protectFields = true; protected $allowedFields = [ @@ -45,7 +46,7 @@ class ChatMessageModel extends Model // Callbacks protected $allowCallbacks = true; protected $beforeInsert = []; - protected $afterInsert = []; + protected $afterInsert = ['callbackNewMessage']; protected $beforeUpdate = []; protected $afterUpdate = []; protected $beforeFind = []; @@ -82,7 +83,6 @@ class ChatMessageModel extends Model if ($auth_user->id == $message->sender_id) { $message->sender_first_name = $auth_user->first_name; $message->sender_last_name = $auth_user->last_name; - } else { $sender_user = $user->find($message->sender_id); $message->sender_first_name = $sender_user->first_name; @@ -133,10 +133,10 @@ class ChatMessageModel extends Model ->where("receiver_id", auth()->user()->id)->countAllResults(); return $messagesFromReceiver; } - public function get_chat_department_messages_count(int $chat_id) : int + public function get_chat_department_messages_count(int $chat_id): int { $chatDepartmentMessagesCount = $this->builder() - ->where("id",$chat_id) + ->where("id", $chat_id) ->countAllResults(); return $chatDepartmentMessagesCount; } @@ -194,4 +194,46 @@ class ChatMessageModel extends Model return $messagesFromReceiver; } + public function callbackNewMessage(array $data) + { + $authUser = auth()->user(); + $chatNotificationModel = model(ChatNotification::class); + $chatMessageEntity = $this->find($data["id"]); + $chatEntity = $chatMessageEntity->chat(); + if ($chatEntity->chat_department_id) { + $chatDepartmentEntity = $chatEntity->department(); + $adminUsers = $chatDepartmentEntity->chatDepartmentAdminUsers(); + $modelFk = $chatEntity->relatedFk(); + $externalUsers = $chatDepartmentEntity->chatDepartmentExternalUsers($modelFk["relatedFkValue"], $modelFk["relatedModel"]); + if ($modelFk["relatedModel"] && $modelFk["relatedFkValue"]) { + + foreach ($adminUsers as $user) { + if ($user->user_id != $authUser->id) { + $chatNotificationModel->insert([ + "user_id" => $user->user_id, + "chat_message_id" => $data["id"] + ]); + } + } + foreach ($externalUsers as $user) { + if ($user->user_id != $authUser->id) { + $chatNotificationModel->insert([ + "user_id" => $user->user_id, + "chat_message_id" => $data["id"] + ]); + } + } + } + }else{ + foreach ($chatEntity->internalUsers() as $user) { + if ($user->user_id != $authUser->id) { + $chatNotificationModel->insert([ + "user_id" => $user->user_id, + "chat_message_id" => $data["id"] + ]); + } + } + } + return $data; + } } diff --git a/ci4/app/Models/Chat/ChatModel.php b/ci4/app/Models/Chat/ChatModel.php index 4055fca9..3106560f 100644 --- a/ci4/app/Models/Chat/ChatModel.php +++ b/ci4/app/Models/Chat/ChatModel.php @@ -2,6 +2,7 @@ namespace App\Models\Chat; +use App\Entities\Chat\ChatEntity; use App\Models\ChatNotification; use App\Models\ChatUser; use App\Models\Facturas\FacturaModel; @@ -16,7 +17,7 @@ class ChatModel extends Model protected $table = 'chats'; protected $primaryKey = 'id'; protected $useAutoIncrement = true; - protected $returnType = 'object'; + protected $returnType = ChatEntity::class; protected $useSoftDeletes = true; protected $protectFields = true; protected $allowedFields = [ @@ -315,12 +316,6 @@ class ChatModel extends Model } public function getChatDepartmentNotifications() { - $chatDeparmentModel = model(ChatDeparmentModel::class); - $chatMessageModel = model(ChatMessageModel::class); - $presupuestoModel = model(PresupuestoModel::class); - $facturaModel = model(FacturaModel::class); - $pedidoModel = model(PedidoModel::class); - $q = $this->builder() ->select([ "chats.id as chatId", @@ -329,53 +324,43 @@ class ChatModel extends Model "chats.presupuesto_id as presupuestoId", "chats.factura_id as facturaId", "chats.title as chatDisplay", + "COUNT(chat_notifications.id) as unreadMessages" ]) ->join("chat_messages", "chat_messages.chat_id = chats.id", "left") ->join("chat_notifications", "chat_notifications.chat_message_id = chat_messages.id", "left") ->where("chat_notifications.user_id", auth()->user()->id) ->where("chat_notifications.viewed", false) - ->where("chats.chat_department_id is NOT NULL", NULL, FALSE); + ->where("chats.chat_department_id is NOT NULL", NULL, FALSE) + ->groupBy('chats.id'); $rows = $q->get()->getResultObject(); $auth_user = auth()->user(); $rows_new = []; foreach ($rows as $row) { - $row->unreadMessages = 0; if ($row->presupuestoId) { - $row->model = $presupuestoModel->find($row->presupuestoId); + // $row->model = $presupuestoModel->find($row->presupuestoId); if ($auth_user->cliente_id) { $row->uri = "/presupuestocliente/edit/" . $row->presupuestoId . "#accordionChatPresupuesto"; } else { $row->uri = "/presupuestoadmin/edit/" . $row->presupuestoId . "#accordionChatPresupuesto"; } $row->title = $row->presupuestoId; - if ($row->chatDepartmentId) { - $row->chatDisplay = $row->model->titulo; - } else { - $row->chatDisplay .= "[INTERNAL]"; - } + $row->avatar = "PRE"; - $row->unreadMessages = $this->countUnreadMessagePresupuesto($row->presupuestoId); $rows_new[] = $row; } elseif ($row->pedidoId) { - $row->model = $pedidoModel->find($row->pedidoId); + // $row->model = $pedidoModel->find($row->pedidoId); $row->uri = "/pedidos/edit/" . $row->pedidoId . "#accordionChatPedido"; $row->title = $row->pedidoId; - if ($row->chatDepartmentId) { - $row->chatDisplay .= "[INTERNAL]"; - } + $row->avatar = "P"; - $row->unreadMessages = $this->countUnreadMessagePedido($row->pedidoId); $rows_new[] = $row; } elseif ($row->facturaId) { - $row->model = $facturaModel->find($row->facturaId); + // $row->model = $facturaModel->find($row->facturaId); $row->uri = "/chat/factura/" . $row->facturaId . "#accordionChatFactura"; $row->avatar = "F"; - if ($row->chatDepartmentId) { - $row->chatDisplay .= "[INTERNAL]"; - } + $row->title = $row->facturaId; - $row->unreadMessages = $this->countUnreadMessageFactura($row->facturaId); $rows_new[] = $row; } } @@ -383,10 +368,6 @@ class ChatModel extends Model } public function getChatInternalNotifications() { - $presupuestoModel = model(PresupuestoModel::class); - $facturaModel = model(FacturaModel::class); - $pedidoModel = model(PedidoModel::class); - $q = $this->builder() ->select([ "chats.id as chatId", @@ -395,52 +376,41 @@ class ChatModel extends Model "chats.presupuesto_id as presupuestoId", "chats.factura_id as facturaId", "chats.title as chatDisplay", + "COUNT(chat_messages.id) as unreadMessages" + ]) ->join("chat_messages", "chat_messages.chat_id = chats.id", "left") ->join("chat_notifications", "chat_notifications.chat_message_id = chat_messages.id", "left") ->where("chat_notifications.user_id", auth()->user()->id) ->where("chat_notifications.viewed", false) - ->where("chats.chat_department_id", null); + ->where("chats.chat_department_id", null) + ->groupBy('chats.id'); + $auth_user = auth()->user(); $rows = $q->get()->getResultObject(); $rows_new = []; foreach ($rows as $row) { - $row->unreadMessages = 0; if ($row->presupuestoId) { - $row->model = $presupuestoModel->find($row->presupuestoId); if ($auth_user->cliente_id) { $row->uri = "/presupuestocliente/edit/" . $row->presupuestoId . "#accordionChatPresupuesto"; } else { $row->uri = "/presupuestoadmin/edit/" . $row->presupuestoId . "#accordionChatPresupuesto"; } $row->title = $row->presupuestoId; - if ($row->chatDepartmentId) { - $row->chatDisplay = $row->model->titulo; - } else { - $row->chatDisplay .= "[INTERNAL]"; - } + $row->chatDisplay .= "[INTERNAL]"; $row->avatar = "PRE"; - $row->unreadMessages = $this->countUnreadMessagePresupuesto($row->presupuestoId); $rows_new[] = $row; } elseif ($row->pedidoId) { - $row->model = $pedidoModel->find($row->pedidoId); $row->uri = "/pedidos/edit/" . $row->pedidoId . "#accordionChatFactura"; $row->title = $row->pedidoId; - if ($row->chatDepartmentId) { - $row->chatDisplay .= "[INTERNAL]"; - } + $row->chatDisplay .= "[INTERNAL]"; $row->avatar = "P"; - $row->unreadMessages = $this->countUnreadMessagePedido($row->pedidoId); $rows_new[] = $row; } elseif ($row->facturaId) { - $row->model = $facturaModel->find($row->facturaId); $row->uri = "/factura/edit/" . $row->facturaId . "#accordionChatFactura"; $row->avatar = "F"; - if ($row->chatDepartmentId) { - $row->chatDisplay .= "[INTERNAL]"; - } + $row->chatDisplay .= "[INTERNAL]"; $row->title = $row->facturaId; - $row->unreadMessages = $this->countUnreadMessageFactura($row->facturaId); $rows_new[] = $row; } } @@ -587,7 +557,7 @@ class ChatModel extends Model } return $data; } - public function countUnreadMessagePresupuesto($presupuesto_id): int|string + public function countUnreadMessagePresupuesto(int $presupuesto_id): int|string { return $this->builder()->select() ->join("chat_messages", "chat_messages.chat_id = chats.id", "left") @@ -676,6 +646,7 @@ class ChatModel extends Model ->orderBy("chat_messages.created_at", 'ASC'); return $q->get()->getFirstRow(); } + /** * Check if all messages of a chat sent to an user have been viewed. * @@ -683,13 +654,12 @@ class ChatModel extends Model * @param integer $user_id * @return boolean True : All messages readed */ - public function isMessageChatViewed(int $chat_id, int $user_id): bool + public function isMessageChatViewed(int $chat_message_id): bool { - $q = $this->builder()->select(["chat_notifications.id"]) + $q = $this->builder()->select(["chat_notifications.id as cnId"]) ->join("chat_messages", "chat_messages.chat_id = chats.id", 'left') ->join("chat_notifications", "chat_notifications.chat_message_id = chat_messages.id", 'left') - ->where("chats.id", $chat_id) - // ->where("chat_notifications.user_id", $user_id) + ->where("chat_messages.id", $chat_message_id) ->where("chat_notifications.viewed", false); $unread_messages_count = $q->countAllResults(); if ($unread_messages_count > 0) { @@ -705,26 +675,43 @@ class ChatModel extends Model * @param integer $chat_id * @return array True : All messages readed */ - public function getUsersNotificationNotViewedFromChat(int $chat_id): array + public function getUsersNotificationNotViewedFromChat(int $chat_message_id): array { $q = $this->builder()->distinct()->select( [ "CONCAT(users.first_name,' ',users.last_name) as userFullName", "users.username as userName", - "SUM(chat_notifications.viewed) as viewed_count", - "COUNT(chat_notifications.id) as notification_count" - + "chat_notifications.viewed" ] ) ->join("chat_messages", "chat_messages.chat_id = chats.id", 'left') ->join("chat_notifications", "chat_notifications.chat_message_id = chat_messages.id", 'left') ->join("users", "users.id = chat_notifications.user_id", 'left') - ->where("chats.id", $chat_id) + ->where("chat_messages.id", $chat_message_id) ->where("chat_notifications.deleted_at", null) ->get()->getResultArray(); return $q; } + public function getUsersNotificationViewedFromChat(int $chat_message_id): array + { + $q = $this->builder()->distinct()->select( + [ + "CONCAT(users.first_name,' ',users.last_name) as userFullName", + "users.username as userName", + "chat_notifications.viewed" + ] + + ) + ->join("chat_messages", "chat_messages.chat_id = chats.id", 'left') + ->join("chat_notifications", "chat_notifications.chat_message_id = chat_messages.id", 'left') + ->join("users", "users.id = chat_notifications.user_id", 'left') + ->where("chat_messages.id", $chat_message_id) + ->where("chat_notifications.deleted_at", null) + ->where('chat_notifications.viewed', true) + ->get()->getResultArray(); + return $q; + } public function getQueryDatatable(int $user_id): BaseBuilder { $query = $this->builder() @@ -755,78 +742,93 @@ class ChatModel extends Model $query = $this->builder() ->select([ "chats.id", + "cm.id as chatMessageId", + "u.id as userId", + "cm.message", "chats.created_at", - "cm.updated_at", - "chats.title", + " + ( + SELECT cm2.updated_at + FROM chat_messages cm2 + WHERE cm2.chat_id = chats.id + ORDER BY cm2.updated_at DESC LIMIT 1 + ) as updated_at", + "CONCAT(u.first_name,' ',u.last_name) as creator", + "CONCAT('[',chats.title,']',' ',presupuestos.titulo) as title", ]) - ->join("chat_users", "chats.id = chat_users.chat_id", "left") ->join("presupuestos", "presupuestos.id = chats.presupuesto_id", 'left') ->join("chat_messages cm", "chats.id = cm.chat_id", "left") - ->where("chats.presupuesto_id is NOT NULL", NULL, FALSE) - ->where("cm.updated_at = ( - SELECT cm2.updated_at - FROM chat_messages cm2 - WHERE cm2.chat_id = chats.id - ORDER BY cm2.updated_at DESC LIMIT 1 - )"); + ->join("users u", "u.id = cm.sender_id", 'left') + ->where("chats.presupuesto_id is NOT NULL", NULL, FALSE); + if (auth()->user()->inGroup("admin") == false) { $query->where('presupuestos.cliente_id', auth()->user()->cliente_id) - ->where("chat_department_id is NOT NULL", NULL, FALSE); + ->where("chats.chat_department_id is NOT NULL", NULL, FALSE); } - return $query; + return $query->groupBy('chatMessageId'); } public function getQueryDatatableMessagePedido(int $user_id): BaseBuilder { $query = $this->builder() ->select([ "chats.id", + "cm.id as chatMessageId", + "u.id as userId", + "cm.message", "chats.created_at", - "cm.updated_at", - "chats.title", - ]) - ->join("chat_users", "chat_users.chat_id = chats.id", "left") - ->join("pedidos_linea", "pedidos_linea.pedido_id = chats.pedido_id", 'left') - ->join("chat_messages cm", "chats.id = cm.chat_id", "left") - ->join("presupuestos", "presupuestos.id = pedidos_linea.presupuesto_id", 'left') - ->where("chats.pedido_id is NOT NULL", NULL, FALSE) - ->where("cm.updated_at = ( + " + ( SELECT cm2.updated_at FROM chat_messages cm2 WHERE cm2.chat_id = chats.id ORDER BY cm2.updated_at DESC LIMIT 1 - )"); + ) as updated_at", + "CONCAT(u.first_name,' ',u.last_name) as creator", + "CONCAT('[',chats.title,']',' ',presupuestos.titulo) as title", + ]) + ->join("pedidos_linea", "pedidos_linea.pedido_id = chats.pedido_id", 'left') + ->join("chat_messages cm", "chats.id = cm.chat_id", "left") + ->join("users u", "u.id = cm.sender_id", 'left') + ->join("presupuestos", "presupuestos.id = pedidos_linea.presupuesto_id", 'left') + ->where("chats.pedido_id is NOT NULL", NULL, FALSE); + if (auth()->user()->inGroup("admin") == false) { $query->where('presupuestos.cliente_id', auth()->user()->cliente_id) - ->where("chat_department_id is NOT NULL", NULL, FALSE); + ->where("chats.chat_department_id is NOT NULL", NULL, FALSE); } - return $query; + return $query->groupBy('chatMessageId'); } public function getQueryDatatableMessageFactura(int $user_id): BaseBuilder { $query = $this->builder() ->select([ "chats.id", + "cm.id as chatMessageId", + "u.id as userId", + "cm.message", "chats.created_at", - "cm.updated_at", - "chats.title", - ]) - ->join("chat_users", "chat_users.chat_id = chats.id", "left") - ->join("chat_messages cm", "chats.id = cm.chat_id", "left") - ->join("facturas", "facturas.id = chats.factura_id", "left") - ->where("chats.factura_id is NOT NULL", NULL, FALSE) - ->where("cm.updated_at = ( + " + ( SELECT cm2.updated_at FROM chat_messages cm2 WHERE cm2.chat_id = chats.id ORDER BY cm2.updated_at DESC LIMIT 1 - )"); + ) as updated_at", + "CONCAT(u.first_name,' ',u.last_name) as creator", + "chats.title", + ]) + ->join("chat_messages cm", "chats.id = cm.chat_id", "left") + ->join("users u", "u.id = cm.sender_id", 'left') + ->join("facturas", "facturas.id = chats.factura_id", "left") + ->where("chats.factura_id is NOT NULL", NULL, FALSE); + if (auth()->user()->inGroup("admin") == false) { if (auth()->user()->inGroup("admin") == false) { $query->where('facturas.cliente_id', auth()->user()->cliente_id) - ->where("chat_department_id is NOT NULL", NULL, FALSE); + ->where("chats.chat_department_id is NOT NULL", NULL, FALSE); } } - return $query; + return $query->groupBy('chatMessageId'); } public function createNewDirectChat(string $title, string $message, array $users) { @@ -903,16 +905,17 @@ class ChatModel extends Model public function setAsViewedChatUserNotifications(int $chat_id, int $user_id) { $query = $this->builder() - ->select("chat_messages.id") + ->select("chat_notifications.id as notificationId") ->join('chat_messages', 'chat_messages.chat_id = chats.id', 'left') + ->join('chat_notifications', 'chat_notifications.chat_message_id = chat_messages.id', 'left') + ->where('chat_notifications.user_id', $user_id) ->where('chat_messages.chat_id', $chat_id) ->get()->getResultObject(); - $chat_messages_ids = array_map(fn($q) => $q->id, $query); - - $this->db->table("chat_notifications") - ->where("user_id", $user_id) - ->whereIn("chat_message_id", $chat_messages_ids) - ->update(["viewed" => true]); + $chat_messages_ids = array_map(fn($q) => $q->notificationId, $query); + $chatNotificationModel = model(ChatNotification::class); + if ($chat_messages_ids) { + $chatNotificationModel->setNotificationsAsViewed($chat_messages_ids); + } } public function setAsViewedChatUserMessages(int $chat_id, int $user_id) { @@ -924,16 +927,17 @@ class ChatModel extends Model public function setAsUnviewedChatUserNotifications(int $chat_id, int $user_id) { $query = $this->builder() - ->select("chat_messages.id") + ->select("chat_notifications.id as notificationId") ->join('chat_messages', 'chat_messages.chat_id = chats.id', 'left') + ->join('chat_notifications', 'chat_notifications.chat_message_id = chat_messages.id', 'left') + ->where('chat_notifications.user_id', $user_id) ->where('chat_messages.chat_id', $chat_id) ->get()->getResultObject(); - $chat_messages_ids = array_map(fn($q) => $q->id, $query); - - $this->db->table("chat_notifications") - ->where("user_id", $user_id) - ->whereIn("chat_message_id", $chat_messages_ids) - ->update(["viewed" => false]); + $chat_messages_ids = array_map(fn($q) => $q->notificationId, $query); + $chatNotificationModel = model(ChatNotification::class); + if ($chat_messages_ids) { + $chatNotificationModel->setNotificationsAsUnViewed($chat_messages_ids); + } } public function setAsUnviewedChatUserMessages(int $chat_id, int $user_id) diff --git a/ci4/app/Models/ChatNotification.php b/ci4/app/Models/ChatNotification.php index 007f26c5..aa1e0a28 100644 --- a/ci4/app/Models/ChatNotification.php +++ b/ci4/app/Models/ChatNotification.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Entities\Chat\ChatNotificationEntity; use CodeIgniter\Model; class ChatNotification extends Model @@ -9,7 +10,7 @@ class ChatNotification extends Model protected $table = 'chat_notifications'; protected $primaryKey = 'id'; protected $useAutoIncrement = true; - protected $returnType = 'array'; + protected $returnType = ChatNotificationEntity::class; protected $useSoftDeletes = false; protected $protectFields = true; protected $allowedFields = [ @@ -59,4 +60,12 @@ class ChatNotification extends Model } return $status; } + public function setNotificationsAsViewed(array $notificationIds) : bool + { + return $this->update($notificationIds,["viewed" => 1]); + } + public function setNotificationsAsUnViewed(array $notificationIds) : bool + { + return $this->update($notificationIds,["viewed" => 0]); + } } diff --git a/ci4/app/Models/ChatUser.php b/ci4/app/Models/ChatUser.php index f51f989f..b6355a53 100644 --- a/ci4/app/Models/ChatUser.php +++ b/ci4/app/Models/ChatUser.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Entities\Chat\ChatUserEntity; use CodeIgniter\Model; class ChatUser extends Model @@ -9,7 +10,7 @@ class ChatUser extends Model protected $table = 'chat_users'; protected $primaryKey = 'id'; protected $useAutoIncrement = true; - protected $returnType = 'array'; + protected $returnType = ChatUserEntity::class; protected $useSoftDeletes = true; protected $protectFields = true; protected $allowedFields = [ diff --git a/ci4/app/Services/ChatService.php b/ci4/app/Services/ChatService.php new file mode 100644 index 00000000..d5d8f9fb --- /dev/null +++ b/ci4/app/Services/ChatService.php @@ -0,0 +1,195 @@ + "presupuesto_id", + "pedido" => "pedido_id", + "factura" => "factura_id", + ]; + protected array $modelClassMap; + public function __construct() + { + $this->emailService = service('email'); + $this->userModel = model(UserModel::class); + $this->chatModel = model(ChatModel::class); + $this->chatMessageModel = model(ChatMessageModel::class); + $this->chatNotificationModel = model(ChatNotification::class); + $this->chatDepartmentUserModel = model(ChatDeparmentUserModel::class); + $this->chatUserModel = model(ChatUser::class); + $this->presupuestoModel = model(PresupuestoModel::class); + $this->chatDepartmentModel = model(ChatDeparmentModel::class); + $this->configVariables = model(ConfigVariableModel::class); + } + public function setChat($chatEntity): self + { + $this->chatEntity = $chatEntity; + return $this; + } + public function storeChatMessage(string $chatDepartmentId, string $model, int $modelId, array $data): ?ChatMessageEntity + { + $this->chatEntity = $this->chatModel->where('chat_department_id', $chatDepartmentId)->where($this->modelFkMap[$model], $modelId)->first(); + if ($this->chatEntity == null) { + $chatId = $this->createChat($chatDepartmentId, $model, $modelId); + $this->chatEntity = $this->chatModel->find($chatId); + } + if ($data["client"]) { + $cliente_in_department = $this->chatDepartmentUserModel + ->where('chat_department_id', $chatDepartmentId) + ->where('user_id', $data['client']) + ->where($this->modelFkMap[$model], $modelId) + ->first(); + if ($cliente_in_department == null) { + $this->chatDepartmentUserModel->insert(['chat_department_id' => $chatDepartmentId, 'user_id' => $data['client'], $this->modelFkMap[$model] => $modelId]); + } + } + $userAdminDepartment = $this->chatDepartmentUserModel + ->where('chat_department_id', $data["chat_department_id"]) + ->where('user_id', auth()->user()->id) + ->where("pedido_id", null) + ->where("factura_id", null) + ->where("presupuesto_id", null) + ->first(); + $userAlreadyInDepartment = $this->chatDepartmentUserModel + ->where('chat_department_id', $data["chat_department_id"]) + ->where('user_id', auth()->user()->id) + ->where($this->modelFkMap[$model], $modelId) + ->first(); + if ($userAdminDepartment == null && $userAlreadyInDepartment == null) { + $this->chatDepartmentUserModel->insert(['chat_department_id' => $data["chat_department_id"], $this->modelFkMap[$model] => $modelId, 'user_id' => auth()->user()->id]); + } + $chat_message_id = $this->chatMessageModel->insert(["chat_id" => $this->chatEntity->id, "sender_id" => auth()->user()->id, "message" => $data["message"]]); + $chatMessageEntity = $this->chatMessageModel->find($chat_message_id); + if ($data["client"]) { + $userClient = $this->userModel->find($data['client']); + if ($userClient) { + $this->sendMessageNotificationEmail($chatMessageEntity, $userClient); + } + } + return $chatMessageEntity; + } + public function createChat(int $chatDepartmentId, string $model, int $modelId): bool|int|string + { + $r = false; + switch ($model) { + case 'presupuesto': + $r = $this->chatModel->createChatPresupuesto($chatDepartmentId, $modelId); + break; + case 'pedido': + $r = $this->chatModel->createChatPedido($chatDepartmentId, $modelId); + break; + case 'factura': + $r = $this->chatModel->createChatFactura($chatDepartmentId, $modelId); + break; + default: + break; + } + return $r; + } + + public function getChatDepartments(string $model, int $modelId): array + { + $chatDepartments = $this->chatDepartmentModel->getModelChatDepartments($this->modelFkMap[$model], $modelId); + $departmentWithChat = array_map(fn($q) => $q["name"], $chatDepartments); + if (count($departmentWithChat) > 0) { + $departmentWithoutChat = $this->chatDepartmentModel->whereNotIn('name', $departmentWithChat)->findAll(); + } else { + $departmentWithoutChat = $this->chatDepartmentModel->findAll(); + } + foreach ($departmentWithoutChat as $value) { + $d = []; + $d["id"] = $value->id; + $d["name"] = $value->name; + $d["display"] = $value->display; + $d["countMessages"] = "0"; + $chatDepartments[] = $d; + } + return $chatDepartments; + } + + public function storeHebra(string $model, int $modelId, array $data): bool + { + $auth_user = auth()->user(); + $chatId = $this->chatModel->insert([$this->modelFkMap[$model] => $modelId, 'title' => $data['title']]); + + if (isset($data["users"])) { + $data["users"][] = $auth_user->id; + $chatUserData = array_map(fn($x) => ["user_id" => $x, "chat_id" => $chatId], $data["users"]); + $this->chatUserModel->insertBatch($chatUserData); + } + $this->chatMessageModel->insert( + [ + 'chat_id' => $chatId, + 'message' => $data['message'], + 'sender_id' => $auth_user->id + ] + ); + return true; + } + public function getHebras(string $model, int $modelId): array + { + $chats = $this->chatModel->where('chat_department_id', null) + ->where($this->modelFkMap[$model], $modelId) + ->findAll(); + foreach ($chats as $c) { + $this->chatModel->setAsViewedChatUserNotifications($c->id, auth()->user()->id); + } + $chatWithHebraData = array_map(fn(ChatEntity $c) => $c->withHebra(), $chats); + return $chatWithHebraData ?? []; + } + public function getAuthUserNotifications(): array + { + $departmentNotifications = $this->chatModel->getChatDepartmentNotifications(); + $internalNotifications = $this->chatModel->getChatInternalNotifications(); + $totalMessages = 0; + $countNotificiationDepartments = array_map(fn($n) => $n->unreadMessages, $departmentNotifications); + $countNotificationInternal = array_map(fn($n) => $n->unreadMessages, $internalNotifications); + $totalMessages = array_sum($countNotificiationDepartments) + array_sum($countNotificationInternal); + + return [ + "departmentNotifications" => $departmentNotifications, + "internalNotifications" => $internalNotifications, + "totalMessages" => $totalMessages + ]; + } + public function sendMessageNotificationEmail(ChatMessageEntity $chatMessageEntity, UserEntity $user): bool + { + $users = auth()->getProvider(); + $toEmail = $users->find($user->id)->getEmail(); + $this->emailService->setTo($toEmail); + $subject = '[Safekat]' . lang('Chat.mail.mail_subject') . '-' . $chatMessageEntity->chat()->title; + $this->emailService->setSubject($subject); + $this->emailService->setMessage(view('themes/vuexy/mail/messageNotification', ["header" => lang('Chat.mail.mail_subject'), "data" => $chatMessageEntity->withUser()])); + return $this->emailService->send(); + } +} diff --git a/ci4/app/Views/themes/vuexy/components/chat_factura.php b/ci4/app/Views/themes/vuexy/components/chat_factura.php index be1ebf0b..df2495c1 100644 --- a/ci4/app/Views/themes/vuexy/components/chat_factura.php +++ b/ci4/app/Views/themes/vuexy/components/chat_factura.php @@ -1,9 +1,5 @@
-user()->inGroup('admin')) { ?> -
- -
- +
@@ -30,12 +26,17 @@