import 'package:dartz/dartz.dart'; import 'package:superport/core/errors/exceptions.dart'; import 'package:superport/core/errors/failures.dart'; import 'package:superport/data/datasources/remote/equipment_remote_datasource.dart'; import 'package:superport/data/models/equipment/equipment_dto.dart'; import 'package:superport/data/models/equipment/equipment_in_request.dart'; import 'package:superport/data/models/equipment/equipment_out_request.dart'; import 'package:superport/data/models/equipment/equipment_request.dart'; import 'package:superport/domain/repositories/equipment_repository.dart'; import 'package:superport/models/equipment_unified_model.dart'; class EquipmentRepositoryImpl implements EquipmentRepository { final EquipmentRemoteDataSource _remoteDataSource; EquipmentRepositoryImpl(this._remoteDataSource); @override Future>> getEquipmentIns({ int? page, int? limit, String? search, String? sortBy, String? sortOrder, }) async { try { final response = await _remoteDataSource.getEquipments( page: page ?? 1, perPage: limit ?? 20, status: 'IN_WAREHOUSE', search: search, ); final equipmentIns = response.items.map((dto) => EquipmentIn( id: dto.id, equipment: Equipment( id: dto.id, manufacturer: dto.manufacturer, name: dto.modelName ?? '', category: 'N/A', // EquipmentListDto에는 category 필드가 없음 subCategory: 'N/A', // EquipmentListDto에는 category 필드가 없음 subSubCategory: 'N/A', // EquipmentListDto에는 category 필드가 없음 serialNumber: dto.serialNumber, quantity: 1, ), inDate: dto.createdAt, status: 'I', type: '신제품', warehouseLocation: dto.warehouseName, remark: null, ) ).toList(); return Right(equipmentIns); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 입고 목록 조회 실패: $e')); } } @override Future> getEquipmentInById(int id) async { try { final response = await _remoteDataSource.getEquipmentDetail(id); final equipmentIn = EquipmentIn( id: response.id, equipment: Equipment( id: response.id, manufacturer: response.manufacturer, name: response.modelName ?? '', category: response.category1 ?? '', subCategory: response.category2 ?? '', subSubCategory: response.category3 ?? '', serialNumber: response.serialNumber, barcode: response.barcode, quantity: 1, inDate: response.purchaseDate, remark: response.remark, ), inDate: response.purchaseDate ?? DateTime.now(), status: 'I', type: '신제품', warehouseLocation: null, remark: response.remark, ); return Right(equipmentIn); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 입고 상세 조회 실패: $e')); } } @override Future> createEquipmentIn(EquipmentIn equipmentIn) async { try { final request = EquipmentInRequest( equipmentId: equipmentIn.equipment.id ?? 0, quantity: equipmentIn.equipment.quantity, warehouseLocationId: 0, // TODO: warehouseLocation string을 ID로 변환 필요 notes: equipmentIn.remark, ); final response = await _remoteDataSource.equipmentIn(request); final newEquipmentIn = EquipmentIn( id: response.transactionId, equipment: Equipment( id: response.equipmentId, manufacturer: 'N/A', // 트랜잭션 응답에는 제조사 정보 없음 name: 'N/A', // 트랜잭션 응답에는 모델명 정보 없음 category: 'N/A', // 트랜잭션 응답에는 카테고리 정보 없음 subCategory: 'N/A', // 트랜잭션 응답에는 카테고리 정보 없음 subSubCategory: 'N/A', // 트랜잭션 응답에는 카테고리 정보 없음 serialNumber: null, quantity: response.quantity, ), inDate: response.transactionDate, status: 'I', type: '신제품', warehouseLocation: null, remark: response.message, ); return Right(newEquipmentIn); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 입고 생성 실패: $e')); } } @override Future> updateEquipmentIn(int id, EquipmentIn equipmentIn) async { try { final request = UpdateEquipmentRequest( manufacturer: equipmentIn.equipment.manufacturer, modelName: equipmentIn.equipment.name, category1: equipmentIn.equipment.category, category2: equipmentIn.equipment.subCategory, category3: equipmentIn.equipment.subSubCategory, serialNumber: equipmentIn.equipment.serialNumber, barcode: equipmentIn.equipment.barcode, purchaseDate: equipmentIn.inDate, remark: equipmentIn.remark, ); final response = await _remoteDataSource.updateEquipment(id, request); final updatedEquipmentIn = EquipmentIn( id: response.id, equipment: Equipment( id: response.id, manufacturer: response.manufacturer, name: response.modelName ?? '', category: response.category1 ?? '', subCategory: response.category2 ?? '', subSubCategory: response.category3 ?? '', serialNumber: response.serialNumber, barcode: response.barcode, quantity: 1, inDate: response.purchaseDate, remark: response.remark, ), inDate: response.purchaseDate ?? DateTime.now(), status: 'I', type: '신제품', warehouseLocation: null, remark: response.remark, ); return Right(updatedEquipmentIn); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 입고 수정 실패: $e')); } } @override Future> deleteEquipmentIn(int id) async { try { await _remoteDataSource.deleteEquipment(id); return const Right(null); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 입고 삭제 실패: $e')); } } @override Future>> getEquipmentOuts({ int? page, int? limit, String? search, String? sortBy, String? sortOrder, }) async { try { final response = await _remoteDataSource.getEquipments( page: page ?? 1, perPage: limit ?? 20, status: 'SHIPPED', search: search, ); final equipmentOuts = response.items.map((dto) => EquipmentOut( id: dto.id, equipment: Equipment( id: dto.id, manufacturer: dto.manufacturer, name: dto.modelName ?? '', category: 'N/A', // EquipmentListDto에는 category 필드가 없음 subCategory: 'N/A', // EquipmentListDto에는 category 필드가 없음 subSubCategory: 'N/A', // EquipmentListDto에는 category 필드가 없음 serialNumber: dto.serialNumber, quantity: 1, ), outDate: dto.createdAt, status: 'O', company: dto.companyName, remark: null, ) ).toList(); return Right(equipmentOuts); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 출고 목록 조회 실패: $e')); } } @override Future> getEquipmentOutById(int id) async { try { final response = await _remoteDataSource.getEquipmentDetail(id); final equipmentOut = EquipmentOut( id: response.id, equipment: Equipment( id: response.id, manufacturer: response.manufacturer, name: response.modelName ?? '', category: response.category1 ?? '', subCategory: response.category2 ?? '', subSubCategory: response.category3 ?? '', serialNumber: response.serialNumber, barcode: response.barcode, quantity: 1, inDate: response.purchaseDate, remark: response.remark, ), outDate: DateTime.now(), // TODO: 실제 출고일 정보 필요 status: 'O', company: null, remark: response.remark, ); return Right(equipmentOut); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 출고 상세 조회 실패: $e')); } } @override Future> createEquipmentOut(EquipmentOut equipmentOut) async { try { final request = EquipmentOutRequest( equipmentId: equipmentOut.equipment.id ?? 0, quantity: equipmentOut.equipment.quantity, companyId: 0, // TODO: company string을 ID로 변환 필요 branchId: null, notes: equipmentOut.remark, ); final response = await _remoteDataSource.equipmentOut(request); final newEquipmentOut = EquipmentOut( id: response.transactionId, equipment: Equipment( id: response.equipmentId, manufacturer: 'N/A', // 트랜잭션 응답에는 제조사 정보 없음 name: 'N/A', // 트랜잭션 응답에는 모델명 정보 없음 category: 'N/A', // 트랜잭션 응답에는 카테고리 정보 없음 subCategory: 'N/A', // 트랜잭션 응답에는 카테고리 정보 없음 subSubCategory: 'N/A', // 트랜잭션 응답에는 카테고리 정보 없음 serialNumber: null, quantity: response.quantity, ), outDate: response.transactionDate, status: 'O', company: null, remark: response.message, ); return Right(newEquipmentOut); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 출고 생성 실패: $e')); } } @override Future> updateEquipmentOut(int id, EquipmentOut equipmentOut) async { try { final request = UpdateEquipmentRequest( currentCompanyId: 0, // TODO: company string을 ID로 변환 필요 currentBranchId: null, remark: equipmentOut.remark, ); final response = await _remoteDataSource.updateEquipment(id, request); final updatedEquipmentOut = EquipmentOut( id: response.id, equipment: Equipment( id: response.id, manufacturer: response.manufacturer, name: response.modelName ?? '', category: response.category1 ?? '', subCategory: response.category2 ?? '', subSubCategory: response.category3 ?? '', serialNumber: response.serialNumber, barcode: response.barcode, quantity: 1, inDate: response.purchaseDate, remark: response.remark, ), outDate: DateTime.now(), // TODO: 실제 출고일 정보 필요 status: 'O', company: null, remark: response.remark, ); return Right(updatedEquipmentOut); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 출고 수정 실패: $e')); } } @override Future> deleteEquipmentOut(int id) async { try { await _remoteDataSource.deleteEquipment(id); return const Right(null); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 출고 삭제 실패: $e')); } } @override Future>> createBatchEquipmentOut(List equipmentOuts) async { try { final results = []; for (final equipmentOut in equipmentOuts) { final request = EquipmentOutRequest( equipmentId: equipmentOut.equipment.id ?? 0, quantity: equipmentOut.equipment.quantity, companyId: 0, // TODO: company string을 ID로 변환 필요 branchId: null, notes: equipmentOut.remark, ); final response = await _remoteDataSource.equipmentOut(request); results.add(EquipmentOut( id: response.transactionId, equipment: Equipment( id: response.equipmentId, manufacturer: 'N/A', // 트랜잭션 응답에는 제조사 정보 없음 name: 'N/A', // 트랜잭션 응답에는 모델명 정보 없음 category: 'N/A', // 트랜잭션 응답에는 카테고리 정보 없음 subCategory: 'N/A', // 트랜잭션 응답에는 카테고리 정보 없음 subSubCategory: 'N/A', // 트랜잭션 응답에는 카테고리 정보 없음 serialNumber: null, quantity: response.quantity, ), outDate: response.transactionDate, status: 'O', company: null, remark: response.message, )); } return Right(results); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 일괄 출고 실패: $e')); } } @override Future>> getManufacturers() async { try { // TODO: 실제 API 엔드포인트 구현 필요 return const Right(['삼성', 'LG', 'Apple', 'Dell', 'HP']); } catch (e) { return Left(ServerFailure(message: '제조사 목록 조회 실패: $e')); } } @override Future>> getEquipmentNames() async { try { // TODO: 실제 API 엔드포인트 구현 필요 return const Right(['노트북', '모니터', '키보드', '마우스', '프린터']); } catch (e) { return Left(ServerFailure(message: '장비명 목록 조회 실패: $e')); } } @override Future>> getEquipmentHistory(int equipmentId) async { try { final history = await _remoteDataSource.getEquipmentHistory(equipmentId); return Right(history); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 이력 조회 실패: $e')); } } @override Future>> searchEquipment({ String? manufacturer, String? name, String? category, String? serialNumber, }) async { try { final response = await _remoteDataSource.getEquipments( search: serialNumber ?? name ?? manufacturer, page: 1, perPage: 50, ); final equipments = response.items.map((dto) => Equipment( id: dto.id, manufacturer: dto.manufacturer, name: dto.modelName ?? '', category: 'N/A', // EquipmentListDto에는 category 필드가 없음 subCategory: 'N/A', // EquipmentListDto에는 category 필드가 없음 subSubCategory: 'N/A', // EquipmentListDto에는 category 필드가 없음 serialNumber: dto.serialNumber, quantity: 1, ) ).toList(); return Right(equipments); } on ServerException catch (e) { return Left(ServerFailure(message: e.message ?? '서버 오류가 발생했습니다')); } catch (e) { return Left(ServerFailure(message: '장비 검색 실패: $e')); } } }