first commit
This commit is contained in:
@@ -0,0 +1,504 @@
|
||||
import UsersManager from "../Users/Users";
|
||||
import CompaniesManager from "../Companies/Companies";
|
||||
import {
|
||||
ConvertU2UMessageConversationParams,
|
||||
CountUnreadConversationParams,
|
||||
CreateMessageConversationParams,
|
||||
DeleteConversationsByCompanyParams,
|
||||
DeleteConversationsByUserParams,
|
||||
DeleteMessageConversationParams,
|
||||
FindConversationItem,
|
||||
FindConversationsResults,
|
||||
IMessageConversation,
|
||||
IMessageConversationsManager,
|
||||
MarkConversationAsReadParams,
|
||||
MESSAGE_CONVERSATION_TYPES,
|
||||
PaginateFindContactsParams,
|
||||
PaginateFindContactsResults,
|
||||
PaginateMessageConversationsParams,
|
||||
PaginateMessageConversationsResults,
|
||||
} from "./MessagesConversations.Interface";
|
||||
import { MessageConversationsAdapterMongoose } from "./MessagesConversations.Adapter.Mongoose";
|
||||
import EmployeesList from "../Employees/Employee";
|
||||
import ClientsList from "../Clients/Clients";
|
||||
import getAvatar from "../../helpers/getAvatar";
|
||||
import UserList from "../Users/Users";
|
||||
import MessagesList from "../Messages/Messages";
|
||||
import { isNull } from "../../helpers/IsNull";
|
||||
import SystemNoficationsList from "../SystemNotifications/SystemNotification";
|
||||
import mongoose from "mongoose";
|
||||
|
||||
type GetConversationParams = {
|
||||
userId: string;
|
||||
};
|
||||
|
||||
class MessageConversationsManager implements IMessageConversationsManager {
|
||||
conversations: MessageConversationsAdapterMongoose;
|
||||
|
||||
constructor() {
|
||||
this.conversations = new MessageConversationsAdapterMongoose();
|
||||
}
|
||||
|
||||
public async deleteConversationsByUser(data: DeleteConversationsByUserParams): Promise<void> {
|
||||
const conversationsFrom = await this.conversations.find({ userIdFrom: data.userId });
|
||||
|
||||
for (const conv of conversationsFrom) {
|
||||
await MessagesList.messages.messageList.deleteMany({ conversationId: conv.id });
|
||||
}
|
||||
|
||||
const conversationsTo = await this.conversations.find({ userIdTo: data.userId });
|
||||
|
||||
for (const conv of conversationsTo) {
|
||||
await MessagesList.messages.messageList.deleteMany({ conversationId: conv.id });
|
||||
}
|
||||
|
||||
await this.conversations.conversationList.deleteMany({ userIdFrom: data.userId });
|
||||
await this.conversations.conversationList.deleteMany({ userIdTo: data.userId });
|
||||
}
|
||||
|
||||
public async deleteConversationsByCompany(
|
||||
data: DeleteConversationsByCompanyParams
|
||||
): Promise<void> {
|
||||
const conversations = await this.conversations.find({ companyId: data.companyId });
|
||||
|
||||
for (const conv of conversations) {
|
||||
await MessagesList.messages.messageList.deleteMany({ conversationId: conv.id });
|
||||
}
|
||||
|
||||
await this.conversations.conversationList.deleteMany({ companyId: data.companyId });
|
||||
}
|
||||
|
||||
public async createConversation(
|
||||
data: CreateMessageConversationParams
|
||||
): Promise<IMessageConversation> {
|
||||
if (data.userIdFrom) {
|
||||
const userFromCheck = await UsersManager.users.findOne({ _id: data.userIdFrom });
|
||||
if (!userFromCheck) {
|
||||
throw new Error("Usuario invalido");
|
||||
}
|
||||
}
|
||||
|
||||
if (data.userIdTo) {
|
||||
const userToCheck = await UsersManager.users.findOne({ _id: data.userIdTo });
|
||||
if (!userToCheck) {
|
||||
throw new Error("Usuario invalido");
|
||||
}
|
||||
}
|
||||
|
||||
if (data.companyId) {
|
||||
const companyCheck = await CompaniesManager.companies.findOne({ _id: data.companyId });
|
||||
|
||||
if (!companyCheck) {
|
||||
throw new Error("La compañia no existe");
|
||||
}
|
||||
}
|
||||
|
||||
const newConversation = await this.conversations.create(data);
|
||||
|
||||
return newConversation;
|
||||
}
|
||||
|
||||
public async deleteConversation(data: DeleteMessageConversationParams): Promise<void> {
|
||||
const checkUser = await UsersManager.users.findOne({ _id: data.sessionUser });
|
||||
if (!checkUser) {
|
||||
throw new Error("Usuario invalido");
|
||||
}
|
||||
|
||||
const checkConversation = await this.conversations.conversationList.findOne({
|
||||
_id: data.id,
|
||||
});
|
||||
|
||||
if (!checkConversation) {
|
||||
throw new Error("Conversacion invalida");
|
||||
}
|
||||
|
||||
if (checkConversation.type == MESSAGE_CONVERSATION_TYPES.USER_TO_USER) {
|
||||
if (String(checkConversation.userIdFrom) !== data.sessionUser) {
|
||||
throw new Error("No tienes permiso para eliminar esta conversacion");
|
||||
}
|
||||
} else if (checkConversation.type == MESSAGE_CONVERSATION_TYPES.USER_TO_ORG) {
|
||||
if (String(checkConversation.userIdFrom) !== data.sessionUser) {
|
||||
throw new Error("No tienes permiso para eliminar esta conversacion");
|
||||
}
|
||||
}
|
||||
|
||||
await this.conversations.delete(data.id);
|
||||
}
|
||||
|
||||
public async paginateConversations(
|
||||
filters: PaginateMessageConversationsParams
|
||||
): Promise<PaginateMessageConversationsResults> {
|
||||
return await this.conversations.paginate(filters);
|
||||
}
|
||||
|
||||
private async getUserRelationWithMe(userId: string, sessionUser: string): Promise<string> {
|
||||
const myOrgs = await EmployeesList.employees.find({ userId: sessionUser });
|
||||
|
||||
for (const org of myOrgs) {
|
||||
const organization = await CompaniesManager.companies.findOne({ _id: org.companyId });
|
||||
|
||||
if (!organization) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Buscamos si es un colaborador en una de mis organizaciones.
|
||||
|
||||
const employee = await EmployeesList.employees.findOne({
|
||||
userId,
|
||||
companyId: org.companyId,
|
||||
});
|
||||
|
||||
if (employee) {
|
||||
return "Colaborador en " + organization.name;
|
||||
}
|
||||
|
||||
//Buscamos si es un cliente en una de mis organizaciones.
|
||||
|
||||
const client = await ClientsList.clients.findOne({
|
||||
userId: userId,
|
||||
companyId: org.companyId,
|
||||
});
|
||||
|
||||
if (client) {
|
||||
return "Cliente de " + organization.name;
|
||||
}
|
||||
}
|
||||
|
||||
const orgsAsClient = await ClientsList.clients.find({
|
||||
userId: sessionUser,
|
||||
});
|
||||
|
||||
for (const organization of orgsAsClient) {
|
||||
const checkColaIsCollaborator = await EmployeesList.employees.findOne({
|
||||
companyId: organization.companyId,
|
||||
userId: userId,
|
||||
});
|
||||
|
||||
if (checkColaIsCollaborator) {
|
||||
const org = await CompaniesManager.companies.findOne({
|
||||
_id: organization.companyId,
|
||||
});
|
||||
if (!org) {
|
||||
continue;
|
||||
}
|
||||
return "Miembro de " + org.name;
|
||||
}
|
||||
}
|
||||
|
||||
return "Otros contactos";
|
||||
}
|
||||
|
||||
public async findConversations(
|
||||
data: PaginateFindContactsParams
|
||||
): Promise<FindConversationsResults> {
|
||||
const items: FindConversationItem[] = [];
|
||||
const conversations = await this.conversations.paginate(data);
|
||||
|
||||
for (const conversation of conversations.data) {
|
||||
let contactName = "";
|
||||
let contactUserId: string | undefined = "";
|
||||
let contactAvatar: string = "";
|
||||
let conversationName = "";
|
||||
let conversationDescription = "";
|
||||
let conversationImage = "";
|
||||
|
||||
if (conversation.type == MESSAGE_CONVERSATION_TYPES.USER_TO_USER) {
|
||||
if (conversation.userIdFrom == data.sessionUser) {
|
||||
const user = await UserList.users.findOne({ _id: conversation.userIdTo });
|
||||
if (!user) {
|
||||
continue;
|
||||
}
|
||||
contactName = UserList.getUserFullName(user);
|
||||
contactUserId = String(conversation.userIdTo);
|
||||
contactAvatar = user.avatar ? user.avatar : "";
|
||||
} else if (conversation.userIdTo == data.sessionUser) {
|
||||
const user = await UserList.users.findOne({ _id: conversation.userIdFrom });
|
||||
if (!user) {
|
||||
continue;
|
||||
}
|
||||
contactName = UserList.getUserFullName(user);
|
||||
contactUserId = String(conversation.userIdFrom);
|
||||
contactAvatar = user.avatar ? user.avatar : "";
|
||||
}
|
||||
|
||||
if (contactUserId) {
|
||||
conversationName = contactName;
|
||||
conversationDescription = await this.getUserRelationWithMe(
|
||||
contactUserId,
|
||||
data.sessionUser
|
||||
);
|
||||
conversationImage = getAvatar(contactUserId, contactAvatar, contactName);
|
||||
}
|
||||
} else if (conversation.type == MESSAGE_CONVERSATION_TYPES.USER_TO_ORG) {
|
||||
if (conversation.userIdFrom == data.sessionUser) {
|
||||
const org = await CompaniesManager.companies.findOne({
|
||||
_id: conversation.companyId,
|
||||
});
|
||||
if (!org) {
|
||||
continue;
|
||||
}
|
||||
conversationName = org.name;
|
||||
conversationDescription = org.description;
|
||||
conversationImage = isNull<string>(org.iconFile, org.name);
|
||||
} else if (conversation.companyId) {
|
||||
const user = await UserList.users.findOne({ _id: conversation.userIdFrom });
|
||||
if (!user) {
|
||||
continue;
|
||||
}
|
||||
conversationName = UserList.getUserFullName(user);
|
||||
conversationDescription = "Consulta a la organización";
|
||||
conversationImage = getAvatar(user.id, user.avatar, conversationName);
|
||||
}
|
||||
}
|
||||
|
||||
let unreadCount = 0;
|
||||
|
||||
if (conversation && conversation.id) {
|
||||
unreadCount = await this.countUnreadMessages({
|
||||
conversationId: conversation.id,
|
||||
sessionUser: data.sessionUser,
|
||||
});
|
||||
}
|
||||
|
||||
items.push({
|
||||
conversation: {
|
||||
id: conversation.id,
|
||||
userIdFrom: conversation.userIdFrom,
|
||||
userIdTo: conversation.userIdTo,
|
||||
companyId: conversation.companyId,
|
||||
type: conversation.type,
|
||||
newMessages: unreadCount,
|
||||
},
|
||||
name: conversationName,
|
||||
description: conversationDescription,
|
||||
image: conversationImage,
|
||||
orderWeight: 1,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
data: items,
|
||||
page: conversations.page,
|
||||
pages: conversations.pages,
|
||||
} as FindConversationsResults;
|
||||
}
|
||||
|
||||
private async getConversationIfExists(
|
||||
data: GetConversationParams
|
||||
): Promise<IMessageConversation | null> {
|
||||
let conversation = await this.conversations.conversationList.findOne({
|
||||
userIdFrom: data.userId,
|
||||
});
|
||||
|
||||
if (!conversation) {
|
||||
conversation = await this.conversations.conversationList.findOne({
|
||||
userIdTo: data.userId,
|
||||
});
|
||||
}
|
||||
|
||||
return conversation;
|
||||
}
|
||||
|
||||
public async paginateFindContacts(
|
||||
data: PaginateFindContactsParams
|
||||
): Promise<PaginateFindContactsResults> {
|
||||
const items: FindConversationItem[] = [];
|
||||
|
||||
//Mostrar las organizaciones en las que el usuario es cliente.
|
||||
const companiesAsClient = await CompaniesManager.getByClientId({
|
||||
clientId: data.sessionUser,
|
||||
sessionUser: data.sessionUser,
|
||||
});
|
||||
|
||||
for (const org of companiesAsClient) {
|
||||
items.push({
|
||||
conversation: {
|
||||
companyId: org.id,
|
||||
type: MESSAGE_CONVERSATION_TYPES.USER_TO_ORG,
|
||||
newMessages: 0,
|
||||
},
|
||||
name: org.name,
|
||||
description: org.description,
|
||||
image: org.logoFile,
|
||||
orderWeight: 1,
|
||||
});
|
||||
|
||||
//Mostrar los colaboradores de esa organizacion.
|
||||
const employeesByOrganization = await EmployeesList.findByCompanyId({
|
||||
companyId: org.id,
|
||||
});
|
||||
|
||||
for (const employee of employeesByOrganization) {
|
||||
const conversation = await this.getConversationIfExists({
|
||||
userId: employee.userId,
|
||||
});
|
||||
|
||||
let unreadCount = 0;
|
||||
|
||||
if (conversation && conversation.id) {
|
||||
unreadCount = await this.countUnreadMessages({
|
||||
conversationId: conversation.id,
|
||||
sessionUser: data.sessionUser,
|
||||
});
|
||||
}
|
||||
|
||||
items.push({
|
||||
conversation: conversation
|
||||
? ({
|
||||
id: conversation.id,
|
||||
userIdFrom: conversation.userIdFrom,
|
||||
userIdTo: conversation.userIdTo,
|
||||
companyId: conversation.companyId,
|
||||
type: conversation.type,
|
||||
newMessages: unreadCount,
|
||||
} as IMessageConversation)
|
||||
: {
|
||||
userIdTo: employee.userId,
|
||||
type: MESSAGE_CONVERSATION_TYPES.USER_TO_USER,
|
||||
newMessages: 0,
|
||||
},
|
||||
name: employee.fullName,
|
||||
description: org.name,
|
||||
image: employee.avatar,
|
||||
orderWeight: 2,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//Mostras los clientes y colaboradores de las organizaciones donde el usuario es colaborador.
|
||||
const companiesAsCollaborator = await EmployeesList.employees.find({
|
||||
userId: data.sessionUser,
|
||||
});
|
||||
|
||||
for (const org of companiesAsCollaborator) {
|
||||
const organization = await CompaniesManager.companies.findOne({ _id: org.companyId });
|
||||
|
||||
if (!organization) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Mostras los clientes de las organizaciones donde el usuario es colaborador.
|
||||
const organizationClients = await ClientsList.clients.find({
|
||||
companyId: org.companyId,
|
||||
});
|
||||
|
||||
for (const client of organizationClients) {
|
||||
if (!client.userId) {
|
||||
continue;
|
||||
}
|
||||
const clientName = ClientsList.getClientFullName(client);
|
||||
items.push({
|
||||
conversation: {
|
||||
userIdFrom: data.sessionUser,
|
||||
userIdTo: client.userId,
|
||||
type: MESSAGE_CONVERSATION_TYPES.USER_TO_USER,
|
||||
newMessages: 0,
|
||||
},
|
||||
name: clientName,
|
||||
description: "Cliente de " + organization.name,
|
||||
image: getAvatar(client.userId, "", clientName),
|
||||
orderWeight: 2,
|
||||
});
|
||||
}
|
||||
|
||||
//Mostrar los colaboradores de las organizaciones donde el usuario es colaborador.
|
||||
const organizationEmployees = await EmployeesList.employees.find({
|
||||
companyId: org.companyId,
|
||||
});
|
||||
|
||||
for (const employee of organizationEmployees) {
|
||||
const employeeUser = await UserList.users.findOne({ _id: employee.userId });
|
||||
if (!employeeUser) {
|
||||
continue;
|
||||
}
|
||||
if (employee.userId == data.sessionUser) {
|
||||
continue;
|
||||
}
|
||||
const employeeName = UserList.getUserFullName(employeeUser);
|
||||
items.push({
|
||||
conversation: {
|
||||
userIdFrom: data.sessionUser,
|
||||
userIdTo: employee.userId,
|
||||
type: MESSAGE_CONVERSATION_TYPES.USER_TO_USER,
|
||||
newMessages: 0,
|
||||
},
|
||||
name: employeeName,
|
||||
description: "Colaborador en " + organization.name,
|
||||
image: getAvatar(employee.userId, "", employeeName),
|
||||
orderWeight: 2,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const query = data.query ? data.query.toUpperCase() : "";
|
||||
|
||||
return {
|
||||
data: items.filter(
|
||||
(i) =>
|
||||
String(i.name + i.description)
|
||||
.toUpperCase()
|
||||
.indexOf(query) >= 0
|
||||
),
|
||||
page: 1,
|
||||
pages: 1,
|
||||
} as PaginateFindContactsResults;
|
||||
}
|
||||
|
||||
public async markConversationAsRead(data: MarkConversationAsReadParams): Promise<void> {
|
||||
const checkUser = await UsersManager.users.findOne({ _id: data.sessionUser });
|
||||
if (!checkUser) {
|
||||
throw new Error("Usuario invalido");
|
||||
}
|
||||
|
||||
const checkConversation = await this.conversations.conversationList.findOne({
|
||||
_id: data.conversationId,
|
||||
});
|
||||
|
||||
if (!checkConversation) {
|
||||
throw new Error("Conversacion invalida");
|
||||
}
|
||||
|
||||
await MessagesList.markAsRead({
|
||||
conversationId: data.conversationId,
|
||||
sessionUser: data.sessionUser,
|
||||
});
|
||||
|
||||
await SystemNoficationsList.deleteConversationNotifications({
|
||||
conversationId: data.conversationId,
|
||||
userId: data.sessionUser,
|
||||
sessionUser: data.sessionUser,
|
||||
});
|
||||
}
|
||||
|
||||
public async convertUserToUser(data: ConvertU2UMessageConversationParams): Promise<void> {
|
||||
const checkUser = await UsersManager.users.findOne({ _id: data.sessionUser });
|
||||
if (!checkUser) {
|
||||
throw new Error("Usuario invalido");
|
||||
}
|
||||
|
||||
const checkConversation = await this.conversations.conversationList.findOne({
|
||||
_id: data.conversationId,
|
||||
});
|
||||
|
||||
if (!checkConversation) {
|
||||
throw new Error("Conversacion invalida");
|
||||
}
|
||||
|
||||
checkConversation.type = MESSAGE_CONVERSATION_TYPES.USER_TO_USER;
|
||||
checkConversation.userIdTo = data.sessionUser;
|
||||
await checkConversation.save();
|
||||
}
|
||||
|
||||
public async countUnreadMessages(data: CountUnreadConversationParams): Promise<number> {
|
||||
const searchCriteria: mongoose.FilterQuery<IMessageConversation> = {};
|
||||
searchCriteria.conversationId = data.conversationId;
|
||||
searchCriteria.readed = false;
|
||||
searchCriteria.userId = { $ne: data.sessionUser };
|
||||
const unreadMessages = await MessagesList.messages.find(searchCriteria);
|
||||
return unreadMessages.length;
|
||||
}
|
||||
}
|
||||
|
||||
const MessageConversationList = new MessageConversationsManager();
|
||||
|
||||
export default MessageConversationList;
|
||||
Reference in New Issue
Block a user