first commit

This commit is contained in:
2026-07-16 20:48:43 -03:00
commit 5696cee264
1111 changed files with 322270 additions and 0 deletions
@@ -0,0 +1,85 @@
import {
FindAppointmentsParams,
IAppointmentsAdapter,
IAppointment,
CreateAppointmentParams,
PaginateAppointmentsParams,
PaginateAppointmentsResults,
} from "./Appointments.Interface";
import { Document, Model, Schema, model } from "mongoose";
export interface IAppointmentDocument extends Omit<IAppointment, "id">, Document {}
export class AppointmentsAdapterMongoose implements IAppointmentsAdapter {
schema: Schema;
AppointmentList: Model<IAppointmentDocument>;
constructor() {
this.schema = new Schema({
companyId: { type: Schema.Types.ObjectId, required: true, ref: "Companie" },
serviceId: { type: Schema.Types.ObjectId, required: true, ref: "Service" },
employeeId: { type: Schema.Types.ObjectId, required: true, ref: "Employee" },
clientId: { type: Schema.Types.ObjectId, required: true, ref: "Client" },
userId: { type: Schema.Types.ObjectId, required: false, ref: "User" },
discountId: { type: Schema.Types.ObjectId, required: false, ref: "Discount" },
start: { type: Date, required: true },
startHour: { type: Number, required: true, default: 0 },
endHour: { type: Number, required: true },
dateDay: { type: Date, required: true },
price: { type: Number, required: true, default: 0 },
length: { type: Number, required: true, default: 0 },
present: { type: Boolean, required: true, default: true },
payment: { type: Boolean, required: true, default: false },
comments: { type: String, required: false, default: "" },
creationDate: { type: Date, required: true, default: Date.now },
});
this.AppointmentList = model<IAppointmentDocument>("Appointment", this.schema);
}
public async create(data: CreateAppointmentParams): Promise<IAppointment> {
return await this.AppointmentList.create(data);
}
public async delete(id: string): Promise<void> {
await this.AppointmentList.deleteOne({ _id: id });
}
public async findByDateRange(
startDate: Date,
endDate: Date,
companyId: string
): Promise<IAppointment[]> {
return this.AppointmentList.find({
dateDay: { $gte: startDate, $lte: endDate },
companyId: companyId,
}).exec();
}
public async find(filters: FindAppointmentsParams): Promise<IAppointment[]> {
return this.AppointmentList.find(filters).exec();
}
public async findOne(filters: FindAppointmentsParams): Promise<IAppointmentDocument | null> {
return this.AppointmentList.findOne(filters).exec();
}
public async paginate(
filters: PaginateAppointmentsParams
): Promise<PaginateAppointmentsResults> {
const { page, limit, ...findFilters } = filters; //Extract page and limit from filters
const count = await this.AppointmentList.countDocuments(findFilters).exec();
const skip = (page - 1) * limit;
const results = await this.AppointmentList.find(findFilters)
.skip(skip)
.limit(filters.limit)
.exec();
return {
data: results,
page: filters.page,
pages: Math.ceil(count / filters.limit),
};
}
}
@@ -0,0 +1,323 @@
import { IHeatMap } from "../../Models/HeatMap/HeatMap.Interface";
import { IClientDocument } from "../Clients/Clients.Adapter.Mongoose";
import { ICompanyDocument } from "../Companies/Companies.Adapter.Mongoose";
import { DiscountType } from "../Discounts/Discounts.Interface";
import { TextObjectFilterResult } from "../TextObjectFilter.model";
export type FindAppointmentsParams = {
_id?: string;
companyId?: string;
serviceId?: string;
employeeId?: string;
clientId?: string;
start?: Date;
dateDay?: Date;
};
export type FindAppointmentsByUserParams = {
sessionUser: string;
};
export type FindAppointmentsByUserPaginatedParams = FindAppointmentsByUserParams & {
page: number;
limit: number;
};
export type FindAppointmentsByCollaboratorParams = {
sessionUser: string;
};
export type FindAppointmentsByCollaboratorPaginatedParams = FindAppointmentsByCollaboratorParams & {
page: number;
limit: number;
};
export enum APPOINTMENT_NOTIFICATION_TYPE {
"CREATION" = "creation",
"REMINDER" = "reminder",
}
export type SendAppointmentNotificationParams = {
appointmentId: string;
sessionUser: string;
type: APPOINTMENT_NOTIFICATION_TYPE;
};
export type MoveAppointmentParams = {
id: string;
companyId: string;
newStart: Date;
newEnd: Date;
sessionUser?: string;
};
export type ChangeServiceParams = {
id: string;
newServiceId: string;
newEmployeeId: string;
sessionUser: string;
};
export type SendWapSystemNotificationParams = {
appointmentId: string;
systemToken: string;
};
export type HeatMapConfig = {
companyId: string;
serviceId: string;
employeeId: string;
fraction: number;
length: number;
heatMapDate: Date;
start: Date;
serviceLimit: number;
serviceLength: number;
};
export type PaginateAppointmentsParams = FindAppointmentsParams & {
page: number;
limit: number;
};
export type PaginateAppointmentsResults = {
data: IAppointment[];
page: number;
pages: number;
};
export type CreateAppointmentParams = {
companyId: string;
serviceId: string;
employeeId: string;
userId?: string; // for user reservations
clientId?: string; // for collaborator reservations
repeatId?: string; // Para ver si tiene un descuento asignado...
start: string | Date;
startHour?: number;
endHour?: number;
dateDay?: Date;
length?: number;
price?: number;
comments?: string;
validation?: boolean;
notification?: boolean;
sessionUser: string;
};
export type UpdateAppointmentParams = {
id: string;
start: string | Date;
length: number;
price: number;
comments: string;
validation?: boolean;
notification?: boolean;
sessionUser: string;
};
export type DeleteAppointmentParams = {
id: string;
validation?: boolean;
sessionUser: string;
};
export type FindAppointmentSchedulesParams = {
companyId: string;
serviceId: string;
employeeId: string;
dateDay: string | Date;
};
export type DeleteAppointmentsByCompanyParams = {
companyId: string;
};
export type ChangeEmployeeToOwnerParams = {
appointmentId: string;
companyId: string;
};
export type CountAppointmentsByMonthParams = {
companyId: string;
month: number;
year: number;
};
export type SetPaymentStatusParams = {
appointmentId: string;
status: boolean;
sessionUser: string;
};
export type ApplyAppointmentDiscountParams = {
companyId: string;
appointmentId: string;
discountId: string;
sessionUser: string;
};
export type DeleteAppointmentDiscountParams = {
appointmentId: string;
companyId: string;
sessionUser: string;
};
export type GetAvailableDatesParams = {
companyId: string;
serviceId: string;
employeeId: string;
length: number; //Cantidad de dias para realizar el chequeo a partir de la fecha de consulta
sessionUser: string; //El el id de un usuario cualquiera. no importa si pertenece o no a la organizacion. Es informacion publica.
};
export type GetAvailableDatesResult = {
availableDates: Date[]; //Fechas que tienen lugar disponible.
inRangeDates: Date[]; //Fechas que estan dentro de un periodo habilitado.
};
export interface AppointmentNotificationIntent {
message: string;
checkClient: IClientDocument;
companyCheck: ICompanyDocument;
}
export interface IAppointment {
id?: string;
companyId: string;
serviceId: string;
employeeId: string;
clientId: string;
userId: string;
discountId: string;
discountType: DiscountType;
discountValue: number;
discountName: string;
discountCode: string;
start: Date;
startHour: number;
endHour: number;
dateDay: Date;
length: number;
price: number;
present: boolean;
payment: boolean;
comments: string;
creationDate: Date;
}
export interface AppointmentEvent {
appointmentId: string;
startTime: number;
endTime: number;
title: string;
clientId: string;
serviceId: string;
employeeId: string;
avatar: string;
color: string;
repeatId: string;
payment: boolean;
discountId: string;
discountType: DiscountType;
discountValue: number;
discountName: string;
discountCode: string;
}
export interface AppointmentAdminByDateView {
events: AppointmentEvent[];
from: number;
to: number;
}
export interface AppointmentEventByClient {
id: string;
companyId: string;
serviceId: string;
serviceName: string;
serviceDescription: string;
collaboratorId: string;
collaboratorName: string;
collaboratorAvatar: string;
appointmentDate: string;
startTime: number;
endTime: number;
title: string;
clientId: string;
clientName: string;
avatar: string;
color: string;
comments: string;
price: number;
length: number;
payment: boolean;
discountId: string;
discountType: DiscountType;
discountValue: number;
discountName: string;
discountCode: string;
clientCtaCteBalance: number;
}
export interface AppointmentAdminByClientView {
events: AppointmentEventByClient[];
}
export interface PaginatedAppointmentEventByClientResult {
data: AppointmentEventByClient[];
page: number;
pages: number;
}
export interface GetAppointmentEventParams {
appointmentId: string;
sessionUser: string;
}
export interface IAppointmentsAdapter {
create(data: CreateAppointmentParams): Promise<IAppointment>;
delete(id: string): Promise<void>;
find(filters: FindAppointmentsParams): Promise<IAppointment[]>;
findOne(filters: FindAppointmentsParams): Promise<IAppointment | null>;
paginate(filters: PaginateAppointmentsParams): Promise<PaginateAppointmentsResults>;
}
export interface IAppointmentsManager {
Appointments: IAppointmentsAdapter;
createAppointment(data: CreateAppointmentParams): Promise<IAppointment>;
updateAppointment(data: UpdateAppointmentParams): Promise<void>;
moveAppointmentForce(data: MoveAppointmentParams): Promise<void>;
changeServiceForce(data: ChangeServiceParams): Promise<void>;
deleteAppointment(data: DeleteAppointmentParams): Promise<void>;
buildHeatMapEmpty(config: HeatMapConfig): IHeatMap;
getHeatMap(config: HeatMapConfig): Promise<IHeatMap>;
updateHeatMap(config: HeatMapConfig, data: CreateAppointmentParams): Promise<void>;
checkAvailability(config: HeatMapConfig, data: CreateAppointmentParams): Promise<boolean>;
findAppointmentsAdminByDate(data: FindAppointmentsParams): Promise<AppointmentAdminByDateView>;
findAppointmentsAdminByClient(data: FindAppointmentsParams): Promise<AppointmentAdminByClientView>;
findAppointmentsByUser(data: FindAppointmentsByUserParams): Promise<AppointmentAdminByClientView>;
findAppointmentsByCollaborator(data: FindAppointmentsByCollaboratorParams): Promise<AppointmentAdminByClientView>;
findAppointmentsByUserPaginated(data: FindAppointmentsByUserPaginatedParams): Promise<PaginatedAppointmentEventByClientResult>;
findAppointmentsByCollaboratorPaginated(data: FindAppointmentsByCollaboratorPaginatedParams): Promise<PaginatedAppointmentEventByClientResult>;
getAppointmentEvent(data: GetAppointmentEventParams): Promise<AppointmentEventByClient>;
getSchedules(data: FindAppointmentSchedulesParams): Promise<TextObjectFilterResult[]>;
getAvailableDates(data: GetAvailableDatesParams): Promise<GetAvailableDatesResult>;
sendWapNotification(data: SendAppointmentNotificationParams): Promise<void>;
sendEmailNotification(data: SendAppointmentNotificationParams): Promise<void>;
sendWapSystemNotification(data: SendWapSystemNotificationParams): Promise<void>;
deleteAppointmentsByCompany(data: DeleteAppointmentsByCompanyParams): Promise<void>;
changeEmployeeToOwner(data: ChangeEmployeeToOwnerParams): Promise<void>;
countAppointmentsByMonth(data: CountAppointmentsByMonthParams): Promise<number>;
setPaymentStatus(data: SetPaymentStatusParams): Promise<void>;
applyDiscount(data: ApplyAppointmentDiscountParams): Promise<void>;
deleteDiscount(data: DeleteAppointmentDiscountParams): Promise<void>;
}
File diff suppressed because it is too large Load Diff