import 'package:injectable/injectable.dart'; import '../../data/models/rent_dto.dart'; import '../repositories/rent_repository.dart'; /// 임대 UseCase (백엔드 스키마 기반) /// 백엔드 API와 100% 호환되는 단순한 CRUD 작업만 제공 @lazySingleton class RentUseCase { final RentRepository _repository; RentUseCase(this._repository); /// 임대 목록 조회 (백엔드 스키마 기반) Future getRents({ int page = 1, int pageSize = 10, String? search, int? equipmentHistoryId, }) async { return await _repository.getRents( page: page, pageSize: pageSize, search: search, equipmentHistoryId: equipmentHistoryId, ); } /// 임대 상세 조회 (백엔드 스키마 기반) Future getRent(int id) async { if (id <= 0) { throw ArgumentError('유효하지 않은 임대 ID입니다.'); } return await _repository.getRent(id); } /// 임대 생성 (백엔드 스키마 기반) Future createRent(RentRequestDto request) async { // 백엔드 스키마 기반 검증만 _validateRentRequest(request); return await _repository.createRent(request); } /// 임대 수정 (백엔드 스키마 기반) Future updateRent(int id, RentUpdateRequestDto request) async { if (id <= 0) { throw ArgumentError('유효하지 않은 임대 ID입니다.'); } _validateRentUpdateRequest(request); return await _repository.updateRent(id, request); } /// 임대 삭제 (백엔드에서 처리) Future deleteRent(int id) async { if (id <= 0) { throw ArgumentError('유효하지 않은 임대 ID입니다.'); } return await _repository.deleteRent(id); } /// 장비 이력별 임대 조회 Future> getRentsByEquipmentHistory(int equipmentHistoryId) async { final response = await getRents( pageSize: 1000, equipmentHistoryId: equipmentHistoryId, ); return response.items; } /// 특정 기간 내 임대 조회 (백엔드 날짜 필터링) Future> getRentsByDateRange({ required DateTime startDate, required DateTime endDate, int? equipmentHistoryId, }) async { final response = await getRents( pageSize: 1000, equipmentHistoryId: equipmentHistoryId, ); // 날짜 범위 필터링 (클라이언트 사이드) return response.items.where((rent) { return rent.startedAt.isAfter(startDate) && rent.endedAt.isBefore(endDate); }).toList(); } /// 현재 진행 중인 임대 조회 Future> getCurrentRents({int? equipmentHistoryId}) async { final response = await getRents( pageSize: 1000, equipmentHistoryId: equipmentHistoryId, ); final now = DateTime.now(); return response.items.where((rent) { return rent.startedAt.isBefore(now) && rent.endedAt.isAfter(now); }).toList(); } /// 종료된 임대 조회 Future> getCompletedRents({int? equipmentHistoryId}) async { final response = await getRents( pageSize: 1000, equipmentHistoryId: equipmentHistoryId, ); final now = DateTime.now(); return response.items.where((rent) { return rent.endedAt.isBefore(now); }).toList(); } /// 예정된 임대 조회 Future> getUpcomingRents({int? equipmentHistoryId}) async { final response = await getRents( pageSize: 1000, equipmentHistoryId: equipmentHistoryId, ); final now = DateTime.now(); return response.items.where((rent) { return rent.startedAt.isAfter(now); }).toList(); } /// 임대 기간 계산 (일수) int calculateRentDays(RentDto rent) { return rent.endedAt.difference(rent.startedAt).inDays; } /// 남은 임대 기간 계산 (일수) int calculateRemainingDays(RentDto rent) { final now = DateTime.now(); if (rent.endedAt.isBefore(now)) { return 0; // 이미 종료됨 } return rent.endedAt.difference(now).inDays; } /// 임대 통계 조회 (단순화) Future getRentStatistics() async { final response = await getRents(pageSize: 1000); final rents = response.items; final now = DateTime.now(); int totalCount = rents.length; int currentCount = rents.where((rent) => rent.startedAt.isBefore(now) && rent.endedAt.isAfter(now) ).length; int completedCount = rents.where((rent) => rent.endedAt.isBefore(now) ).length; int upcomingCount = rents.where((rent) => rent.startedAt.isAfter(now) ).length; return RentStatistics( totalCount: totalCount, currentCount: currentCount, completedCount: completedCount, upcomingCount: upcomingCount, ); } /// Private 헬퍼 메서드 void _validateRentRequest(RentRequestDto request) { // 날짜 검증 (백엔드 스키마 기반) if (request.endedAt.isBefore(request.startedAt) || request.endedAt.isAtSameMomentAs(request.startedAt)) { throw ArgumentError('종료일은 시작일보다 이후여야 합니다.'); } } void _validateRentUpdateRequest(RentUpdateRequestDto request) { // 날짜 검증 (선택적 필드) if (request.startedAt != null && request.endedAt != null) { if (request.endedAt!.isBefore(request.startedAt!) || request.endedAt!.isAtSameMomentAs(request.startedAt!)) { throw ArgumentError('종료일은 시작일보다 이후여야 합니다.'); } } } } /// 임대 통계 모델 (단순화) class RentStatistics { final int totalCount; final int currentCount; final int completedCount; final int upcomingCount; RentStatistics({ required this.totalCount, required this.currentCount, required this.completedCount, required this.upcomingCount, }); }