feat: introduce service-based availability filtering for collaborator schedules and overrides

This commit is contained in:
2026-07-19 23:36:18 -03:00
parent f017f7e9aa
commit b01149a19e
10 changed files with 493 additions and 31 deletions
+37 -3
View File
@@ -70,7 +70,7 @@ import { DiscountType } from "../Discounts/Discounts.Interface";
import Discounts from "../Discounts/Discounts";
import { validatePermissionsByCompany, validateSessionUser } from "../../helpers/check";
import Templates from "../Templates/Templates";
import { CollaboratorSchedulesView } from "../Schedules/Schedules.Interface";
import { CollaboratorSchedulesView, ScheduleItem } from "../Schedules/Schedules.Interface";
import ClientAccount from "../ClientAccounts/ClientAccount";
import SchedulesDisabledList from "../SchedulesDisabled/SchedulesDisabled";
import DiscountsEmail from "../DiscountsEmail/DiscountsEmail";
@@ -89,6 +89,14 @@ class AppointmentManager implements IAppointmentsManager {
this.Appointments = new AppointmentsAdapterMongoose();
}
private isScheduleAvailableForService(schedule: ScheduleItem, serviceId?: string): boolean {
if (!serviceId || !schedule.serviceScope || schedule.serviceScope === "all") {
return true;
}
return schedule.serviceScope === "specific" && (schedule.serviceIds || []).includes(serviceId);
}
public async setPaymentStatus(data: SetPaymentStatusParams): Promise<void> {
const sessionUser = await UsersManager.users.findOne({
_id: data.sessionUser,
@@ -935,6 +943,7 @@ class AppointmentManager implements IAppointmentsManager {
dateDay: dayjs(data.start).startOf("day").toDate(),
from: checkFrom,
to: checkTo,
serviceId: data.serviceId,
});
} else {
//chequear que el colaborador este disponible.
@@ -944,6 +953,7 @@ class AppointmentManager implements IAppointmentsManager {
weekDay: weekDay,
from: checkFrom,
to: checkTo,
serviceId: data.serviceId,
});
}
@@ -2289,6 +2299,10 @@ public async updateAppointment(data: UpdateAppointmentParams): Promise<void> {
continue;
}
if (!this.isScheduleAvailableForService(schedule, data.serviceId)) {
continue;
}
const scheduleDataFrom = schedule.from.split(":");
const scheduleDataTo = schedule.to.split(":");
const hourFrom = parseInt(scheduleDataFrom[0]);
@@ -2761,7 +2775,17 @@ public async updateAppointment(data: UpdateAppointmentParams): Promise<void> {
date: currentDate.toDate(),
});
if (hasOverride && hasOverride.schedules.length > 0) {
if (
hasOverride &&
hasOverride.schedules.some(
(schedule) =>
!schedule.disabled &&
(!schedule.serviceScope ||
schedule.serviceScope === "all" ||
(schedule.serviceScope === "specific" &&
(schedule.serviceIds || []).includes(data.serviceId)))
)
) {
returnAvailableDates.push(currentDate.toDate());
} else if (!hasOverride) {
// Check if the current date is within any enabled schedule range
@@ -2784,7 +2808,17 @@ public async updateAppointment(data: UpdateAppointmentParams): Promise<void> {
weekDay: currentDate.day(),
});
if (schedule && schedule.schedules.length > 0) {
if (
schedule &&
schedule.schedules.some(
(scheduleItem) =>
!scheduleItem.disabled &&
(!scheduleItem.serviceScope ||
scheduleItem.serviceScope === "all" ||
(scheduleItem.serviceScope === "specific" &&
(scheduleItem.serviceIds || []).includes(data.serviceId)))
)
) {
returnAvailableDates.push(currentDate.toDate());
}
}