- 전체 371개 파일 중 82개 미사용 파일 식별 - Phase 1: 33개 파일 삭제 예정 (100% 안전) - Phase 2: 30개 파일 삭제 검토 예정 - Phase 3: 19개 파일 수동 검토 예정 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
328 lines
7.9 KiB
Dart
328 lines
7.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:injectable/injectable.dart';
|
|
|
|
import '../../../core/constants/app_constants.dart';
|
|
import '../../../data/models/rent_dto.dart';
|
|
import '../../../domain/usecases/rent_usecase.dart';
|
|
|
|
@injectable
|
|
class RentController with ChangeNotifier {
|
|
final RentUseCase _rentUseCase;
|
|
|
|
// 상태 관리 (단순화)
|
|
bool _isLoading = false;
|
|
String? _error;
|
|
List<RentDto> _rents = []; // 단순한 List 구조
|
|
RentDto? _selectedRent;
|
|
|
|
// 필터링 상태
|
|
String? _selectedStatus;
|
|
int? _selectedEquipmentHistoryId;
|
|
|
|
RentController(this._rentUseCase);
|
|
|
|
// Getters (단순화)
|
|
bool get isLoading => _isLoading;
|
|
String? get error => _error;
|
|
bool get hasError => _error != null;
|
|
RentDto? get selectedRent => _selectedRent;
|
|
String? get selectedStatus => _selectedStatus;
|
|
int? get selectedEquipmentHistoryId => _selectedEquipmentHistoryId;
|
|
|
|
// 편의 메서드 (백엔드 실제 구조)
|
|
List<RentDto> get rents => _rents;
|
|
int get totalRents => _rents.length;
|
|
|
|
// 페이징 관련 getter (UI 호환성)
|
|
int get currentPage => 1; // 단순화된 페이징 구조
|
|
int get totalPages => (_rents.length / AppConstants.rentPageSize).ceil();
|
|
int get totalItems => _rents.length;
|
|
|
|
|
|
void _setLoading(bool loading) {
|
|
_isLoading = loading;
|
|
notifyListeners();
|
|
}
|
|
|
|
void _setError(String? error) {
|
|
_error = error;
|
|
notifyListeners();
|
|
}
|
|
|
|
void clearError() {
|
|
_error = null;
|
|
notifyListeners();
|
|
}
|
|
|
|
/// 임대 목록 조회 (백엔드 실제 파라미터)
|
|
Future<void> loadRents({
|
|
int page = 1,
|
|
int perPage = AppConstants.rentPageSize,
|
|
int? equipmentId,
|
|
int? companyId,
|
|
bool? isActive,
|
|
DateTime? dateFrom,
|
|
DateTime? dateTo,
|
|
bool refresh = false,
|
|
}) async {
|
|
try {
|
|
if (refresh) {
|
|
_rents.clear();
|
|
notifyListeners();
|
|
}
|
|
|
|
_setLoading(true);
|
|
|
|
final response = await _rentUseCase.getRents(
|
|
page: page,
|
|
perPage: perPage,
|
|
equipmentId: equipmentId,
|
|
companyId: companyId,
|
|
isActive: isActive,
|
|
dateFrom: dateFrom,
|
|
dateTo: dateTo,
|
|
);
|
|
|
|
// 올바른 RentListResponse.items 접근
|
|
_rents = response.items;
|
|
|
|
clearError();
|
|
} catch (e) {
|
|
_setError('임대 목록을 불러오는데 실패했습니다: $e');
|
|
} finally {
|
|
_setLoading(false);
|
|
}
|
|
}
|
|
|
|
/// 임대 상세 조회
|
|
Future<void> loadRent(int id) async {
|
|
try {
|
|
_setLoading(true);
|
|
|
|
final response = await _rentUseCase.getRent(id);
|
|
_selectedRent = response; // response가 직접 RentDto
|
|
|
|
clearError();
|
|
} catch (e) {
|
|
_setError('임대 상세 정보를 불러오는데 실패했습니다: $e');
|
|
} finally {
|
|
_setLoading(false);
|
|
}
|
|
}
|
|
|
|
/// 임대 생성 (백엔드 실제 스키마)
|
|
Future<bool> createRent({
|
|
required int equipmentHistoryId,
|
|
required DateTime startedAt,
|
|
required DateTime endedAt,
|
|
}) async {
|
|
try {
|
|
_setLoading(true);
|
|
|
|
await _rentUseCase.createRent(
|
|
RentRequestDto(
|
|
equipmentHistoryId: equipmentHistoryId,
|
|
startedAt: startedAt,
|
|
endedAt: endedAt,
|
|
),
|
|
);
|
|
|
|
// 목록 새로고침
|
|
await loadRents(refresh: true);
|
|
|
|
clearError();
|
|
return true;
|
|
} catch (e) {
|
|
_setError('임대 생성에 실패했습니다: $e');
|
|
return false;
|
|
} finally {
|
|
_setLoading(false);
|
|
}
|
|
}
|
|
|
|
/// 임대 수정 (백엔드 실제 스키마)
|
|
Future<bool> updateRent({
|
|
required int id,
|
|
DateTime? startedAt,
|
|
DateTime? endedAt,
|
|
}) async {
|
|
try {
|
|
_setLoading(true);
|
|
|
|
await _rentUseCase.updateRent(
|
|
id,
|
|
RentUpdateRequestDto(
|
|
startedAt: startedAt,
|
|
endedAt: endedAt,
|
|
),
|
|
);
|
|
|
|
// 목록 새로고침
|
|
await loadRents(refresh: true);
|
|
|
|
clearError();
|
|
return true;
|
|
} catch (e) {
|
|
_setError('임대 수정에 실패했습니다: $e');
|
|
return false;
|
|
} finally {
|
|
_setLoading(false);
|
|
}
|
|
}
|
|
|
|
/// 임대 삭제
|
|
Future<bool> deleteRent(int id) async {
|
|
try {
|
|
_setLoading(true);
|
|
|
|
await _rentUseCase.deleteRent(id);
|
|
|
|
// 목록 새로고침
|
|
await loadRents(refresh: true);
|
|
|
|
clearError();
|
|
return true;
|
|
} catch (e) {
|
|
_setError('임대 삭제에 실패했습니다: $e');
|
|
return false;
|
|
} finally {
|
|
_setLoading(false);
|
|
}
|
|
}
|
|
|
|
|
|
// 백엔드에서 반납/연장 처리는 endedAt 수정으로 처리
|
|
Future<bool> updateRentEndDate(int id, DateTime newEndDate) async {
|
|
return await updateRent(
|
|
id: id,
|
|
endedAt: newEndDate,
|
|
);
|
|
}
|
|
|
|
/// 진행중인 임대 조회 (백엔드 실존 API)
|
|
Future<void> loadActiveRents() async {
|
|
try {
|
|
_setLoading(true);
|
|
|
|
final activeRents = await _rentUseCase.getActiveRents();
|
|
_rents = activeRents;
|
|
|
|
clearError();
|
|
} catch (e) {
|
|
_setError('진행중인 임대를 불러오는데 실패했습니다: $e');
|
|
} finally {
|
|
_setLoading(false);
|
|
}
|
|
}
|
|
|
|
/// 장비별 임대 조회 (백엔드 필터링)
|
|
Future<void> loadRentsByEquipment(int equipmentId) async {
|
|
try {
|
|
_setLoading(true);
|
|
|
|
final equipmentRents = await _rentUseCase.getRentsByEquipment(equipmentId);
|
|
_rents = equipmentRents;
|
|
|
|
clearError();
|
|
} catch (e) {
|
|
_setError('장비별 임대를 불러오는데 실패했습니다: $e');
|
|
} finally {
|
|
_setLoading(false);
|
|
}
|
|
}
|
|
|
|
/// 필터 초기화
|
|
void clearFilters() {
|
|
_selectedStatus = null;
|
|
_selectedEquipmentHistoryId = null;
|
|
notifyListeners();
|
|
}
|
|
|
|
/// 장비 이력 필터 설정 (UI 호환성)
|
|
void setEquipmentHistoryFilter(int? equipmentHistoryId) {
|
|
_selectedEquipmentHistoryId = equipmentHistoryId;
|
|
notifyListeners();
|
|
}
|
|
|
|
/// 선택된 임대 초기화
|
|
void clearSelectedRent() {
|
|
_selectedRent = null;
|
|
notifyListeners();
|
|
}
|
|
|
|
// 백엔드 계산 필드 활용 (강력한 기능)
|
|
String getRentStatus(RentDto rent) {
|
|
// 백엔드에서 계산된 is_active 필드 활용
|
|
if (rent.isActive == true) return '진행중';
|
|
|
|
// 날짜 기반 판단 (Fallback)
|
|
final now = DateTime.now();
|
|
if (rent.startedAt.isAfter(now)) return '예약';
|
|
if (rent.endedAt.isBefore(now)) return '종료';
|
|
return '진행중';
|
|
}
|
|
|
|
// 백엔드에서 계산된 남은 일수 활용
|
|
int getRemainingDays(RentDto rent) {
|
|
return rent.daysRemaining ?? 0;
|
|
}
|
|
|
|
// 백엔드에서 계산된 총 일수 활용
|
|
int getTotalDays(RentDto rent) {
|
|
return rent.totalDays ?? 0;
|
|
}
|
|
|
|
// UI 호환성을 위한 상태 표시명
|
|
String getRentStatusDisplayName(String status) {
|
|
switch (status.toLowerCase()) {
|
|
case '예약':
|
|
case 'reserved':
|
|
return '예약';
|
|
case '진행중':
|
|
case 'active':
|
|
return '진행중';
|
|
case '종료':
|
|
case 'completed':
|
|
return '종료';
|
|
default:
|
|
return status;
|
|
}
|
|
}
|
|
|
|
/// 새로고침
|
|
Future<void> refresh() async {
|
|
await loadRents(refresh: true);
|
|
}
|
|
|
|
/// 임대 반납 처리 (백엔드 PUT API 활용)
|
|
Future<bool> returnRent(int id) async {
|
|
return await updateRent(
|
|
id: id,
|
|
endedAt: DateTime.now(),
|
|
);
|
|
}
|
|
|
|
/// 상태 필터 설정 (UI 호환성)
|
|
void setStatusFilter(String? status) {
|
|
_selectedStatus = status;
|
|
notifyListeners();
|
|
}
|
|
|
|
/// 임대 기간 계산 (UI 호환성)
|
|
int calculateRentDays(DateTime startDate, DateTime endDate) {
|
|
return endDate.difference(startDate).inDays;
|
|
}
|
|
|
|
/// 임대 총 비용 계산 (문자열 날짜 기반)
|
|
double calculateTotalRent(String startDate, String endDate, double dailyRate) {
|
|
try {
|
|
final start = DateTime.parse(startDate);
|
|
final end = DateTime.parse(endDate);
|
|
final days = end.difference(start).inDays;
|
|
return days * dailyRate;
|
|
} catch (e) {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
} |