backup: 사용하지 않는 파일 삭제 전 복구 지점
- 전체 371개 파일 중 82개 미사용 파일 식별 - Phase 1: 33개 파일 삭제 예정 (100% 안전) - Phase 2: 30개 파일 삭제 검토 예정 - Phase 3: 19개 파일 수동 검토 예정 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
280
lib/screens/equipment/controllers/equipment_controller.dart
Normal file
280
lib/screens/equipment/controllers/equipment_controller.dart
Normal file
@@ -0,0 +1,280 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:injectable/injectable.dart';
|
||||
|
||||
import '../../../data/models/equipment/equipment_dto.dart';
|
||||
import '../../../domain/usecases/equipment/get_equipments_usecase.dart';
|
||||
import '../../../domain/usecases/equipment/get_equipment_detail_usecase.dart';
|
||||
import '../../../domain/usecases/equipment/create_equipment_usecase.dart';
|
||||
import '../../../domain/usecases/equipment/update_equipment_usecase.dart';
|
||||
import '../../../domain/usecases/equipment/delete_equipment_usecase.dart';
|
||||
import '../../../domain/usecases/equipment/restore_equipment_usecase.dart';
|
||||
import '../../../core/constants/app_constants.dart';
|
||||
|
||||
@injectable
|
||||
class EquipmentController with ChangeNotifier {
|
||||
final GetEquipmentsUseCase _getEquipmentsUseCase;
|
||||
final GetEquipmentDetailUseCase _getEquipmentDetailUseCase;
|
||||
final CreateEquipmentUseCase _createEquipmentUseCase;
|
||||
final UpdateEquipmentUseCase _updateEquipmentUseCase;
|
||||
final DeleteEquipmentUseCase _deleteEquipmentUseCase;
|
||||
final RestoreEquipmentUseCase _restoreEquipmentUseCase;
|
||||
|
||||
// 상태 관리
|
||||
bool _isLoading = false;
|
||||
String? _error;
|
||||
List<EquipmentDto> _equipments = [];
|
||||
EquipmentDto? _selectedEquipment;
|
||||
|
||||
// 페이지네이션
|
||||
int _currentPage = 1;
|
||||
int _totalPages = 0;
|
||||
int _totalItems = 0;
|
||||
final int _pageSize = AppConstants.equipmentPageSize;
|
||||
|
||||
// 필터
|
||||
String? _searchQuery;
|
||||
bool _includeDeleted = false;
|
||||
|
||||
EquipmentController(
|
||||
this._getEquipmentsUseCase,
|
||||
this._getEquipmentDetailUseCase,
|
||||
this._createEquipmentUseCase,
|
||||
this._updateEquipmentUseCase,
|
||||
this._deleteEquipmentUseCase,
|
||||
this._restoreEquipmentUseCase,
|
||||
);
|
||||
|
||||
// Getters
|
||||
bool get isLoading => _isLoading;
|
||||
String? get error => _error;
|
||||
bool get hasError => _error != null;
|
||||
List<EquipmentDto> get equipments => _equipments;
|
||||
EquipmentDto? get selectedEquipment => _selectedEquipment;
|
||||
int get currentPage => _currentPage;
|
||||
int get totalPages => _totalPages;
|
||||
int get totalItems => _totalItems;
|
||||
int get pageSize => _pageSize;
|
||||
String? get searchQuery => _searchQuery;
|
||||
bool get includeDeleted => _includeDeleted;
|
||||
|
||||
void _setLoading(bool loading) {
|
||||
_isLoading = loading;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void _setError(String? error) {
|
||||
_error = error;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void clearError() {
|
||||
_error = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// 장비 목록 조회
|
||||
Future<void> loadEquipments({
|
||||
int page = 1,
|
||||
int perPage = AppConstants.equipmentPageSize,
|
||||
String? search,
|
||||
bool refresh = false,
|
||||
}) async {
|
||||
try {
|
||||
if (refresh) {
|
||||
_equipments.clear();
|
||||
_currentPage = 1;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
_setLoading(true);
|
||||
|
||||
final params = GetEquipmentsParams(
|
||||
page: page,
|
||||
perPage: perPage,
|
||||
search: search,
|
||||
);
|
||||
|
||||
final response = await _getEquipmentsUseCase(params);
|
||||
|
||||
response.fold(
|
||||
(failure) => _setError('장비 목록을 불러오는데 실패했습니다: ${failure.message}'),
|
||||
(data) {
|
||||
_equipments = data.items;
|
||||
_currentPage = page;
|
||||
_totalPages = data.totalPages;
|
||||
_totalItems = data.totalElements;
|
||||
_searchQuery = search;
|
||||
clearError();
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
_setError('장비 목록을 불러오는데 실패했습니다: $e');
|
||||
} finally {
|
||||
_setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// 장비 상세 조회
|
||||
Future<void> loadEquipment(int id) async {
|
||||
try {
|
||||
_setLoading(true);
|
||||
|
||||
final response = await _getEquipmentDetailUseCase(id);
|
||||
|
||||
response.fold(
|
||||
(failure) => _setError('장비 정보를 불러오는데 실패했습니다: ${failure.message}'),
|
||||
(equipment) {
|
||||
_selectedEquipment = equipment;
|
||||
clearError();
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
_setError('장비 정보를 불러오는데 실패했습니다: $e');
|
||||
} finally {
|
||||
_setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// 장비 생성
|
||||
Future<bool> createEquipment(EquipmentRequestDto request) async {
|
||||
try {
|
||||
_setLoading(true);
|
||||
|
||||
final response = await _createEquipmentUseCase(request);
|
||||
|
||||
return response.fold(
|
||||
(failure) {
|
||||
_setError('장비 생성에 실패했습니다: ${failure.message}');
|
||||
return false;
|
||||
},
|
||||
(equipment) {
|
||||
// 목록 새로고침
|
||||
loadEquipments(refresh: true);
|
||||
clearError();
|
||||
return true;
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
_setError('장비 생성에 실패했습니다: $e');
|
||||
return false;
|
||||
} finally {
|
||||
_setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// 장비 수정
|
||||
Future<bool> updateEquipment(int id, EquipmentUpdateRequestDto request) async {
|
||||
try {
|
||||
_setLoading(true);
|
||||
|
||||
final params = UpdateEquipmentParams(id: id, request: request);
|
||||
final response = await _updateEquipmentUseCase(params);
|
||||
|
||||
return response.fold(
|
||||
(failure) {
|
||||
_setError('장비 수정에 실패했습니다: ${failure.message}');
|
||||
return false;
|
||||
},
|
||||
(equipment) {
|
||||
// 목록 새로고침
|
||||
loadEquipments(refresh: true);
|
||||
clearError();
|
||||
return true;
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
_setError('장비 수정에 실패했습니다: $e');
|
||||
return false;
|
||||
} finally {
|
||||
_setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// 장비 삭제 (Soft Delete)
|
||||
Future<bool> deleteEquipment(int id) async {
|
||||
try {
|
||||
_setLoading(true);
|
||||
|
||||
final response = await _deleteEquipmentUseCase(id);
|
||||
|
||||
return response.fold(
|
||||
(failure) {
|
||||
_setError('장비 삭제에 실패했습니다: ${failure.message}');
|
||||
return false;
|
||||
},
|
||||
(_) {
|
||||
// 목록 새로고침
|
||||
loadEquipments(refresh: true);
|
||||
clearError();
|
||||
return true;
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
_setError('장비 삭제에 실패했습니다: $e');
|
||||
return false;
|
||||
} finally {
|
||||
_setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// 장비 복구
|
||||
Future<bool> restoreEquipment(int id) async {
|
||||
try {
|
||||
_setLoading(true);
|
||||
|
||||
final response = await _restoreEquipmentUseCase(id);
|
||||
|
||||
return response.fold(
|
||||
(failure) {
|
||||
_setError('장비 복구에 실패했습니다: ${failure.message}');
|
||||
return false;
|
||||
},
|
||||
(equipment) {
|
||||
// 목록 새로고침
|
||||
loadEquipments(refresh: true);
|
||||
clearError();
|
||||
return true;
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
_setError('장비 복구에 실패했습니다: $e');
|
||||
return false;
|
||||
} finally {
|
||||
_setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// 페이지 변경
|
||||
Future<void> goToPage(int page) async {
|
||||
if (page < 1 || page > _totalPages || page == _currentPage) return;
|
||||
|
||||
await loadEquipments(
|
||||
page: page,
|
||||
search: _searchQuery,
|
||||
);
|
||||
}
|
||||
|
||||
/// 검색 설정
|
||||
void setSearch(String? search) {
|
||||
_searchQuery = search;
|
||||
loadEquipments(
|
||||
search: search,
|
||||
refresh: true,
|
||||
);
|
||||
}
|
||||
|
||||
/// 새로고침
|
||||
Future<void> refresh() async {
|
||||
await loadEquipments(
|
||||
page: 1,
|
||||
search: _searchQuery,
|
||||
refresh: true,
|
||||
);
|
||||
}
|
||||
|
||||
/// 선택된 장비 초기화
|
||||
void clearSelectedEquipment() {
|
||||
_selectedEquipment = null;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,14 @@ import 'package:flutter/material.dart';
|
||||
import 'package:injectable/injectable.dart';
|
||||
import '../../../data/models/equipment/equipment_dto.dart';
|
||||
import '../../../data/models/company/company_dto.dart';
|
||||
import '../../../data/models/model_dto.dart';
|
||||
import '../../../data/models/model/model_dto.dart';
|
||||
import '../../../data/models/vendor_dto.dart';
|
||||
import '../../../domain/usecases/equipment/create_equipment_usecase.dart';
|
||||
import '../../../domain/usecases/equipment/update_equipment_usecase.dart';
|
||||
import '../../../domain/usecases/equipment/get_equipment_detail_usecase.dart';
|
||||
import '../../../domain/usecases/company/get_companies_usecase.dart';
|
||||
import '../../../domain/usecases/model_usecase.dart';
|
||||
import '../../../domain/usecases/models/get_models_usecase.dart';
|
||||
import '../../../domain/usecases/vendor_usecase.dart';
|
||||
import '../../../core/errors/failures.dart';
|
||||
|
||||
/// 장비 폼 컨트롤러 (생성/수정)
|
||||
@@ -18,19 +20,22 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
final UpdateEquipmentUseCase _updateEquipmentUseCase;
|
||||
final GetEquipmentDetailUseCase _getEquipmentDetailUseCase;
|
||||
final GetCompaniesUseCase _getCompaniesUseCase;
|
||||
final ModelUseCase _modelUseCase;
|
||||
final GetModelsUseCase _getModelsUseCase;
|
||||
final VendorUseCase _vendorUseCase;
|
||||
|
||||
EquipmentFormController(
|
||||
this._createEquipmentUseCase,
|
||||
this._updateEquipmentUseCase,
|
||||
this._getEquipmentDetailUseCase,
|
||||
this._getCompaniesUseCase,
|
||||
this._modelUseCase,
|
||||
this._getModelsUseCase,
|
||||
this._vendorUseCase,
|
||||
);
|
||||
|
||||
// 상태 관리
|
||||
bool _isLoading = false;
|
||||
bool _isLoadingCompanies = false;
|
||||
bool _isLoadingVendors = false;
|
||||
bool _isLoadingModels = false;
|
||||
bool _isSaving = false;
|
||||
String? _error;
|
||||
@@ -41,11 +46,13 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
|
||||
// 드롭다운 데이터
|
||||
List<CompanyDto> _companies = [];
|
||||
List<VendorDto> _vendors = [];
|
||||
List<ModelDto> _models = [];
|
||||
List<ModelDto> _filteredModels = [];
|
||||
|
||||
// 선택된 값
|
||||
int? _selectedCompanyId;
|
||||
int? _selectedVendorId;
|
||||
int? _selectedModelId;
|
||||
|
||||
// 폼 컨트롤러들
|
||||
@@ -57,12 +64,13 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
|
||||
// 날짜 필드들
|
||||
DateTime? _purchasedAt;
|
||||
DateTime _warrantyStartedAt = DateTime.now();
|
||||
DateTime _warrantyEndedAt = DateTime.now().add(const Duration(days: 365));
|
||||
DateTime _warrantyStartedAt = DateTime.now().toUtc();
|
||||
DateTime _warrantyEndedAt = DateTime.now().toUtc().add(const Duration(days: 365));
|
||||
|
||||
// Getters
|
||||
bool get isLoading => _isLoading;
|
||||
bool get isLoadingCompanies => _isLoadingCompanies;
|
||||
bool get isLoadingVendors => _isLoadingVendors;
|
||||
bool get isLoadingModels => _isLoadingModels;
|
||||
bool get isSaving => _isSaving;
|
||||
String? get error => _error;
|
||||
@@ -70,9 +78,11 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
bool get isEditMode => _equipmentId != null;
|
||||
|
||||
List<CompanyDto> get companies => _companies;
|
||||
List<VendorDto> get vendors => _vendors;
|
||||
List<ModelDto> get filteredModels => _filteredModels;
|
||||
|
||||
int? get selectedCompanyId => _selectedCompanyId;
|
||||
int? get selectedVendorId => _selectedVendorId;
|
||||
int? get selectedModelId => _selectedModelId;
|
||||
|
||||
DateTime? get purchasedAt => _purchasedAt;
|
||||
@@ -105,10 +115,11 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
/// 초기 데이터 로드 (회사, 모델)
|
||||
/// 초기 데이터 로드 (회사, 제조사, 모델)
|
||||
Future<void> _loadInitialData() async {
|
||||
await Future.wait([
|
||||
_loadCompanies(),
|
||||
_loadVendors(),
|
||||
_loadModels(),
|
||||
]);
|
||||
}
|
||||
@@ -142,14 +153,41 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
/// 제조사 목록 로드
|
||||
Future<void> _loadVendors() async {
|
||||
_isLoadingVendors = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final vendorResponse = await _vendorUseCase.getVendors(limit: 1000); // 모든 제조사 가져오기
|
||||
_vendors = (vendorResponse.items as List)
|
||||
.whereType<VendorDto>()
|
||||
.where((vendor) => vendor.isActive)
|
||||
.toList()
|
||||
..sort((a, b) => a.name.compareTo(b.name));
|
||||
} catch (e) {
|
||||
_error = '제조사 목록을 불러오는데 실패했습니다: $e';
|
||||
} finally {
|
||||
_isLoadingVendors = false;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
/// 모델 목록 로드
|
||||
Future<void> _loadModels() async {
|
||||
_isLoadingModels = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
_models = await _modelUseCase.getModels();
|
||||
_filteredModels = _models;
|
||||
const params = GetModelsParams(page: 1, perPage: 1000);
|
||||
final result = await _getModelsUseCase(params);
|
||||
result.fold(
|
||||
(failure) => throw Exception(failure.message),
|
||||
(modelResponse) {
|
||||
_models = modelResponse.items;
|
||||
_filteredModels = _models;
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
_error = '모델 목록을 불러오는데 실패했습니다: $e';
|
||||
} finally {
|
||||
@@ -184,9 +222,9 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
warrantyNumberController.text = equipment.warrantyNumber;
|
||||
remarkController.text = equipment.remark ?? '';
|
||||
|
||||
_purchasedAt = equipment.purchasedAt;
|
||||
_warrantyStartedAt = equipment.warrantyStartedAt;
|
||||
_warrantyEndedAt = equipment.warrantyEndedAt;
|
||||
_purchasedAt = equipment.purchasedAt?.toUtc(); // ✅ UTC 타임존으로 변환
|
||||
_warrantyStartedAt = equipment.warrantyStartedAt.toUtc(); // ✅ UTC 타임존으로 변환
|
||||
_warrantyEndedAt = equipment.warrantyEndedAt.toUtc(); // ✅ UTC 타임존으로 변환
|
||||
|
||||
// 선택된 회사에 따라 모델 필터링
|
||||
_filterModelsByCompany(_selectedCompanyId);
|
||||
@@ -197,8 +235,14 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
/// 회사 선택
|
||||
void selectCompany(int? companyId) {
|
||||
_selectedCompanyId = companyId;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// 제조사 선택 (제조사별 모델 필터링 활성화)
|
||||
void selectVendor(int? vendorId) {
|
||||
_selectedVendorId = vendorId;
|
||||
_selectedModelId = null; // 모델 선택 초기화
|
||||
_filterModelsByCompany(companyId);
|
||||
_filterModelsByVendor(vendorId); // 실제 제조사별 필터링 실행
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -208,13 +252,23 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// 회사별 모델 필터링
|
||||
/// 제조사별 모델 필터링 (실제 구현)
|
||||
void _filterModelsByVendor(int? vendorId) {
|
||||
if (vendorId == null) {
|
||||
_filteredModels = _models;
|
||||
} else {
|
||||
// vendorsId 기준으로 실제 필터링 구현
|
||||
_filteredModels = _models.where((model) => model.vendorsId == vendorId).toList();
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// 레거시 호환성을 위한 Company 기반 필터링 (현재는 전체 모델 표시)
|
||||
void _filterModelsByCompany(int? companyId) {
|
||||
if (companyId == null) {
|
||||
_filteredModels = _models;
|
||||
} else {
|
||||
// 실제로는 vendor로 필터링해야 하지만,
|
||||
// 현재 구조에서는 모든 모델을 보여주고 사용자가 선택하도록 함
|
||||
// 회사별 모델 필터링은 현재 구조에서는 불가능 (모든 모델 표시)
|
||||
_filteredModels = _models;
|
||||
}
|
||||
notifyListeners();
|
||||
@@ -222,13 +276,13 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
|
||||
/// 구매일 선택
|
||||
void setPurchasedAt(DateTime? date) {
|
||||
_purchasedAt = date;
|
||||
_purchasedAt = date?.toUtc(); // ✅ UTC 타임존으로 변환
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// 워런티 시작일 선택
|
||||
void setWarrantyStartedAt(DateTime date) {
|
||||
_warrantyStartedAt = date;
|
||||
_warrantyStartedAt = date.toUtc(); // ✅ UTC 타임존으로 변환
|
||||
// 시작일이 종료일보다 늦으면 종료일을 1년 후로 설정
|
||||
if (_warrantyStartedAt.isAfter(_warrantyEndedAt)) {
|
||||
_warrantyEndedAt = _warrantyStartedAt.add(const Duration(days: 365));
|
||||
@@ -238,7 +292,7 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
|
||||
/// 워런티 종료일 선택
|
||||
void setWarrantyEndedAt(DateTime date) {
|
||||
_warrantyEndedAt = date;
|
||||
_warrantyEndedAt = date.toUtc(); // ✅ UTC 타임존으로 변환
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -298,17 +352,17 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
/// 장비 생성
|
||||
Future<bool> _createEquipment() async {
|
||||
final request = EquipmentRequestDto(
|
||||
companiesId: _selectedCompanyId!,
|
||||
modelsId: _selectedModelId!,
|
||||
companiesId: _selectedCompanyId, // 백엔드: Option<i32> - null 허용
|
||||
modelsId: _selectedModelId, // 백엔드: Option<i32> - null 허용
|
||||
serialNumber: serialNumberController.text.trim(),
|
||||
barcode: barcodeController.text.trim().isNotEmpty
|
||||
? barcodeController.text.trim()
|
||||
: null,
|
||||
purchasedAt: _purchasedAt,
|
||||
purchasedAt: (_purchasedAt ?? DateTime.now()).toUtc(), // 백엔드: 필수 필드 - 기본값 제공
|
||||
purchasePrice: int.tryParse(purchasePriceController.text) ?? 0,
|
||||
warrantyNumber: warrantyNumberController.text.trim(),
|
||||
warrantyStartedAt: _warrantyStartedAt,
|
||||
warrantyEndedAt: _warrantyEndedAt,
|
||||
warrantyStartedAt: _warrantyStartedAt.toUtc(), // ✅ UTC 타임존으로 변환
|
||||
warrantyEndedAt: _warrantyEndedAt.toUtc(), // ✅ UTC 타임존으로 변환
|
||||
remark: remarkController.text.trim().isNotEmpty
|
||||
? remarkController.text.trim()
|
||||
: null,
|
||||
@@ -337,11 +391,11 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
barcode: barcodeController.text.trim().isNotEmpty
|
||||
? barcodeController.text.trim()
|
||||
: null,
|
||||
purchasedAt: _purchasedAt,
|
||||
purchasedAt: _purchasedAt?.toUtc(), // ✅ UTC 타임존으로 변환
|
||||
purchasePrice: int.tryParse(purchasePriceController.text) ?? 0,
|
||||
warrantyNumber: warrantyNumberController.text.trim(),
|
||||
warrantyStartedAt: _warrantyStartedAt,
|
||||
warrantyEndedAt: _warrantyEndedAt,
|
||||
warrantyStartedAt: _warrantyStartedAt.toUtc(), // ✅ UTC 타임존으로 변환
|
||||
warrantyEndedAt: _warrantyEndedAt.toUtc(), // ✅ UTC 타임존으로 변환
|
||||
remark: remarkController.text.trim().isNotEmpty
|
||||
? remarkController.text.trim()
|
||||
: null,
|
||||
@@ -376,8 +430,8 @@ class EquipmentFormController extends ChangeNotifier {
|
||||
remarkController.clear();
|
||||
|
||||
_purchasedAt = null;
|
||||
_warrantyStartedAt = DateTime.now();
|
||||
_warrantyEndedAt = DateTime.now().add(const Duration(days: 365));
|
||||
_warrantyStartedAt = DateTime.now().toUtc(); // ✅ UTC 타임존으로 변환
|
||||
_warrantyEndedAt = DateTime.now().toUtc().add(const Duration(days: 365)); // ✅ UTC 타임존으로 변환
|
||||
|
||||
_error = null;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import '../../../data/models/equipment_history_dto.dart';
|
||||
import '../../../domain/usecases/equipment_history_usecase.dart';
|
||||
import '../../../utils/constants.dart';
|
||||
import '../../../core/constants/app_constants.dart';
|
||||
|
||||
class EquipmentHistoryController extends ChangeNotifier {
|
||||
final EquipmentHistoryUseCase _useCase;
|
||||
@@ -18,7 +18,7 @@ class EquipmentHistoryController extends ChangeNotifier {
|
||||
|
||||
// 페이지네이션
|
||||
int _currentPage = 1;
|
||||
int _pageSize = PaginationConstants.defaultPageSize;
|
||||
int _pageSize = AppConstants.historyPageSize;
|
||||
int _totalCount = 0;
|
||||
|
||||
// 필터 (백엔드 실제 필드만)
|
||||
@@ -242,7 +242,7 @@ class EquipmentHistoryController extends ChangeNotifier {
|
||||
try {
|
||||
final result = await _useCase.getEquipmentHistories(
|
||||
page: 1,
|
||||
pageSize: 100,
|
||||
pageSize: AppConstants.bulkPageSize,
|
||||
transactionType: transactionType,
|
||||
equipmentsId: equipmentId,
|
||||
warehousesId: warehouseId,
|
||||
@@ -286,7 +286,7 @@ class EquipmentHistoryController extends ChangeNotifier {
|
||||
try {
|
||||
final result = await _useCase.getEquipmentHistories(
|
||||
page: 1,
|
||||
pageSize: 1000,
|
||||
pageSize: AppConstants.maxBulkPageSize,
|
||||
equipmentsId: equipmentId,
|
||||
warehousesId: warehouseId,
|
||||
);
|
||||
@@ -309,7 +309,7 @@ class EquipmentHistoryController extends ChangeNotifier {
|
||||
try {
|
||||
final result = await _useCase.getEquipmentHistories(
|
||||
page: 1,
|
||||
pageSize: 1000,
|
||||
pageSize: AppConstants.maxBulkPageSize,
|
||||
warehousesId: warehouseId,
|
||||
);
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async' show unawaited;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:superport/models/equipment_unified_model.dart';
|
||||
@@ -13,6 +14,7 @@ import 'package:superport/data/models/equipment_history_dto.dart';
|
||||
///
|
||||
/// 폼의 전체 상태, 유효성, 저장, 데이터 로딩 등 비즈니스 로직을 담당한다.
|
||||
class EquipmentInFormController extends ChangeNotifier {
|
||||
bool _disposed = false;
|
||||
final EquipmentService _equipmentService = GetIt.instance<EquipmentService>();
|
||||
// final WarehouseService _warehouseService = GetIt.instance<WarehouseService>(); // 사용되지 않음 - 제거
|
||||
// final CompanyService _companyService = GetIt.instance<CompanyService>(); // 사용되지 않음 - 제거
|
||||
@@ -37,15 +39,18 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
|
||||
/// canSave 상태 업데이트 (UI 렌더링 문제 해결)
|
||||
void _updateCanSave() {
|
||||
if (_disposed) return; // dispose된 경우 업데이트 방지
|
||||
|
||||
final hasEquipmentNumber = _serialNumber.trim().isNotEmpty;
|
||||
final hasModelsId = _modelsId != null; // models_id 필수
|
||||
final hasWarrantyNumber = warrantyNumberController.text.trim().isNotEmpty; // warranty_number 필수
|
||||
final isNotSaving = !_isSaving;
|
||||
|
||||
final newCanSave = isNotSaving && hasEquipmentNumber && hasModelsId;
|
||||
final newCanSave = isNotSaving && hasEquipmentNumber && hasModelsId && hasWarrantyNumber;
|
||||
|
||||
if (_canSave != newCanSave) {
|
||||
_canSave = newCanSave;
|
||||
print('🚀 [canSave 상태 변경] $_canSave → serialNumber: "$_serialNumber", modelsId: $_modelsId');
|
||||
print('🚀 [canSave 상태 변경] $_canSave → serialNumber: "$_serialNumber", modelsId: $_modelsId, warrantyNumber: "${warrantyNumberController.text}"');
|
||||
notifyListeners(); // 명시적 UI 업데이트
|
||||
}
|
||||
}
|
||||
@@ -55,6 +60,7 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
|
||||
// 입력 상태 변수 (백엔드 API 구조에 맞게 수정)
|
||||
String _serialNumber = ''; // 장비번호 (필수) - private으로 변경
|
||||
String _barcode = ''; // 바코드 (선택사항) - 새로 추가
|
||||
int? _modelsId; // 모델 ID (필수) - Vendor→Model cascade에서 선택
|
||||
int? _vendorId; // 벤더 ID (UI용, API에는 전송 안함)
|
||||
|
||||
@@ -72,6 +78,14 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
String get barcode => _barcode;
|
||||
set barcode(String value) {
|
||||
if (_barcode != value) {
|
||||
_barcode = value;
|
||||
print('DEBUG [Controller] barcode updated: "$_barcode"');
|
||||
}
|
||||
}
|
||||
|
||||
String get manufacturer => _manufacturer;
|
||||
set manufacturer(String value) {
|
||||
if (_manufacturer != value) {
|
||||
@@ -116,12 +130,13 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
|
||||
// Vendor→Model 선택 콜백
|
||||
void onVendorModelChanged(int? vendorId, int? modelId) {
|
||||
if (_disposed) return;
|
||||
_vendorId = vendorId;
|
||||
_modelsId = modelId;
|
||||
_updateCanSave();
|
||||
notifyListeners();
|
||||
}
|
||||
DateTime? purchaseDate; // 구매일
|
||||
DateTime? purchaseDate = DateTime.now(); // 구매일 (기본값: 현재 날짜)
|
||||
double? purchasePrice; // 구매가격
|
||||
|
||||
// 삭제된 필드들 (백엔드 미지원)
|
||||
@@ -142,6 +157,7 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
int _initialStock = 1; // 초기 재고 수량 (기본값: 1)
|
||||
int get initialStock => _initialStock;
|
||||
set initialStock(int value) {
|
||||
if (_disposed) return;
|
||||
if (_initialStock != value && value > 0) {
|
||||
_initialStock = value;
|
||||
notifyListeners();
|
||||
@@ -188,8 +204,17 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
|
||||
EquipmentInFormController({this.equipmentInId}) {
|
||||
isEditMode = equipmentInId != null;
|
||||
_loadDropdownData();
|
||||
|
||||
// 워런티 번호 기본값 설정
|
||||
if (warrantyNumberController.text.isEmpty) {
|
||||
warrantyNumberController.text = 'WR-${DateTime.now().millisecondsSinceEpoch}';
|
||||
}
|
||||
|
||||
_updateCanSave(); // 초기 canSave 상태 설정
|
||||
|
||||
// ✅ 비동기 드롭다운 데이터 로드 시작 (await 불가능하므로 별도 처리)
|
||||
unawaited(_loadDropdownData());
|
||||
|
||||
// 수정 모드일 때 초기 데이터 로드는 initializeForEdit() 메서드로 이동
|
||||
}
|
||||
|
||||
@@ -243,8 +268,28 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
void _processDropdownData(Map<String, dynamic> data) {
|
||||
manufacturers = data['manufacturers'] as List<String>? ?? [];
|
||||
equipmentNames = data['equipment_names'] as List<String>? ?? [];
|
||||
companies = data['companies'] as Map<int, String>? ?? {};
|
||||
warehouses = data['warehouses'] as Map<int, String>? ?? {};
|
||||
|
||||
// ✅ List<Map> → Map<int, String> 안전한 변환 (사전 로드된 데이터)
|
||||
try {
|
||||
final companiesList = data['companies'] as List<dynamic>? ?? [];
|
||||
companies = Map<int, String>.fromIterable(
|
||||
companiesList.where((item) => item != null && item['id'] != null && item['name'] != null),
|
||||
key: (item) => item['id'] as int,
|
||||
value: (item) => item['name'] as String,
|
||||
);
|
||||
|
||||
final warehousesList = data['warehouses'] as List<dynamic>? ?? [];
|
||||
warehouses = Map<int, String>.fromIterable(
|
||||
warehousesList.where((item) => item != null && item['id'] != null && item['name'] != null),
|
||||
key: (item) => item['id'] as int,
|
||||
value: (item) => item['name'] as String,
|
||||
);
|
||||
|
||||
} catch (e) {
|
||||
DebugLogger.logError('사전 로드된 드롭다운 데이터 변환 실패', error: e);
|
||||
companies = {};
|
||||
warehouses = {};
|
||||
}
|
||||
|
||||
DebugLogger.log('드롭다운 데이터 처리 완료', tag: 'EQUIPMENT_IN', data: {
|
||||
'manufacturers_count': manufacturers.length,
|
||||
@@ -255,7 +300,7 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
}
|
||||
|
||||
// 드롭다운 데이터 로드 (매번 API 호출)
|
||||
void _loadDropdownData() async {
|
||||
Future<void> _loadDropdownData() async {
|
||||
try {
|
||||
DebugLogger.log('Equipment 폼 드롭다운 데이터 로드 시작', tag: 'EQUIPMENT_IN');
|
||||
final result = await _lookupsService.getEquipmentFormDropdownData();
|
||||
@@ -268,13 +313,33 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
equipmentNames = [];
|
||||
companies = {};
|
||||
warehouses = {};
|
||||
notifyListeners();
|
||||
if (!_disposed) notifyListeners();
|
||||
},
|
||||
(data) {
|
||||
manufacturers = data['manufacturers'] as List<String>;
|
||||
equipmentNames = data['equipment_names'] as List<String>;
|
||||
companies = data['companies'] as Map<int, String>;
|
||||
warehouses = data['warehouses'] as Map<int, String>;
|
||||
|
||||
// ✅ List<Map> → Map<int, String> 안전한 변환
|
||||
try {
|
||||
final companiesList = data['companies'] as List<dynamic>? ?? [];
|
||||
companies = Map<int, String>.fromIterable(
|
||||
companiesList.where((item) => item != null && item['id'] != null && item['name'] != null),
|
||||
key: (item) => item['id'] as int,
|
||||
value: (item) => item['name'] as String,
|
||||
);
|
||||
|
||||
final warehousesList = data['warehouses'] as List<dynamic>? ?? [];
|
||||
warehouses = Map<int, String>.fromIterable(
|
||||
warehousesList.where((item) => item != null && item['id'] != null && item['name'] != null),
|
||||
key: (item) => item['id'] as int,
|
||||
value: (item) => item['name'] as String,
|
||||
);
|
||||
|
||||
} catch (e) {
|
||||
DebugLogger.logError('드롭다운 데이터 변환 실패', error: e);
|
||||
companies = {};
|
||||
warehouses = {};
|
||||
}
|
||||
|
||||
DebugLogger.log('드롭다운 데이터 로드 성공', tag: 'EQUIPMENT_IN', data: {
|
||||
'manufacturers_count': manufacturers.length,
|
||||
@@ -283,7 +348,7 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
'warehouses_count': warehouses.length,
|
||||
});
|
||||
|
||||
notifyListeners();
|
||||
if (!_disposed) notifyListeners();
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
@@ -292,29 +357,45 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
equipmentNames = [];
|
||||
companies = {};
|
||||
warehouses = {};
|
||||
notifyListeners();
|
||||
if (!_disposed) notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
// 기존의 개별 로드 메서드들은 _loadDropdownData()로 통합됨
|
||||
// warehouseLocations, partnerCompanies 리스트 변수들도 제거됨
|
||||
|
||||
// 전달받은 장비 데이터로 폼 초기화
|
||||
// 전달받은 장비 데이터로 폼 초기화 (간소화: 백엔드 JOIN 데이터 직접 활용)
|
||||
void _loadFromEquipment(EquipmentDto equipment) {
|
||||
serialNumber = equipment.serialNumber;
|
||||
barcode = equipment.barcode ?? '';
|
||||
modelsId = equipment.modelsId;
|
||||
// vendorId는 ModelDto에서 가져와야 함 (필요 시)
|
||||
purchasePrice = equipment.purchasePrice.toDouble();
|
||||
initialStock = 1; // EquipmentDto에는 initialStock 필드가 없음
|
||||
purchasePrice = equipment.purchasePrice > 0 ? equipment.purchasePrice.toDouble() : null;
|
||||
initialStock = 1;
|
||||
selectedCompanyId = equipment.companiesId;
|
||||
// selectedWarehouseId는 현재 위치를 추적해야 함 (EquipmentHistory에서)
|
||||
remarkController.text = equipment.remark ?? '';
|
||||
warrantyNumberController.text = equipment.warrantyNumber;
|
||||
|
||||
// ✅ 간소화: 백엔드 JOIN 데이터 직접 사용 (복잡한 Controller 조회 제거)
|
||||
manufacturer = equipment.vendorName ?? '제조사 정보 없음';
|
||||
name = equipment.modelName ?? '모델 정보 없음';
|
||||
|
||||
// 날짜 필드 설정
|
||||
purchaseDate = equipment.purchasedAt;
|
||||
warrantyStartDate = equipment.warrantyStartedAt;
|
||||
warrantyEndDate = equipment.warrantyEndedAt;
|
||||
|
||||
// TextEditingController 동기화
|
||||
remarkController.text = equipment.remark ?? '';
|
||||
warrantyNumberController.text = equipment.warrantyNumber;
|
||||
|
||||
// 수정 모드에서 입고지 기본값 설정
|
||||
if (isEditMode && selectedWarehouseId == null && warehouses.isNotEmpty) {
|
||||
selectedWarehouseId = warehouses.keys.first;
|
||||
}
|
||||
|
||||
// preloadedEquipment에 저장 (UI에서 JOIN 데이터 접근용)
|
||||
preloadedEquipment = equipment;
|
||||
|
||||
_updateCanSave();
|
||||
notifyListeners(); // UI 즉시 업데이트
|
||||
}
|
||||
|
||||
// 기존 데이터 로드(수정 모드)
|
||||
@@ -404,7 +485,7 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
_updateCanSave(); // 데이터 로드 완료 시 canSave 상태 업데이트
|
||||
notifyListeners();
|
||||
if (!_disposed) notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,7 +523,7 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
_isSaving = true;
|
||||
_error = null;
|
||||
_updateCanSave(); // 저장 시작 시 canSave 상태 업데이트
|
||||
notifyListeners();
|
||||
if (!_disposed) notifyListeners();
|
||||
|
||||
try {
|
||||
|
||||
@@ -501,7 +582,7 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
companiesId: validCompanyId,
|
||||
modelsId: _modelsId,
|
||||
serialNumber: _serialNumber.trim(),
|
||||
barcode: null,
|
||||
barcode: _barcode.trim().isEmpty ? null : _barcode.trim(),
|
||||
purchasedAt: purchaseDate,
|
||||
purchasePrice: purchasePrice?.toInt(),
|
||||
warrantyNumber: validWarrantyNumber,
|
||||
@@ -538,17 +619,19 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
'companiesId': selectedCompanyId,
|
||||
});
|
||||
|
||||
// Equipment 객체를 EquipmentRequestDto로 변환
|
||||
// Equipment 객체를 EquipmentRequestDto로 변환 (백엔드 스펙에 맞게)
|
||||
final createRequest = EquipmentRequestDto(
|
||||
companiesId: selectedCompanyId ?? 0,
|
||||
modelsId: _modelsId ?? 0,
|
||||
companiesId: selectedCompanyId, // 백엔드: Option<i32> - null 허용
|
||||
modelsId: _modelsId, // 백엔드: Option<i32> - null 허용
|
||||
serialNumber: _serialNumber,
|
||||
barcode: null,
|
||||
purchasedAt: null,
|
||||
barcode: _barcode.trim().isEmpty ? null : _barcode.trim(),
|
||||
purchasedAt: (purchaseDate ?? DateTime.now()).toUtc(), // 단순 UTC 변환
|
||||
purchasePrice: purchasePrice?.toInt() ?? 0,
|
||||
warrantyNumber: '',
|
||||
warrantyStartedAt: DateTime.now(),
|
||||
warrantyEndedAt: DateTime.now().add(Duration(days: 365)),
|
||||
warrantyNumber: warrantyNumberController.text.isNotEmpty
|
||||
? warrantyNumberController.text
|
||||
: 'WR-${DateTime.now().millisecondsSinceEpoch}',
|
||||
warrantyStartedAt: warrantyStartDate.toUtc(), // 단순 UTC 변환
|
||||
warrantyEndedAt: warrantyEndDate.toUtc(), // 단순 UTC 변환
|
||||
remark: remarkController.text.isNotEmpty ? remarkController.text : null,
|
||||
);
|
||||
|
||||
@@ -602,21 +685,22 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
return true;
|
||||
} on Failure catch (e) {
|
||||
_error = e.message;
|
||||
notifyListeners();
|
||||
if (!_disposed) notifyListeners();
|
||||
return false;
|
||||
} catch (e) {
|
||||
_error = 'An unexpected error occurred: $e';
|
||||
notifyListeners();
|
||||
if (!_disposed) notifyListeners();
|
||||
return false;
|
||||
} finally {
|
||||
_isSaving = false;
|
||||
_updateCanSave(); // 저장 완료 시 canSave 상태 업데이트
|
||||
notifyListeners();
|
||||
if (!_disposed) notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
// 에러 처리
|
||||
void clearError() {
|
||||
if (_disposed) return;
|
||||
_error = null;
|
||||
notifyListeners();
|
||||
}
|
||||
@@ -625,6 +709,7 @@ class EquipmentInFormController extends ChangeNotifier {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_disposed = true; // dispose 상태 설정
|
||||
remarkController.dispose();
|
||||
warrantyNumberController.dispose();
|
||||
super.dispose();
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:superport/core/services/lookups_service.dart';
|
||||
import 'package:superport/data/models/lookups/lookup_data.dart';
|
||||
import 'package:superport/utils/constants.dart';
|
||||
import 'package:superport/data/models/equipment/equipment_dto.dart';
|
||||
import 'package:superport/domain/usecases/equipment/search_equipment_usecase.dart';
|
||||
|
||||
/// 장비 목록 화면의 상태 및 비즈니스 로직을 담당하는 컨트롤러 (리팩토링 버전)
|
||||
/// BaseListController를 상속받아 공통 기능을 재사용
|
||||
@@ -76,7 +77,7 @@ class EquipmentListController extends BaseListController<UnifiedEquipment> {
|
||||
status: _statusFilter != null ?
|
||||
EquipmentStatusConverter.clientToServer(_statusFilter) : null,
|
||||
search: params.search,
|
||||
// companyId: _companyIdFilter, // 비활성화: EquipmentService에서 지원하지 않음
|
||||
companyId: _companyIdFilter, // ✅ 활성화: 회사별 필터링 지원
|
||||
// includeInactive: _includeInactive, // 비활성화: EquipmentService에서 지원하지 않음
|
||||
),
|
||||
onError: (failure) {
|
||||
@@ -110,6 +111,15 @@ class EquipmentListController extends BaseListController<UnifiedEquipment> {
|
||||
equipmentNumber: dto.serialNumber ?? 'Unknown', // 장비번호 (required)
|
||||
serialNumber: dto.serialNumber ?? 'Unknown', // 시리얼번호 (required)
|
||||
quantity: 1, // 기본 수량
|
||||
// ⚡ [FIX] 누락된 구매 정보 필드들 추가
|
||||
purchasePrice: dto.purchasePrice.toDouble(), // int → double 변환
|
||||
purchaseDate: dto.purchasedAt, // 구매일
|
||||
barcode: dto.barcode, // 바코드
|
||||
remark: dto.remark, // 비고
|
||||
// 보증 정보
|
||||
warrantyLicense: dto.warrantyNumber,
|
||||
warrantyStartDate: dto.warrantyStartedAt,
|
||||
warrantyEndDate: dto.warrantyEndedAt,
|
||||
);
|
||||
|
||||
// 간단한 Company 정보 생성 (사용하지 않으므로 제거)
|
||||
@@ -129,6 +139,10 @@ class EquipmentListController extends BaseListController<UnifiedEquipment> {
|
||||
warehouseLocation: null, // EquipmentDto에 warehouse_name 필드 없음
|
||||
// currentBranch는 EquipmentListDto에 없으므로 null (백엔드 API 구조 변경으로 지점 개념 제거)
|
||||
currentBranch: null,
|
||||
// ⚡ [FIX] 백엔드 직접 제공 필드들 추가 - 화면에서 N/A 문제 해결
|
||||
companyName: dto.companyName, // API company_name → UI 회사명 컬럼
|
||||
vendorName: dto.vendorName, // API vendor_name → UI 제조사 컬럼
|
||||
modelName: dto.modelName, // API model_name → UI 모델명 컬럼
|
||||
);
|
||||
// 🔧 [DEBUG] 변환된 UnifiedEquipment 로깅 (필요 시 활성화)
|
||||
// print('DEBUG [EquipmentListController] UnifiedEquipment ID: ${unifiedEquipment.id}, currentCompany: "${unifiedEquipment.currentCompany}", warehouseLocation: "${unifiedEquipment.warehouseLocation}"');
|
||||
@@ -197,12 +211,34 @@ class EquipmentListController extends BaseListController<UnifiedEquipment> {
|
||||
try {
|
||||
final result = await _lookupsService.getEquipmentFormDropdownData();
|
||||
result.fold(
|
||||
(failure) => throw failure,
|
||||
(data) => cachedDropdownData = data,
|
||||
(failure) {
|
||||
debugPrint('❌ 드롭다운 데이터 로드 실패: ${failure.message}');
|
||||
// 실패해도 빈 데이터로 초기화하여 타입 오류 방지
|
||||
cachedDropdownData = {
|
||||
'manufacturers': <String>[],
|
||||
'equipment_names': <String>[],
|
||||
'companies': <Map<String, dynamic>>[],
|
||||
'warehouses': <Map<String, dynamic>>[],
|
||||
'category1_list': <String>[],
|
||||
'category_combinations': <dynamic>[],
|
||||
};
|
||||
},
|
||||
(data) {
|
||||
debugPrint('✅ 드롭다운 데이터 로드 성공: ${data.keys}');
|
||||
cachedDropdownData = data;
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
print('Failed to preload dropdown data: $e');
|
||||
// 캐시 실패해도 계속 진행
|
||||
debugPrint('❌ 드롭다운 데이터 로드 예외: $e');
|
||||
// 예외 발생 시에도 빈 데이터로 초기화
|
||||
cachedDropdownData = {
|
||||
'manufacturers': <String>[],
|
||||
'equipment_names': <String>[],
|
||||
'companies': <Map<String, dynamic>>[],
|
||||
'warehouses': <Map<String, dynamic>>[],
|
||||
'category1_list': <String>[],
|
||||
'category_combinations': <dynamic>[],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +284,60 @@ class EquipmentListController extends BaseListController<UnifiedEquipment> {
|
||||
loadData(isRefresh: true);
|
||||
}
|
||||
|
||||
/// 시리얼번호로 장비 검색
|
||||
Future<EquipmentDto?> searchBySerial(String serial) async {
|
||||
try {
|
||||
final useCase = GetIt.instance<GetEquipmentBySerialUseCase>();
|
||||
final result = await useCase(serial);
|
||||
|
||||
return result.fold(
|
||||
(failure) {
|
||||
throw Exception(failure.message);
|
||||
},
|
||||
(equipment) => equipment,
|
||||
);
|
||||
} catch (e) {
|
||||
debugPrint('시리얼번호 검색 실패: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
/// 바코드로 장비 검색
|
||||
Future<EquipmentDto?> searchByBarcode(String barcode) async {
|
||||
try {
|
||||
final useCase = GetIt.instance<GetEquipmentByBarcodeUseCase>();
|
||||
final result = await useCase(barcode);
|
||||
|
||||
return result.fold(
|
||||
(failure) {
|
||||
throw Exception(failure.message);
|
||||
},
|
||||
(equipment) => equipment,
|
||||
);
|
||||
} catch (e) {
|
||||
debugPrint('바코드 검색 실패: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
/// 회사별 장비 목록 조회
|
||||
Future<List<EquipmentDto>?> getEquipmentsByCompany(int companyId) async {
|
||||
try {
|
||||
final useCase = GetIt.instance<GetEquipmentsByCompanyUseCase>();
|
||||
final result = await useCase(companyId);
|
||||
|
||||
return result.fold(
|
||||
(failure) {
|
||||
throw Exception(failure.message);
|
||||
},
|
||||
(equipments) => equipments,
|
||||
);
|
||||
} catch (e) {
|
||||
debugPrint('회사별 장비 조회 실패: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
/// 필터 초기화
|
||||
void clearFilters() {
|
||||
_statusFilter = null;
|
||||
|
||||
Reference in New Issue
Block a user