improvement: a flow added for owner users to make it possible for them to participate in treatments or tasks.
This commit is contained in:
@@ -13,6 +13,9 @@ import {
|
||||
type WorkingHoursBlockInput,
|
||||
} from '../../common/working-hours';
|
||||
import { UpsertWorkingHoursDto } from './dto/upsert-working-hours.dto';
|
||||
import {
|
||||
hasEffectivePermission,
|
||||
} from '../../common/membership-permissions';
|
||||
|
||||
@Injectable()
|
||||
export class StaffWorkingHoursService {
|
||||
@@ -21,7 +24,7 @@ export class StaffWorkingHoursService {
|
||||
async getWorkingHours(actorUserId: string, organizationId: string, membershipId: string) {
|
||||
await this.assertCanViewStaff(actorUserId, organizationId);
|
||||
|
||||
const membership = await this.findMembership(membershipId, organizationId);
|
||||
const membership = await this.findStaffMembership(membershipId, organizationId);
|
||||
const schedule = await this.prisma.staffWorkingHoursSchedule.findUnique({
|
||||
where: { membershipId: membership.id },
|
||||
include: {
|
||||
@@ -63,7 +66,62 @@ export class StaffWorkingHoursService {
|
||||
) {
|
||||
await this.assertCanEditStaff(actorUserId, organizationId);
|
||||
|
||||
const membership = await this.findMembership(membershipId, organizationId);
|
||||
const membership = await this.findStaffMembership(membershipId, organizationId);
|
||||
return this.persistWorkingHours(membership, organizationId, dto);
|
||||
}
|
||||
|
||||
async getMyWorkingHours(userId: string, organizationId: string) {
|
||||
const membership = await this.findOwnerMembership(userId, organizationId);
|
||||
await this.assertOwnerCanManageWorkingHours(membership);
|
||||
|
||||
const schedule = await this.prisma.staffWorkingHoursSchedule.findUnique({
|
||||
where: { membershipId: membership.id },
|
||||
include: {
|
||||
blocks: { orderBy: [{ dayOfWeek: 'asc' }, { sortOrder: 'asc' }, { startMinute: 'asc' }] },
|
||||
},
|
||||
});
|
||||
|
||||
if (!schedule) {
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
autoRepeatWeekly: true,
|
||||
blocks: [],
|
||||
hasWorkingHours: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
autoRepeatWeekly: schedule.autoRepeatWeekly,
|
||||
blocks: schedule.blocks.map((b) => ({
|
||||
dayOfWeek: b.dayOfWeek,
|
||||
startMinute: b.startMinute,
|
||||
endMinute: b.endMinute,
|
||||
sortOrder: b.sortOrder,
|
||||
})),
|
||||
hasWorkingHours: schedule.blocks.length > 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async upsertMyWorkingHours(
|
||||
userId: string,
|
||||
organizationId: string,
|
||||
dto: UpsertWorkingHoursDto,
|
||||
) {
|
||||
const membership = await this.findOwnerMembership(userId, organizationId);
|
||||
await this.assertOwnerCanManageWorkingHours(membership);
|
||||
return this.persistWorkingHours(membership, organizationId, dto);
|
||||
}
|
||||
|
||||
private async persistWorkingHours(
|
||||
membership: { id: string; userId: string },
|
||||
organizationId: string,
|
||||
dto: UpsertWorkingHoursDto,
|
||||
) {
|
||||
const validationError = validateWorkingHoursBlocks(dto.blocks);
|
||||
if (validationError) {
|
||||
throw new BadRequestException(validationError);
|
||||
@@ -205,7 +263,7 @@ export class StaffWorkingHoursService {
|
||||
);
|
||||
}
|
||||
|
||||
private async findMembership(membershipId: string, organizationId: string) {
|
||||
private async findStaffMembership(membershipId: string, organizationId: string) {
|
||||
const membership = await this.prisma.membership.findFirst({
|
||||
where: { id: membershipId, organizationId },
|
||||
select: { id: true, isOwner: true, userId: true },
|
||||
@@ -219,6 +277,32 @@ export class StaffWorkingHoursService {
|
||||
return membership;
|
||||
}
|
||||
|
||||
private async findOwnerMembership(userId: string, organizationId: string) {
|
||||
const membership = await this.prisma.membership.findFirst({
|
||||
where: { userId, organizationId, isOwner: true },
|
||||
include: {
|
||||
permissions: { include: { permission: true } },
|
||||
organization: { include: { type: true, plan: true } },
|
||||
},
|
||||
});
|
||||
if (!membership) {
|
||||
throw new ForbiddenException('Only organization owners can manage their working hours');
|
||||
}
|
||||
return membership;
|
||||
}
|
||||
|
||||
private async assertOwnerCanManageWorkingHours(membership: {
|
||||
isOwner: boolean;
|
||||
permissions: { permission: { name: string } }[];
|
||||
organization: { type: { name: string }; plan?: { name: string } | null; planId?: string | null };
|
||||
}) {
|
||||
if (!hasEffectivePermission(membership, 'TAB_TREATMENT_EDIT')) {
|
||||
throw new ForbiddenException(
|
||||
'Enable treatment participation before setting working hours',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async assertCanViewStaff(userId: string, organizationId: string) {
|
||||
const actor = await this.getActorMembership(userId, organizationId);
|
||||
if (!actor || !this.canViewStaff(actor)) {
|
||||
|
||||
Reference in New Issue
Block a user