From a8d371dbe97cddb14a52d15c891e04c997d7ce00 Mon Sep 17 00:00:00 2001 From: donpat1to Date: Sun, 19 Oct 2025 11:22:49 +0200 Subject: [PATCH] removed unused function shiftassignmentservice.ts --- .../src/services/shiftAssignmentService.ts | 299 ------------------ 1 file changed, 299 deletions(-) diff --git a/frontend/src/services/shiftAssignmentService.ts b/frontend/src/services/shiftAssignmentService.ts index 0b23444..9016583 100644 --- a/frontend/src/services/shiftAssignmentService.ts +++ b/frontend/src/services/shiftAssignmentService.ts @@ -152,305 +152,6 @@ export class ShiftAssignmentService { resolutionReport: , }; } - - - private static async createWeeklyPattern( - definedShifts: ScheduledShift[], - employees: Employee[], - availabilities: EmployeeAvailability[], - enforceNoTraineeAlone: boolean - ): Promise { - - // Get first week of shifts (7 days from the start) - const firstWeekShifts = this.getFirstWeekShifts(definedShifts); - - console.log('📅 First week analysis:'); - console.log('- Shifts in first week:', firstWeekShifts.length); - - // Fix: Use Array.from instead of spread operator with Set - const uniqueDays = Array.from(new Set(firstWeekShifts.map(s => this.getDayOfWeek(s.date)))).sort(); - console.log('- Days covered:', uniqueDays); - - // Build availability map - const availabilityMap = this.buildAvailabilityMap(availabilities); - const employeeMap = new Map(employees.map(emp => [emp.id, emp])); - - // Initialize assignment state for first week - const weeklyAssignments: { [shiftId: string]: string[] } = {}; - const employeeAssignmentCount: { [employeeId: string]: number } = {}; - - employees.forEach(emp => { - employeeAssignmentCount[emp.id] = 0; - }); - - firstWeekShifts.forEach(shift => { - weeklyAssignments[shift.id] = []; - }); - - // Sort employees by capacity and experience - const sortedEmployees = [...employees].sort((a, b) => { - const aCapacity = this.getMaxAssignments(a); - const bCapacity = this.getMaxAssignments(b); - const aIsManager = a.role === 'admin'; - const bIsManager = b.role === 'admin'; - - if (aIsManager !== bIsManager) return aIsManager ? -1 : 1; - if (a.employeeType !== b.employeeType) { - if (a.employeeType === 'experienced') return -1; - if (b.employeeType === 'experienced') return 1; - } - return bCapacity - aCapacity; - }); - - // Sort shifts by priority (those with fewer available employees first) - const sortedShifts = [...firstWeekShifts].sort((a, b) => { - const aAvailable = this.countAvailableEmployees(a, employees, availabilityMap); - const bAvailable = this.countAvailableEmployees(b, employees, availabilityMap); - return aAvailable - bAvailable; - }); - - // Assign employees to first week shifts - for (const employee of sortedEmployees) { - const maxAssignments = this.getMaxAssignments(employee); - - // Get available shifts for this employee in first week - const availableShifts = sortedShifts - .filter(shift => { - if (employeeAssignmentCount[employee.id] >= maxAssignments) return false; - if (weeklyAssignments[shift.id].length >= shift.requiredEmployees) return false; - - const dayOfWeek = this.getDayOfWeek(shift.date); - const shiftKey = `${dayOfWeek}-${shift.timeSlotId}`; - - return this.isEmployeeAvailable(employee, shiftKey, availabilityMap) && - this.isAssignmentCompatible(employee, weeklyAssignments[shift.id], employeeMap, enforceNoTraineeAlone); - }) - .sort((a, b) => { - // Prefer shifts with fewer current assignments - return weeklyAssignments[a.id].length - weeklyAssignments[b.id].length; - }); - - // Assign to available shifts until capacity is reached - for (const shift of availableShifts) { - if (employeeAssignmentCount[employee.id] >= maxAssignments) break; - - weeklyAssignments[shift.id].push(employee.id); - employeeAssignmentCount[employee.id]++; - console.log(`✅ Assigned ${employee.name} to weekly pattern shift`); - - if (employeeAssignmentCount[employee.id] >= maxAssignments) break; - } - } - - // Ensure all shifts in first week have at least one employee - for (const shift of firstWeekShifts) { - if (weeklyAssignments[shift.id].length === 0) { - const dayOfWeek = this.getDayOfWeek(shift.date); - const shiftKey = `${dayOfWeek}-${shift.timeSlotId}`; - - const availableEmployees = employees - .filter(emp => - this.isEmployeeAvailable(emp, shiftKey, availabilityMap) && - this.canAssignByContract(emp, employeeAssignmentCount) - ) - .sort((a, b) => { - const aPref = availabilityMap.get(a.id)?.get(shiftKey) || 3; - const bPref = availabilityMap.get(b.id)?.get(shiftKey) || 3; - const aCount = employeeAssignmentCount[a.id] || 0; - const bCount = employeeAssignmentCount[b.id] || 0; - - if (aPref !== bPref) return aPref - bPref; - return aCount - bCount; - }); - - if (availableEmployees.length > 0) { - const bestCandidate = availableEmployees[0]; - weeklyAssignments[shift.id].push(bestCandidate.id); - employeeAssignmentCount[bestCandidate.id]++; - console.log(`🆘 Emergency assigned ${bestCandidate.name} to weekly pattern`); - } - } - } - - return { - weekShifts: firstWeekShifts, - assignments: weeklyAssignments, - weekNumber: 1 - }; - } - - private static applyWeeklyPattern( - allShifts: ScheduledShift[], - weeklyPattern: WeeklyPattern - ): { [shiftId: string]: string[] } { - - const assignments: { [shiftId: string]: string[] } = {}; - - console.log('🔄 Applying weekly pattern to all shifts:', { - patternShifts: weeklyPattern.weekShifts.length, - allShifts: allShifts.length, - patternAssignments: Object.keys(weeklyPattern.assignments).length - }); - - // Group pattern shifts by day-timeSlot for easy lookup - const patternMap = new Map(); - - weeklyPattern.weekShifts.forEach((patternShift: ScheduledShift) => { - const dayOfWeek = this.getDayOfWeek(patternShift.date); - const patternKey = `${dayOfWeek}-${patternShift.timeSlotId}`; - - if (weeklyPattern.assignments[patternShift.id]) { - patternMap.set(patternKey, weeklyPattern.assignments[patternShift.id]); - console.log(`📋 Pattern mapping: ${patternKey} → ${weeklyPattern.assignments[patternShift.id].length} employees`); - } - }); - - // Apply pattern to all shifts - allShifts.forEach(shift => { - const dayOfWeek = this.getDayOfWeek(shift.date); - const patternKey = `${dayOfWeek}-${shift.timeSlotId}`; - - const patternAssignment = patternMap.get(patternKey); - - if (patternAssignment) { - assignments[shift.id] = [...patternAssignment]; - } else { - assignments[shift.id] = []; - console.warn(`❌ No pattern assignment found for: ${patternKey} (Shift: ${shift.id})`); - } - }); - - // Debug: Check assignment coverage - const assignedShifts = Object.values(assignments).filter(a => a.length > 0).length; - const totalShifts = allShifts.length; - - console.log(`📊 Pattern application result: ${assignedShifts}/${totalShifts} shifts assigned (${Math.round((assignedShifts/totalShifts)*100)}%)`); - - return assignments; - } - - private static getFirstWeekShifts(shifts: ScheduledShift[]): ScheduledShift[] { - if (shifts.length === 0) return []; - - // Sort by date and get the first 7 days - const sortedShifts = [...shifts].sort((a, b) => a.date.localeCompare(b.date)); - const firstDate = new Date(sortedShifts[0].date); - const firstWeekEnd = new Date(firstDate); - firstWeekEnd.setDate(firstWeekEnd.getDate() + 6); // 7 days total - - return sortedShifts.filter(shift => { - const shiftDate = new Date(shift.date); - return shiftDate >= firstDate && shiftDate <= firstWeekEnd; - }); - } - - // ========== EXISTING HELPER METHODS ========== - - static async getDefinedShifts(shiftPlan: ShiftPlan): Promise { - try { - const scheduledShifts = await shiftAssignmentService.getScheduledShiftsForPlan(shiftPlan.id); - console.log('📋 Loaded scheduled shifts:', scheduledShifts.length); - - if (!shiftPlan.shifts || shiftPlan.shifts.length === 0) { - console.warn('⚠️ No shifts defined in shift plan'); - return scheduledShifts; - } - - // Use first week for weekly pattern (7 days) - const firstWeekShifts = this.getFirstWeekShifts(scheduledShifts); - console.log('📅 Using first week shifts for pattern:', firstWeekShifts.length); - - return firstWeekShifts; - - } catch (err) { - console.error("❌ Failed to load scheduled shifts:", err); - return []; - } - } - - private static countAvailableEmployees( - scheduledShift: ScheduledShift, - employees: Employee[], - availabilityMap: Map> - ): number { - const dayOfWeek = this.getDayOfWeek(scheduledShift.date); - const shiftKey = `${dayOfWeek}-${scheduledShift.timeSlotId}`; - - return employees.filter(emp => - this.isEmployeeAvailable(emp, shiftKey, availabilityMap) - ).length; - } - - private static isAssignmentCompatible( - candidate: Employee, - currentAssignments: string[], - employeeMap: Map, - enforceNoTraineeAlone: boolean - ): boolean { - if (!enforceNoTraineeAlone || currentAssignments.length === 0) return true; - - const currentEmployees = currentAssignments.map(id => employeeMap.get(id)).filter(Boolean) as Employee[]; - - if (candidate.employeeType === 'trainee') { - const hasExperiencedOrChef = currentEmployees.some(emp => - emp.employeeType === 'experienced' || emp.role === 'admin' - ); - return hasExperiencedOrChef; - } - - return true; - } - - private static buildAvailabilityMap(availabilities: EmployeeAvailability[]): Map> { - const map = new Map>(); - - availabilities.forEach(avail => { - if (!map.has(avail.employeeId)) { - map.set(avail.employeeId, new Map()); - } - - const shiftKey = `${avail.dayOfWeek}-${avail.timeSlotId}`; - map.get(avail.employeeId)!.set(shiftKey, avail.preferenceLevel); - }); - - return map; - } - - private static isEmployeeAvailable( - employee: Employee, - shiftKey: string, - availabilityMap: Map> - ): boolean { - if (!employee.isActive) return false; - - const employeeAvailability = availabilityMap.get(employee.id); - if (!employeeAvailability) return false; - - const preference = employeeAvailability.get(shiftKey); - return preference !== undefined && preference !== 3; - } - - private static canAssignByContract( - employee: Employee, - assignmentCount: { [employeeId: string]: number } - ): boolean { - const currentCount = assignmentCount[employee.id] || 0; - const maxAssignments = this.getMaxAssignments(employee); - return currentCount < maxAssignments; - } - - private static getMaxAssignments(employee: Employee): number { - switch (employee.contractType) { - case 'small': return 1; - case 'large': return 2; - default: return 999; - } - } - - private static getDayOfWeek(dateString: string): number { - const date = new Date(dateString); - return date.getDay() === 0 ? 7 : date.getDay(); - } } export const shiftAssignmentService = new ShiftAssignmentService(); \ No newline at end of file