- 라이선스 모델 전면 개편 (상세 필드 추가, 계산 필드 구현) - API 응답 처리 개선 (HTTP 상태 코드 기반) - 장비 출고 폼 컨트롤러 추가 - 회사 지점 정보 모델 추가 - 공통 데이터 모델 구조 추가 - 전체 서비스 레이어 API 호출 방식 통일 - UI 컴포넌트 마이너 개선
1158 lines
34 KiB
Dart
1158 lines
34 KiB
Dart
import 'package:superport/models/equipment_unified_model.dart';
|
|
import 'package:superport/models/company_model.dart';
|
|
import 'package:superport/models/user_model.dart';
|
|
import 'package:superport/models/license_model.dart';
|
|
import 'package:superport/models/address_model.dart';
|
|
import 'package:superport/models/warehouse_location_model.dart';
|
|
import 'package:superport/utils/constants.dart'; // 장비 상태/유형 상수 import
|
|
|
|
class MockDataService {
|
|
// 싱글톤 패턴
|
|
static final MockDataService _instance = MockDataService._internal();
|
|
|
|
// 정적 초기화 플래그
|
|
static bool _isInitialized = false;
|
|
|
|
factory MockDataService() => _instance;
|
|
|
|
MockDataService._internal() {
|
|
// 정적 플래그를 사용하여 딱 한 번만 초기화
|
|
if (!_isInitialized) {
|
|
initialize();
|
|
_isInitialized = true;
|
|
}
|
|
}
|
|
|
|
// 모의 데이터 저장소
|
|
final List<EquipmentIn> _equipmentIns = [];
|
|
final List<EquipmentOut> _equipmentOuts = [];
|
|
final List<Company> _companies = [];
|
|
final List<User> _users = [];
|
|
final List<License> _licenses = [];
|
|
final List<WarehouseLocation> _warehouseLocations = [];
|
|
|
|
// ID 카운터
|
|
int _equipmentInIdCounter = 1;
|
|
int _equipmentOutIdCounter = 1;
|
|
int _companyIdCounter = 1;
|
|
int _userIdCounter = 1;
|
|
int _licenseIdCounter = 1;
|
|
int _warehouseLocationIdCounter = 1;
|
|
|
|
// 초기 데이터 생성
|
|
void initialize() {
|
|
// 본사 지점명 및 주소 변경을 위한 함수
|
|
Branch _convertHeadOfficeBranch(Branch branch, int companyId) {
|
|
// 이름이 '본사'인 경우만 변환
|
|
if (branch.name == '본사') {
|
|
// 본사 지점의 이름을 '중앙지점'으로, 주소를 임의의 다른 값으로 변경
|
|
return Branch(
|
|
id: branch.id,
|
|
companyId: companyId,
|
|
name: '중앙지점', // 본사 → 중앙지점으로 변경
|
|
address: Address(
|
|
zipCode: '04533', // 임의의 다른 우편번호
|
|
region: '서울특별시', // 임의의 다른 지역
|
|
detailAddress: '중구 을지로 100', // 임의의 다른 상세주소
|
|
),
|
|
contactName: branch.contactName,
|
|
contactPosition: branch.contactPosition,
|
|
contactPhone: branch.contactPhone,
|
|
contactEmail: branch.contactEmail,
|
|
);
|
|
}
|
|
// 본사가 아니면 그대로 반환
|
|
return branch;
|
|
}
|
|
|
|
// 모의 회사 데이터 추가
|
|
addCompany(
|
|
Company(
|
|
name: 'LG전자',
|
|
address: Address(
|
|
zipCode: '03184',
|
|
region: '서울특별시',
|
|
detailAddress: '종로구 새문안로 58',
|
|
),
|
|
contactName: '김영수',
|
|
contactPosition: '팀장',
|
|
contactPhone: '010-1234-5678',
|
|
contactEmail: 'kim.youngsoo@lg.com',
|
|
companyTypes: [CompanyType.customer, CompanyType.partner], // 고객사+파트너사
|
|
branches: [
|
|
_convertHeadOfficeBranch(
|
|
Branch(
|
|
companyId: 1,
|
|
name: '본사',
|
|
address: Address(
|
|
zipCode: '03184',
|
|
region: '서울특별시',
|
|
detailAddress: '종로구 새문안로 58',
|
|
),
|
|
contactName: '박지은',
|
|
contactPosition: '과장',
|
|
contactPhone: '010-2345-6789',
|
|
contactEmail: 'park.jieun@lg.com',
|
|
),
|
|
1,
|
|
),
|
|
Branch(
|
|
companyId: 1,
|
|
name: '강남지점',
|
|
address: Address(
|
|
zipCode: '06194',
|
|
region: '서울특별시',
|
|
detailAddress: '강남구 테헤란로 534',
|
|
),
|
|
contactName: '이민호',
|
|
contactPosition: '대리',
|
|
contactPhone: '010-3456-7890',
|
|
contactEmail: 'lee.minho@lg.com',
|
|
),
|
|
Branch(
|
|
companyId: 1,
|
|
name: '판교지점',
|
|
address: Address(
|
|
zipCode: '13494',
|
|
region: '경기도',
|
|
detailAddress: '성남시 분당구 판교로 160',
|
|
),
|
|
contactName: '정수진',
|
|
contactPosition: '사원',
|
|
contactPhone: '010-4567-8901',
|
|
contactEmail: 'jung.soojin@lg.com',
|
|
),
|
|
],
|
|
),
|
|
);
|
|
|
|
addCompany(
|
|
Company(
|
|
name: '삼성전자',
|
|
address: Address(
|
|
zipCode: '06620',
|
|
region: '서울특별시',
|
|
detailAddress: '서초구 서초대로 74길 11',
|
|
),
|
|
contactName: '최동욱',
|
|
contactPosition: '부장',
|
|
contactPhone: '010-5678-9012',
|
|
contactEmail: 'choi.dongwook@samsung.com',
|
|
companyTypes: [CompanyType.partner], // 파트너사
|
|
branches: [
|
|
_convertHeadOfficeBranch(
|
|
Branch(
|
|
companyId: 2,
|
|
name: '본사',
|
|
address: Address(
|
|
zipCode: '06620',
|
|
region: '서울특별시',
|
|
detailAddress: '서초구 서초대로 74길 11',
|
|
),
|
|
contactName: '한미영',
|
|
contactPosition: '팀장',
|
|
contactPhone: '010-6789-0123',
|
|
contactEmail: 'han.miyoung@samsung.com',
|
|
),
|
|
2,
|
|
),
|
|
Branch(
|
|
companyId: 2,
|
|
name: '수원사업장',
|
|
address: Address(
|
|
zipCode: '16677',
|
|
region: '경기도',
|
|
detailAddress: '수원시 영통구 삼성로 129',
|
|
),
|
|
contactName: '장현우',
|
|
contactPosition: '과장',
|
|
contactPhone: '010-7890-1234',
|
|
contactEmail: 'jang.hyunwoo@samsung.com',
|
|
),
|
|
],
|
|
),
|
|
);
|
|
|
|
addCompany(
|
|
Company(
|
|
name: '현대자동차',
|
|
address: Address(
|
|
zipCode: '06797',
|
|
region: '서울특별시',
|
|
detailAddress: '서초구 헌릉로 12',
|
|
),
|
|
contactName: '김태희',
|
|
contactPosition: '상무',
|
|
contactPhone: '010-8901-2345',
|
|
contactEmail: 'kim.taehee@hyundai.com',
|
|
companyTypes: [CompanyType.customer], // 고객사
|
|
branches: [
|
|
_convertHeadOfficeBranch(
|
|
Branch(
|
|
companyId: 3,
|
|
name: '본사',
|
|
address: Address(
|
|
zipCode: '06797',
|
|
region: '서울특별시',
|
|
detailAddress: '서초구 헌릉로 12',
|
|
),
|
|
contactName: '이준호',
|
|
contactPosition: '팀장',
|
|
contactPhone: '010-9012-3456',
|
|
contactEmail: 'lee.junho@hyundai.com',
|
|
),
|
|
3,
|
|
),
|
|
Branch(
|
|
companyId: 3,
|
|
name: '울산공장',
|
|
address: Address(
|
|
zipCode: '44100',
|
|
region: '울산광역시',
|
|
detailAddress: '북구 산업로 1000',
|
|
),
|
|
contactName: '송지원',
|
|
contactPosition: '대리',
|
|
contactPhone: '010-0123-4567',
|
|
contactEmail: 'song.jiwon@hyundai.com',
|
|
),
|
|
],
|
|
),
|
|
);
|
|
|
|
addCompany(
|
|
Company(
|
|
name: 'SK하이닉스',
|
|
address: Address(
|
|
zipCode: '17084',
|
|
region: '경기도',
|
|
detailAddress: '이천시 부발읍 경충대로 2091',
|
|
),
|
|
contactName: '박서준',
|
|
contactPosition: '이사',
|
|
contactPhone: '010-1122-3344',
|
|
contactEmail: 'park.seojoon@sk.com',
|
|
companyTypes: [CompanyType.partner, CompanyType.customer], // 파트너사+고객사
|
|
branches: [
|
|
_convertHeadOfficeBranch(
|
|
Branch(
|
|
companyId: 4,
|
|
name: '본사',
|
|
address: Address(
|
|
zipCode: '17084',
|
|
region: '경기도',
|
|
detailAddress: '이천시 부발읍 경충대로 2091',
|
|
),
|
|
contactName: '강지영',
|
|
contactPosition: '팀장',
|
|
contactPhone: '010-2233-4455',
|
|
contactEmail: 'kang.jiyoung@sk.com',
|
|
),
|
|
4,
|
|
),
|
|
Branch(
|
|
companyId: 4,
|
|
name: '청주사업장',
|
|
address: Address(
|
|
zipCode: '28422',
|
|
region: '충청북도',
|
|
detailAddress: '청주시 흥덕구 대신로 215',
|
|
),
|
|
contactName: '윤성민',
|
|
contactPosition: '과장',
|
|
contactPhone: '010-3344-5566',
|
|
contactEmail: 'yoon.sungmin@sk.com',
|
|
),
|
|
],
|
|
),
|
|
);
|
|
|
|
// 모의 사용자 데이터 추가
|
|
addUser(
|
|
User(
|
|
companyId: 1,
|
|
name: '홍길동',
|
|
role: 'S', // 관리자
|
|
),
|
|
);
|
|
|
|
addUser(
|
|
User(
|
|
companyId: 1,
|
|
name: '김철수',
|
|
role: 'M', // 멤버
|
|
),
|
|
);
|
|
|
|
// ===== 실제 네트워크/IT 장비 및 소모품 기반 입고 샘플 데이터 20개 추가 =====
|
|
final List<Map<String, dynamic>> realEquipments = [
|
|
// 시리얼넘버가 있는 네트워크/IT 장비 (수량 1)
|
|
{
|
|
'manufacturer': 'Cisco',
|
|
'name': 'Catalyst 9300',
|
|
'category': '네트워크',
|
|
'subCategory': '스위치',
|
|
'subSubCategory': 'Layer3',
|
|
'serialNumber': 'FDO1234A1BC',
|
|
'barcode': 'CISCO9300-001',
|
|
},
|
|
{
|
|
'manufacturer': 'HPE',
|
|
'name': 'Aruba 2930F',
|
|
'category': '네트워크',
|
|
'subCategory': '스위치',
|
|
'subSubCategory': 'Layer2',
|
|
'serialNumber': 'CN12345678',
|
|
'barcode': 'ARUBA2930F-001',
|
|
},
|
|
{
|
|
'manufacturer': 'Dell',
|
|
'name': 'PowerEdge R740',
|
|
'category': '서버',
|
|
'subCategory': '랙마운트',
|
|
'subSubCategory': '2U',
|
|
'serialNumber': '6JH1234',
|
|
'barcode': 'DELLR740-001',
|
|
},
|
|
{
|
|
'manufacturer': 'Juniper',
|
|
'name': 'EX4300',
|
|
'category': '네트워크',
|
|
'subCategory': '스위치',
|
|
'subSubCategory': 'Layer3',
|
|
'serialNumber': 'JNPR123456',
|
|
'barcode': 'JUNEX4300-001',
|
|
},
|
|
{
|
|
'manufacturer': 'Fortinet',
|
|
'name': 'FortiGate 100F',
|
|
'category': '보안',
|
|
'subCategory': '방화벽',
|
|
'subSubCategory': 'UTM',
|
|
'serialNumber': 'FGT100F1234',
|
|
'barcode': 'FORTI100F-001',
|
|
},
|
|
{
|
|
'manufacturer': 'Mikrotik',
|
|
'name': 'CCR1009',
|
|
'category': '네트워크',
|
|
'subCategory': '라우터',
|
|
'subSubCategory': 'Cloud Core',
|
|
'serialNumber': 'MKTKCCR1009',
|
|
'barcode': 'MIKROCCR1009-001',
|
|
},
|
|
{
|
|
'manufacturer': 'Ubiquiti',
|
|
'name': 'UniFi AP AC Pro',
|
|
'category': '네트워크',
|
|
'subCategory': '무선AP',
|
|
'subSubCategory': 'WiFi5',
|
|
'serialNumber': 'UBNTUAPACPRO',
|
|
'barcode': 'UBNTUAPACPRO-001',
|
|
},
|
|
{
|
|
'manufacturer': 'Netgear',
|
|
'name': 'GS108',
|
|
'category': '네트워크',
|
|
'subCategory': '스위치',
|
|
'subSubCategory': 'SOHO',
|
|
'serialNumber': 'NGGS108SN01',
|
|
'barcode': 'NETGEARGS108-001',
|
|
},
|
|
{
|
|
'manufacturer': 'Aruba',
|
|
'name': 'Instant On 1930',
|
|
'category': '네트워크',
|
|
'subCategory': '스위치',
|
|
'subSubCategory': 'SMB',
|
|
'serialNumber': 'ARUBA1930SN',
|
|
'barcode': 'ARUBA1930-001',
|
|
},
|
|
{
|
|
'manufacturer': 'TP-Link',
|
|
'name': 'TL-SG3428',
|
|
'category': '네트워크',
|
|
'subCategory': '스위치',
|
|
'subSubCategory': 'L2+',
|
|
'serialNumber': 'TPLSG3428SN',
|
|
'barcode': 'TPLINKSG3428-001',
|
|
},
|
|
{
|
|
'manufacturer': '삼성',
|
|
'name': 'Galaxy Book Pro',
|
|
'category': '노트북',
|
|
'subCategory': '울트라북',
|
|
'subSubCategory': 'i7',
|
|
'serialNumber': 'SMSGALBOOKPRO',
|
|
'barcode': 'SMSGALBOOKPRO-001',
|
|
},
|
|
{
|
|
'manufacturer': 'LG',
|
|
'name': 'Gram 16',
|
|
'category': '노트북',
|
|
'subCategory': '경량',
|
|
'subSubCategory': 'i5',
|
|
'serialNumber': 'LGGRAM16SN',
|
|
'barcode': 'LGGRAM16-001',
|
|
},
|
|
{
|
|
'manufacturer': 'Apple',
|
|
'name': 'MacBook Pro 14',
|
|
'category': '노트북',
|
|
'subCategory': 'Mac',
|
|
'subSubCategory': 'M1 Pro',
|
|
'serialNumber': 'MBP14M1PRO',
|
|
'barcode': 'APPLEMBP14-001',
|
|
},
|
|
{
|
|
'manufacturer': 'Lenovo',
|
|
'name': 'ThinkPad X1 Carbon',
|
|
'category': '노트북',
|
|
'subCategory': '비즈니스',
|
|
'subSubCategory': 'Gen9',
|
|
'serialNumber': 'LNVX1CARBON',
|
|
'barcode': 'LENOVOX1-001',
|
|
},
|
|
{
|
|
'manufacturer': 'HP',
|
|
'name': 'EliteBook 840',
|
|
'category': '노트북',
|
|
'subCategory': '비즈니스',
|
|
'subSubCategory': 'G8',
|
|
'serialNumber': 'HPEB840G8',
|
|
'barcode': 'HPEB840-001',
|
|
},
|
|
// 시리얼넘버 없는 소모품 (수량만 존재)
|
|
{
|
|
'manufacturer': 'Logitech',
|
|
'name': 'M720 Triathlon',
|
|
'category': '입력장치',
|
|
'subCategory': '마우스',
|
|
'subSubCategory': '무선',
|
|
'quantity': 15,
|
|
},
|
|
{
|
|
'manufacturer': 'Samsung',
|
|
'name': 'AA-SK2PWBB',
|
|
'category': '입력장치',
|
|
'subCategory': '키보드',
|
|
'subSubCategory': '유선',
|
|
'quantity': 10,
|
|
},
|
|
{
|
|
'manufacturer': 'Anker',
|
|
'name': 'PowerCore 10000',
|
|
'category': '액세서리',
|
|
'subCategory': '보조배터리',
|
|
'subSubCategory': '10000mAh',
|
|
'quantity': 8,
|
|
},
|
|
{
|
|
'manufacturer': 'Xiaomi',
|
|
'name': 'Mi Power Bank 3',
|
|
'category': '액세서리',
|
|
'subCategory': '보조배터리',
|
|
'subSubCategory': '20000mAh',
|
|
'quantity': 12,
|
|
},
|
|
{
|
|
'manufacturer': 'LG',
|
|
'name': 'MK430',
|
|
'category': '입력장치',
|
|
'subCategory': '키보드',
|
|
'subSubCategory': '무선',
|
|
'quantity': 7,
|
|
},
|
|
];
|
|
|
|
// 입고 데이터 생성
|
|
for (int i = 0; i < 20; i++) {
|
|
final eq = realEquipments[i % realEquipments.length];
|
|
addEquipmentIn(
|
|
EquipmentIn(
|
|
equipment: Equipment(
|
|
manufacturer: eq['manufacturer'],
|
|
name: eq['name'],
|
|
category: eq['category'],
|
|
subCategory: eq['subCategory'],
|
|
subSubCategory: eq['subSubCategory'],
|
|
serialNumber: eq['serialNumber'],
|
|
barcode: eq['barcode'],
|
|
quantity: eq['serialNumber'] != null ? 1 : eq['quantity'],
|
|
),
|
|
inDate: DateTime.now().subtract(Duration(days: 2 * i)),
|
|
warehouseLocation: '입고지${i % 3 + 1}',
|
|
partnerCompany: '파트너사${i % 4 + 1}',
|
|
type: i % 2 == 0 ? EquipmentType.new_ : EquipmentType.used,
|
|
remark:
|
|
eq['serialNumber'] != null
|
|
? '실제 네트워크/IT 장비 입고 샘플'
|
|
: '실제 소모품 입고 샘플',
|
|
),
|
|
);
|
|
}
|
|
|
|
// 출고 데이터 생성
|
|
for (int i = 0; i < 20; i++) {
|
|
final eq = realEquipments[(i + 3) % realEquipments.length];
|
|
addEquipmentOut(
|
|
EquipmentOut(
|
|
equipment: Equipment(
|
|
manufacturer: eq['manufacturer'],
|
|
name: eq['name'],
|
|
category: eq['category'],
|
|
subCategory: eq['subCategory'],
|
|
subSubCategory: eq['subSubCategory'],
|
|
serialNumber: eq['serialNumber'],
|
|
barcode: eq['barcode'],
|
|
quantity: eq['serialNumber'] != null ? 1 : eq['quantity'],
|
|
),
|
|
outDate: DateTime.now().subtract(Duration(days: 3 * i)),
|
|
status: EquipmentStatus.out,
|
|
company: '출고회사${i % 4 + 1}',
|
|
manager: '담당자${i % 6 + 1}',
|
|
license: '라이센스${i % 2 + 1}',
|
|
returnDate: null,
|
|
returnType: null,
|
|
remark:
|
|
eq['serialNumber'] != null
|
|
? '실제 네트워크/IT 장비 출고 샘플'
|
|
: '실제 소모품 출고 샘플',
|
|
),
|
|
);
|
|
}
|
|
|
|
// 대여 데이터 생성
|
|
for (int i = 0; i < 20; i++) {
|
|
final eq = realEquipments[(i + 5) % realEquipments.length];
|
|
addEquipmentOut(
|
|
EquipmentOut(
|
|
equipment: Equipment(
|
|
manufacturer: eq['manufacturer'],
|
|
name: eq['name'],
|
|
category: eq['category'],
|
|
subCategory: eq['subCategory'],
|
|
subSubCategory: eq['subSubCategory'],
|
|
serialNumber: eq['serialNumber'],
|
|
barcode: eq['barcode'],
|
|
quantity: eq['serialNumber'] != null ? 1 : eq['quantity'],
|
|
),
|
|
outDate: DateTime.now().subtract(Duration(days: 4 * i)),
|
|
status: EquipmentStatus.rent, // 대여 상태 코드 'T'
|
|
company: '대여회사${i % 5 + 1}',
|
|
manager: '대여담당자${i % 7 + 1}',
|
|
license: '대여라이센스${i % 3 + 1}',
|
|
returnDate:
|
|
eq['serialNumber'] != null
|
|
? DateTime.now().subtract(Duration(days: 4 * i - 2))
|
|
: null,
|
|
returnType: eq['serialNumber'] != null ? '정상반납' : null,
|
|
remark:
|
|
eq['serialNumber'] != null
|
|
? '실제 네트워크/IT 장비 대여 샘플'
|
|
: '실제 소모품 대여 샘플',
|
|
),
|
|
);
|
|
}
|
|
|
|
// 유지보수 샘플 데이터(12개월, 모든 방문주기/점검형태 조합) 추가
|
|
final List<String> visitCycles = [
|
|
'미방문',
|
|
'장애시 지원',
|
|
'월',
|
|
'격월',
|
|
'분기',
|
|
'반기',
|
|
'년',
|
|
];
|
|
final List<String> inspectionTypes = ['방문', '원격'];
|
|
for (final visit in visitCycles) {
|
|
for (final inspection in inspectionTypes) {
|
|
addLicense(
|
|
License(
|
|
licenseKey: 'LIC-${DateTime.now().millisecondsSinceEpoch}-$visit-$inspection',
|
|
productName: '12개월,$visit,$inspection',
|
|
companyId: 1,
|
|
purchaseDate: DateTime.now(),
|
|
expiryDate: DateTime.now().add(const Duration(days: 365)),
|
|
remark: '방문주기: $visit',
|
|
),
|
|
);
|
|
}
|
|
}
|
|
// 1번 유지보수 샘플 아이템 삭제
|
|
deleteLicense(1);
|
|
|
|
// 입고지 mock 데이터 추가
|
|
addWarehouseLocation(
|
|
WarehouseLocation(
|
|
id: _warehouseLocationIdCounter,
|
|
name: '당사',
|
|
address: Address(
|
|
zipCode: '01234',
|
|
region: '서울특별시',
|
|
detailAddress: '강남구 테헤란로 1',
|
|
),
|
|
remark: '본사 전용 입고지',
|
|
),
|
|
);
|
|
addWarehouseLocation(
|
|
WarehouseLocation(
|
|
id: _warehouseLocationIdCounter,
|
|
name: '서울 입고지',
|
|
address: Address(
|
|
zipCode: '04524',
|
|
region: '서울특별시',
|
|
detailAddress: '중구 퇴계로 100',
|
|
),
|
|
remark: '본사 창고',
|
|
),
|
|
);
|
|
addWarehouseLocation(
|
|
WarehouseLocation(
|
|
id: _warehouseLocationIdCounter,
|
|
name: '부산 입고지',
|
|
address: Address(
|
|
zipCode: '48942',
|
|
region: '부산광역시',
|
|
detailAddress: '중구 중앙대로 50',
|
|
),
|
|
remark: '부산지점 창고',
|
|
),
|
|
);
|
|
}
|
|
|
|
// 장비 입고 관련 메소드
|
|
List<EquipmentIn> getAllEquipmentIns() {
|
|
return _equipmentIns;
|
|
}
|
|
|
|
EquipmentIn? getEquipmentInById(int id) {
|
|
try {
|
|
return _equipmentIns.firstWhere((e) => e.id == id);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
void addEquipmentIn(EquipmentIn equipmentIn) {
|
|
final newEquipmentIn = EquipmentIn(
|
|
id: _equipmentInIdCounter++,
|
|
equipment: equipmentIn.equipment,
|
|
inDate: equipmentIn.inDate,
|
|
status: equipmentIn.status,
|
|
type: equipmentIn.type,
|
|
warehouseLocation: equipmentIn.warehouseLocation,
|
|
partnerCompany: equipmentIn.partnerCompany,
|
|
);
|
|
_equipmentIns.add(newEquipmentIn);
|
|
}
|
|
|
|
void updateEquipmentIn(EquipmentIn equipmentIn) {
|
|
final index = _equipmentIns.indexWhere((e) => e.id == equipmentIn.id);
|
|
if (index != -1) {
|
|
_equipmentIns[index] = equipmentIn;
|
|
}
|
|
}
|
|
|
|
void deleteEquipmentIn(int id) {
|
|
_equipmentIns.removeWhere((e) => e.id == id);
|
|
}
|
|
|
|
// 장비 출고 관련 메소드
|
|
List<EquipmentOut> getAllEquipmentOuts() {
|
|
return _equipmentOuts;
|
|
}
|
|
|
|
EquipmentOut? getEquipmentOutById(int id) {
|
|
try {
|
|
return _equipmentOuts.firstWhere((e) => e.id == id);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// 기존 입고 장비를 출고 상태로 변경
|
|
void changeEquipmentStatus(int equipmentInId, EquipmentOut equipmentOut) {
|
|
// 장비 상태 변경 시작: 입고 ID $equipmentInId
|
|
|
|
// 입고된 장비를 찾습니다
|
|
final index = _equipmentIns.indexWhere((e) => e.id == equipmentInId);
|
|
if (index != -1) {
|
|
// 장비를 찾음: ${_equipmentIns[index].equipment.name}
|
|
|
|
// 입고 장비의 상태를 출고(O)로 변경
|
|
final equipment = _equipmentIns[index].equipment;
|
|
_equipmentIns[index] = EquipmentIn(
|
|
id: _equipmentIns[index].id,
|
|
equipment: equipment,
|
|
inDate: _equipmentIns[index].inDate,
|
|
status: 'O', // 상태를 출고로 변경
|
|
);
|
|
// 입고 장비 상태를 "O"로 변경: ID ${_equipmentIns[index].id}
|
|
|
|
// 출고 정보 저장
|
|
final newEquipmentOut = EquipmentOut(
|
|
id: _equipmentOutIdCounter++,
|
|
equipment: equipment,
|
|
outDate: equipmentOut.outDate,
|
|
status: equipmentOut.status,
|
|
company: equipmentOut.company,
|
|
manager: equipmentOut.manager,
|
|
license: equipmentOut.license,
|
|
returnDate: equipmentOut.returnDate,
|
|
returnType: equipmentOut.returnType,
|
|
);
|
|
_equipmentOuts.add(newEquipmentOut);
|
|
// 출고 정보 추가: ID ${newEquipmentOut.id}
|
|
|
|
// 장비 상태 변경 완료
|
|
} else {
|
|
// 오류: ID $equipmentInId인 입고 장비를 찾을 수 없음
|
|
}
|
|
}
|
|
|
|
void addEquipmentOut(EquipmentOut equipmentOut) {
|
|
final newEquipmentOut = EquipmentOut(
|
|
id: _equipmentOutIdCounter++,
|
|
equipment: equipmentOut.equipment,
|
|
outDate: equipmentOut.outDate,
|
|
status: equipmentOut.status,
|
|
company: equipmentOut.company,
|
|
manager: equipmentOut.manager,
|
|
license: equipmentOut.license,
|
|
returnDate: equipmentOut.returnDate,
|
|
returnType: equipmentOut.returnType,
|
|
);
|
|
_equipmentOuts.add(newEquipmentOut);
|
|
}
|
|
|
|
void updateEquipmentOut(EquipmentOut equipmentOut) {
|
|
final index = _equipmentOuts.indexWhere((e) => e.id == equipmentOut.id);
|
|
if (index != -1) {
|
|
_equipmentOuts[index] = equipmentOut;
|
|
}
|
|
}
|
|
|
|
void deleteEquipmentOut(int id) {
|
|
_equipmentOuts.removeWhere((e) => e.id == id);
|
|
}
|
|
|
|
// 제조사명 목록 반환
|
|
List<String> getAllManufacturers() {
|
|
final manufacturers = <String>[];
|
|
|
|
for (final equipment in _equipmentIns) {
|
|
if (equipment.equipment.manufacturer.isNotEmpty &&
|
|
!manufacturers.contains(equipment.equipment.manufacturer)) {
|
|
manufacturers.add(equipment.equipment.manufacturer);
|
|
}
|
|
}
|
|
|
|
for (final equipment in _equipmentOuts) {
|
|
if (equipment.equipment.manufacturer.isNotEmpty &&
|
|
!manufacturers.contains(equipment.equipment.manufacturer)) {
|
|
manufacturers.add(equipment.equipment.manufacturer);
|
|
}
|
|
}
|
|
|
|
// 기본 제조사 추가 (초기 데이터가 없을 경우)
|
|
manufacturers.addAll([
|
|
'삼성',
|
|
'삼성전자',
|
|
'삼성디스플레이',
|
|
'LG',
|
|
'LG전자',
|
|
'LG디스플레이',
|
|
'Apple',
|
|
'HP',
|
|
'Dell',
|
|
'Lenovo',
|
|
'Asus',
|
|
'Acer',
|
|
'한성컴퓨터',
|
|
'기가바이트',
|
|
'MSI',
|
|
'Intel',
|
|
'AMD',
|
|
]);
|
|
|
|
return manufacturers..sort();
|
|
}
|
|
|
|
// 모든 장비명 가져오기
|
|
List<String> getAllEquipmentNames() {
|
|
final equipmentNames = <String>[];
|
|
|
|
for (final equipment in _equipmentIns) {
|
|
if (equipment.equipment.name.isNotEmpty &&
|
|
!equipmentNames.contains(equipment.equipment.name)) {
|
|
equipmentNames.add(equipment.equipment.name);
|
|
}
|
|
}
|
|
|
|
for (final equipment in _equipmentOuts) {
|
|
if (equipment.equipment.name.isNotEmpty &&
|
|
!equipmentNames.contains(equipment.equipment.name)) {
|
|
equipmentNames.add(equipment.equipment.name);
|
|
}
|
|
}
|
|
|
|
return equipmentNames..sort();
|
|
}
|
|
|
|
// 회사명 목록 가져오기
|
|
List<String> getAllCompanyNames() {
|
|
return _companies.map((company) => company.name).toList();
|
|
}
|
|
|
|
// 지점명 목록 가져오기
|
|
List<String> getAllBranchNames() {
|
|
final branchNames = <String>[];
|
|
|
|
for (final company in _companies) {
|
|
if (company.branches != null) {
|
|
for (final branch in company.branches!) {
|
|
if (branch.name.isNotEmpty && !branchNames.contains(branch.name)) {
|
|
branchNames.add(branch.name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return branchNames..sort();
|
|
}
|
|
|
|
// 회사 관련 메소드
|
|
List<Company> getAllCompanies() {
|
|
return List.from(_companies);
|
|
}
|
|
|
|
Company? getCompanyById(int id) {
|
|
try {
|
|
return _companies.firstWhere((company) => company.id == id);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// 이름으로 회사를 찾는 메서드 추가
|
|
Company? findCompanyByName(String name) {
|
|
if (name.isEmpty) return null;
|
|
|
|
try {
|
|
return _companies.firstWhere(
|
|
(company) => company.name.toLowerCase() == name.toLowerCase(),
|
|
);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
void addCompany(Company company) {
|
|
final newCompany = Company(
|
|
id: _companyIdCounter++,
|
|
name: company.name,
|
|
address: company.address,
|
|
contactName: company.contactName,
|
|
contactPosition: company.contactPosition,
|
|
contactPhone: company.contactPhone,
|
|
contactEmail: company.contactEmail,
|
|
companyTypes: company.companyTypes,
|
|
remark: company.remark,
|
|
branches:
|
|
company.branches?.map((branch) {
|
|
return Branch(
|
|
id:
|
|
branch.id ??
|
|
(_companyIdCounter * 100 +
|
|
(company.branches?.indexOf(branch) ?? 0)),
|
|
companyId: _companyIdCounter - 1,
|
|
name: branch.name,
|
|
address: branch.address,
|
|
contactName: branch.contactName,
|
|
contactPosition: branch.contactPosition,
|
|
contactPhone: branch.contactPhone,
|
|
contactEmail: branch.contactEmail,
|
|
remark: branch.remark,
|
|
);
|
|
}).toList(),
|
|
);
|
|
_companies.add(newCompany);
|
|
}
|
|
|
|
void updateCompany(Company company) {
|
|
final index = _companies.indexWhere((c) => c.id == company.id);
|
|
if (index != -1) {
|
|
_companies[index] = company;
|
|
}
|
|
}
|
|
|
|
void updateBranch(int companyId, Branch branch) {
|
|
final companyIndex = _companies.indexWhere((c) => c.id == companyId);
|
|
if (companyIndex != -1) {
|
|
final company = _companies[companyIndex];
|
|
if (company.branches != null) {
|
|
final branchIndex = company.branches!.indexWhere((b) => b.id == branch.id);
|
|
if (branchIndex != -1) {
|
|
company.branches![branchIndex] = branch;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void deleteCompany(int id) {
|
|
_companies.removeWhere((c) => c.id == id);
|
|
}
|
|
|
|
// 사용자 관련 메소드
|
|
List<User> getAllUsers() {
|
|
return _users;
|
|
}
|
|
|
|
User? getUserById(int id) {
|
|
try {
|
|
return _users.firstWhere((u) => u.id == id);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
void addUser(User user) {
|
|
final newUser = User(
|
|
id: _userIdCounter++,
|
|
companyId: user.companyId,
|
|
branchId: user.branchId,
|
|
name: user.name,
|
|
role: user.role,
|
|
position: user.position,
|
|
email: user.email,
|
|
phoneNumbers: user.phoneNumbers,
|
|
);
|
|
_users.add(newUser);
|
|
}
|
|
|
|
void updateUser(User user) {
|
|
final index = _users.indexWhere((u) => u.id == user.id);
|
|
if (index != -1) {
|
|
_users[index] = user;
|
|
}
|
|
}
|
|
|
|
void deleteUser(int id) {
|
|
_users.removeWhere((u) => u.id == id);
|
|
}
|
|
|
|
// 라이센스 관련 메소드
|
|
List<License> getAllLicenses() {
|
|
return _licenses;
|
|
}
|
|
|
|
License? getLicenseById(int id) {
|
|
try {
|
|
return _licenses.firstWhere((l) => l.id == id);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
void addLicense(License license) {
|
|
final newLicense = License(
|
|
id: _licenseIdCounter++,
|
|
licenseKey: license.licenseKey,
|
|
productName: license.productName,
|
|
vendor: license.vendor,
|
|
licenseType: license.licenseType,
|
|
userCount: license.userCount,
|
|
purchaseDate: license.purchaseDate,
|
|
expiryDate: license.expiryDate,
|
|
purchasePrice: license.purchasePrice,
|
|
companyId: license.companyId,
|
|
branchId: license.branchId,
|
|
assignedUserId: license.assignedUserId,
|
|
remark: license.remark,
|
|
isActive: license.isActive,
|
|
);
|
|
_licenses.add(newLicense);
|
|
}
|
|
|
|
void updateLicense(License license) {
|
|
final index = _licenses.indexWhere((l) => l.id == license.id);
|
|
if (index != -1) {
|
|
_licenses[index] = license;
|
|
}
|
|
}
|
|
|
|
void deleteLicense(int id) {
|
|
_licenses.removeWhere((l) => l.id == id);
|
|
}
|
|
|
|
// 장비 통합 관련 메소드
|
|
List<UnifiedEquipment> getAllEquipments() {
|
|
final List<UnifiedEquipment> allEquipments = [];
|
|
|
|
// 입고 장비를 통합 목록에 추가 (출고 상태가 아닌 장비만)
|
|
for (var equipmentIn in _equipmentIns) {
|
|
// 상태가 'O'(출고)가 아닌 장비만 목록에 포함
|
|
if (equipmentIn.status != 'O') {
|
|
allEquipments.add(
|
|
UnifiedEquipment.fromEquipmentIn(
|
|
equipmentIn.id,
|
|
equipmentIn.equipment,
|
|
equipmentIn.inDate,
|
|
equipmentIn.status,
|
|
type: equipmentIn.type,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
// 출고 장비를 통합 목록에 추가
|
|
for (var equipmentOut in _equipmentOuts) {
|
|
allEquipments.add(
|
|
UnifiedEquipment(
|
|
id: equipmentOut.id,
|
|
equipment: equipmentOut.equipment,
|
|
date: equipmentOut.outDate,
|
|
status: equipmentOut.status,
|
|
),
|
|
);
|
|
}
|
|
|
|
// 날짜 기준 내림차순 정렬 (최신 항목이 먼저 표시)
|
|
allEquipments.sort((a, b) => b.date.compareTo(a.date));
|
|
|
|
return allEquipments;
|
|
}
|
|
|
|
// ID로 통합 장비 조회
|
|
UnifiedEquipment? getEquipmentById(int id, String status) {
|
|
// 상태가 입고인 경우
|
|
if (status == 'I') {
|
|
final equipmentIn = getEquipmentInById(id);
|
|
if (equipmentIn != null) {
|
|
return UnifiedEquipment(
|
|
id: equipmentIn.id,
|
|
equipment: equipmentIn.equipment,
|
|
date: equipmentIn.inDate,
|
|
status: equipmentIn.status,
|
|
);
|
|
}
|
|
}
|
|
// 상태가 출고인 경우
|
|
else if (status == 'O') {
|
|
final equipmentOut = getEquipmentOutById(id);
|
|
if (equipmentOut != null) {
|
|
return UnifiedEquipment(
|
|
id: equipmentOut.id,
|
|
equipment: equipmentOut.equipment,
|
|
date: equipmentOut.outDate,
|
|
status: equipmentOut.status,
|
|
);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// 통합 장비 삭제
|
|
void deleteEquipment(int id, String status) {
|
|
if (status == 'I') {
|
|
deleteEquipmentIn(id);
|
|
} else if (status == 'O') {
|
|
deleteEquipmentOut(id);
|
|
}
|
|
}
|
|
|
|
// 입고지 전체 조회
|
|
List<WarehouseLocation> getAllWarehouseLocations() {
|
|
return _warehouseLocations;
|
|
}
|
|
|
|
// 입고지 ID로 조회
|
|
WarehouseLocation? getWarehouseLocationById(int id) {
|
|
try {
|
|
return _warehouseLocations.firstWhere((w) => w.id == id);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// 입고지 추가
|
|
void addWarehouseLocation(WarehouseLocation location) {
|
|
final newLocation = WarehouseLocation(
|
|
id: _warehouseLocationIdCounter++,
|
|
name: location.name,
|
|
address: location.address,
|
|
remark: location.remark,
|
|
);
|
|
_warehouseLocations.add(newLocation);
|
|
}
|
|
|
|
// 입고지 수정
|
|
void updateWarehouseLocation(WarehouseLocation location) {
|
|
final index = _warehouseLocations.indexWhere((w) => w.id == location.id);
|
|
if (index != -1) {
|
|
_warehouseLocations[index] = location;
|
|
}
|
|
}
|
|
|
|
// 입고지 삭제
|
|
void deleteWarehouseLocation(int id) {
|
|
_warehouseLocations.removeWhere((w) => w.id == id);
|
|
}
|
|
|
|
// 카테고리명 목록 반환
|
|
List<String> getAllCategories() {
|
|
final categories = <String>[];
|
|
for (final equipment in _equipmentIns) {
|
|
if (equipment.equipment.category.isNotEmpty &&
|
|
!categories.contains(equipment.equipment.category)) {
|
|
categories.add(equipment.equipment.category);
|
|
}
|
|
}
|
|
for (final equipment in _equipmentOuts) {
|
|
if (equipment.equipment.category.isNotEmpty &&
|
|
!categories.contains(equipment.equipment.category)) {
|
|
categories.add(equipment.equipment.category);
|
|
}
|
|
}
|
|
return categories..sort();
|
|
}
|
|
|
|
// 서브카테고리명 목록 반환
|
|
List<String> getAllSubCategories() {
|
|
final subCategories = <String>[];
|
|
for (final equipment in _equipmentIns) {
|
|
if (equipment.equipment.subCategory.isNotEmpty &&
|
|
!subCategories.contains(equipment.equipment.subCategory)) {
|
|
subCategories.add(equipment.equipment.subCategory);
|
|
}
|
|
}
|
|
for (final equipment in _equipmentOuts) {
|
|
if (equipment.equipment.subCategory.isNotEmpty &&
|
|
!subCategories.contains(equipment.equipment.subCategory)) {
|
|
subCategories.add(equipment.equipment.subCategory);
|
|
}
|
|
}
|
|
return subCategories..sort();
|
|
}
|
|
|
|
// 서브서브카테고리명 목록 반환
|
|
List<String> getAllSubSubCategories() {
|
|
final subSubCategories = <String>[];
|
|
for (final equipment in _equipmentIns) {
|
|
if (equipment.equipment.subSubCategory.isNotEmpty &&
|
|
!subSubCategories.contains(equipment.equipment.subSubCategory)) {
|
|
subSubCategories.add(equipment.equipment.subSubCategory);
|
|
}
|
|
}
|
|
for (final equipment in _equipmentOuts) {
|
|
if (equipment.equipment.subSubCategory.isNotEmpty &&
|
|
!subSubCategories.contains(equipment.equipment.subSubCategory)) {
|
|
subSubCategories.add(equipment.equipment.subSubCategory);
|
|
}
|
|
}
|
|
return subSubCategories..sort();
|
|
}
|
|
}
|