import 'package:injectable/injectable.dart'; import '../../core/constants/app_constants.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 perPage = AppConstants.rentPageSize, int? equipmentId, int? companyId, bool? isActive, DateTime? dateFrom, DateTime? dateTo, }) async { return await _repository.getRents( page: page, perPage: perPage, equipmentId: equipmentId, companyId: companyId, isActive: isActive, dateFrom: dateFrom, dateTo: dateTo, ); } /// 임대 상세 조회 (백엔드 스키마 기반) 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); } /// 진행중인 임대 조회 (백엔드 실존 API) Future> getActiveRents() async { return await _repository.getActiveRents(); } /// 장비별 임대 조회 (백엔드 필터링) Future> getRentsByEquipment(int equipmentId) async { final response = await getRents( perPage: 1000, equipmentId: equipmentId, ); return response.items; } /// 회사별 임대 조회 (백엔드 필터링) Future> getRentsByCompany(int companyId) async { final response = await getRents( perPage: 1000, companyId: companyId, ); return response.items; } /// 특정 기간 내 임대 조회 (백엔드 날짜 필터링) Future> getRentsByDateRange({ required DateTime dateFrom, required DateTime dateTo, int? equipmentId, int? companyId, }) async { final response = await getRents( perPage: 1000, equipmentId: equipmentId, companyId: companyId, dateFrom: dateFrom, dateTo: dateTo, ); return response.items; } /// 현재 진행 중인 임대 조회 (백엔드 계산값 활용) Future> getCurrentRents({int? equipmentId, int? companyId}) async { final response = await getRents( perPage: 1000, equipmentId: equipmentId, companyId: companyId, isActive: true, // 백엔드 필터링 ); return response.items; } /// 종료된 임대 조회 (백엔드 필터링) Future> getCompletedRents({int? equipmentId, int? companyId}) async { final response = await getRents( perPage: 1000, equipmentId: equipmentId, companyId: companyId, isActive: false, // 백엔드 필터링 ); return response.items; } /// 예정된 임대 조회 (백엔드 필터링) Future> getUpcomingRents({int? equipmentId, int? companyId}) async { final now = DateTime.now(); final tomorrow = now.add(Duration(days: 1)); final response = await getRents( perPage: 1000, equipmentId: equipmentId, companyId: companyId, dateFrom: tomorrow, // 내일부터 시작하는 임대 ); return response.items; } /// 임대 기간 계산 (일수) 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(perPage: 1000); final rents = response.items; // 백엔드 계산 필드 활용 int totalCount = rents.length; int currentCount = rents.where((rent) => rent.isActive == true).length; int completedCount = rents.where((rent) => rent.isActive == false && rent.endedAt.isBefore(DateTime.now())).length; int upcomingCount = rents.where((rent) => rent.startedAt.isAfter(DateTime.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, }); }