138 lines
3.9 KiB
Dart
138 lines
3.9 KiB
Dart
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
|
|
part 'maintenance_schedule.freezed.dart';
|
|
|
|
@freezed
|
|
class MaintenanceSchedule with _$MaintenanceSchedule {
|
|
const MaintenanceSchedule._();
|
|
|
|
const factory MaintenanceSchedule({
|
|
required int equipmentHistoryId,
|
|
required String maintenanceType,
|
|
required int periodMonths,
|
|
required DateTime startDate,
|
|
required DateTime endDate,
|
|
DateTime? lastMaintenanceDate,
|
|
DateTime? nextMaintenanceDate,
|
|
required double cost,
|
|
String? description,
|
|
@Default([]) List<DateTime> scheduledDates,
|
|
@Default(MaintenanceScheduleStatus.active) MaintenanceScheduleStatus status,
|
|
}) = _MaintenanceSchedule;
|
|
|
|
// 다음 유지보수 날짜 계산
|
|
DateTime calculateNextMaintenanceDate() {
|
|
final lastDate = lastMaintenanceDate ?? startDate;
|
|
return lastDate.add(Duration(days: periodMonths * 30));
|
|
}
|
|
|
|
// 남은 일수 계산
|
|
int getDaysUntilNextMaintenance() {
|
|
final next = nextMaintenanceDate ?? calculateNextMaintenanceDate();
|
|
return next.difference(DateTime.now()).inDays;
|
|
}
|
|
|
|
// 만료 여부 확인
|
|
bool isOverdue() {
|
|
final daysUntil = getDaysUntilNextMaintenance();
|
|
return daysUntil < 0;
|
|
}
|
|
|
|
// 곧 만료 예정 여부 확인 (30일 이내)
|
|
bool isUpcoming({int daysThreshold = 30}) {
|
|
final daysUntil = getDaysUntilNextMaintenance();
|
|
return daysUntil >= 0 && daysUntil <= daysThreshold;
|
|
}
|
|
|
|
// 전체 스케줄 생성
|
|
List<DateTime> generateFullSchedule() {
|
|
final schedules = <DateTime>[];
|
|
var currentDate = startDate;
|
|
|
|
while (currentDate.isBefore(endDate)) {
|
|
schedules.add(currentDate);
|
|
currentDate = currentDate.add(Duration(days: periodMonths * 30));
|
|
}
|
|
|
|
return schedules;
|
|
}
|
|
|
|
// 남은 유지보수 횟수 계산
|
|
int getRemainingMaintenanceCount() {
|
|
final now = DateTime.now();
|
|
final schedules = generateFullSchedule();
|
|
return schedules.where((date) => date.isAfter(now)).length;
|
|
}
|
|
|
|
// 총 비용 계산
|
|
double getTotalCost() {
|
|
final totalCount = generateFullSchedule().length;
|
|
return cost * totalCount;
|
|
}
|
|
|
|
// 남은 비용 계산
|
|
double getRemainingCost() {
|
|
return cost * getRemainingMaintenanceCount();
|
|
}
|
|
}
|
|
|
|
enum MaintenanceScheduleStatus {
|
|
active, // 활성
|
|
paused, // 일시중지
|
|
completed,// 완료
|
|
cancelled // 취소
|
|
}
|
|
|
|
// 유지보수 알림 설정
|
|
@freezed
|
|
class MaintenanceAlert with _$MaintenanceAlert {
|
|
const MaintenanceAlert._();
|
|
|
|
const factory MaintenanceAlert({
|
|
required int maintenanceId,
|
|
required int equipmentHistoryId,
|
|
required String equipmentName,
|
|
required DateTime scheduledDate,
|
|
required String maintenanceType,
|
|
required int daysUntil,
|
|
required AlertPriority priority,
|
|
String? description,
|
|
double? estimatedCost,
|
|
}) = _MaintenanceAlert;
|
|
|
|
// Backward compatibility getter
|
|
int get daysUntilDue => daysUntil;
|
|
|
|
factory MaintenanceAlert.fromSchedule(
|
|
MaintenanceSchedule schedule,
|
|
String equipmentName,
|
|
) {
|
|
final daysUntil = schedule.getDaysUntilNextMaintenance();
|
|
final priority = _getPriority(daysUntil);
|
|
|
|
return MaintenanceAlert(
|
|
maintenanceId: 0, // Will be set from actual maintenance
|
|
equipmentHistoryId: schedule.equipmentHistoryId,
|
|
equipmentName: equipmentName,
|
|
scheduledDate: schedule.nextMaintenanceDate ?? schedule.calculateNextMaintenanceDate(),
|
|
maintenanceType: schedule.maintenanceType,
|
|
daysUntil: daysUntil,
|
|
priority: priority,
|
|
description: schedule.description,
|
|
);
|
|
}
|
|
|
|
static AlertPriority _getPriority(int daysUntil) {
|
|
if (daysUntil < 0) return AlertPriority.critical;
|
|
if (daysUntil <= 7) return AlertPriority.high;
|
|
if (daysUntil <= 30) return AlertPriority.medium;
|
|
return AlertPriority.low;
|
|
}
|
|
}
|
|
|
|
enum AlertPriority {
|
|
critical, // 만료됨
|
|
high, // 7일 이내
|
|
medium, // 30일 이내
|
|
low // 30일 초과
|
|
} |