Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; import { LeaveConflictRule, LeaveConflictResult, StaffingThreshold, LeaveRequest, } from '../schemas'; @Injectable() export class ConflictDetectionService { constructor( @InjectModel(LeaveConflictRule.name) private ruleModel: Model<LeaveConflictRule>, @InjectModel(LeaveConflictResult.name) private resultModel: Model<LeaveConflictResult>, @InjectModel(StaffingThreshold.name) private thresholdModel: Model<StaffingThreshold>, @InjectModel(LeaveRequest.name) private requestModel: Model<LeaveRequest>, ) {} async detectConflicts( tenantId: string, employeeId: string, startDate: string, endDate: string, leaveRequestId: string, ): Promise<any[]> { const conflicts: any[] = []; // 1. Blackout Periods check const thresholds = await this.thresholdModel .find({ tenantId, status: 'active', blackoutStartDate: { $lte: endDate }, blackoutEndDate: { $gte: startDate }, }) .exec(); for (const t of thresholds) { conflicts.push({ ruleType: 'BlackoutPeriod', severity: 'Block', message: `Requested dates fall within the blackout period: ${t.name}`, details: { thresholdId: t._id }, }); } // 2. Team Capacity check (simulated based on overlapping requests) const activeLeaves = await this.requestModel .find({ tenantId, status: { $in: ['approved', 'pending_approval'] }, startDate: { $lte: endDate }, endDate: { $gte: startDate }, employeeId: { $ne: employeeId }, }) .exec(); if (activeLeaves.length >= 3) { conflicts.push({ ruleType: 'TeamCapacity', severity: 'Warning', message: `High number of team members on leave during this period (${activeLeaves.length} employees)`, details: { count: activeLeaves.length }, }); } // Save results if a leaveRequestId was provided if (leaveRequestId && conflicts.length > 0) { await this.resultModel.deleteMany({ tenantId, leaveRequestId }); await this.resultModel.insertMany( conflicts.map((c) => ({ ...c, tenantId, leaveRequestId, status: 'active', })), ); } return conflicts; } } |