feat: 소프트 딜리트 기능 전면 구현 완료
Some checks failed
Flutter Test & Quality Check / Test on macos-latest (push) Has been cancelled
Flutter Test & Quality Check / Test on ubuntu-latest (push) Has been cancelled
Flutter Test & Quality Check / Build APK (push) Has been cancelled

## 주요 변경사항
- Company, Equipment, License, Warehouse Location 모든 화면에 소프트 딜리트 구현
- 관리자 권한으로 삭제된 데이터 조회 가능 (includeInactive 파라미터)
- 데이터 무결성 보장을 위한 논리 삭제 시스템 완성

## 기능 개선
- 각 리스트 컨트롤러에 toggleIncludeInactive() 메서드 추가
- UI에 "비활성 포함" 체크박스 추가 (관리자 전용)
- API 데이터소스에 includeInactive 파라미터 지원

## 문서 정리
- 불필요한 문서 파일 제거 및 재구성
- CLAUDE.md 프로젝트 상태 업데이트 (진행률 80%)
- 테스트 결과 문서화 (test20250812v01.md)

## UI 컴포넌트
- Equipment 화면 위젯 모듈화 (custom_dropdown_field, equipment_basic_info_section)
- 폼 유효성 검증 강화

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
JiWoong Sul
2025-08-12 20:02:54 +09:00
parent 1645182b38
commit e7860ae028
48 changed files with 2096 additions and 1242 deletions

View File

@@ -183,48 +183,40 @@ class _EquipmentInFormScreenState extends State<EquipmentInFormScreen> {
equipmentInId: widget.equipmentInId,
);
print('DEBUG: initState - equipmentInId: ${widget.equipmentInId}, isEditMode: ${_controller.isEditMode}');
// 컨트롤러 변경 리스너 추가 (데이터 로드 전에 추가해야 변경사항을 감지할 수 있음)
_controller.addListener(_onControllerUpdated);
// 수정 모드일 때 데이터 로드
if (_controller.isEditMode) {
print('DEBUG: Edit mode detected, loading equipment data...');
WidgetsBinding.instance.addPostFrameCallback((_) async {
await _controller.initializeForEdit();
// 데이터 로드 후 텍스트 컨트롤러 업데이트
_updateTextControllers();
print('DEBUG: Equipment data loaded, calling _updateTextControllers directly');
// 데이터 로드 후 직접 UI 업데이트 호출
if (mounted) {
_updateTextControllers();
}
});
}
_manufacturerFocusNode = FocusNode();
_nameFieldFocusNode = FocusNode();
_partnerController = TextEditingController(
text: _controller.partnerCompany ?? '',
);
// 추가 컨트롤러 초기화
_warehouseController = TextEditingController(
text: _controller.warehouseLocation ?? '',
);
_manufacturerController = TextEditingController(
text: _controller.manufacturer,
);
_equipmentNameController = TextEditingController(text: _controller.name);
_categoryController = TextEditingController(text: _controller.category);
_subCategoryController = TextEditingController(
text: _controller.subCategory,
);
_subSubCategoryController = TextEditingController(
text: _controller.subSubCategory,
);
// 추가 필드 컨트롤러 초기화
_nameController = TextEditingController(text: _controller.name);
_serialNumberController = TextEditingController(text: _controller.serialNumber);
_barcodeController = TextEditingController(text: _controller.barcode);
_quantityController = TextEditingController(text: _controller.quantity.toString());
_warrantyCodeController = TextEditingController(text: _controller.warrantyCode ?? '');
// 컨트롤러들을 빈 값으로 초기화 (나중에 데이터 로드 시 업데이트됨)
_partnerController = TextEditingController();
_warehouseController = TextEditingController();
_manufacturerController = TextEditingController();
_equipmentNameController = TextEditingController();
_categoryController = TextEditingController();
_subCategoryController = TextEditingController();
_subSubCategoryController = TextEditingController();
_nameController = TextEditingController();
_serialNumberController = TextEditingController();
_barcodeController = TextEditingController();
_quantityController = TextEditingController(text: '1');
_warrantyCodeController = TextEditingController();
// 포커스 변경 리스너 추가
_partnerFocusNode.addListener(_onPartnerFocusChange);
@@ -236,11 +228,34 @@ class _EquipmentInFormScreenState extends State<EquipmentInFormScreen> {
_subSubCategoryFocusNode.addListener(_onSubSubCategoryFocusChange);
}
// 컨트롤러 데이터 변경 시 텍스트 컨트롤러 업데이트
void _onControllerUpdated() {
print('DEBUG [_onControllerUpdated] Called - isEditMode: ${_controller.isEditMode}, isLoading: ${_controller.isLoading}, actualEquipmentId: ${_controller.actualEquipmentId}');
// 데이터 로딩이 완료되고 수정 모드일 때 텍스트 컨트롤러 업데이트
// actualEquipmentId가 설정되었다는 것은 데이터가 로드되었다는 의미
if (_controller.isEditMode && !_controller.isLoading && _controller.actualEquipmentId != null) {
print('DEBUG [_onControllerUpdated] Condition met, updating text controllers');
print('DEBUG [_onControllerUpdated] manufacturer: "${_controller.manufacturer}", name: "${_controller.name}"');
_updateTextControllers();
}
}
// 텍스트 컨트롤러 업데이트 메서드
void _updateTextControllers() {
print('DEBUG [_updateTextControllers] Called');
print('DEBUG [_updateTextControllers] Before update:');
print(' manufacturerController.text="${_manufacturerController.text}"');
print(' nameController.text="${_nameController.text}"');
print('DEBUG [_updateTextControllers] Controller values:');
print(' controller.manufacturer="${_controller.manufacturer}"');
print(' controller.name="${_controller.name}"');
print(' controller.serialNumber="${_controller.serialNumber}"');
print(' controller.quantity=${_controller.quantity}');
setState(() {
_manufacturerController.text = _controller.manufacturer;
_nameController.text = _controller.name;
_equipmentNameController.text = _controller.name; // 장비명 컨트롤러 추가
_categoryController.text = _controller.category;
_subCategoryController.text = _controller.subCategory;
_subSubCategoryController.text = _controller.subSubCategory;
@@ -252,10 +267,15 @@ class _EquipmentInFormScreenState extends State<EquipmentInFormScreen> {
_warrantyCodeController.text = _controller.warrantyCode ?? '';
_controller.remarkController.text = _controller.remarkController.text;
});
print('DEBUG [_updateTextControllers] After update:');
print(' manufacturerController.text="${_manufacturerController.text}"');
print(' nameController.text="${_nameController.text}"');
}
@override
void dispose() {
_controller.removeListener(_onControllerUpdated);
_manufacturerFocusNode.dispose();
_nameFieldFocusNode.dispose();
_partnerOverlayEntry?.remove();