1093 lines
41 KiB
TypeScript
1093 lines
41 KiB
TypeScript
import fs from "fs";
|
|
import path from "path";
|
|
import { rm } from "fs/promises";
|
|
import { CompaniesAdapterMongoose } from "./Companies.Adapter.Mongoose";
|
|
import {
|
|
CreateCompanyParams,
|
|
FindCompaniesParams,
|
|
UpdateCompanyParams,
|
|
ICompaniesAdapter,
|
|
ICompaniesManager,
|
|
ICompany,
|
|
PaginateCompaniesParams,
|
|
PaginateCompaniesResults,
|
|
SetCompanyFileParams,
|
|
DeleteCompanyFileParams,
|
|
MyOranizationsView,
|
|
MyOranizationsViewParams,
|
|
OranizationsViewByIdParams,
|
|
ClientOranizationsViewParams,
|
|
ClientOrganizationView,
|
|
DeleteCompanyParams,
|
|
SetOrganizationPublishedStatusParams,
|
|
COMPANY_PUBLISHED_STATUS,
|
|
SetNotificationAutoParams,
|
|
FixCompanyPostParams,
|
|
MoveCompanyFixedPostParams,
|
|
SysAdminPaginateCompaniesParams,
|
|
SysAdminUpdateCompanyParams,
|
|
SysAdminSetCompanyBannedParams,
|
|
} from "./Companies.Interface";
|
|
import UsersManager from "../Users/Users";
|
|
import EmployeesList from "../Employees/Employee";
|
|
import { EmployeeRoles } from "../Employees/Employees.Interface";
|
|
import { NoPermissionMessage } from "../../helpers/NoPermissionMessage";
|
|
import { isNull } from "../../helpers/IsNull";
|
|
import sharp from "sharp";
|
|
import getHeader from "../../helpers/getHeader";
|
|
import MetricsList from "../../Models/Metrics/Metrics";
|
|
import { TextObjectFilterResult } from "../TextObjectFilter.model";
|
|
import { NotificationsManager } from "../Notifications/Notifications";
|
|
import ClientsList from "../Clients/Clients";
|
|
import { validateSessionUser, validatePermissionsByCompany } from "../../helpers/check";
|
|
import { resizeAndCrop } from "../../helpers/resizeAndCrop";
|
|
import HeatMapList from "../HeatMap/HeatMap";
|
|
import AppointmentList from "../Appointments/Appointments";
|
|
import EmployeesServicesList from "../EmployeesServices/EmployeesServices";
|
|
import SchedulesEnabledList from "../SchedulesEnabled/SchedulesEnabled";
|
|
import SchedulesList from "../Schedules/Schedules";
|
|
import ServiceList from "../Services/Service";
|
|
import MessageConversationList from "../MessageConversations/MessagesConversations";
|
|
import WapServerList from "../WapServer/WapServer";
|
|
import RepeatsList from "../Repeats/Repeats";
|
|
import ClientAccount from "../ClientAccounts/ClientAccount";
|
|
import Payments from "../Payments/Payments";
|
|
import Discounts from "../Discounts/Discounts";
|
|
import Templates from "../Templates/Templates";
|
|
|
|
import Posts from "../Posts/Posts";
|
|
import SchedulesDisabledList from "../SchedulesDisabled/SchedulesDisabled";
|
|
import DiscountsEmail from "../DiscountsEmail/DiscountsEmail";
|
|
import { NotificationType } from "../../Models/SystemNotifications/SystemNotification.Interface";
|
|
|
|
class CompaniesManager implements ICompaniesManager {
|
|
companies: ICompaniesAdapter;
|
|
|
|
constructor() {
|
|
this.companies = new CompaniesAdapterMongoose();
|
|
}
|
|
|
|
private async validatePublicRatingFlagsPlan(ownerId: string): Promise<void> {
|
|
const { default: PlanSubscriptionsList } = await import("../PlanSubscriptions/PlanSubscriptons");
|
|
const subscription = await PlanSubscriptionsList.getSubscriptionByUser({
|
|
sessionUser: ownerId,
|
|
});
|
|
|
|
if (!subscription || subscription.plan.price === 0) {
|
|
throw new Error("Esta configuración está disponible solo para planes pagos.");
|
|
}
|
|
}
|
|
|
|
public async toggleFixedPost(data: FixCompanyPostParams): Promise<void> {
|
|
await validateSessionUser({
|
|
sessionUser: data.sessionUser,
|
|
});
|
|
|
|
const { company } = await validatePermissionsByCompany({
|
|
companyId: data.companyId,
|
|
sessionUser: data.sessionUser,
|
|
});
|
|
|
|
const checkPost = await Posts.posts.findOne({
|
|
id: data.postId,
|
|
});
|
|
|
|
if (!checkPost) {
|
|
throw new Error("El post que intenta actualizar no existe");
|
|
}
|
|
|
|
checkPost.fixed = !checkPost.fixed;
|
|
|
|
await checkPost.save();
|
|
|
|
if (checkPost.fixed) {
|
|
company.fixedPostIds?.push(checkPost.id);
|
|
} else {
|
|
company.fixedPostIds = company.fixedPostIds?.filter(
|
|
(item) => String(item) !== String(checkPost.id)
|
|
);
|
|
}
|
|
|
|
await company.save();
|
|
}
|
|
|
|
public async moveFixedPost(data: MoveCompanyFixedPostParams): Promise<void> {
|
|
await validateSessionUser({
|
|
sessionUser: data.sessionUser,
|
|
});
|
|
|
|
const { company } = await validatePermissionsByCompany({
|
|
companyId: data.companyId,
|
|
sessionUser: data.sessionUser,
|
|
});
|
|
|
|
const checkPost = await Posts.posts.findOne({
|
|
id: data.postId,
|
|
});
|
|
|
|
if (!checkPost) {
|
|
throw new Error("El post que intenta actualizar no existe");
|
|
}
|
|
|
|
if (!checkPost.fixed) {
|
|
throw new Error("El post no es fijo");
|
|
}
|
|
|
|
const currentPosition = company.fixedPostIds?.findIndex(
|
|
(item) => String(item) === String(data.postId)
|
|
);
|
|
|
|
if (currentPosition === undefined || currentPosition < 0) {
|
|
throw new Error("No es posible mover el post");
|
|
}
|
|
|
|
company.fixedPostIds = company.fixedPostIds?.filter((item) => String(item) !== String(data.postId));
|
|
|
|
company.fixedPostIds?.splice(currentPosition + data.moveLength, 0, data.postId);
|
|
|
|
await company.save();
|
|
}
|
|
|
|
public async setNotificationAuto(data: SetNotificationAutoParams): Promise<void> {
|
|
const sessionUser = await UsersManager.users.findOne({
|
|
_id: data.sessionUser,
|
|
});
|
|
|
|
if (!sessionUser) {
|
|
throw new Error("No se ha encontrado el usuario o no tiene permisos para realizar esta acción");
|
|
}
|
|
|
|
const companyCheck = await this.companies.findOne({
|
|
_id: data.companyId,
|
|
});
|
|
|
|
if (!companyCheck) {
|
|
throw new Error("La compañia no existe");
|
|
}
|
|
if (!(await EmployeesList.checkPermission(companyCheck, data.sessionUser, EmployeeRoles.ADMIN))) {
|
|
throw new Error(NoPermissionMessage());
|
|
}
|
|
|
|
companyCheck.automaticNotifications = isNull<boolean>(data.status, false);
|
|
await companyCheck.save();
|
|
}
|
|
|
|
public async setPublishedStatus(data: SetOrganizationPublishedStatusParams): Promise<void> {
|
|
const sessionUser = await UsersManager.users.findOne({
|
|
_id: data.sessionUser,
|
|
});
|
|
|
|
if (!sessionUser) {
|
|
throw new Error("No se ha encontrado el usuario o no tiene permisos para realizar esta acción");
|
|
}
|
|
|
|
const companyCheck = await this.companies.findOne({
|
|
_id: data.companyId,
|
|
});
|
|
|
|
if (!companyCheck) {
|
|
throw new Error("La compañia no existe");
|
|
}
|
|
if (!(await EmployeesList.checkPermission(companyCheck, data.sessionUser, EmployeeRoles.ADMIN))) {
|
|
throw new Error(NoPermissionMessage());
|
|
}
|
|
|
|
companyCheck.published = data.published;
|
|
await companyCheck.save();
|
|
}
|
|
|
|
public async deleteCompany(data: DeleteCompanyParams): Promise<void> {
|
|
const userCheck = await UsersManager.users.findOne({
|
|
_id: data.sessionUser,
|
|
});
|
|
|
|
if (!userCheck) {
|
|
throw new Error("No se ha encontrado el usuario o no tiene permisos para realizar esta acción");
|
|
}
|
|
|
|
const companyCheck = await this.companies.findOne({
|
|
_id: data.companyId,
|
|
});
|
|
|
|
if (!companyCheck) {
|
|
throw new Error("La compañia no existe");
|
|
}
|
|
|
|
if (String(companyCheck.ownerId) !== data.sessionUser) {
|
|
throw new Error(
|
|
"No tienes permisos para realizar esta acción. Solo el dueño puede eliminar la organización."
|
|
);
|
|
}
|
|
|
|
try {
|
|
//eliminar heatmaps
|
|
await HeatMapList.deleteHeatMapByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
//eliminar appointments
|
|
await AppointmentList.deleteAppointmentsByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
//eliminar los employees services
|
|
await EmployeesServicesList.deleteEmployeeServiceByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
//eliminar schedules enabled.
|
|
await SchedulesEnabledList.deleteSchedulesEnabledByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
|
|
//eliminar schedules disabled.
|
|
await SchedulesDisabledList.deleteSchedulesDisabledByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
|
|
//eliminar scheduyles.
|
|
await SchedulesList.deleteSchedulesByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
//eliminar employees
|
|
await EmployeesList.deleteEmployeesByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
//eliminar metrics
|
|
await MetricsList.deleteMetricsByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
//eliminar services
|
|
await ServiceList.deleteServicesByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
//eliminar cuenta corriente de los clientes
|
|
await ClientAccount.deleteClientsAccountsByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
//eliminar pagos
|
|
await Payments.deletePaymentsByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
//eliminar clients
|
|
await ClientsList.deleteClientsByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
//eliminar conversations
|
|
await MessageConversationList.deleteConversationsByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
|
|
//eliminar las repeticiones
|
|
await RepeatsList.deleteRepeatsByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
|
|
//eliminar los templates
|
|
await Templates.deleteTemplatesByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
|
|
try {
|
|
//eliminar wap server asignations
|
|
const companyServer = companyCheck.wapServerId;
|
|
|
|
if (companyServer) {
|
|
await WapServerList.deleteBot({
|
|
companyId: data.companyId,
|
|
sessionUser: data.sessionUser,
|
|
});
|
|
|
|
const server = await WapServerList.servers.findOne({
|
|
id: companyServer,
|
|
});
|
|
|
|
if (server) {
|
|
server.countBots -= 1;
|
|
await server.save();
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
|
|
//eliminar los descuentos por email
|
|
await DiscountsEmail.deleteDiscountsEmailByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
|
|
//eliminar descuentos
|
|
await Discounts.deleteDiscountsByCompany({
|
|
companyId: data.companyId,
|
|
});
|
|
|
|
const companyName = `${companyCheck.name}`;
|
|
|
|
//eliminar imagenes de la company
|
|
await this.deleteCompanyFiles(data.companyId);
|
|
//eliminar company
|
|
await this.companies.delete(data.companyId);
|
|
|
|
await NotificationsManager.sendSystemNotification({
|
|
subject: "Organización eliminada",
|
|
message: `La organización ${companyName} ha sido eliminada.`,
|
|
userId: data.sessionUser,
|
|
});
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
}
|
|
|
|
private async deleteCompanyFiles(companyId: string): Promise<void> {
|
|
const rootDir =
|
|
process.env.NODE_ENV !== "production"
|
|
? process.env.UPLOAD_COMPANY_FILES_ROOT_DEV
|
|
: process.env.UPLOAD_COMPANY_FILES_ROOT_PRO;
|
|
|
|
if (!rootDir) {
|
|
throw new Error("No se ha encontrado la ruta de los archivos");
|
|
}
|
|
|
|
const companyDir = path.join(__dirname, rootDir, companyId);
|
|
|
|
try {
|
|
await rm(companyDir, { recursive: true, force: true });
|
|
} catch (err) {
|
|
console.error(`Error al eliminar el directorio ${companyDir}:`, err);
|
|
}
|
|
}
|
|
|
|
public getSlug(name: string): string {
|
|
return name
|
|
.replaceAll(".", "")
|
|
.replaceAll(",", "")
|
|
.replaceAll(":", "")
|
|
.replaceAll(";", "")
|
|
.replaceAll("!", "")
|
|
.replaceAll("<", "")
|
|
.replaceAll(">", "")
|
|
.replaceAll("'", "")
|
|
.replaceAll('"', "")
|
|
.replaceAll("#", "")
|
|
.replaceAll("$", "")
|
|
.replaceAll("%", "")
|
|
.replaceAll("&", "")
|
|
.replaceAll("/", "")
|
|
.replaceAll("(", "")
|
|
.replaceAll(")", "")
|
|
.replaceAll("=", "")
|
|
.replaceAll("¿", "")
|
|
.replaceAll("?", "")
|
|
.replaceAll("*", "")
|
|
.replaceAll("+", "")
|
|
.replaceAll("-", "")
|
|
.replaceAll("|", "")
|
|
.replaceAll("{", "")
|
|
.replaceAll("}", "")
|
|
.replaceAll("[", "")
|
|
.replaceAll("]", "")
|
|
.split(" ")
|
|
.filter((item) => item.length > 0)
|
|
.reduce((acc, item) => acc + "-" + item.toLowerCase(), "")
|
|
.substring(1);
|
|
}
|
|
|
|
public async createCompany(data: CreateCompanyParams): Promise<ICompany> {
|
|
const owner = UsersManager.users.findOne({ _id: data.ownerId });
|
|
|
|
if (!owner) throw new Error("El propietario de la empresa no es un usuario registrado.");
|
|
|
|
const checkCompany = await this.isValidName(data);
|
|
|
|
if (!checkCompany) {
|
|
throw new Error("El nombre de la organización no es válido. Por favor, pruebe con otro nombre.");
|
|
}
|
|
|
|
await MetricsList.calculateMetrics({ userId: data.ownerId });
|
|
const canAdd = await MetricsList.canAddOrganization(data.ownerId);
|
|
|
|
if (!canAdd) {
|
|
throw new Error("Ha alcanzado el limite de organizaciones permitidas de acuerdo a su plan.");
|
|
}
|
|
|
|
const invalidNames = [
|
|
"admin",
|
|
"components",
|
|
"fonts",
|
|
"helpers",
|
|
"hooks",
|
|
"landing",
|
|
"messenger",
|
|
"theme",
|
|
"user",
|
|
];
|
|
|
|
if (invalidNames.includes(data.name.toLowerCase())) {
|
|
throw new Error("El nombre de la organización no es válido. Por favor, pruebe con otro nombre.");
|
|
}
|
|
|
|
const newCompany = await this.companies.create({
|
|
...data,
|
|
...{
|
|
slug: this.getSlug(data.name),
|
|
name: data.name.toLocaleLowerCase(),
|
|
},
|
|
});
|
|
|
|
if (!newCompany.id) {
|
|
throw new Error("Ha ocurrido un error al crear la compañia.");
|
|
}
|
|
|
|
await NotificationsManager.sendSystemNotification({
|
|
userId: String(data.ownerId),
|
|
subject: "Se ha creado una nueva compañia",
|
|
message: `Se ha creado la compañia ${data.name} exitosamente.`,
|
|
type: NotificationType.COMPANY,
|
|
code: String((newCompany as any)._id)
|
|
});
|
|
|
|
await MetricsList.addOrganization({
|
|
userId: data.ownerId,
|
|
quantity: 1,
|
|
});
|
|
|
|
const newEmplyee = await EmployeesList.createEmployee({
|
|
companyId: newCompany.id,
|
|
userId: String(newCompany.ownerId),
|
|
roles: [EmployeeRoles.OWNER, EmployeeRoles.ADMIN],
|
|
sessionUser: String(newCompany.ownerId),
|
|
});
|
|
|
|
//Valida el empleado como aceptado por ambas partes. Solo paso employeeId ya que
|
|
//un employee solo pertenece a una empresa.
|
|
await EmployeesList.validateFull({
|
|
employeeId: String(newEmplyee.id),
|
|
sessionUser: String(newCompany.ownerId),
|
|
});
|
|
|
|
await NotificationsManager.sendSystemNotification({
|
|
userId: String(data.ownerId),
|
|
subject: "Administrador asignado",
|
|
message: `Su usuario ha sido asignado como administrador de la compañia ${data.name}.`,
|
|
type: NotificationType.COMPANY,
|
|
code: String((newCompany as any)._id)
|
|
});
|
|
|
|
return newCompany;
|
|
}
|
|
|
|
public async updateCompany(data: UpdateCompanyParams): Promise<void> {
|
|
await validateSessionUser({ sessionUser: data.sessionUser });
|
|
await validatePermissionsByCompany({ companyId: data.id, sessionUser: data.sessionUser });
|
|
|
|
const companyCheck = await this.companies.findOne({ _id: data.id });
|
|
|
|
if (!companyCheck) {
|
|
throw new Error("La compañia no existe");
|
|
}
|
|
|
|
if (data.name) {
|
|
const otherCompany = await this.companies.findOne({
|
|
name: data.name,
|
|
});
|
|
if (otherCompany && otherCompany.id !== data.id) {
|
|
throw new Error(
|
|
"El nuevo nombre de la organización no es válido. Por favor, pruebe con otro nombree ya que su elección actual esta en uso"
|
|
);
|
|
}
|
|
|
|
data.name = data.name.toLocaleLowerCase();
|
|
}
|
|
|
|
if (!(await EmployeesList.checkPermission(companyCheck, data.sessionUser, EmployeeRoles.ADMIN))) {
|
|
throw new Error(NoPermissionMessage());
|
|
}
|
|
|
|
if (
|
|
data.showPublicScores !== undefined ||
|
|
data.showPublicOpinions !== undefined ||
|
|
data.showPublicProfessionals !== undefined
|
|
) {
|
|
await this.validatePublicRatingFlagsPlan(String(companyCheck.ownerId));
|
|
}
|
|
|
|
let updateData = {
|
|
...data,
|
|
};
|
|
|
|
if (data.name) {
|
|
updateData = {
|
|
...updateData,
|
|
...{ name: data.name.toLocaleLowerCase() },
|
|
...{ slug: this.getSlug(data.name) },
|
|
};
|
|
}
|
|
|
|
await this.companies.update(updateData);
|
|
}
|
|
|
|
public async isValidName(data: FindCompaniesParams): Promise<boolean> {
|
|
if (!data.name) return false;
|
|
const checkSlug = this.getSlug(data.name);
|
|
const checkCompany = await this.companies.findOne({ slug: checkSlug });
|
|
|
|
if (checkCompany) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public async getById(data: OranizationsViewByIdParams): Promise<MyOranizationsView> {
|
|
const sessionUser = await UsersManager.users.findOne({
|
|
_id: data.sessionUser,
|
|
});
|
|
|
|
if (!sessionUser) {
|
|
throw new Error("No se ha encontrado el usuario o no tiene permisos para realizar esta acción");
|
|
}
|
|
|
|
const company = await this.companies.findOne({ _id: data.id });
|
|
|
|
//TODO: chequear si es el dueño. y si esta aceptado
|
|
|
|
if (!company) {
|
|
throw new Error("La compañia no existe");
|
|
}
|
|
|
|
const employ = await EmployeesList.employees.findOne({
|
|
companyId: data.id,
|
|
userId: String(data.sessionUser),
|
|
removed: { $ne: true },
|
|
} as any);
|
|
|
|
if (!employ) {
|
|
throw new Error("El usuario no participa de la organización");
|
|
}
|
|
|
|
const defColor = "#" + String(process.env.DEFAULT_HEADER_COLOR);
|
|
const defFontColor = "#" + String(process.env.DEFAULT_HEADER_FONT_COLOR);
|
|
const defFontShadowColor = "#" + String(process.env.DEFAULT_HEADER_FONT_SHADOW_COLOR);
|
|
|
|
const isAdmin = await EmployeesList.checkPermission(company, data.sessionUser, EmployeeRoles.ADMIN);
|
|
|
|
return {
|
|
id: isNull<string>(company.id, ""),
|
|
name: isNull<string>(company.name, ""),
|
|
slug: isNull<string>(company.slug, ""),
|
|
description: isNull<string>(company.description, ""),
|
|
categoryId: isNull<number>(company.categoryId, 50000),
|
|
ownerId: company.ownerId,
|
|
employeeId: String(employ.id),
|
|
isOwner: String(company.ownerId) == String(data.sessionUser) ? true : false,
|
|
isAdmin: isAdmin,
|
|
hostOk: employ.hostOk ? true : false,
|
|
guestOk: employ.guestOk ? true : false,
|
|
fullOk: employ.hostOk && employ.guestOk ? true : false,
|
|
/*headerFile: isNull<string>(company.headerFile, ""),*/
|
|
|
|
headerFile: getHeader(company.id, isNull<string>(company.headerFile, ""), ""),
|
|
|
|
headerColor: isNull<string>(company.headerColor, defColor),
|
|
headerFontColor: isNull<string>(company.headerFontColor, defFontColor),
|
|
headerFontShadowColor: isNull<string>(company.headerFontShadowColor, defFontShadowColor),
|
|
iconFile: isNull<string>(company.iconFile, ""),
|
|
logoFile: isNull<string>(company.logoFile, ""),
|
|
phoneAreaCode: isNull<string>(company.phoneAreaCode, ""),
|
|
phoneNumber: isNull<string>(company.phoneNumber, ""),
|
|
heatMapFraction: isNull<number>(company.heatMapFraction, 60),
|
|
appointmentTime: isNull<number>(company.appointmentTime, 24),
|
|
cancellationTime: isNull<number>(company.cancellationTime, 24),
|
|
street: isNull<string>(company.street, ""),
|
|
streetNumber: isNull<string>(company.streetNumber, ""),
|
|
builingFloor: isNull<string>(company.builingFloor, ""),
|
|
buildingApartament: isNull<string>(company.buildingApartament, ""),
|
|
block: isNull<string>(company.block, ""),
|
|
city: isNull<string>(company.city, ""),
|
|
state: isNull<string>(company.state, ""),
|
|
country: isNull<string>(company.country, ""),
|
|
zipCode: isNull<string>(company.zipCode, ""),
|
|
latitude: isNull<number>(company.latitude, 0),
|
|
longitude: isNull<number>(company.longitude, 0),
|
|
published: isNull<COMPANY_PUBLISHED_STATUS>(company.published, COMPANY_PUBLISHED_STATUS.PRIVATE),
|
|
automaticNotifications: isNull<boolean>(company.automaticNotifications, false),
|
|
appointmentAlert: isNull<string>(company.appointmentAlert, ""),
|
|
|
|
templateWapNotifId: isNull<string>(company.templateWapNotifId, ""),
|
|
templateWapAltaId: isNull<string>(company.templateWapAltaId, ""),
|
|
templateEmailNotifId: isNull<string>(company.templateEmailNotifId, ""),
|
|
templateEmailAltaId: isNull<string>(company.templateEmailAltaId, ""),
|
|
onboardingStep: company.onboardingStep,
|
|
onboardingCompleted: company.onboardingCompleted,
|
|
showPublicScores: company.showPublicScores ?? true,
|
|
showPublicOpinions: company.showPublicOpinions ?? true,
|
|
showPublicProfessionals: company.showPublicProfessionals ?? true,
|
|
};
|
|
}
|
|
|
|
public async getByClientId(data: ClientOranizationsViewParams): Promise<ClientOrganizationView[]> {
|
|
const clientCompanies = await ClientsList.clients.find({
|
|
userId: data.clientId,
|
|
});
|
|
|
|
const returnData: ClientOrganizationView[] = [];
|
|
|
|
//Organizaciones del cliente.
|
|
for (const orgItem of clientCompanies) {
|
|
const company = await this.companies.findOne({
|
|
_id: orgItem.companyId,
|
|
});
|
|
|
|
if (!company) {
|
|
continue;
|
|
}
|
|
|
|
returnData.push({
|
|
id: isNull<string>(company._id, ""),
|
|
name: isNull<string>(company.name, ""),
|
|
slug: isNull<string>(company.slug, ""),
|
|
description: isNull<string>(company.description, ""),
|
|
iconFile: isNull<string>(company.iconFile, ""),
|
|
logoFile: isNull<string>(company.logoFile, ""),
|
|
});
|
|
}
|
|
|
|
return returnData;
|
|
}
|
|
|
|
public async getByUserId(data: MyOranizationsViewParams): Promise<MyOranizationsView[]> {
|
|
const ownerCompanies = await this.companies.find({
|
|
ownerId: data.sessionUser,
|
|
});
|
|
|
|
const returnData: MyOranizationsView[] = [];
|
|
|
|
const defColor = "#" + String(process.env.DEFAULT_HEADER_COLOR);
|
|
const defFontColor = "#" + String(process.env.DEFAULT_HEADER_FONT_COLOR);
|
|
const defFontShadowColor = "#" + String(process.env.DEFAULT_HEADER_FONT_SHADOW_COLOR);
|
|
|
|
//Organizaciones del usuario
|
|
for (const company of ownerCompanies) {
|
|
const companyDoc = await this.companies.findOne({
|
|
_id: company.id,
|
|
});
|
|
|
|
if (!companyDoc) {
|
|
continue;
|
|
}
|
|
|
|
const employ = await EmployeesList.employees.findOne({
|
|
companyId: String(company.id),
|
|
userId: String(data.sessionUser),
|
|
});
|
|
|
|
if (!employ) {
|
|
continue;
|
|
}
|
|
|
|
const isAdmin = await EmployeesList.checkPermission(
|
|
companyDoc,
|
|
data.sessionUser,
|
|
EmployeeRoles.ADMIN
|
|
);
|
|
|
|
returnData.push({
|
|
id: isNull<string>(company.id, ""),
|
|
name: isNull<string>(company.name, ""),
|
|
slug: isNull<string>(company.slug, ""),
|
|
description: isNull<string>(company.description, ""),
|
|
categoryId: isNull<number>(company.categoryId, 50000),
|
|
ownerId: company.ownerId,
|
|
employeeId: employ ? String(employ.id) : "",
|
|
isOwner: true,
|
|
isAdmin: isAdmin,
|
|
hostOk: true,
|
|
guestOk: true,
|
|
fullOk: true,
|
|
//headerFile: isNull<string>(company.headerFile, ""),
|
|
|
|
headerFile: getHeader(
|
|
isNull<string>(company.id, ""),
|
|
isNull<string>(company.headerFile, ""),
|
|
""
|
|
),
|
|
|
|
headerColor: isNull<string>(company.headerColor, defColor),
|
|
headerFontColor: isNull<string>(company.headerFontColor, defFontColor),
|
|
headerFontShadowColor: isNull<string>(company.headerFontShadowColor, defFontShadowColor),
|
|
iconFile: isNull<string>(company.iconFile, ""),
|
|
logoFile: isNull<string>(company.logoFile, ""),
|
|
phoneAreaCode: isNull<string>(company.phoneAreaCode, ""),
|
|
phoneNumber: isNull<string>(company.phoneNumber, ""),
|
|
heatMapFraction: isNull<number>(company.heatMapFraction, 60),
|
|
appointmentTime: isNull<number>(company.appointmentTime, 24),
|
|
cancellationTime: isNull<number>(company.cancellationTime, 24),
|
|
street: isNull<string>(company.street, ""),
|
|
streetNumber: isNull<string>(company.streetNumber, ""),
|
|
builingFloor: isNull<string>(company.builingFloor, ""),
|
|
buildingApartament: isNull<string>(company.buildingApartament, ""),
|
|
block: isNull<string>(company.block, ""),
|
|
city: isNull<string>(company.city, ""),
|
|
state: isNull<string>(company.state, ""),
|
|
country: isNull<string>(company.country, ""),
|
|
zipCode: isNull<string>(company.zipCode, ""),
|
|
latitude: isNull<number>(company.latitude, 0),
|
|
longitude: isNull<number>(company.longitude, 0),
|
|
published: isNull<COMPANY_PUBLISHED_STATUS>(
|
|
company.published,
|
|
COMPANY_PUBLISHED_STATUS.PRIVATE
|
|
),
|
|
automaticNotifications: isNull<boolean>(company.automaticNotifications, false),
|
|
appointmentAlert: isNull<string>(company.appointmentAlert, ""),
|
|
templateWapNotifId: isNull<string>(company.templateWapNotifId, ""),
|
|
templateEmailNotifId: isNull<string>(company.templateEmailNotifId, ""),
|
|
templateWapAltaId: isNull<string>(company.templateWapAltaId, ""),
|
|
templateEmailAltaId: isNull<string>(company.templateEmailAltaId, ""),
|
|
onboardingStep: company.onboardingStep,
|
|
onboardingCompleted: company.onboardingCompleted,
|
|
showPublicScores: company.showPublicScores ?? true,
|
|
showPublicOpinions: company.showPublicOpinions ?? true,
|
|
showPublicProfessionals: company.showPublicProfessionals ?? true,
|
|
});
|
|
}
|
|
|
|
//Organizaciones en las que participa como colaborador.
|
|
const orgCollaborator = await EmployeesList.employees.find({
|
|
userId: data.sessionUser,
|
|
removed: { $ne: true },
|
|
} as any);
|
|
|
|
for (const item of orgCollaborator) {
|
|
if (item.companyId) {
|
|
const company = await this.companies.findOne({
|
|
_id: item.companyId,
|
|
});
|
|
|
|
if (company) {
|
|
if (String(company.ownerId) == String(data.sessionUser)) {
|
|
continue;
|
|
}
|
|
|
|
const isAdmin = await EmployeesList.checkPermission(
|
|
company,
|
|
data.sessionUser,
|
|
EmployeeRoles.ADMIN
|
|
);
|
|
|
|
returnData.push({
|
|
id: isNull<string>(company.id, ""),
|
|
name: isNull<string>(company.name, ""),
|
|
slug: isNull<string>(company.slug, ""),
|
|
description: isNull<string>(company.description, ""),
|
|
categoryId: isNull<number>(company.categoryId, 50000),
|
|
ownerId: company.ownerId,
|
|
employeeId: String(item.id),
|
|
isOwner: false,
|
|
isAdmin: isAdmin,
|
|
hostOk: item.hostOk ? true : false,
|
|
guestOk: item.guestOk ? true : false,
|
|
fullOk: item.hostOk && item.guestOk ? true : false,
|
|
headerFile: isNull<string>(company.headerFile, ""),
|
|
iconFile: isNull<string>(company.iconFile, ""),
|
|
logoFile: isNull<string>(company.logoFile, ""),
|
|
phoneAreaCode: isNull<string>(company.phoneAreaCode, ""),
|
|
phoneNumber: isNull<string>(company.phoneNumber, ""),
|
|
heatMapFraction: isNull<number>(company.heatMapFraction, 60),
|
|
appointmentTime: isNull<number>(company.appointmentTime, 24),
|
|
cancellationTime: isNull<number>(company.cancellationTime, 24),
|
|
street: isNull<string>(company.street, ""),
|
|
streetNumber: isNull<string>(company.streetNumber, ""),
|
|
builingFloor: isNull<string>(company.builingFloor, ""),
|
|
buildingApartament: isNull<string>(company.buildingApartament, ""),
|
|
block: isNull<string>(company.block, ""),
|
|
city: isNull<string>(company.city, ""),
|
|
state: isNull<string>(company.state, ""),
|
|
country: isNull<string>(company.country, ""),
|
|
zipCode: isNull<string>(company.zipCode, ""),
|
|
latitude: isNull<number>(company.latitude, 0),
|
|
longitude: isNull<number>(company.longitude, 0),
|
|
published: isNull<COMPANY_PUBLISHED_STATUS>(
|
|
company.published,
|
|
COMPANY_PUBLISHED_STATUS.PRIVATE
|
|
),
|
|
automaticNotifications: isNull<boolean>(company.automaticNotifications, false),
|
|
appointmentAlert: isNull<string>(company.appointmentAlert, ""),
|
|
templateWapNotifId: isNull<string>(company.templateWapNotifId, ""),
|
|
templateEmailNotifId: isNull<string>(company.templateEmailNotifId, ""),
|
|
templateWapAltaId: isNull<string>(company.templateWapAltaId, ""),
|
|
templateEmailAltaId: isNull<string>(company.templateEmailAltaId, ""),
|
|
onboardingStep: company.onboardingStep,
|
|
onboardingCompleted: company.onboardingCompleted,
|
|
showPublicScores: company.showPublicScores ?? true,
|
|
showPublicOpinions: company.showPublicOpinions ?? true,
|
|
showPublicProfessionals: company.showPublicProfessionals ?? true,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
return returnData;
|
|
}
|
|
|
|
public async paginate(filters: PaginateCompaniesParams): Promise<PaginateCompaniesResults> {
|
|
return await this.companies.paginate(filters);
|
|
}
|
|
|
|
public async setCompanyHeader(data: SetCompanyFileParams): Promise<void> {
|
|
const sessionUser = await UsersManager.users.findOne({
|
|
_id: data.sessionUser,
|
|
});
|
|
|
|
if (!sessionUser) {
|
|
throw new Error("No se ha encontrado el usuario o no tiene permisos para realizar esta acción");
|
|
}
|
|
|
|
const companyCheck = await this.companies.findOne({
|
|
_id: data.companyId,
|
|
});
|
|
|
|
if (!companyCheck) {
|
|
throw new Error("La compañia no existe");
|
|
}
|
|
|
|
if (!(await EmployeesList.checkPermission(companyCheck, data.sessionUser, EmployeeRoles.ADMIN))) {
|
|
throw new Error(NoPermissionMessage());
|
|
}
|
|
|
|
if (!data.file) {
|
|
throw new Error("No se ha enviado el archivo");
|
|
}
|
|
|
|
const rootDir =
|
|
process.env.NODE_ENV !== "production"
|
|
? process.env.UPLOAD_COMPANY_FILES_ROOT_DEV
|
|
: process.env.UPLOAD_COMPANY_FILES_ROOT_PRO;
|
|
|
|
const uploadPath = path.join(__dirname, rootDir + data.companyId);
|
|
|
|
if (!fs.existsSync(uploadPath)) {
|
|
fs.mkdirSync(uploadPath, { recursive: true });
|
|
}
|
|
|
|
const fileExtension = data.file.originalname.split(".").pop();
|
|
const newFileName = "header." + fileExtension;
|
|
|
|
const filePath = path.join(uploadPath, newFileName);
|
|
|
|
const bufferImage = await resizeAndCrop(sharp(data.file.buffer), 1138, 248);
|
|
|
|
bufferImage.webp().toFile(filePath);
|
|
|
|
//await sharp(data.file.buffer).resize({ height: 150 }).webp().toFile(filePath);
|
|
|
|
companyCheck.headerFile = newFileName;
|
|
await companyCheck.save();
|
|
}
|
|
|
|
public async setCompanyIcon(data: SetCompanyFileParams): Promise<void> {
|
|
const sessionUser = await UsersManager.users.findOne({
|
|
_id: data.sessionUser,
|
|
});
|
|
|
|
if (!sessionUser) {
|
|
throw new Error("No se ha encontrado el usuario o no tiene permisos para realizar esta acción");
|
|
}
|
|
|
|
const companyCheck = await this.companies.findOne({
|
|
_id: data.companyId,
|
|
});
|
|
|
|
if (!companyCheck) {
|
|
throw new Error("La compañia no existe");
|
|
}
|
|
|
|
if (!(await EmployeesList.checkPermission(companyCheck, data.sessionUser, EmployeeRoles.ADMIN))) {
|
|
throw new Error(NoPermissionMessage());
|
|
}
|
|
|
|
if (!data.file) {
|
|
throw new Error("No se ha enviado el archivo");
|
|
}
|
|
|
|
const rootDir =
|
|
process.env.NODE_ENV !== "production"
|
|
? process.env.UPLOAD_COMPANY_FILES_ROOT_DEV
|
|
: process.env.UPLOAD_COMPANY_FILES_ROOT_PRO;
|
|
|
|
const uploadPath = path.join(__dirname, rootDir + data.companyId);
|
|
|
|
if (!fs.existsSync(uploadPath)) {
|
|
fs.mkdirSync(uploadPath, { recursive: true });
|
|
}
|
|
|
|
const fileExtension = data.file.originalname.split(".").pop();
|
|
const newFileName = "icon." + fileExtension;
|
|
|
|
const filePath = path.join(uploadPath, newFileName);
|
|
const uint8Array = new Uint8Array(data.file.buffer);
|
|
fs.writeFileSync(filePath, uint8Array);
|
|
|
|
companyCheck.iconFile = newFileName;
|
|
await companyCheck.save();
|
|
}
|
|
|
|
public async deleteCompanyHeader(data: DeleteCompanyFileParams): Promise<void> {
|
|
const sessionUser = await UsersManager.users.findOne({
|
|
_id: data.sessionUser,
|
|
});
|
|
|
|
if (!sessionUser) {
|
|
throw new Error("No se ha encontrado el usuario o no tiene permisos para realizar esta acción");
|
|
}
|
|
|
|
const companyCheck = await this.companies.findOne({
|
|
_id: data.companyId,
|
|
});
|
|
|
|
if (!companyCheck) {
|
|
throw new Error("La compañia no existe");
|
|
}
|
|
|
|
if (!(await EmployeesList.checkPermission(companyCheck, data.sessionUser, EmployeeRoles.ADMIN))) {
|
|
throw new Error(NoPermissionMessage());
|
|
}
|
|
|
|
if (!companyCheck.headerFile) {
|
|
throw new Error("No hay ningun archivo para borrar");
|
|
}
|
|
|
|
const rootDir =
|
|
process.env.NODE_ENV !== "production"
|
|
? process.env.UPLOAD_COMPANY_FILES_ROOT_DEV
|
|
: process.env.UPLOAD_COMPANY_FILES_ROOT_PRO;
|
|
|
|
const uploadPath = path.join(__dirname, rootDir + data.companyId);
|
|
|
|
const filePath = path.join(uploadPath, companyCheck.headerFile);
|
|
|
|
if (!fs.existsSync(filePath)) {
|
|
throw new Error("El archivo no existe");
|
|
}
|
|
|
|
fs.unlinkSync(filePath);
|
|
|
|
companyCheck.headerFile = undefined;
|
|
await companyCheck.save();
|
|
}
|
|
|
|
public async deleteCompanyIcon(data: DeleteCompanyFileParams): Promise<void> {
|
|
const sessionUser = await UsersManager.users.findOne({
|
|
_id: data.sessionUser,
|
|
});
|
|
|
|
if (!sessionUser) {
|
|
throw new Error("No se ha encontrado el usuario o no tiene permisos para realizar esta acción");
|
|
}
|
|
|
|
const companyCheck = await this.companies.findOne({
|
|
_id: data.companyId,
|
|
});
|
|
|
|
if (!companyCheck) {
|
|
throw new Error("La compañia no existe");
|
|
}
|
|
|
|
if (!(await EmployeesList.checkPermission(companyCheck, data.sessionUser, EmployeeRoles.ADMIN))) {
|
|
throw new Error(NoPermissionMessage());
|
|
}
|
|
|
|
if (!companyCheck.iconFile) {
|
|
throw new Error("No hay ningun archivo para borrar");
|
|
}
|
|
|
|
const rootDir =
|
|
process.env.NODE_ENV !== "production"
|
|
? process.env.UPLOAD_COMPANY_FILES_ROOT_DEV
|
|
: process.env.UPLOAD_COMPANY_FILES_ROOT_PRO;
|
|
|
|
const uploadPath = path.join(__dirname, rootDir + data.companyId);
|
|
|
|
const filePath = path.join(uploadPath, companyCheck.iconFile);
|
|
|
|
if (!fs.existsSync(filePath)) {
|
|
throw new Error("El archivo no existe");
|
|
}
|
|
|
|
fs.unlinkSync(filePath);
|
|
|
|
companyCheck.iconFile = undefined;
|
|
await companyCheck.save();
|
|
}
|
|
|
|
public async filterAll(data: PaginateCompaniesParams): Promise<TextObjectFilterResult[]> {
|
|
const companies = await this.companies.paginateFilterAll(data);
|
|
const returnData: TextObjectFilterResult[] = [];
|
|
|
|
for (const company of companies.data) {
|
|
returnData.push({
|
|
id: isNull<string>(company.id, ""),
|
|
name: company.name,
|
|
description: company.description,
|
|
});
|
|
}
|
|
|
|
return returnData;
|
|
}
|
|
|
|
public getCompanyAddress(data: ICompany): string {
|
|
const address = `${isNull<string>(data.street, "")} ${isNull<string>(
|
|
data.streetNumber,
|
|
""
|
|
)} ${isNull<string>(data.builingFloor, "")} ${isNull<string>(
|
|
data.buildingApartament,
|
|
""
|
|
)} ${isNull<string>(data.block, "")} - ${isNull<string>(data.city, "")}, ${isNull<string>(
|
|
data.state,
|
|
""
|
|
)}, ${isNull<string>(data.country, "")} - CP: ${isNull<string>(data.zipCode, "")}`;
|
|
return address;
|
|
}
|
|
|
|
public async sysAdminPaginate(data: SysAdminPaginateCompaniesParams): Promise<PaginateCompaniesResults> {
|
|
return await this.companies.sysAdminPaginate(data);
|
|
}
|
|
|
|
public async sysAdminUpdate(data: SysAdminUpdateCompanyParams): Promise<void> {
|
|
const companyCheck = await this.companies.findOne({ _id: data.id });
|
|
if (!companyCheck) {
|
|
throw new Error("La compañia no existe");
|
|
}
|
|
|
|
if (data.name) {
|
|
const otherCompany = await this.companies.findOne({ name: data.name.toLocaleLowerCase() });
|
|
if (otherCompany && otherCompany.id !== data.id) {
|
|
throw new Error("El nuevo nombre de la organización está en uso.");
|
|
}
|
|
data.name = data.name.toLocaleLowerCase();
|
|
}
|
|
|
|
let updateData: any = { ...data, sessionUser: "" };
|
|
if (data.name) {
|
|
updateData = {
|
|
...updateData,
|
|
slug: this.getSlug(data.name)
|
|
};
|
|
}
|
|
|
|
await this.companies.update(updateData as UpdateCompanyParams);
|
|
}
|
|
|
|
public async sysAdminSetBanned(data: SysAdminSetCompanyBannedParams): Promise<void> {
|
|
const companyCheck = await this.companies.findOne({ _id: data.id });
|
|
if (!companyCheck) {
|
|
throw new Error("La compañia no existe");
|
|
}
|
|
await this.companies.update({
|
|
id: data.id,
|
|
banned: data.banned,
|
|
sessionUser: "" // sysadmin override
|
|
});
|
|
}
|
|
}
|
|
|
|
const CompaniesList = new CompaniesManager();
|
|
|
|
export default CompaniesList;
|