updated shiftplan view assign shifts non static

This commit is contained in:
2025-10-19 11:20:36 +02:00
parent 970651c021
commit 058f2cf5cc
3 changed files with 15 additions and 131 deletions

View File

@@ -4,8 +4,8 @@ import { useParams, useNavigate } from 'react-router-dom';
import { useAuth } from '../../contexts/AuthContext';
import { shiftPlanService } from '../../services/shiftPlanService';
import { employeeService } from '../../services/employeeService';
import { shiftAssignmentService, ShiftAssignmentService } from '../../services/shiftAssignmentService';
import { IntelligentShiftScheduler, SchedulingResult, AssignmentResult } from '../../services/scheduling/useScheduling';
import { shiftAssignmentService } from '../../services/shiftAssignmentService';
import { AssignmentResult } from '../../models/scheduling';
import { ShiftPlan, TimeSlot, ScheduledShift } from '../../models/ShiftPlan';
import { Employee, EmployeeAvailability } from '../../models/Employee';
import { useNotification } from '../../contexts/NotificationContext';
@@ -421,11 +421,11 @@ const ShiftPlanView: React.FC = () => {
};
// Use the freshly loaded data, not the state
const result = await ShiftAssignmentService.assignShifts(
const result = await shiftAssignmentService.assignShifts(
shiftPlan,
refreshedEmployees, // Use fresh array, not state
refreshedAvailabilities, // Use fresh array, not state
constraints // Now this variable is defined
refreshedEmployees,
refreshedAvailabilities,
constraints
);
setAssignmentResult(result);

View File

@@ -3,7 +3,7 @@ import { ShiftPlan, ScheduledShift } from '../models/ShiftPlan';
import { Employee, EmployeeAvailability } from '../models/Employee';
import { authService } from './authService';
//import { IntelligentShiftScheduler, AssignmentResult, WeeklyPattern } from './scheduling/useScheduling';
import { isScheduledShift } from '../models/helpers';
import { AssignmentResult } from '../models/scheduling';
const API_BASE_URL = 'http://localhost:3002/api/scheduled-shifts';
@@ -134,7 +134,7 @@ export class ShiftAssignmentService {
}
}
static async assignShifts(
async assignShifts(
shiftPlan: ShiftPlan,
employees: Employee[],
availabilities: EmployeeAvailability[],
@@ -143,65 +143,13 @@ export class ShiftAssignmentService {
console.log('🧠 Starting intelligent scheduling for FIRST WEEK ONLY...');
// Load all scheduled shifts
const scheduledShifts = await shiftAssignmentService.getScheduledShiftsForPlan(shiftPlan.id);
if (scheduledShifts.length === 0) {
return {
assignments: {},
violations: ['❌ KRITISCH: Keine Schichten verfügbar für die Zuordnung'],
success: false,
resolutionReport: ['🚨 ABBRUCH: Keine Schichten im Plan verfügbar']
};
}
// Set cache for scheduler
IntelligentShiftScheduler.scheduledShiftsCache.set(shiftPlan.id, {
shifts: scheduledShifts,
timestamp: Date.now()
});
// 🔥 RUN SCHEDULING FOR FIRST WEEK ONLY
const schedulingResult = await IntelligentShiftScheduler.generateOptimalSchedule(
shiftPlan,
employees.filter(emp => emp.isActive),
availabilities,
constraints
);
// Get first week shifts for pattern
const firstWeekShifts = this.getFirstWeekShifts(scheduledShifts);
console.log('🔄 Creating weekly pattern from FIRST WEEK:', {
firstWeekShifts: firstWeekShifts.length,
allShifts: scheduledShifts.length,
patternAssignments: Object.keys(schedulingResult.assignments).length
});
const weeklyPattern: WeeklyPattern = {
weekShifts: firstWeekShifts,
assignments: schedulingResult.assignments, // 🔥 Diese enthalten nur erste Woche
weekNumber: 1
};
// 🔥 APPLY PATTERN TO ALL WEEKS
const allAssignments = this.applyWeeklyPattern(scheduledShifts, weeklyPattern);
console.log('✅ Pattern applied to all weeks:', {
firstWeekAssignments: Object.keys(schedulingResult.assignments).length,
allWeeksAssignments: Object.keys(allAssignments).length
});
// Clean cache
IntelligentShiftScheduler.scheduledShiftsCache.delete(shiftPlan.id);
return {
assignments: allAssignments, // 🔥 Diese enthalten alle Wochen
violations: schedulingResult.violations,
success: schedulingResult.success,
pattern: weeklyPattern,
resolutionReport: schedulingResult.resolutionReport,
qualityMetrics: schedulingResult.qualityMetrics
assignments: ,
violations: ,
success: ,
resolutionReport: ,
};
}
@@ -381,20 +329,6 @@ export class ShiftAssignmentService {
return assignments;
}
private static groupShiftsByWeek(shifts: ScheduledShift[]): { [weekNumber: string]: ScheduledShift[] } {
const weeks: { [weekNumber: string]: ScheduledShift[] } = {};
shifts.forEach(shift => {
const weekNumber = this.getWeekNumber(shift.date);
if (!weeks[weekNumber]) {
weeks[weekNumber] = [];
}
weeks[weekNumber].push(shift);
});
return weeks;
}
private static getFirstWeekShifts(shifts: ScheduledShift[]): ScheduledShift[] {
if (shifts.length === 0) return [];
@@ -410,26 +344,6 @@ export class ShiftAssignmentService {
});
}
private static findMatchingPatternShift(
shift: ScheduledShift,
patternShifts: ScheduledShift[]
): ScheduledShift | null {
const shiftDayOfWeek = this.getDayOfWeek(shift.date);
const shiftTimeSlot = shift.timeSlotId;
return patternShifts.find(patternShift =>
this.getDayOfWeek(patternShift.date) === shiftDayOfWeek &&
patternShift.timeSlotId === shiftTimeSlot
) || null;
}
private static getWeekNumber(dateString: string): number {
const date = new Date(dateString);
const firstDayOfYear = new Date(date.getFullYear(), 0, 1);
const pastDaysOfYear = (date.getTime() - firstDayOfYear.getTime()) / 86400000;
return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);
}
// ========== EXISTING HELPER METHODS ==========
static async getDefinedShifts(shiftPlan: ShiftPlan): Promise<ScheduledShift[]> {
@@ -533,36 +447,6 @@ export class ShiftAssignmentService {
}
}
private static findViolations(
assignments: { [shiftId: string]: string[] },
employees: Employee[],
definedShifts: ScheduledShift[],
enforceNoTraineeAlone: boolean
): string[] {
const violations: string[] = [];
const employeeMap = new Map(employees.map(emp => [emp.id, emp]));
definedShifts.forEach(scheduledShift => {
const assignedEmployeeIds = assignments[scheduledShift.id] || [];
if (assignedEmployeeIds.length === 0) {
violations.push(`Shift has no assigned employees`);
return;
}
const assignedEmployees = assignedEmployeeIds.map(id => employeeMap.get(id)).filter(Boolean) as Employee[];
if (enforceNoTraineeAlone && assignedEmployees.length === 1) {
const soloEmployee = assignedEmployees[0];
if (soloEmployee.employeeType === 'trainee') {
violations.push(`Trainee ${soloEmployee.name} is working alone`);
}
}
});
return violations;
}
private static getDayOfWeek(dateString: string): number {
const date = new Date(dateString);
return date.getDay() === 0 ? 7 : date.getDay();