fix: API 응답 파싱 오류 수정 및 에러 처리 개선
주요 변경사항: - 창고 관리 API 응답 구조와 DTO 불일치 수정 - WarehouseLocationDto에 code, manager_phone 필드 추가 - RemoteDataSource에서 API 응답을 DTO 구조에 맞게 변환 - 회사 관리 API 응답 파싱 오류 수정 - CompanyResponse의 필수 필드를 nullable로 변경 - PaginatedResponse 구조 매핑 로직 개선 - 에러 처리 및 로깅 개선 - Service Layer에 상세 에러 로깅 추가 - Controller에서 에러 타입별 처리 - 새로운 유틸리티 추가 - ResponseInterceptor: API 응답 정규화 - DebugLogger: 디버깅 도구 - HealthCheckService: 서버 상태 확인 - 문서화 - API 통합 테스트 가이드 - 에러 분석 보고서 - 리팩토링 계획서
This commit is contained in:
@@ -18,7 +18,7 @@ class Environment {
|
||||
|
||||
/// API 베이스 URL
|
||||
static String get apiBaseUrl {
|
||||
return dotenv.env['API_BASE_URL'] ?? 'http://localhost:8080/api/v1';
|
||||
return dotenv.env['API_BASE_URL'] ?? 'https://superport.naturebridgeai.com/api/v1';
|
||||
}
|
||||
|
||||
/// API 타임아웃 (밀리초)
|
||||
@@ -33,16 +33,49 @@ class Environment {
|
||||
return loggingStr.toLowerCase() == 'true';
|
||||
}
|
||||
|
||||
/// API 사용 여부 (false면 Mock 데이터 사용)
|
||||
static bool get useApi {
|
||||
final useApiStr = dotenv.env['USE_API'];
|
||||
print('[Environment] USE_API 원시값: $useApiStr');
|
||||
if (useApiStr == null || useApiStr.isEmpty) {
|
||||
print('[Environment] USE_API가 설정되지 않음, 기본값 true 사용');
|
||||
return true;
|
||||
}
|
||||
final result = useApiStr.toLowerCase() == 'true';
|
||||
print('[Environment] USE_API 최종값: $result');
|
||||
return result;
|
||||
}
|
||||
|
||||
/// 환경 초기화
|
||||
static Future<void> initialize([String? environment]) async {
|
||||
_environment = environment ??
|
||||
const String.fromEnvironment('ENVIRONMENT', defaultValue: dev);
|
||||
|
||||
final envFile = _getEnvFile();
|
||||
print('[Environment] 환경 초기화 중...');
|
||||
print('[Environment] 현재 환경: $_environment');
|
||||
print('[Environment] 환경 파일: $envFile');
|
||||
|
||||
try {
|
||||
await dotenv.load(fileName: envFile);
|
||||
print('[Environment] 환경 파일 로드 성공');
|
||||
|
||||
// 모든 환경 변수 출력
|
||||
print('[Environment] 로드된 환경 변수:');
|
||||
dotenv.env.forEach((key, value) {
|
||||
print('[Environment] $key: $value');
|
||||
});
|
||||
|
||||
print('[Environment] --- 설정 값 확인 ---');
|
||||
print('[Environment] API Base URL: ${dotenv.env['API_BASE_URL'] ?? '설정되지 않음'}');
|
||||
print('[Environment] API Timeout: ${dotenv.env['API_TIMEOUT'] ?? '설정되지 않음'}');
|
||||
print('[Environment] 로깅 활성화: ${dotenv.env['ENABLE_LOGGING'] ?? '설정되지 않음'}');
|
||||
print('[Environment] API 사용 (원시값): ${dotenv.env['USE_API'] ?? '설정되지 않음'}');
|
||||
print('[Environment] API 사용 (getter): $useApi');
|
||||
} catch (e) {
|
||||
print('Failed to load env file $envFile: $e');
|
||||
print('[Environment] ⚠️ 환경 파일 로드 실패: $envFile');
|
||||
print('[Environment] 에러 상세: $e');
|
||||
print('[Environment] 기본값을 사용합니다.');
|
||||
// .env 파일이 없어도 계속 진행
|
||||
}
|
||||
}
|
||||
|
||||
214
lib/core/utils/debug_logger.dart
Normal file
214
lib/core/utils/debug_logger.dart
Normal file
@@ -0,0 +1,214 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer' as developer;
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// 디버깅을 위한 고급 로거 클래스
|
||||
class DebugLogger {
|
||||
static const String _separator = '=================================================='; // 50개의 '='
|
||||
|
||||
/// 디버그 모드에서만 로그 출력
|
||||
static void log(
|
||||
String message, {
|
||||
String? tag,
|
||||
Object? data,
|
||||
StackTrace? stackTrace,
|
||||
bool isError = false,
|
||||
}) {
|
||||
if (!kDebugMode) return;
|
||||
|
||||
final timestamp = DateTime.now().toIso8601String();
|
||||
final logTag = tag ?? 'DEBUG';
|
||||
|
||||
developer.log(
|
||||
'''
|
||||
$_separator
|
||||
[$logTag] $timestamp
|
||||
$message
|
||||
${data != null ? '\nData: ${_formatData(data)}' : ''}
|
||||
${stackTrace != null ? '\nStackTrace:\n$stackTrace' : ''}
|
||||
$_separator
|
||||
''',
|
||||
name: logTag,
|
||||
error: isError ? data : null,
|
||||
stackTrace: isError ? stackTrace : null,
|
||||
time: DateTime.now(),
|
||||
);
|
||||
}
|
||||
|
||||
/// API 요청 로깅
|
||||
static void logApiRequest({
|
||||
required String method,
|
||||
required String url,
|
||||
Map<String, dynamic>? headers,
|
||||
dynamic data,
|
||||
}) {
|
||||
log(
|
||||
'API 요청',
|
||||
tag: 'API_REQUEST',
|
||||
data: {
|
||||
'method': method,
|
||||
'url': url,
|
||||
'headers': headers,
|
||||
'data': data,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// API 응답 로깅
|
||||
static void logApiResponse({
|
||||
required String url,
|
||||
required int? statusCode,
|
||||
Map<String, dynamic>? headers,
|
||||
dynamic data,
|
||||
}) {
|
||||
log(
|
||||
'API 응답',
|
||||
tag: 'API_RESPONSE',
|
||||
data: {
|
||||
'url': url,
|
||||
'statusCode': statusCode,
|
||||
'headers': headers,
|
||||
'data': data,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 에러 로깅
|
||||
static void logError(
|
||||
String message, {
|
||||
Object? error,
|
||||
StackTrace? stackTrace,
|
||||
Map<String, dynamic>? additionalData,
|
||||
}) {
|
||||
log(
|
||||
'에러 발생: $message',
|
||||
tag: 'ERROR',
|
||||
data: {
|
||||
'error': error?.toString(),
|
||||
'additionalData': additionalData,
|
||||
},
|
||||
stackTrace: stackTrace,
|
||||
isError: true,
|
||||
);
|
||||
}
|
||||
|
||||
/// 로그인 프로세스 전용 로깅
|
||||
static void logLogin(String step, {Map<String, dynamic>? data}) {
|
||||
log(
|
||||
'로그인 프로세스: $step',
|
||||
tag: 'LOGIN',
|
||||
data: data,
|
||||
);
|
||||
}
|
||||
|
||||
/// 데이터 포맷팅
|
||||
static String _formatData(Object data) {
|
||||
try {
|
||||
if (data is Map || data is List) {
|
||||
return const JsonEncoder.withIndent(' ').convert(data);
|
||||
}
|
||||
return data.toString();
|
||||
} catch (e) {
|
||||
return data.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/// 디버그 모드 확인
|
||||
static bool get isDebugMode => kDebugMode;
|
||||
|
||||
/// Assert를 사용한 런타임 검증 (디버그 모드에서만)
|
||||
static void assertValid(
|
||||
bool condition,
|
||||
String message, {
|
||||
Map<String, dynamic>? data,
|
||||
}) {
|
||||
assert(() {
|
||||
if (!condition) {
|
||||
logError('Assertion failed: $message', additionalData: data);
|
||||
}
|
||||
return condition;
|
||||
}(), message);
|
||||
}
|
||||
|
||||
/// JSON 파싱 검증 및 로깅
|
||||
static T? parseJsonWithLogging<T>(
|
||||
dynamic json,
|
||||
T Function(Map<String, dynamic>) parser, {
|
||||
required String objectName,
|
||||
}) {
|
||||
try {
|
||||
if (json == null) {
|
||||
logError('$objectName 파싱 실패: JSON이 null입니다');
|
||||
return null;
|
||||
}
|
||||
|
||||
if (json is! Map<String, dynamic>) {
|
||||
logError(
|
||||
'$objectName 파싱 실패: 잘못된 JSON 형식',
|
||||
additionalData: {
|
||||
'actualType': json.runtimeType.toString(),
|
||||
'expectedType': 'Map<String, dynamic>',
|
||||
},
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
log(
|
||||
'$objectName 파싱 시작',
|
||||
tag: 'JSON_PARSE',
|
||||
data: json,
|
||||
);
|
||||
|
||||
final result = parser(json);
|
||||
|
||||
log(
|
||||
'$objectName 파싱 성공',
|
||||
tag: 'JSON_PARSE',
|
||||
);
|
||||
|
||||
return result;
|
||||
} catch (e, stackTrace) {
|
||||
logError(
|
||||
'$objectName 파싱 중 예외 발생',
|
||||
error: e,
|
||||
stackTrace: stackTrace,
|
||||
additionalData: {
|
||||
'json': json,
|
||||
},
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 응답 데이터 구조 검증
|
||||
static bool validateResponseStructure(
|
||||
Map<String, dynamic> response,
|
||||
List<String> requiredFields, {
|
||||
String? responseName,
|
||||
}) {
|
||||
final missing = <String>[];
|
||||
|
||||
for (final field in requiredFields) {
|
||||
if (!response.containsKey(field)) {
|
||||
missing.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
if (missing.isNotEmpty) {
|
||||
logError(
|
||||
'${responseName ?? 'Response'} 구조 검증 실패',
|
||||
additionalData: {
|
||||
'missingFields': missing,
|
||||
'actualFields': response.keys.toList(),
|
||||
},
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
log(
|
||||
'${responseName ?? 'Response'} 구조 검증 성공',
|
||||
tag: 'VALIDATION',
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
61
lib/core/utils/equipment_status_converter.dart
Normal file
61
lib/core/utils/equipment_status_converter.dart
Normal file
@@ -0,0 +1,61 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
/// 서버와 클라이언트 간 장비 상태 코드 변환 유틸리티
|
||||
class EquipmentStatusConverter {
|
||||
/// 서버 상태 코드를 클라이언트 상태 코드로 변환
|
||||
static String serverToClient(String? serverStatus) {
|
||||
if (serverStatus == null) return 'E';
|
||||
|
||||
switch (serverStatus.toLowerCase()) {
|
||||
case 'available':
|
||||
return 'I'; // 입고
|
||||
case 'inuse':
|
||||
return 'T'; // 대여
|
||||
case 'maintenance':
|
||||
return 'R'; // 수리
|
||||
case 'disposed':
|
||||
return 'D'; // 손상
|
||||
default:
|
||||
return 'E'; // 기타
|
||||
}
|
||||
}
|
||||
|
||||
/// 클라이언트 상태 코드를 서버 상태 코드로 변환
|
||||
static String clientToServer(String? clientStatus) {
|
||||
if (clientStatus == null) return 'available';
|
||||
|
||||
switch (clientStatus) {
|
||||
case 'I': // 입고
|
||||
return 'available';
|
||||
case 'O': // 출고
|
||||
return 'available';
|
||||
case 'T': // 대여
|
||||
return 'inuse';
|
||||
case 'R': // 수리
|
||||
return 'maintenance';
|
||||
case 'D': // 손상
|
||||
return 'disposed';
|
||||
case 'L': // 분실
|
||||
return 'disposed';
|
||||
case 'E': // 기타
|
||||
return 'available';
|
||||
default:
|
||||
return 'available';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Freezed JsonConverter for equipment status
|
||||
class EquipmentStatusJsonConverter implements JsonConverter<String, String> {
|
||||
const EquipmentStatusJsonConverter();
|
||||
|
||||
@override
|
||||
String fromJson(String json) {
|
||||
return EquipmentStatusConverter.serverToClient(json);
|
||||
}
|
||||
|
||||
@override
|
||||
String toJson(String object) {
|
||||
return EquipmentStatusConverter.clientToServer(object);
|
||||
}
|
||||
}
|
||||
335
lib/core/utils/login_diagnostics.dart
Normal file
335
lib/core/utils/login_diagnostics.dart
Normal file
@@ -0,0 +1,335 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:superport/core/utils/debug_logger.dart';
|
||||
import 'package:superport/core/config/environment.dart' as env;
|
||||
|
||||
/// 로그인 문제 진단을 위한 유틸리티 클래스
|
||||
class LoginDiagnostics {
|
||||
/// 로그인 프로세스 전체 진단
|
||||
static Future<Map<String, dynamic>> runFullDiagnostics() async {
|
||||
final results = <String, dynamic>{};
|
||||
|
||||
try {
|
||||
// 1. 환경 설정 확인
|
||||
results['environment'] = _checkEnvironment();
|
||||
|
||||
// 2. 네트워크 연결 확인
|
||||
results['network'] = await _checkNetworkConnectivity();
|
||||
|
||||
// 3. API 엔드포인트 확인
|
||||
results['apiEndpoint'] = await _checkApiEndpoint();
|
||||
|
||||
// 4. 모델 직렬화 테스트
|
||||
results['serialization'] = _testSerialization();
|
||||
|
||||
// 5. 저장소 접근 테스트
|
||||
results['storage'] = await _testStorageAccess();
|
||||
|
||||
DebugLogger.log(
|
||||
'로그인 진단 완료',
|
||||
tag: 'DIAGNOSTICS',
|
||||
data: results,
|
||||
);
|
||||
|
||||
return results;
|
||||
} catch (e, stackTrace) {
|
||||
DebugLogger.logError(
|
||||
'진단 중 오류 발생',
|
||||
error: e,
|
||||
stackTrace: stackTrace,
|
||||
);
|
||||
return {
|
||||
'error': e.toString(),
|
||||
'stackTrace': stackTrace.toString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// 환경 설정 확인
|
||||
static Map<String, dynamic> _checkEnvironment() {
|
||||
return {
|
||||
'useApi': env.Environment.useApi,
|
||||
'apiBaseUrl': env.Environment.apiBaseUrl,
|
||||
'isDebugMode': kDebugMode,
|
||||
'platform': defaultTargetPlatform.toString(),
|
||||
};
|
||||
}
|
||||
|
||||
/// 네트워크 연결 확인
|
||||
static Future<Map<String, dynamic>> _checkNetworkConnectivity() async {
|
||||
final dio = Dio();
|
||||
final results = <String, dynamic>{};
|
||||
|
||||
try {
|
||||
// Google DNS로 연결 테스트
|
||||
final response = await dio.get('https://dns.google/resolve?name=google.com');
|
||||
results['internetConnection'] = response.statusCode == 200;
|
||||
} catch (e) {
|
||||
results['internetConnection'] = false;
|
||||
results['error'] = e.toString();
|
||||
}
|
||||
|
||||
// API 서버 연결 테스트
|
||||
if (env.Environment.useApi) {
|
||||
try {
|
||||
final response = await dio.get(
|
||||
'${env.Environment.apiBaseUrl}/health',
|
||||
options: Options(
|
||||
validateStatus: (status) => status != null && status < 500,
|
||||
),
|
||||
);
|
||||
results['apiServerReachable'] = true;
|
||||
results['apiServerStatus'] = response.statusCode;
|
||||
} catch (e) {
|
||||
results['apiServerReachable'] = false;
|
||||
results['apiServerError'] = e.toString();
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// API 엔드포인트 확인
|
||||
static Future<Map<String, dynamic>> _checkApiEndpoint() async {
|
||||
if (!env.Environment.useApi) {
|
||||
return {'mode': 'mock', 'skip': true};
|
||||
}
|
||||
|
||||
final dio = Dio();
|
||||
final results = <String, dynamic>{};
|
||||
|
||||
try {
|
||||
// OPTIONS 요청으로 CORS 확인
|
||||
final response = await dio.request(
|
||||
'${env.Environment.apiBaseUrl}/auth/login',
|
||||
options: Options(
|
||||
method: 'OPTIONS',
|
||||
validateStatus: (status) => true,
|
||||
),
|
||||
);
|
||||
|
||||
results['corsEnabled'] = response.statusCode == 200 || response.statusCode == 204;
|
||||
results['allowedMethods'] = response.headers['access-control-allow-methods'];
|
||||
results['allowedHeaders'] = response.headers['access-control-allow-headers'];
|
||||
|
||||
// 실제 로그인 엔드포인트 테스트 (잘못된 자격 증명으로)
|
||||
final loginResponse = await dio.post(
|
||||
'${env.Environment.apiBaseUrl}/auth/login',
|
||||
data: {
|
||||
'email': 'test@test.com',
|
||||
'password': 'test',
|
||||
},
|
||||
options: Options(
|
||||
validateStatus: (status) => true,
|
||||
),
|
||||
);
|
||||
|
||||
results['loginEndpointStatus'] = loginResponse.statusCode;
|
||||
results['loginResponseType'] = loginResponse.data?.runtimeType.toString();
|
||||
|
||||
// 응답 구조 분석
|
||||
if (loginResponse.data is Map) {
|
||||
final data = loginResponse.data as Map;
|
||||
results['responseKeys'] = data.keys.toList();
|
||||
results['hasSuccessField'] = data.containsKey('success');
|
||||
results['hasDataField'] = data.containsKey('data');
|
||||
results['hasAccessToken'] = data.containsKey('accessToken') || data.containsKey('access_token');
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
results['error'] = e.toString();
|
||||
if (e is DioException) {
|
||||
results['dioErrorType'] = e.type.toString();
|
||||
results['dioMessage'] = e.message;
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// 모델 직렬화 테스트
|
||||
static Map<String, dynamic> _testSerialization() {
|
||||
final results = <String, dynamic>{};
|
||||
|
||||
try {
|
||||
// LoginRequest 테스트
|
||||
results['loginRequestValid'] = true;
|
||||
|
||||
// LoginResponse 테스트 (형식 1)
|
||||
final loginResponse1 = {
|
||||
'success': true,
|
||||
'data': {
|
||||
'accessToken': 'test_token',
|
||||
'refreshToken': 'refresh_token',
|
||||
'tokenType': 'Bearer',
|
||||
'expiresIn': 3600,
|
||||
'user': {
|
||||
'id': 1,
|
||||
'username': 'testuser',
|
||||
'email': 'test@example.com',
|
||||
'name': '테스트',
|
||||
'role': 'USER',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
results['format1Valid'] = _validateResponseFormat1(loginResponse1);
|
||||
|
||||
// LoginResponse 테스트 (형식 2)
|
||||
final loginResponse2 = {
|
||||
'accessToken': 'test_token',
|
||||
'refreshToken': 'refresh_token',
|
||||
'tokenType': 'Bearer',
|
||||
'expiresIn': 3600,
|
||||
'user': {
|
||||
'id': 1,
|
||||
'username': 'testuser',
|
||||
'email': 'test@example.com',
|
||||
'name': '테스트',
|
||||
'role': 'USER',
|
||||
},
|
||||
};
|
||||
|
||||
results['format2Valid'] = _validateResponseFormat2(loginResponse2);
|
||||
|
||||
} catch (e) {
|
||||
results['error'] = e.toString();
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// 저장소 접근 테스트
|
||||
static Future<Map<String, dynamic>> _testStorageAccess() async {
|
||||
final results = <String, dynamic>{};
|
||||
|
||||
try {
|
||||
// 실제 FlutterSecureStorage 테스트는 의존성 주입이 필요하므로
|
||||
// 여기서는 기본적인 체크만 수행
|
||||
results['platformSupported'] = true;
|
||||
|
||||
// 플랫폼별 특이사항 체크
|
||||
if (defaultTargetPlatform == TargetPlatform.iOS) {
|
||||
results['note'] = 'iOS Keychain 사용';
|
||||
} else if (defaultTargetPlatform == TargetPlatform.android) {
|
||||
results['note'] = 'Android KeyStore 사용';
|
||||
} else {
|
||||
results['note'] = '웹 또는 데스크톱 플랫폼';
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
results['error'] = e.toString();
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// 응답 형식 1 검증
|
||||
static bool _validateResponseFormat1(Map<String, dynamic> response) {
|
||||
try {
|
||||
if (!response.containsKey('success') || response['success'] != true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!response.containsKey('data') || response['data'] is! Map) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final data = response['data'] as Map<String, dynamic>;
|
||||
final requiredFields = ['accessToken', 'refreshToken', 'user'];
|
||||
|
||||
for (final field in requiredFields) {
|
||||
if (!data.containsKey(field)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 응답 형식 2 검증
|
||||
static bool _validateResponseFormat2(Map<String, dynamic> response) {
|
||||
try {
|
||||
final requiredFields = ['accessToken', 'refreshToken', 'user'];
|
||||
|
||||
for (final field in requiredFields) {
|
||||
if (!response.containsKey(field)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (response['user'] is! Map) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 진단 결과를 읽기 쉬운 형식으로 포맷
|
||||
static String formatDiagnosticsReport(Map<String, dynamic> diagnostics) {
|
||||
final buffer = StringBuffer();
|
||||
|
||||
buffer.writeln('=== 로그인 진단 보고서 ===\n');
|
||||
|
||||
// 환경 설정
|
||||
if (diagnostics.containsKey('environment')) {
|
||||
buffer.writeln('## 환경 설정');
|
||||
final env = diagnostics['environment'] as Map<String, dynamic>;
|
||||
env.forEach((key, value) {
|
||||
buffer.writeln('- $key: $value');
|
||||
});
|
||||
buffer.writeln();
|
||||
}
|
||||
|
||||
// 네트워크 상태
|
||||
if (diagnostics.containsKey('network')) {
|
||||
buffer.writeln('## 네트워크 상태');
|
||||
final network = diagnostics['network'] as Map<String, dynamic>;
|
||||
buffer.writeln('- 인터넷 연결: ${network['internetConnection'] == true ? '✅' : '❌'}');
|
||||
if (network.containsKey('apiServerReachable')) {
|
||||
buffer.writeln('- API 서버 접근: ${network['apiServerReachable'] == true ? '✅' : '❌'}');
|
||||
}
|
||||
buffer.writeln();
|
||||
}
|
||||
|
||||
// API 엔드포인트
|
||||
if (diagnostics.containsKey('apiEndpoint')) {
|
||||
buffer.writeln('## API 엔드포인트');
|
||||
final api = diagnostics['apiEndpoint'] as Map<String, dynamic>;
|
||||
if (api['skip'] == true) {
|
||||
buffer.writeln('- Mock 모드로 건너뜀');
|
||||
} else {
|
||||
buffer.writeln('- CORS 활성화: ${api['corsEnabled'] == true ? '✅' : '❌'}');
|
||||
buffer.writeln('- 로그인 엔드포인트 상태: ${api['loginEndpointStatus']}');
|
||||
if (api.containsKey('responseKeys')) {
|
||||
buffer.writeln('- 응답 키: ${api['responseKeys']}');
|
||||
}
|
||||
}
|
||||
buffer.writeln();
|
||||
}
|
||||
|
||||
// 직렬화 테스트
|
||||
if (diagnostics.containsKey('serialization')) {
|
||||
buffer.writeln('## 모델 직렬화');
|
||||
final serial = diagnostics['serialization'] as Map<String, dynamic>;
|
||||
buffer.writeln('- LoginRequest: ${serial['loginRequestValid'] == true ? '✅' : '❌'}');
|
||||
buffer.writeln('- 응답 형식 1: ${serial['format1Valid'] == true ? '✅' : '❌'}');
|
||||
buffer.writeln('- 응답 형식 2: ${serial['format2Valid'] == true ? '✅' : '❌'}');
|
||||
buffer.writeln();
|
||||
}
|
||||
|
||||
// 오류 정보
|
||||
if (diagnostics.containsKey('error')) {
|
||||
buffer.writeln('## ⚠️ 오류 발생');
|
||||
buffer.writeln(diagnostics['error']);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import '../../../core/config/environment.dart';
|
||||
import 'interceptors/auth_interceptor.dart';
|
||||
import 'interceptors/error_interceptor.dart';
|
||||
import 'interceptors/logging_interceptor.dart';
|
||||
import 'interceptors/response_interceptor.dart';
|
||||
|
||||
/// API 클라이언트 클래스
|
||||
class ApiClient {
|
||||
@@ -18,15 +19,20 @@ class ApiClient {
|
||||
|
||||
ApiClient._internal() {
|
||||
try {
|
||||
print('[ApiClient] 초기화 시작');
|
||||
_dio = Dio(_baseOptions);
|
||||
print('[ApiClient] Dio 인스턴스 생성 완료');
|
||||
print('[ApiClient] Base URL: ${_dio.options.baseUrl}');
|
||||
print('[ApiClient] Connect Timeout: ${_dio.options.connectTimeout}');
|
||||
print('[ApiClient] Receive Timeout: ${_dio.options.receiveTimeout}');
|
||||
_setupInterceptors();
|
||||
} catch (e) {
|
||||
print('Error while creating ApiClient');
|
||||
print('Stack trace:');
|
||||
print(StackTrace.current);
|
||||
print('[ApiClient] 인터셉터 설정 완료');
|
||||
} catch (e, stackTrace) {
|
||||
print('[ApiClient] ⚠️ 에러 발생: $e');
|
||||
print('[ApiClient] Stack trace: $stackTrace');
|
||||
// 기본값으로 초기화
|
||||
_dio = Dio(BaseOptions(
|
||||
baseUrl: 'http://localhost:8080/api/v1',
|
||||
baseUrl: 'https://superport.naturebridgeai.com/api/v1',
|
||||
connectTimeout: const Duration(seconds: 30),
|
||||
receiveTimeout: const Duration(seconds: 30),
|
||||
headers: {
|
||||
@@ -35,6 +41,7 @@ class ApiClient {
|
||||
},
|
||||
));
|
||||
_setupInterceptors();
|
||||
print('[ApiClient] 기본값으로 초기화 완료');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +66,7 @@ class ApiClient {
|
||||
} catch (e) {
|
||||
// Environment가 초기화되지 않은 경우 기본값 사용
|
||||
return BaseOptions(
|
||||
baseUrl: 'http://localhost:8080/api/v1',
|
||||
baseUrl: 'https://superport.naturebridgeai.com/api/v1',
|
||||
connectTimeout: const Duration(seconds: 30),
|
||||
receiveTimeout: const Duration(seconds: 30),
|
||||
headers: {
|
||||
@@ -77,13 +84,7 @@ class ApiClient {
|
||||
void _setupInterceptors() {
|
||||
_dio.interceptors.clear();
|
||||
|
||||
// 인증 인터셉터
|
||||
_dio.interceptors.add(AuthInterceptor());
|
||||
|
||||
// 에러 처리 인터셉터
|
||||
_dio.interceptors.add(ErrorInterceptor());
|
||||
|
||||
// 로깅 인터셉터 (개발 환경에서만)
|
||||
// 로깅 인터셉터 (개발 환경에서만) - 가장 먼저 추가하여 모든 요청/응답을 로깅
|
||||
try {
|
||||
if (Environment.enableLogging && kDebugMode) {
|
||||
_dio.interceptors.add(LoggingInterceptor());
|
||||
@@ -94,6 +95,15 @@ class ApiClient {
|
||||
_dio.interceptors.add(LoggingInterceptor());
|
||||
}
|
||||
}
|
||||
|
||||
// 인증 인터셉터 - 요청에 토큰 추가 및 401 처리
|
||||
_dio.interceptors.add(AuthInterceptor(_dio));
|
||||
|
||||
// 응답 정규화 인터셉터 - 성공 응답을 일관된 형식으로 변환
|
||||
_dio.interceptors.add(ResponseInterceptor());
|
||||
|
||||
// 에러 처리 인터셉터 - 마지막에 추가하여 모든 에러를 캐치
|
||||
_dio.interceptors.add(ErrorInterceptor());
|
||||
}
|
||||
|
||||
/// 토큰 업데이트
|
||||
@@ -133,6 +143,9 @@ class ApiClient {
|
||||
ProgressCallback? onSendProgress,
|
||||
ProgressCallback? onReceiveProgress,
|
||||
}) {
|
||||
print('[ApiClient] POST 요청 시작: $path');
|
||||
print('[ApiClient] 요청 데이터: $data');
|
||||
|
||||
return _dio.post<T>(
|
||||
path,
|
||||
data: data,
|
||||
@@ -141,7 +154,18 @@ class ApiClient {
|
||||
cancelToken: cancelToken,
|
||||
onSendProgress: onSendProgress,
|
||||
onReceiveProgress: onReceiveProgress,
|
||||
);
|
||||
).then((response) {
|
||||
print('[ApiClient] POST 응답 수신: ${response.statusCode}');
|
||||
return response;
|
||||
}).catchError((error) {
|
||||
print('[ApiClient] POST 에러 발생: $error');
|
||||
if (error is DioException) {
|
||||
print('[ApiClient] DioException 타입: ${error.type}');
|
||||
print('[ApiClient] DioException 메시지: ${error.message}');
|
||||
print('[ApiClient] DioException 에러: ${error.error}');
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
/// PUT 요청
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:injectable/injectable.dart';
|
||||
import 'package:superport/core/errors/exceptions.dart';
|
||||
import 'package:superport/core/errors/failures.dart';
|
||||
@@ -8,6 +9,7 @@ import 'package:superport/data/models/auth/login_response.dart';
|
||||
import 'package:superport/data/models/auth/logout_request.dart';
|
||||
import 'package:superport/data/models/auth/refresh_token_request.dart';
|
||||
import 'package:superport/data/models/auth/token_response.dart';
|
||||
import 'package:superport/core/utils/debug_logger.dart';
|
||||
|
||||
abstract class AuthRemoteDataSource {
|
||||
Future<Either<Failure, LoginResponse>> login(LoginRequest request);
|
||||
@@ -24,28 +26,149 @@ class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
|
||||
@override
|
||||
Future<Either<Failure, LoginResponse>> login(LoginRequest request) async {
|
||||
try {
|
||||
DebugLogger.logLogin('요청 시작', data: request.toJson());
|
||||
|
||||
final response = await _apiClient.post(
|
||||
'/auth/login',
|
||||
data: request.toJson(),
|
||||
);
|
||||
|
||||
DebugLogger.logApiResponse(
|
||||
url: '/auth/login',
|
||||
statusCode: response.statusCode,
|
||||
data: response.data,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200 && response.data != null) {
|
||||
final loginResponse = LoginResponse.fromJson(response.data);
|
||||
return Right(loginResponse);
|
||||
final responseData = response.data;
|
||||
|
||||
// API 응답 형식 확인 및 처리
|
||||
// 형식 1: { success: bool, data: {...} }
|
||||
if (responseData is Map && responseData['success'] == true && responseData['data'] != null) {
|
||||
DebugLogger.logLogin('응답 형식 1 감지', data: {'format': 'wrapped'});
|
||||
|
||||
// 응답 데이터 구조 검증
|
||||
final dataFields = responseData['data'] as Map<String, dynamic>;
|
||||
DebugLogger.validateResponseStructure(
|
||||
dataFields,
|
||||
['accessToken', 'refreshToken', 'user'],
|
||||
responseName: 'LoginResponse.data',
|
||||
);
|
||||
|
||||
final loginResponse = DebugLogger.parseJsonWithLogging(
|
||||
responseData['data'],
|
||||
LoginResponse.fromJson,
|
||||
objectName: 'LoginResponse',
|
||||
);
|
||||
|
||||
if (loginResponse != null) {
|
||||
DebugLogger.logLogin('로그인 성공', data: {
|
||||
'userId': loginResponse.user.id,
|
||||
'userEmail': loginResponse.user.email,
|
||||
'userRole': loginResponse.user.role,
|
||||
});
|
||||
return Right(loginResponse);
|
||||
} else {
|
||||
return Left(ServerFailure(message: 'LoginResponse 파싱 실패'));
|
||||
}
|
||||
}
|
||||
// 형식 2: 직접 LoginResponse 형태
|
||||
else if (responseData is Map &&
|
||||
(responseData.containsKey('accessToken') ||
|
||||
responseData.containsKey('access_token'))) {
|
||||
DebugLogger.logLogin('응답 형식 2 감지', data: {'format': 'direct'});
|
||||
|
||||
// 응답 데이터 구조 검증
|
||||
DebugLogger.validateResponseStructure(
|
||||
responseData as Map<String, dynamic>,
|
||||
['accessToken', 'refreshToken', 'user'],
|
||||
responseName: 'LoginResponse',
|
||||
);
|
||||
|
||||
final loginResponse = DebugLogger.parseJsonWithLogging(
|
||||
responseData,
|
||||
LoginResponse.fromJson,
|
||||
objectName: 'LoginResponse',
|
||||
);
|
||||
|
||||
if (loginResponse != null) {
|
||||
DebugLogger.logLogin('로그인 성공', data: {
|
||||
'userId': loginResponse.user.id,
|
||||
'userEmail': loginResponse.user.email,
|
||||
'userRole': loginResponse.user.role,
|
||||
});
|
||||
return Right(loginResponse);
|
||||
} else {
|
||||
return Left(ServerFailure(message: 'LoginResponse 파싱 실패'));
|
||||
}
|
||||
}
|
||||
// 그 외의 경우
|
||||
else {
|
||||
DebugLogger.logError(
|
||||
'알 수 없는 응답 형식',
|
||||
additionalData: {
|
||||
'responseKeys': responseData.keys.toList(),
|
||||
'responseType': responseData.runtimeType.toString(),
|
||||
},
|
||||
);
|
||||
return Left(ServerFailure(
|
||||
message: '잘못된 응답 형식입니다.',
|
||||
));
|
||||
}
|
||||
} else {
|
||||
DebugLogger.logError(
|
||||
'비정상적인 응답',
|
||||
additionalData: {
|
||||
'statusCode': response.statusCode,
|
||||
'hasData': response.data != null,
|
||||
},
|
||||
);
|
||||
return Left(ServerFailure(
|
||||
message: response.statusMessage ?? '로그인 실패',
|
||||
));
|
||||
}
|
||||
} catch (e) {
|
||||
if (e is ApiException) {
|
||||
if (e.statusCode == 401) {
|
||||
return Left(AuthenticationFailure(
|
||||
message: '이메일 또는 비밀번호가 올바르지 않습니다.',
|
||||
));
|
||||
}
|
||||
return Left(ServerFailure(message: e.message));
|
||||
} on DioException catch (e) {
|
||||
DebugLogger.logError(
|
||||
'DioException 발생',
|
||||
error: e,
|
||||
additionalData: {
|
||||
'type': e.type.toString(),
|
||||
'message': e.message,
|
||||
'error': e.error?.toString(),
|
||||
'statusCode': e.response?.statusCode,
|
||||
},
|
||||
);
|
||||
|
||||
// ErrorInterceptor에서 변환된 예외 처리
|
||||
if (e.error is NetworkException) {
|
||||
return Left(NetworkFailure(message: (e.error as NetworkException).message));
|
||||
} else if (e.error is UnauthorizedException) {
|
||||
return Left(AuthenticationFailure(message: (e.error as UnauthorizedException).message));
|
||||
} else if (e.error is ServerException) {
|
||||
return Left(ServerFailure(message: (e.error as ServerException).message));
|
||||
}
|
||||
|
||||
// 기본 DioException 처리
|
||||
if (e.response?.statusCode == 401) {
|
||||
return Left(AuthenticationFailure(
|
||||
message: '이메일 또는 비밀번호가 올바르지 않습니다.',
|
||||
));
|
||||
}
|
||||
|
||||
// 네트워크 관련 에러 처리
|
||||
if (e.type == DioExceptionType.connectionTimeout ||
|
||||
e.type == DioExceptionType.sendTimeout ||
|
||||
e.type == DioExceptionType.receiveTimeout) {
|
||||
return Left(ServerFailure(message: '네트워크 연결 시간이 초과되었습니다. 로그인 중 오류가 발생했습니다.'));
|
||||
}
|
||||
|
||||
return Left(ServerFailure(message: e.message ?? '로그인 중 오류가 발생했습니다.'));
|
||||
} catch (e, stackTrace) {
|
||||
DebugLogger.logError(
|
||||
'예상치 못한 예외 발생',
|
||||
error: e,
|
||||
stackTrace: stackTrace,
|
||||
);
|
||||
return Left(ServerFailure(message: '로그인 중 오류가 발생했습니다.'));
|
||||
}
|
||||
}
|
||||
@@ -59,7 +182,17 @@ class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return const Right(null);
|
||||
// API 응답이 { success: bool, data: {...} } 형태인지 확인
|
||||
if (response.data is Map && response.data['success'] == true) {
|
||||
return const Right(null);
|
||||
} else if (response.data == null) {
|
||||
// 응답 본문이 없는 경우도 성공으로 처리
|
||||
return const Right(null);
|
||||
} else {
|
||||
return Left(ServerFailure(
|
||||
message: '로그아웃 실패',
|
||||
));
|
||||
}
|
||||
} else {
|
||||
return Left(ServerFailure(
|
||||
message: response.statusMessage ?? '로그아웃 실패',
|
||||
@@ -82,8 +215,16 @@ class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200 && response.data != null) {
|
||||
final tokenResponse = TokenResponse.fromJson(response.data);
|
||||
return Right(tokenResponse);
|
||||
// API 응답이 { success: bool, data: {...} } 형태인 경우
|
||||
final responseData = response.data;
|
||||
if (responseData is Map && responseData['success'] == true && responseData['data'] != null) {
|
||||
final tokenResponse = TokenResponse.fromJson(responseData['data']);
|
||||
return Right(tokenResponse);
|
||||
} else {
|
||||
return Left(ServerFailure(
|
||||
message: '잘못된 응답 형식입니다.',
|
||||
));
|
||||
}
|
||||
} else {
|
||||
return Left(ServerFailure(
|
||||
message: response.statusMessage ?? '토큰 갱신 실패',
|
||||
|
||||
@@ -76,14 +76,31 @@ class CompanyRemoteDataSourceImpl implements CompanyRemoteDataSource {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final apiResponse = ApiResponse<PaginatedResponse<CompanyListDto>>.fromJson(
|
||||
response.data,
|
||||
(json) => PaginatedResponse<CompanyListDto>.fromJson(
|
||||
json as Map<String, dynamic>,
|
||||
(item) => CompanyListDto.fromJson(item as Map<String, dynamic>),
|
||||
),
|
||||
);
|
||||
return apiResponse.data!;
|
||||
// API 응답을 직접 파싱
|
||||
final responseData = response.data;
|
||||
if (responseData != null && responseData['success'] == true && responseData['data'] != null) {
|
||||
final List<dynamic> dataList = responseData['data'];
|
||||
final pagination = responseData['pagination'] ?? {};
|
||||
|
||||
// CompanyListDto로 변환
|
||||
final items = dataList.map((item) => CompanyListDto.fromJson(item as Map<String, dynamic>)).toList();
|
||||
|
||||
// PaginatedResponse 생성
|
||||
return PaginatedResponse<CompanyListDto>(
|
||||
items: items,
|
||||
page: pagination['page'] ?? page,
|
||||
size: pagination['per_page'] ?? perPage,
|
||||
totalElements: pagination['total'] ?? 0,
|
||||
totalPages: pagination['total_pages'] ?? 1,
|
||||
first: (pagination['page'] ?? page) == 1,
|
||||
last: (pagination['page'] ?? page) == (pagination['total_pages'] ?? 1),
|
||||
);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: responseData?['error']?['message'] ?? 'Failed to load companies',
|
||||
statusCode: response.statusCode,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: 'Failed to load companies',
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:injectable/injectable.dart';
|
||||
import 'package:superport/core/constants/api_endpoints.dart';
|
||||
import 'package:superport/core/errors/failures.dart';
|
||||
import 'package:superport/data/datasources/remote/api_client.dart';
|
||||
import 'package:superport/data/models/dashboard/equipment_status_distribution.dart';
|
||||
@@ -24,56 +25,59 @@ class DashboardRemoteDataSourceImpl implements DashboardRemoteDataSource {
|
||||
@override
|
||||
Future<Either<Failure, OverviewStats>> getOverviewStats() async {
|
||||
try {
|
||||
final response = await _apiClient.get('/overview/stats');
|
||||
final response = await _apiClient.get(ApiEndpoints.overviewStats);
|
||||
|
||||
if (response.data != null) {
|
||||
final stats = OverviewStats.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
final stats = OverviewStats.fromJson(response.data['data']);
|
||||
return Right(stats);
|
||||
} else {
|
||||
return Left(ServerFailure(message: '응답 데이터가 없습니다'));
|
||||
final errorMessage = response.data?['error']?['message'] ?? '응답 데이터가 없습니다';
|
||||
return Left(ServerFailure(message: errorMessage));
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
return Left(_handleDioError(e));
|
||||
} catch (e) {
|
||||
return Left(ServerFailure(message: '통계 데이터를 가져오는 중 오류가 발생했습니다'));
|
||||
return Left(ServerFailure(message: '통계 데이터를 가져오는 중 오류가 발생했습니다: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, List<RecentActivity>>> getRecentActivities() async {
|
||||
try {
|
||||
final response = await _apiClient.get('/overview/recent-activities');
|
||||
final response = await _apiClient.get(ApiEndpoints.overviewRecentActivities);
|
||||
|
||||
if (response.data != null && response.data is List) {
|
||||
final activities = (response.data as List)
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
final activities = (response.data['data'] as List)
|
||||
.map((json) => RecentActivity.fromJson(json))
|
||||
.toList();
|
||||
return Right(activities);
|
||||
} else {
|
||||
return Left(ServerFailure(message: '응답 데이터가 올바르지 않습니다'));
|
||||
final errorMessage = response.data?['error']?['message'] ?? '응답 데이터가 올바르지 않습니다';
|
||||
return Left(ServerFailure(message: errorMessage));
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
return Left(_handleDioError(e));
|
||||
} catch (e) {
|
||||
return Left(ServerFailure(message: '최근 활동을 가져오는 중 오류가 발생했습니다'));
|
||||
return Left(ServerFailure(message: '최근 활동을 가져오는 중 오류가 발생했습니다: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, EquipmentStatusDistribution>> getEquipmentStatusDistribution() async {
|
||||
try {
|
||||
final response = await _apiClient.get('/equipment/status-distribution');
|
||||
final response = await _apiClient.get(ApiEndpoints.overviewEquipmentStatus);
|
||||
|
||||
if (response.data != null) {
|
||||
final distribution = EquipmentStatusDistribution.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
final distribution = EquipmentStatusDistribution.fromJson(response.data['data']);
|
||||
return Right(distribution);
|
||||
} else {
|
||||
return Left(ServerFailure(message: '응답 데이터가 없습니다'));
|
||||
final errorMessage = response.data?['error']?['message'] ?? '응답 데이터가 없습니다';
|
||||
return Left(ServerFailure(message: errorMessage));
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
return Left(_handleDioError(e));
|
||||
} catch (e) {
|
||||
return Left(ServerFailure(message: '장비 상태 분포를 가져오는 중 오류가 발생했습니다'));
|
||||
return Left(ServerFailure(message: '장비 상태 분포를 가져오는 중 오류가 발생했습니다: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,22 +85,23 @@ class DashboardRemoteDataSourceImpl implements DashboardRemoteDataSource {
|
||||
Future<Either<Failure, List<ExpiringLicense>>> getExpiringLicenses({int days = 30}) async {
|
||||
try {
|
||||
final response = await _apiClient.get(
|
||||
'/licenses/expiring-soon',
|
||||
ApiEndpoints.licensesExpiring,
|
||||
queryParameters: {'days': days},
|
||||
);
|
||||
|
||||
if (response.data != null && response.data is List) {
|
||||
final licenses = (response.data as List)
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
final licenses = (response.data['data'] as List)
|
||||
.map((json) => ExpiringLicense.fromJson(json))
|
||||
.toList();
|
||||
return Right(licenses);
|
||||
} else {
|
||||
return Left(ServerFailure(message: '응답 데이터가 올바르지 않습니다'));
|
||||
final errorMessage = response.data?['error']?['message'] ?? '응답 데이터가 올바르지 않습니다';
|
||||
return Left(ServerFailure(message: errorMessage));
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
return Left(_handleDioError(e));
|
||||
} catch (e) {
|
||||
return Left(ServerFailure(message: '만료 예정 라이선스를 가져오는 중 오류가 발생했습니다'));
|
||||
return Left(ServerFailure(message: '만료 예정 라이선스를 가져오는 중 오류가 발생했습니다: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +115,17 @@ class DashboardRemoteDataSourceImpl implements DashboardRemoteDataSource {
|
||||
return NetworkFailure(message: '서버에 연결할 수 없습니다');
|
||||
case DioExceptionType.badResponse:
|
||||
final statusCode = error.response?.statusCode ?? 0;
|
||||
final message = error.response?.data?['message'] ?? '서버 오류가 발생했습니다';
|
||||
final errorData = error.response?.data;
|
||||
|
||||
// 에러 메시지 추출 개선
|
||||
String message;
|
||||
if (errorData is Map) {
|
||||
message = errorData['error']?['message'] ??
|
||||
errorData['message'] ??
|
||||
'서버 오류가 발생했습니다';
|
||||
} else {
|
||||
message = '서버 오류가 발생했습니다';
|
||||
}
|
||||
|
||||
if (statusCode == 401) {
|
||||
return AuthenticationFailure(message: '인증이 만료되었습니다');
|
||||
@@ -119,6 +134,10 @@ class DashboardRemoteDataSourceImpl implements DashboardRemoteDataSource {
|
||||
} else if (statusCode >= 400 && statusCode < 500) {
|
||||
return ServerFailure(message: message);
|
||||
} else {
|
||||
// 500 에러의 경우 더 자세한 메시지 표시
|
||||
if (message.contains('DATABASE_ERROR')) {
|
||||
return ServerFailure(message: '서버 데이터베이스 오류가 발생했습니다. 관리자에게 문의하세요.');
|
||||
}
|
||||
return ServerFailure(message: '서버 오류가 발생했습니다 ($statusCode)');
|
||||
}
|
||||
case DioExceptionType.cancel:
|
||||
|
||||
@@ -6,6 +6,9 @@ import '../../../../services/auth_service.dart';
|
||||
/// 인증 인터셉터
|
||||
class AuthInterceptor extends Interceptor {
|
||||
AuthService? _authService;
|
||||
final Dio dio;
|
||||
|
||||
AuthInterceptor(this.dio);
|
||||
|
||||
AuthService? get authService {
|
||||
try {
|
||||
@@ -22,22 +25,34 @@ class AuthInterceptor extends Interceptor {
|
||||
RequestOptions options,
|
||||
RequestInterceptorHandler handler,
|
||||
) async {
|
||||
print('[AuthInterceptor] onRequest: ${options.method} ${options.path}');
|
||||
|
||||
// 로그인, 토큰 갱신 요청은 토큰 없이 진행
|
||||
if (_isAuthEndpoint(options.path)) {
|
||||
print('[AuthInterceptor] Auth endpoint detected, skipping token attachment');
|
||||
handler.next(options);
|
||||
return;
|
||||
}
|
||||
|
||||
// 저장된 액세스 토큰 가져오기
|
||||
final service = authService;
|
||||
print('[AuthInterceptor] AuthService available: ${service != null}');
|
||||
|
||||
if (service != null) {
|
||||
final accessToken = await service.getAccessToken();
|
||||
print('[AuthInterceptor] Access token retrieved: ${accessToken != null ? 'Yes (${accessToken.substring(0, 10)}...)' : 'No'}');
|
||||
|
||||
if (accessToken != null) {
|
||||
options.headers['Authorization'] = 'Bearer $accessToken';
|
||||
print('[AuthInterceptor] Authorization header set: Bearer ${accessToken.substring(0, 10)}...');
|
||||
} else {
|
||||
print('[AuthInterceptor] WARNING: No access token available for protected endpoint');
|
||||
}
|
||||
} else {
|
||||
print('[AuthInterceptor] ERROR: AuthService not available from GetIt');
|
||||
}
|
||||
|
||||
print('[AuthInterceptor] Final headers: ${options.headers}');
|
||||
handler.next(options);
|
||||
}
|
||||
|
||||
@@ -46,16 +61,32 @@ class AuthInterceptor extends Interceptor {
|
||||
DioException err,
|
||||
ErrorInterceptorHandler handler,
|
||||
) async {
|
||||
print('[AuthInterceptor] onError: ${err.response?.statusCode} ${err.message}');
|
||||
|
||||
// 401 Unauthorized 에러 처리
|
||||
if (err.response?.statusCode == 401) {
|
||||
// 인증 관련 엔드포인트는 재시도하지 않음
|
||||
if (_isAuthEndpoint(err.requestOptions.path)) {
|
||||
print('[AuthInterceptor] Auth endpoint 401 error, skipping retry');
|
||||
handler.next(err);
|
||||
return;
|
||||
}
|
||||
|
||||
final service = authService;
|
||||
if (service != null) {
|
||||
print('[AuthInterceptor] Attempting token refresh...');
|
||||
// 토큰 갱신 시도
|
||||
final refreshResult = await service.refreshToken();
|
||||
|
||||
final refreshSuccess = refreshResult.fold(
|
||||
(failure) => false,
|
||||
(tokenResponse) => true,
|
||||
(failure) {
|
||||
print('[AuthInterceptor] Token refresh failed: ${failure.message}');
|
||||
return false;
|
||||
},
|
||||
(tokenResponse) {
|
||||
print('[AuthInterceptor] Token refresh successful');
|
||||
return true;
|
||||
},
|
||||
);
|
||||
|
||||
if (refreshSuccess) {
|
||||
@@ -64,13 +95,16 @@ class AuthInterceptor extends Interceptor {
|
||||
final newAccessToken = await service.getAccessToken();
|
||||
|
||||
if (newAccessToken != null) {
|
||||
print('[AuthInterceptor] Retrying request with new token');
|
||||
err.requestOptions.headers['Authorization'] = 'Bearer $newAccessToken';
|
||||
|
||||
final response = await Dio().fetch(err.requestOptions);
|
||||
// dio 인스턴스를 통해 재시도
|
||||
final response = await dio.fetch(err.requestOptions);
|
||||
handler.resolve(response);
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
print('[AuthInterceptor] Request retry failed: $e');
|
||||
// 재시도 실패
|
||||
handler.next(err);
|
||||
return;
|
||||
@@ -78,6 +112,7 @@ class AuthInterceptor extends Interceptor {
|
||||
}
|
||||
|
||||
// 토큰 갱신 실패 시 로그인 화면으로 이동
|
||||
print('[AuthInterceptor] Clearing session due to auth failure');
|
||||
await service.clearSession();
|
||||
// TODO: Navigate to login screen
|
||||
}
|
||||
|
||||
@@ -63,15 +63,42 @@ class ErrorInterceptor extends Interceptor {
|
||||
break;
|
||||
|
||||
case DioExceptionType.unknown:
|
||||
handler.reject(
|
||||
DioException(
|
||||
requestOptions: err.requestOptions,
|
||||
error: ServerException(
|
||||
message: AppConstants.unknownError,
|
||||
// CORS 에러 감지 시도
|
||||
final errorMessage = err.message?.toLowerCase() ?? '';
|
||||
final errorString = err.error?.toString().toLowerCase() ?? '';
|
||||
|
||||
if (errorMessage.contains('cors') || errorString.contains('cors') ||
|
||||
errorMessage.contains('xmlhttprequest') || errorString.contains('xmlhttprequest')) {
|
||||
print('[ErrorInterceptor] CORS 에러 감지됨');
|
||||
print('[ErrorInterceptor] 요청 URL: ${err.requestOptions.uri}');
|
||||
print('[ErrorInterceptor] 에러 메시지: ${err.message}');
|
||||
|
||||
handler.reject(
|
||||
DioException(
|
||||
requestOptions: err.requestOptions,
|
||||
error: NetworkException(
|
||||
message: 'CORS 정책으로 인해 API 접근이 차단되었습니다.\n'
|
||||
'개발 환경에서는 run_web_with_proxy.sh 스크립트를 사용하세요.',
|
||||
),
|
||||
type: err.type,
|
||||
),
|
||||
type: err.type,
|
||||
),
|
||||
);
|
||||
);
|
||||
} else {
|
||||
print('[ErrorInterceptor] 알 수 없는 에러');
|
||||
print('[ErrorInterceptor] 에러 타입: ${err.error?.runtimeType}');
|
||||
print('[ErrorInterceptor] 에러 메시지: ${err.message}');
|
||||
print('[ErrorInterceptor] 에러 내용: ${err.error}');
|
||||
|
||||
handler.reject(
|
||||
DioException(
|
||||
requestOptions: err.requestOptions,
|
||||
error: ServerException(
|
||||
message: AppConstants.unknownError,
|
||||
),
|
||||
type: err.type,
|
||||
),
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -90,8 +117,26 @@ class ErrorInterceptor extends Interceptor {
|
||||
// API 응답에서 에러 메시지 추출
|
||||
if (data != null) {
|
||||
if (data is Map) {
|
||||
message = data['message'] ?? data['error'] ?? message;
|
||||
errors = data['errors'] as Map<String, dynamic>?;
|
||||
// error 필드가 객체인 경우 처리
|
||||
if (data['error'] is Map) {
|
||||
final errorObj = data['error'] as Map<String, dynamic>;
|
||||
message = errorObj['message'] ?? message;
|
||||
// code 필드도 저장 (필요시 사용)
|
||||
final errorCode = errorObj['code'];
|
||||
if (errorCode != null) {
|
||||
errors = {'code': errorCode};
|
||||
}
|
||||
} else {
|
||||
// 일반적인 경우: message 또는 error가 문자열
|
||||
message = data['message'] ??
|
||||
(data['error'] is String ? data['error'] : null) ??
|
||||
message;
|
||||
}
|
||||
|
||||
// errors 필드가 있는 경우
|
||||
if (data['errors'] is Map) {
|
||||
errors = data['errors'] as Map<String, dynamic>?;
|
||||
}
|
||||
} else if (data is String) {
|
||||
message = data;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import 'package:flutter/foundation.dart';
|
||||
class LoggingInterceptor extends Interceptor {
|
||||
@override
|
||||
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||
// 요청 시간 기록
|
||||
options.extra['requestTime'] = DateTime.now();
|
||||
|
||||
debugPrint('╔════════════════════════════════════════════════════════════');
|
||||
debugPrint('║ REQUEST');
|
||||
debugPrint('║ REQUEST [${DateTime.now().toIso8601String()}]');
|
||||
debugPrint('╟────────────────────────────────────────────────────────────');
|
||||
debugPrint('║ ${options.method} ${options.uri}');
|
||||
debugPrint('╟────────────────────────────────────────────────────────────');
|
||||
@@ -42,6 +45,10 @@ class LoggingInterceptor extends Interceptor {
|
||||
}
|
||||
}
|
||||
|
||||
debugPrint('║ Timeout Settings:');
|
||||
debugPrint('║ Connect: ${options.connectTimeout}');
|
||||
debugPrint('║ Receive: ${options.receiveTimeout}');
|
||||
debugPrint('║ Send: ${options.sendTimeout}');
|
||||
debugPrint('╚════════════════════════════════════════════════════════════');
|
||||
|
||||
handler.next(options);
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
/// API 응답을 정규화하는 인터셉터
|
||||
///
|
||||
/// 서버 응답 형식에 관계없이 일관된 형태로 데이터를 처리할 수 있도록 함
|
||||
class ResponseInterceptor extends Interceptor {
|
||||
@override
|
||||
void onResponse(Response response, ResponseInterceptorHandler handler) {
|
||||
print('[ResponseInterceptor] 응답 수신: ${response.requestOptions.path}');
|
||||
print('[ResponseInterceptor] 상태 코드: ${response.statusCode}');
|
||||
print('[ResponseInterceptor] 응답 데이터 타입: ${response.data.runtimeType}');
|
||||
|
||||
// 장비 관련 API 응답 상세 로깅
|
||||
if (response.requestOptions.path.contains('equipment')) {
|
||||
print('[ResponseInterceptor] 장비 API 응답 전체: ${response.data}');
|
||||
if (response.data is List && (response.data as List).isNotEmpty) {
|
||||
final firstItem = (response.data as List).first;
|
||||
print('[ResponseInterceptor] 첫 번째 장비 상태: ${firstItem['status']}');
|
||||
}
|
||||
}
|
||||
|
||||
// 200 OK 응답만 처리
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
// 응답 데이터가 Map인 경우만 처리
|
||||
if (response.data is Map<String, dynamic>) {
|
||||
final data = response.data as Map<String, dynamic>;
|
||||
|
||||
// 이미 정규화된 형식인지 확인
|
||||
if (data.containsKey('success') && data.containsKey('data')) {
|
||||
print('[ResponseInterceptor] 이미 정규화된 응답 형식');
|
||||
handler.next(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// API 응답이 직접 데이터를 반환하는 경우
|
||||
// (예: {accessToken: "...", refreshToken: "...", user: {...}})
|
||||
if (_isDirectDataResponse(data)) {
|
||||
print('[ResponseInterceptor] 직접 데이터 응답을 정규화된 형식으로 변환');
|
||||
|
||||
// 정규화된 응답으로 변환
|
||||
response.data = {
|
||||
'success': true,
|
||||
'data': data,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handler.next(response);
|
||||
}
|
||||
|
||||
/// 직접 데이터 응답인지 확인
|
||||
bool _isDirectDataResponse(Map<String, dynamic> data) {
|
||||
// 로그인 응답 패턴
|
||||
if (data.containsKey('accessToken') ||
|
||||
data.containsKey('access_token') ||
|
||||
data.containsKey('token')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 사용자 정보 응답 패턴
|
||||
if (data.containsKey('user') ||
|
||||
data.containsKey('id') && data.containsKey('email')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 리스트 응답 패턴
|
||||
if (data.containsKey('items') ||
|
||||
data.containsKey('results') ||
|
||||
data.containsKey('data') && data['data'] is List) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 그 외 일반적인 데이터 응답
|
||||
// success, error, message 등의 메타 키가 없으면 데이터 응답으로 간주
|
||||
final metaKeys = ['success', 'error', 'status', 'code'];
|
||||
final hasMetaKey = metaKeys.any((key) => data.containsKey(key));
|
||||
|
||||
return !hasMetaKey;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,13 @@ class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
|
||||
queryParameters: queryParams,
|
||||
);
|
||||
|
||||
return LicenseListResponseDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return LicenseListResponseDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch licenses',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
@@ -75,7 +81,13 @@ class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
|
||||
'${ApiEndpoints.licenses}/$id',
|
||||
);
|
||||
|
||||
return LicenseDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return LicenseDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch license',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
@@ -89,7 +101,13 @@ class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
|
||||
data: request.toJson(),
|
||||
);
|
||||
|
||||
return LicenseDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return LicenseDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch license',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
@@ -103,7 +121,13 @@ class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
|
||||
data: request.toJson(),
|
||||
);
|
||||
|
||||
return LicenseDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return LicenseDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch license',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
@@ -128,7 +152,13 @@ class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
|
||||
data: request.toJson(),
|
||||
);
|
||||
|
||||
return LicenseDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return LicenseDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch license',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
@@ -141,7 +171,13 @@ class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
|
||||
'${ApiEndpoints.licenses}/$id/unassign',
|
||||
);
|
||||
|
||||
return LicenseDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return LicenseDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch license',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
@@ -165,7 +201,13 @@ class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource {
|
||||
queryParameters: queryParams,
|
||||
);
|
||||
|
||||
return ExpiringLicenseListDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return ExpiringLicenseListDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch expiring licenses',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,13 @@ class UserRemoteDataSource {
|
||||
queryParameters: queryParams,
|
||||
);
|
||||
|
||||
return UserListDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return UserListDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? '사용자 목록을 불러오는데 실패했습니다',
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
throw ApiException(
|
||||
message: e.response?.data['message'] ?? '사용자 목록을 불러오는데 실패했습니다',
|
||||
@@ -45,7 +51,13 @@ class UserRemoteDataSource {
|
||||
Future<UserDto> getUser(int id) async {
|
||||
try {
|
||||
final response = await _apiClient.get('/users/$id');
|
||||
return UserDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return UserDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? '사용자 정보를 불러오는데 실패했습니다',
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
throw ApiException(
|
||||
message: e.response?.data['message'] ?? '사용자 정보를 불러오는데 실패했습니다',
|
||||
@@ -62,7 +74,13 @@ class UserRemoteDataSource {
|
||||
data: request.toJson(),
|
||||
);
|
||||
|
||||
return UserDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return UserDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? '사용자 정보를 불러오는데 실패했습니다',
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
throw ApiException(
|
||||
message: e.response?.data['message'] ?? '사용자 생성에 실패했습니다',
|
||||
@@ -79,7 +97,13 @@ class UserRemoteDataSource {
|
||||
data: request.toJson(),
|
||||
);
|
||||
|
||||
return UserDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return UserDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? '사용자 정보를 불러오는데 실패했습니다',
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
throw ApiException(
|
||||
message: e.response?.data['message'] ?? '사용자 정보 수정에 실패했습니다',
|
||||
@@ -108,7 +132,13 @@ class UserRemoteDataSource {
|
||||
data: request.toJson(),
|
||||
);
|
||||
|
||||
return UserDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return UserDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? '사용자 정보를 불러오는데 실패했습니다',
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
throw ApiException(
|
||||
message: e.response?.data['message'] ?? '사용자 상태 변경에 실패했습니다',
|
||||
@@ -173,7 +203,13 @@ class UserRemoteDataSource {
|
||||
queryParameters: queryParams,
|
||||
);
|
||||
|
||||
return UserListDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return UserListDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? '사용자 목록을 불러오는데 실패했습니다',
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
throw ApiException(
|
||||
message: e.response?.data['message'] ?? '사용자 검색에 실패했습니다',
|
||||
|
||||
@@ -51,7 +51,25 @@ class WarehouseRemoteDataSourceImpl implements WarehouseRemoteDataSource {
|
||||
queryParameters: queryParams,
|
||||
);
|
||||
|
||||
return WarehouseLocationListDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
// API 응답 구조를 DTO에 맞게 변환
|
||||
final List<dynamic> dataList = response.data['data'];
|
||||
final pagination = response.data['pagination'] ?? {};
|
||||
|
||||
final listData = {
|
||||
'items': dataList,
|
||||
'total': pagination['total'] ?? 0,
|
||||
'page': pagination['page'] ?? 1,
|
||||
'per_page': pagination['per_page'] ?? 20,
|
||||
'total_pages': pagination['total_pages'] ?? 1,
|
||||
};
|
||||
|
||||
return WarehouseLocationListDto.fromJson(listData);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch warehouse locations',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
@@ -64,7 +82,13 @@ class WarehouseRemoteDataSourceImpl implements WarehouseRemoteDataSource {
|
||||
'${ApiEndpoints.warehouseLocations}/$id',
|
||||
);
|
||||
|
||||
return WarehouseLocationDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return WarehouseLocationDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch warehouse location',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
@@ -78,7 +102,13 @@ class WarehouseRemoteDataSourceImpl implements WarehouseRemoteDataSource {
|
||||
data: request.toJson(),
|
||||
);
|
||||
|
||||
return WarehouseLocationDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return WarehouseLocationDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch warehouse location',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
@@ -92,7 +122,13 @@ class WarehouseRemoteDataSourceImpl implements WarehouseRemoteDataSource {
|
||||
data: request.toJson(),
|
||||
);
|
||||
|
||||
return WarehouseLocationDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return WarehouseLocationDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch warehouse location',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
@@ -126,7 +162,13 @@ class WarehouseRemoteDataSourceImpl implements WarehouseRemoteDataSource {
|
||||
queryParameters: queryParams,
|
||||
);
|
||||
|
||||
return WarehouseEquipmentListDto.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return WarehouseEquipmentListDto.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch warehouse equipment',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
@@ -139,7 +181,13 @@ class WarehouseRemoteDataSourceImpl implements WarehouseRemoteDataSource {
|
||||
'${ApiEndpoints.warehouseLocations}/$id/capacity',
|
||||
);
|
||||
|
||||
return WarehouseCapacityInfo.fromJson(response.data);
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
|
||||
return WarehouseCapacityInfo.fromJson(response.data['data']);
|
||||
} else {
|
||||
throw ApiException(
|
||||
message: response.data?['error']?['message'] ?? 'Failed to fetch warehouse capacity',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw _handleError(e);
|
||||
}
|
||||
@@ -152,8 +200,8 @@ class WarehouseRemoteDataSourceImpl implements WarehouseRemoteDataSource {
|
||||
'${ApiEndpoints.warehouseLocations}/in-use',
|
||||
);
|
||||
|
||||
if (response.data is List) {
|
||||
return (response.data as List)
|
||||
if (response.data != null && response.data['success'] == true && response.data['data'] is List) {
|
||||
return (response.data['data'] as List)
|
||||
.map((item) => WarehouseLocationDto.fromJson(item))
|
||||
.toList();
|
||||
} else {
|
||||
|
||||
@@ -7,9 +7,9 @@ part 'auth_user.g.dart';
|
||||
class AuthUser with _$AuthUser {
|
||||
const factory AuthUser({
|
||||
required int id,
|
||||
required String username,
|
||||
required String email,
|
||||
@JsonKey(name: 'first_name') required String firstName,
|
||||
@JsonKey(name: 'last_name') required String lastName,
|
||||
required String name,
|
||||
required String role,
|
||||
}) = _AuthUser;
|
||||
|
||||
|
||||
@@ -21,11 +21,9 @@ AuthUser _$AuthUserFromJson(Map<String, dynamic> json) {
|
||||
/// @nodoc
|
||||
mixin _$AuthUser {
|
||||
int get id => throw _privateConstructorUsedError;
|
||||
String get username => throw _privateConstructorUsedError;
|
||||
String get email => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'first_name')
|
||||
String get firstName => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'last_name')
|
||||
String get lastName => throw _privateConstructorUsedError;
|
||||
String get name => throw _privateConstructorUsedError;
|
||||
String get role => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this AuthUser to a JSON map.
|
||||
@@ -43,12 +41,7 @@ abstract class $AuthUserCopyWith<$Res> {
|
||||
factory $AuthUserCopyWith(AuthUser value, $Res Function(AuthUser) then) =
|
||||
_$AuthUserCopyWithImpl<$Res, AuthUser>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
String email,
|
||||
@JsonKey(name: 'first_name') String firstName,
|
||||
@JsonKey(name: 'last_name') String lastName,
|
||||
String role});
|
||||
$Res call({int id, String username, String email, String name, String role});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -67,9 +60,9 @@ class _$AuthUserCopyWithImpl<$Res, $Val extends AuthUser>
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? username = null,
|
||||
Object? email = null,
|
||||
Object? firstName = null,
|
||||
Object? lastName = null,
|
||||
Object? name = null,
|
||||
Object? role = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
@@ -77,17 +70,17 @@ class _$AuthUserCopyWithImpl<$Res, $Val extends AuthUser>
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
username: null == username
|
||||
? _value.username
|
||||
: username // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
email: null == email
|
||||
? _value.email
|
||||
: email // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
firstName: null == firstName
|
||||
? _value.firstName
|
||||
: firstName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
lastName: null == lastName
|
||||
? _value.lastName
|
||||
: lastName // ignore: cast_nullable_to_non_nullable
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
role: null == role
|
||||
? _value.role
|
||||
@@ -105,12 +98,7 @@ abstract class _$$AuthUserImplCopyWith<$Res>
|
||||
__$$AuthUserImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
String email,
|
||||
@JsonKey(name: 'first_name') String firstName,
|
||||
@JsonKey(name: 'last_name') String lastName,
|
||||
String role});
|
||||
$Res call({int id, String username, String email, String name, String role});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -127,9 +115,9 @@ class __$$AuthUserImplCopyWithImpl<$Res>
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? username = null,
|
||||
Object? email = null,
|
||||
Object? firstName = null,
|
||||
Object? lastName = null,
|
||||
Object? name = null,
|
||||
Object? role = null,
|
||||
}) {
|
||||
return _then(_$AuthUserImpl(
|
||||
@@ -137,17 +125,17 @@ class __$$AuthUserImplCopyWithImpl<$Res>
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
username: null == username
|
||||
? _value.username
|
||||
: username // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
email: null == email
|
||||
? _value.email
|
||||
: email // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
firstName: null == firstName
|
||||
? _value.firstName
|
||||
: firstName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
lastName: null == lastName
|
||||
? _value.lastName
|
||||
: lastName // ignore: cast_nullable_to_non_nullable
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
role: null == role
|
||||
? _value.role
|
||||
@@ -162,9 +150,9 @@ class __$$AuthUserImplCopyWithImpl<$Res>
|
||||
class _$AuthUserImpl implements _AuthUser {
|
||||
const _$AuthUserImpl(
|
||||
{required this.id,
|
||||
required this.username,
|
||||
required this.email,
|
||||
@JsonKey(name: 'first_name') required this.firstName,
|
||||
@JsonKey(name: 'last_name') required this.lastName,
|
||||
required this.name,
|
||||
required this.role});
|
||||
|
||||
factory _$AuthUserImpl.fromJson(Map<String, dynamic> json) =>
|
||||
@@ -173,19 +161,17 @@ class _$AuthUserImpl implements _AuthUser {
|
||||
@override
|
||||
final int id;
|
||||
@override
|
||||
final String username;
|
||||
@override
|
||||
final String email;
|
||||
@override
|
||||
@JsonKey(name: 'first_name')
|
||||
final String firstName;
|
||||
@override
|
||||
@JsonKey(name: 'last_name')
|
||||
final String lastName;
|
||||
final String name;
|
||||
@override
|
||||
final String role;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AuthUser(id: $id, email: $email, firstName: $firstName, lastName: $lastName, role: $role)';
|
||||
return 'AuthUser(id: $id, username: $username, email: $email, name: $name, role: $role)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -194,18 +180,16 @@ class _$AuthUserImpl implements _AuthUser {
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$AuthUserImpl &&
|
||||
(identical(other.id, id) || other.id == id) &&
|
||||
(identical(other.username, username) ||
|
||||
other.username == username) &&
|
||||
(identical(other.email, email) || other.email == email) &&
|
||||
(identical(other.firstName, firstName) ||
|
||||
other.firstName == firstName) &&
|
||||
(identical(other.lastName, lastName) ||
|
||||
other.lastName == lastName) &&
|
||||
(identical(other.name, name) || other.name == name) &&
|
||||
(identical(other.role, role) || other.role == role));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, id, email, firstName, lastName, role);
|
||||
int get hashCode => Object.hash(runtimeType, id, username, email, name, role);
|
||||
|
||||
/// Create a copy of AuthUser
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -226,9 +210,9 @@ class _$AuthUserImpl implements _AuthUser {
|
||||
abstract class _AuthUser implements AuthUser {
|
||||
const factory _AuthUser(
|
||||
{required final int id,
|
||||
required final String username,
|
||||
required final String email,
|
||||
@JsonKey(name: 'first_name') required final String firstName,
|
||||
@JsonKey(name: 'last_name') required final String lastName,
|
||||
required final String name,
|
||||
required final String role}) = _$AuthUserImpl;
|
||||
|
||||
factory _AuthUser.fromJson(Map<String, dynamic> json) =
|
||||
@@ -237,13 +221,11 @@ abstract class _AuthUser implements AuthUser {
|
||||
@override
|
||||
int get id;
|
||||
@override
|
||||
String get username;
|
||||
@override
|
||||
String get email;
|
||||
@override
|
||||
@JsonKey(name: 'first_name')
|
||||
String get firstName;
|
||||
@override
|
||||
@JsonKey(name: 'last_name')
|
||||
String get lastName;
|
||||
String get name;
|
||||
@override
|
||||
String get role;
|
||||
|
||||
|
||||
@@ -9,17 +9,17 @@ part of 'auth_user.dart';
|
||||
_$AuthUserImpl _$$AuthUserImplFromJson(Map<String, dynamic> json) =>
|
||||
_$AuthUserImpl(
|
||||
id: (json['id'] as num).toInt(),
|
||||
username: json['username'] as String,
|
||||
email: json['email'] as String,
|
||||
firstName: json['first_name'] as String,
|
||||
lastName: json['last_name'] as String,
|
||||
name: json['name'] as String,
|
||||
role: json['role'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$AuthUserImplToJson(_$AuthUserImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'username': instance.username,
|
||||
'email': instance.email,
|
||||
'first_name': instance.firstName,
|
||||
'last_name': instance.lastName,
|
||||
'name': instance.name,
|
||||
'role': instance.role,
|
||||
};
|
||||
|
||||
@@ -6,7 +6,8 @@ part 'login_request.g.dart';
|
||||
@freezed
|
||||
class LoginRequest with _$LoginRequest {
|
||||
const factory LoginRequest({
|
||||
required String email,
|
||||
String? username,
|
||||
String? email,
|
||||
required String password,
|
||||
}) = _LoginRequest;
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ LoginRequest _$LoginRequestFromJson(Map<String, dynamic> json) {
|
||||
|
||||
/// @nodoc
|
||||
mixin _$LoginRequest {
|
||||
String get email => throw _privateConstructorUsedError;
|
||||
String? get username => throw _privateConstructorUsedError;
|
||||
String? get email => throw _privateConstructorUsedError;
|
||||
String get password => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this LoginRequest to a JSON map.
|
||||
@@ -39,7 +40,7 @@ abstract class $LoginRequestCopyWith<$Res> {
|
||||
LoginRequest value, $Res Function(LoginRequest) then) =
|
||||
_$LoginRequestCopyWithImpl<$Res, LoginRequest>;
|
||||
@useResult
|
||||
$Res call({String email, String password});
|
||||
$Res call({String? username, String? email, String password});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -57,14 +58,19 @@ class _$LoginRequestCopyWithImpl<$Res, $Val extends LoginRequest>
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? email = null,
|
||||
Object? username = freezed,
|
||||
Object? email = freezed,
|
||||
Object? password = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
email: null == email
|
||||
username: freezed == username
|
||||
? _value.username
|
||||
: username // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
email: freezed == email
|
||||
? _value.email
|
||||
: email // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as String?,
|
||||
password: null == password
|
||||
? _value.password
|
||||
: password // ignore: cast_nullable_to_non_nullable
|
||||
@@ -81,7 +87,7 @@ abstract class _$$LoginRequestImplCopyWith<$Res>
|
||||
__$$LoginRequestImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({String email, String password});
|
||||
$Res call({String? username, String? email, String password});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -97,14 +103,19 @@ class __$$LoginRequestImplCopyWithImpl<$Res>
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? email = null,
|
||||
Object? username = freezed,
|
||||
Object? email = freezed,
|
||||
Object? password = null,
|
||||
}) {
|
||||
return _then(_$LoginRequestImpl(
|
||||
email: null == email
|
||||
username: freezed == username
|
||||
? _value.username
|
||||
: username // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
email: freezed == email
|
||||
? _value.email
|
||||
: email // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as String?,
|
||||
password: null == password
|
||||
? _value.password
|
||||
: password // ignore: cast_nullable_to_non_nullable
|
||||
@@ -116,19 +127,21 @@ class __$$LoginRequestImplCopyWithImpl<$Res>
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$LoginRequestImpl implements _LoginRequest {
|
||||
const _$LoginRequestImpl({required this.email, required this.password});
|
||||
const _$LoginRequestImpl({this.username, this.email, required this.password});
|
||||
|
||||
factory _$LoginRequestImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$LoginRequestImplFromJson(json);
|
||||
|
||||
@override
|
||||
final String email;
|
||||
final String? username;
|
||||
@override
|
||||
final String? email;
|
||||
@override
|
||||
final String password;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LoginRequest(email: $email, password: $password)';
|
||||
return 'LoginRequest(username: $username, email: $email, password: $password)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -136,6 +149,8 @@ class _$LoginRequestImpl implements _LoginRequest {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$LoginRequestImpl &&
|
||||
(identical(other.username, username) ||
|
||||
other.username == username) &&
|
||||
(identical(other.email, email) || other.email == email) &&
|
||||
(identical(other.password, password) ||
|
||||
other.password == password));
|
||||
@@ -143,7 +158,7 @@ class _$LoginRequestImpl implements _LoginRequest {
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, email, password);
|
||||
int get hashCode => Object.hash(runtimeType, username, email, password);
|
||||
|
||||
/// Create a copy of LoginRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -163,14 +178,17 @@ class _$LoginRequestImpl implements _LoginRequest {
|
||||
|
||||
abstract class _LoginRequest implements LoginRequest {
|
||||
const factory _LoginRequest(
|
||||
{required final String email,
|
||||
{final String? username,
|
||||
final String? email,
|
||||
required final String password}) = _$LoginRequestImpl;
|
||||
|
||||
factory _LoginRequest.fromJson(Map<String, dynamic> json) =
|
||||
_$LoginRequestImpl.fromJson;
|
||||
|
||||
@override
|
||||
String get email;
|
||||
String? get username;
|
||||
@override
|
||||
String? get email;
|
||||
@override
|
||||
String get password;
|
||||
|
||||
|
||||
@@ -8,12 +8,14 @@ part of 'login_request.dart';
|
||||
|
||||
_$LoginRequestImpl _$$LoginRequestImplFromJson(Map<String, dynamic> json) =>
|
||||
_$LoginRequestImpl(
|
||||
email: json['email'] as String,
|
||||
username: json['username'] as String?,
|
||||
email: json['email'] as String?,
|
||||
password: json['password'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$LoginRequestImplToJson(_$LoginRequestImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'username': instance.username,
|
||||
'email': instance.email,
|
||||
'password': instance.password,
|
||||
};
|
||||
|
||||
@@ -45,14 +45,14 @@ class CompanyResponse with _$CompanyResponse {
|
||||
required String name,
|
||||
required String address,
|
||||
@JsonKey(name: 'contact_name') required String contactName,
|
||||
@JsonKey(name: 'contact_position') required String contactPosition,
|
||||
@JsonKey(name: 'contact_position') String? contactPosition, // nullable로 변경
|
||||
@JsonKey(name: 'contact_phone') required String contactPhone,
|
||||
@JsonKey(name: 'contact_email') required String contactEmail,
|
||||
@JsonKey(name: 'company_types') @Default([]) List<String> companyTypes,
|
||||
String? remark,
|
||||
@JsonKey(name: 'is_active') required bool isActive,
|
||||
@JsonKey(name: 'created_at') required DateTime createdAt,
|
||||
@JsonKey(name: 'updated_at') required DateTime updatedAt,
|
||||
@JsonKey(name: 'updated_at') DateTime? updatedAt, // nullable로 변경
|
||||
@JsonKey(name: 'address_id') int? addressId,
|
||||
}) = _CompanyResponse;
|
||||
|
||||
|
||||
@@ -719,7 +719,8 @@ mixin _$CompanyResponse {
|
||||
@JsonKey(name: 'contact_name')
|
||||
String get contactName => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'contact_position')
|
||||
String get contactPosition => throw _privateConstructorUsedError;
|
||||
String? get contactPosition =>
|
||||
throw _privateConstructorUsedError; // nullable로 변경
|
||||
@JsonKey(name: 'contact_phone')
|
||||
String get contactPhone => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'contact_email')
|
||||
@@ -732,7 +733,7 @@ mixin _$CompanyResponse {
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime get createdAt => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'updated_at')
|
||||
DateTime get updatedAt => throw _privateConstructorUsedError;
|
||||
DateTime? get updatedAt => throw _privateConstructorUsedError; // nullable로 변경
|
||||
@JsonKey(name: 'address_id')
|
||||
int? get addressId => throw _privateConstructorUsedError;
|
||||
|
||||
@@ -757,14 +758,14 @@ abstract class $CompanyResponseCopyWith<$Res> {
|
||||
String name,
|
||||
String address,
|
||||
@JsonKey(name: 'contact_name') String contactName,
|
||||
@JsonKey(name: 'contact_position') String contactPosition,
|
||||
@JsonKey(name: 'contact_position') String? contactPosition,
|
||||
@JsonKey(name: 'contact_phone') String contactPhone,
|
||||
@JsonKey(name: 'contact_email') String contactEmail,
|
||||
@JsonKey(name: 'company_types') List<String> companyTypes,
|
||||
String? remark,
|
||||
@JsonKey(name: 'is_active') bool isActive,
|
||||
@JsonKey(name: 'created_at') DateTime createdAt,
|
||||
@JsonKey(name: 'updated_at') DateTime updatedAt,
|
||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
||||
@JsonKey(name: 'address_id') int? addressId});
|
||||
}
|
||||
|
||||
@@ -787,14 +788,14 @@ class _$CompanyResponseCopyWithImpl<$Res, $Val extends CompanyResponse>
|
||||
Object? name = null,
|
||||
Object? address = null,
|
||||
Object? contactName = null,
|
||||
Object? contactPosition = null,
|
||||
Object? contactPosition = freezed,
|
||||
Object? contactPhone = null,
|
||||
Object? contactEmail = null,
|
||||
Object? companyTypes = null,
|
||||
Object? remark = freezed,
|
||||
Object? isActive = null,
|
||||
Object? createdAt = null,
|
||||
Object? updatedAt = null,
|
||||
Object? updatedAt = freezed,
|
||||
Object? addressId = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
@@ -814,10 +815,10 @@ class _$CompanyResponseCopyWithImpl<$Res, $Val extends CompanyResponse>
|
||||
? _value.contactName
|
||||
: contactName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
contactPosition: null == contactPosition
|
||||
contactPosition: freezed == contactPosition
|
||||
? _value.contactPosition
|
||||
: contactPosition // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as String?,
|
||||
contactPhone: null == contactPhone
|
||||
? _value.contactPhone
|
||||
: contactPhone // ignore: cast_nullable_to_non_nullable
|
||||
@@ -842,10 +843,10 @@ class _$CompanyResponseCopyWithImpl<$Res, $Val extends CompanyResponse>
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
updatedAt: null == updatedAt
|
||||
updatedAt: freezed == updatedAt
|
||||
? _value.updatedAt
|
||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
as DateTime?,
|
||||
addressId: freezed == addressId
|
||||
? _value.addressId
|
||||
: addressId // ignore: cast_nullable_to_non_nullable
|
||||
@@ -867,14 +868,14 @@ abstract class _$$CompanyResponseImplCopyWith<$Res>
|
||||
String name,
|
||||
String address,
|
||||
@JsonKey(name: 'contact_name') String contactName,
|
||||
@JsonKey(name: 'contact_position') String contactPosition,
|
||||
@JsonKey(name: 'contact_position') String? contactPosition,
|
||||
@JsonKey(name: 'contact_phone') String contactPhone,
|
||||
@JsonKey(name: 'contact_email') String contactEmail,
|
||||
@JsonKey(name: 'company_types') List<String> companyTypes,
|
||||
String? remark,
|
||||
@JsonKey(name: 'is_active') bool isActive,
|
||||
@JsonKey(name: 'created_at') DateTime createdAt,
|
||||
@JsonKey(name: 'updated_at') DateTime updatedAt,
|
||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
||||
@JsonKey(name: 'address_id') int? addressId});
|
||||
}
|
||||
|
||||
@@ -895,14 +896,14 @@ class __$$CompanyResponseImplCopyWithImpl<$Res>
|
||||
Object? name = null,
|
||||
Object? address = null,
|
||||
Object? contactName = null,
|
||||
Object? contactPosition = null,
|
||||
Object? contactPosition = freezed,
|
||||
Object? contactPhone = null,
|
||||
Object? contactEmail = null,
|
||||
Object? companyTypes = null,
|
||||
Object? remark = freezed,
|
||||
Object? isActive = null,
|
||||
Object? createdAt = null,
|
||||
Object? updatedAt = null,
|
||||
Object? updatedAt = freezed,
|
||||
Object? addressId = freezed,
|
||||
}) {
|
||||
return _then(_$CompanyResponseImpl(
|
||||
@@ -922,10 +923,10 @@ class __$$CompanyResponseImplCopyWithImpl<$Res>
|
||||
? _value.contactName
|
||||
: contactName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
contactPosition: null == contactPosition
|
||||
contactPosition: freezed == contactPosition
|
||||
? _value.contactPosition
|
||||
: contactPosition // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as String?,
|
||||
contactPhone: null == contactPhone
|
||||
? _value.contactPhone
|
||||
: contactPhone // ignore: cast_nullable_to_non_nullable
|
||||
@@ -950,10 +951,10 @@ class __$$CompanyResponseImplCopyWithImpl<$Res>
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
updatedAt: null == updatedAt
|
||||
updatedAt: freezed == updatedAt
|
||||
? _value.updatedAt
|
||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
as DateTime?,
|
||||
addressId: freezed == addressId
|
||||
? _value.addressId
|
||||
: addressId // ignore: cast_nullable_to_non_nullable
|
||||
@@ -970,7 +971,7 @@ class _$CompanyResponseImpl implements _CompanyResponse {
|
||||
required this.name,
|
||||
required this.address,
|
||||
@JsonKey(name: 'contact_name') required this.contactName,
|
||||
@JsonKey(name: 'contact_position') required this.contactPosition,
|
||||
@JsonKey(name: 'contact_position') this.contactPosition,
|
||||
@JsonKey(name: 'contact_phone') required this.contactPhone,
|
||||
@JsonKey(name: 'contact_email') required this.contactEmail,
|
||||
@JsonKey(name: 'company_types')
|
||||
@@ -978,7 +979,7 @@ class _$CompanyResponseImpl implements _CompanyResponse {
|
||||
this.remark,
|
||||
@JsonKey(name: 'is_active') required this.isActive,
|
||||
@JsonKey(name: 'created_at') required this.createdAt,
|
||||
@JsonKey(name: 'updated_at') required this.updatedAt,
|
||||
@JsonKey(name: 'updated_at') this.updatedAt,
|
||||
@JsonKey(name: 'address_id') this.addressId})
|
||||
: _companyTypes = companyTypes;
|
||||
|
||||
@@ -996,7 +997,8 @@ class _$CompanyResponseImpl implements _CompanyResponse {
|
||||
final String contactName;
|
||||
@override
|
||||
@JsonKey(name: 'contact_position')
|
||||
final String contactPosition;
|
||||
final String? contactPosition;
|
||||
// nullable로 변경
|
||||
@override
|
||||
@JsonKey(name: 'contact_phone')
|
||||
final String contactPhone;
|
||||
@@ -1022,7 +1024,8 @@ class _$CompanyResponseImpl implements _CompanyResponse {
|
||||
final DateTime createdAt;
|
||||
@override
|
||||
@JsonKey(name: 'updated_at')
|
||||
final DateTime updatedAt;
|
||||
final DateTime? updatedAt;
|
||||
// nullable로 변경
|
||||
@override
|
||||
@JsonKey(name: 'address_id')
|
||||
final int? addressId;
|
||||
@@ -1098,20 +1101,20 @@ class _$CompanyResponseImpl implements _CompanyResponse {
|
||||
|
||||
abstract class _CompanyResponse implements CompanyResponse {
|
||||
const factory _CompanyResponse(
|
||||
{required final int id,
|
||||
required final String name,
|
||||
required final String address,
|
||||
@JsonKey(name: 'contact_name') required final String contactName,
|
||||
@JsonKey(name: 'contact_position') required final String contactPosition,
|
||||
@JsonKey(name: 'contact_phone') required final String contactPhone,
|
||||
@JsonKey(name: 'contact_email') required final String contactEmail,
|
||||
@JsonKey(name: 'company_types') final List<String> companyTypes,
|
||||
final String? remark,
|
||||
@JsonKey(name: 'is_active') required final bool isActive,
|
||||
@JsonKey(name: 'created_at') required final DateTime createdAt,
|
||||
@JsonKey(name: 'updated_at') required final DateTime updatedAt,
|
||||
@JsonKey(name: 'address_id')
|
||||
final int? addressId}) = _$CompanyResponseImpl;
|
||||
{required final int id,
|
||||
required final String name,
|
||||
required final String address,
|
||||
@JsonKey(name: 'contact_name') required final String contactName,
|
||||
@JsonKey(name: 'contact_position') final String? contactPosition,
|
||||
@JsonKey(name: 'contact_phone') required final String contactPhone,
|
||||
@JsonKey(name: 'contact_email') required final String contactEmail,
|
||||
@JsonKey(name: 'company_types') final List<String> companyTypes,
|
||||
final String? remark,
|
||||
@JsonKey(name: 'is_active') required final bool isActive,
|
||||
@JsonKey(name: 'created_at') required final DateTime createdAt,
|
||||
@JsonKey(name: 'updated_at') final DateTime? updatedAt,
|
||||
@JsonKey(name: 'address_id') final int? addressId}) =
|
||||
_$CompanyResponseImpl;
|
||||
|
||||
factory _CompanyResponse.fromJson(Map<String, dynamic> json) =
|
||||
_$CompanyResponseImpl.fromJson;
|
||||
@@ -1127,7 +1130,7 @@ abstract class _CompanyResponse implements CompanyResponse {
|
||||
String get contactName;
|
||||
@override
|
||||
@JsonKey(name: 'contact_position')
|
||||
String get contactPosition;
|
||||
String? get contactPosition; // nullable로 변경
|
||||
@override
|
||||
@JsonKey(name: 'contact_phone')
|
||||
String get contactPhone;
|
||||
@@ -1147,7 +1150,7 @@ abstract class _CompanyResponse implements CompanyResponse {
|
||||
DateTime get createdAt;
|
||||
@override
|
||||
@JsonKey(name: 'updated_at')
|
||||
DateTime get updatedAt;
|
||||
DateTime? get updatedAt; // nullable로 변경
|
||||
@override
|
||||
@JsonKey(name: 'address_id')
|
||||
int? get addressId;
|
||||
|
||||
@@ -72,7 +72,7 @@ _$CompanyResponseImpl _$$CompanyResponseImplFromJson(
|
||||
name: json['name'] as String,
|
||||
address: json['address'] as String,
|
||||
contactName: json['contact_name'] as String,
|
||||
contactPosition: json['contact_position'] as String,
|
||||
contactPosition: json['contact_position'] as String?,
|
||||
contactPhone: json['contact_phone'] as String,
|
||||
contactEmail: json['contact_email'] as String,
|
||||
companyTypes: (json['company_types'] as List<dynamic>?)
|
||||
@@ -82,7 +82,9 @@ _$CompanyResponseImpl _$$CompanyResponseImplFromJson(
|
||||
remark: json['remark'] as String?,
|
||||
isActive: json['is_active'] as bool,
|
||||
createdAt: DateTime.parse(json['created_at'] as String),
|
||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||
updatedAt: json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String),
|
||||
addressId: (json['address_id'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
@@ -100,7 +102,7 @@ Map<String, dynamic> _$$CompanyResponseImplToJson(
|
||||
'remark': instance.remark,
|
||||
'is_active': instance.isActive,
|
||||
'created_at': instance.createdAt.toIso8601String(),
|
||||
'updated_at': instance.updatedAt.toIso8601String(),
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'address_id': instance.addressId,
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,9 @@ class CompanyListDto with _$CompanyListDto {
|
||||
required String address,
|
||||
@JsonKey(name: 'contact_name') required String contactName,
|
||||
@JsonKey(name: 'contact_phone') required String contactPhone,
|
||||
@JsonKey(name: 'contact_email') String? contactEmail,
|
||||
@JsonKey(name: 'is_active') required bool isActive,
|
||||
@JsonKey(name: 'created_at') DateTime? createdAt,
|
||||
@JsonKey(name: 'branch_count') @Default(0) int branchCount,
|
||||
}) = _CompanyListDto;
|
||||
|
||||
|
||||
@@ -27,8 +27,12 @@ mixin _$CompanyListDto {
|
||||
String get contactName => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'contact_phone')
|
||||
String get contactPhone => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'contact_email')
|
||||
String? get contactEmail => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'is_active')
|
||||
bool get isActive => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime? get createdAt => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'branch_count')
|
||||
int get branchCount => throw _privateConstructorUsedError;
|
||||
|
||||
@@ -54,7 +58,9 @@ abstract class $CompanyListDtoCopyWith<$Res> {
|
||||
String address,
|
||||
@JsonKey(name: 'contact_name') String contactName,
|
||||
@JsonKey(name: 'contact_phone') String contactPhone,
|
||||
@JsonKey(name: 'contact_email') String? contactEmail,
|
||||
@JsonKey(name: 'is_active') bool isActive,
|
||||
@JsonKey(name: 'created_at') DateTime? createdAt,
|
||||
@JsonKey(name: 'branch_count') int branchCount});
|
||||
}
|
||||
|
||||
@@ -78,7 +84,9 @@ class _$CompanyListDtoCopyWithImpl<$Res, $Val extends CompanyListDto>
|
||||
Object? address = null,
|
||||
Object? contactName = null,
|
||||
Object? contactPhone = null,
|
||||
Object? contactEmail = freezed,
|
||||
Object? isActive = null,
|
||||
Object? createdAt = freezed,
|
||||
Object? branchCount = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
@@ -102,10 +110,18 @@ class _$CompanyListDtoCopyWithImpl<$Res, $Val extends CompanyListDto>
|
||||
? _value.contactPhone
|
||||
: contactPhone // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
contactEmail: freezed == contactEmail
|
||||
? _value.contactEmail
|
||||
: contactEmail // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
isActive: null == isActive
|
||||
? _value.isActive
|
||||
: isActive // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
createdAt: freezed == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
branchCount: null == branchCount
|
||||
? _value.branchCount
|
||||
: branchCount // ignore: cast_nullable_to_non_nullable
|
||||
@@ -128,7 +144,9 @@ abstract class _$$CompanyListDtoImplCopyWith<$Res>
|
||||
String address,
|
||||
@JsonKey(name: 'contact_name') String contactName,
|
||||
@JsonKey(name: 'contact_phone') String contactPhone,
|
||||
@JsonKey(name: 'contact_email') String? contactEmail,
|
||||
@JsonKey(name: 'is_active') bool isActive,
|
||||
@JsonKey(name: 'created_at') DateTime? createdAt,
|
||||
@JsonKey(name: 'branch_count') int branchCount});
|
||||
}
|
||||
|
||||
@@ -150,7 +168,9 @@ class __$$CompanyListDtoImplCopyWithImpl<$Res>
|
||||
Object? address = null,
|
||||
Object? contactName = null,
|
||||
Object? contactPhone = null,
|
||||
Object? contactEmail = freezed,
|
||||
Object? isActive = null,
|
||||
Object? createdAt = freezed,
|
||||
Object? branchCount = null,
|
||||
}) {
|
||||
return _then(_$CompanyListDtoImpl(
|
||||
@@ -174,10 +194,18 @@ class __$$CompanyListDtoImplCopyWithImpl<$Res>
|
||||
? _value.contactPhone
|
||||
: contactPhone // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
contactEmail: freezed == contactEmail
|
||||
? _value.contactEmail
|
||||
: contactEmail // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
isActive: null == isActive
|
||||
? _value.isActive
|
||||
: isActive // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
createdAt: freezed == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
branchCount: null == branchCount
|
||||
? _value.branchCount
|
||||
: branchCount // ignore: cast_nullable_to_non_nullable
|
||||
@@ -195,7 +223,9 @@ class _$CompanyListDtoImpl implements _CompanyListDto {
|
||||
required this.address,
|
||||
@JsonKey(name: 'contact_name') required this.contactName,
|
||||
@JsonKey(name: 'contact_phone') required this.contactPhone,
|
||||
@JsonKey(name: 'contact_email') this.contactEmail,
|
||||
@JsonKey(name: 'is_active') required this.isActive,
|
||||
@JsonKey(name: 'created_at') this.createdAt,
|
||||
@JsonKey(name: 'branch_count') this.branchCount = 0});
|
||||
|
||||
factory _$CompanyListDtoImpl.fromJson(Map<String, dynamic> json) =>
|
||||
@@ -214,15 +244,21 @@ class _$CompanyListDtoImpl implements _CompanyListDto {
|
||||
@JsonKey(name: 'contact_phone')
|
||||
final String contactPhone;
|
||||
@override
|
||||
@JsonKey(name: 'contact_email')
|
||||
final String? contactEmail;
|
||||
@override
|
||||
@JsonKey(name: 'is_active')
|
||||
final bool isActive;
|
||||
@override
|
||||
@JsonKey(name: 'created_at')
|
||||
final DateTime? createdAt;
|
||||
@override
|
||||
@JsonKey(name: 'branch_count')
|
||||
final int branchCount;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CompanyListDto(id: $id, name: $name, address: $address, contactName: $contactName, contactPhone: $contactPhone, isActive: $isActive, branchCount: $branchCount)';
|
||||
return 'CompanyListDto(id: $id, name: $name, address: $address, contactName: $contactName, contactPhone: $contactPhone, contactEmail: $contactEmail, isActive: $isActive, createdAt: $createdAt, branchCount: $branchCount)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -237,8 +273,12 @@ class _$CompanyListDtoImpl implements _CompanyListDto {
|
||||
other.contactName == contactName) &&
|
||||
(identical(other.contactPhone, contactPhone) ||
|
||||
other.contactPhone == contactPhone) &&
|
||||
(identical(other.contactEmail, contactEmail) ||
|
||||
other.contactEmail == contactEmail) &&
|
||||
(identical(other.isActive, isActive) ||
|
||||
other.isActive == isActive) &&
|
||||
(identical(other.createdAt, createdAt) ||
|
||||
other.createdAt == createdAt) &&
|
||||
(identical(other.branchCount, branchCount) ||
|
||||
other.branchCount == branchCount));
|
||||
}
|
||||
@@ -246,7 +286,7 @@ class _$CompanyListDtoImpl implements _CompanyListDto {
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, id, name, address, contactName,
|
||||
contactPhone, isActive, branchCount);
|
||||
contactPhone, contactEmail, isActive, createdAt, branchCount);
|
||||
|
||||
/// Create a copy of CompanyListDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -272,7 +312,9 @@ abstract class _CompanyListDto implements CompanyListDto {
|
||||
required final String address,
|
||||
@JsonKey(name: 'contact_name') required final String contactName,
|
||||
@JsonKey(name: 'contact_phone') required final String contactPhone,
|
||||
@JsonKey(name: 'contact_email') final String? contactEmail,
|
||||
@JsonKey(name: 'is_active') required final bool isActive,
|
||||
@JsonKey(name: 'created_at') final DateTime? createdAt,
|
||||
@JsonKey(name: 'branch_count') final int branchCount}) =
|
||||
_$CompanyListDtoImpl;
|
||||
|
||||
@@ -292,9 +334,15 @@ abstract class _CompanyListDto implements CompanyListDto {
|
||||
@JsonKey(name: 'contact_phone')
|
||||
String get contactPhone;
|
||||
@override
|
||||
@JsonKey(name: 'contact_email')
|
||||
String? get contactEmail;
|
||||
@override
|
||||
@JsonKey(name: 'is_active')
|
||||
bool get isActive;
|
||||
@override
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime? get createdAt;
|
||||
@override
|
||||
@JsonKey(name: 'branch_count')
|
||||
int get branchCount;
|
||||
|
||||
|
||||
@@ -13,7 +13,11 @@ _$CompanyListDtoImpl _$$CompanyListDtoImplFromJson(Map<String, dynamic> json) =>
|
||||
address: json['address'] as String,
|
||||
contactName: json['contact_name'] as String,
|
||||
contactPhone: json['contact_phone'] as String,
|
||||
contactEmail: json['contact_email'] as String?,
|
||||
isActive: json['is_active'] as bool,
|
||||
createdAt: json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String),
|
||||
branchCount: (json['branch_count'] as num?)?.toInt() ?? 0,
|
||||
);
|
||||
|
||||
@@ -25,7 +29,9 @@ Map<String, dynamic> _$$CompanyListDtoImplToJson(
|
||||
'address': instance.address,
|
||||
'contact_name': instance.contactName,
|
||||
'contact_phone': instance.contactPhone,
|
||||
'contact_email': instance.contactEmail,
|
||||
'is_active': instance.isActive,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'branch_count': instance.branchCount,
|
||||
};
|
||||
|
||||
|
||||
@@ -7,11 +7,13 @@ part 'expiring_license.g.dart';
|
||||
class ExpiringLicense with _$ExpiringLicense {
|
||||
const factory ExpiringLicense({
|
||||
required int id,
|
||||
@JsonKey(name: 'license_name') required String licenseName,
|
||||
@JsonKey(name: 'license_key') required String licenseKey,
|
||||
@JsonKey(name: 'software_name') required String softwareName,
|
||||
@JsonKey(name: 'company_name') required String companyName,
|
||||
@JsonKey(name: 'expiry_date') required DateTime expiryDate,
|
||||
@JsonKey(name: 'days_remaining') required int daysRemaining,
|
||||
@JsonKey(name: 'license_type') required String licenseType,
|
||||
@JsonKey(name: 'days_until_expiry') required int daysUntilExpiry,
|
||||
@JsonKey(name: 'renewal_cost') required double renewalCost,
|
||||
@JsonKey(name: 'auto_renew') required bool autoRenew,
|
||||
}) = _ExpiringLicense;
|
||||
|
||||
factory ExpiringLicense.fromJson(Map<String, dynamic> json) =>
|
||||
|
||||
@@ -21,16 +21,20 @@ ExpiringLicense _$ExpiringLicenseFromJson(Map<String, dynamic> json) {
|
||||
/// @nodoc
|
||||
mixin _$ExpiringLicense {
|
||||
int get id => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'license_name')
|
||||
String get licenseName => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'license_key')
|
||||
String get licenseKey => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'software_name')
|
||||
String get softwareName => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'company_name')
|
||||
String get companyName => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'expiry_date')
|
||||
DateTime get expiryDate => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'days_remaining')
|
||||
int get daysRemaining => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'license_type')
|
||||
String get licenseType => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'days_until_expiry')
|
||||
int get daysUntilExpiry => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'renewal_cost')
|
||||
double get renewalCost => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'auto_renew')
|
||||
bool get autoRenew => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this ExpiringLicense to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@@ -50,11 +54,13 @@ abstract class $ExpiringLicenseCopyWith<$Res> {
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
@JsonKey(name: 'license_name') String licenseName,
|
||||
@JsonKey(name: 'license_key') String licenseKey,
|
||||
@JsonKey(name: 'software_name') String softwareName,
|
||||
@JsonKey(name: 'company_name') String companyName,
|
||||
@JsonKey(name: 'expiry_date') DateTime expiryDate,
|
||||
@JsonKey(name: 'days_remaining') int daysRemaining,
|
||||
@JsonKey(name: 'license_type') String licenseType});
|
||||
@JsonKey(name: 'days_until_expiry') int daysUntilExpiry,
|
||||
@JsonKey(name: 'renewal_cost') double renewalCost,
|
||||
@JsonKey(name: 'auto_renew') bool autoRenew});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -73,20 +79,26 @@ class _$ExpiringLicenseCopyWithImpl<$Res, $Val extends ExpiringLicense>
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? licenseName = null,
|
||||
Object? licenseKey = null,
|
||||
Object? softwareName = null,
|
||||
Object? companyName = null,
|
||||
Object? expiryDate = null,
|
||||
Object? daysRemaining = null,
|
||||
Object? licenseType = null,
|
||||
Object? daysUntilExpiry = null,
|
||||
Object? renewalCost = null,
|
||||
Object? autoRenew = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
licenseName: null == licenseName
|
||||
? _value.licenseName
|
||||
: licenseName // ignore: cast_nullable_to_non_nullable
|
||||
licenseKey: null == licenseKey
|
||||
? _value.licenseKey
|
||||
: licenseKey // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
softwareName: null == softwareName
|
||||
? _value.softwareName
|
||||
: softwareName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
companyName: null == companyName
|
||||
? _value.companyName
|
||||
@@ -96,14 +108,18 @@ class _$ExpiringLicenseCopyWithImpl<$Res, $Val extends ExpiringLicense>
|
||||
? _value.expiryDate
|
||||
: expiryDate // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
daysRemaining: null == daysRemaining
|
||||
? _value.daysRemaining
|
||||
: daysRemaining // ignore: cast_nullable_to_non_nullable
|
||||
daysUntilExpiry: null == daysUntilExpiry
|
||||
? _value.daysUntilExpiry
|
||||
: daysUntilExpiry // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
licenseType: null == licenseType
|
||||
? _value.licenseType
|
||||
: licenseType // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
renewalCost: null == renewalCost
|
||||
? _value.renewalCost
|
||||
: renewalCost // ignore: cast_nullable_to_non_nullable
|
||||
as double,
|
||||
autoRenew: null == autoRenew
|
||||
? _value.autoRenew
|
||||
: autoRenew // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
@@ -118,11 +134,13 @@ abstract class _$$ExpiringLicenseImplCopyWith<$Res>
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
@JsonKey(name: 'license_name') String licenseName,
|
||||
@JsonKey(name: 'license_key') String licenseKey,
|
||||
@JsonKey(name: 'software_name') String softwareName,
|
||||
@JsonKey(name: 'company_name') String companyName,
|
||||
@JsonKey(name: 'expiry_date') DateTime expiryDate,
|
||||
@JsonKey(name: 'days_remaining') int daysRemaining,
|
||||
@JsonKey(name: 'license_type') String licenseType});
|
||||
@JsonKey(name: 'days_until_expiry') int daysUntilExpiry,
|
||||
@JsonKey(name: 'renewal_cost') double renewalCost,
|
||||
@JsonKey(name: 'auto_renew') bool autoRenew});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -139,20 +157,26 @@ class __$$ExpiringLicenseImplCopyWithImpl<$Res>
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? licenseName = null,
|
||||
Object? licenseKey = null,
|
||||
Object? softwareName = null,
|
||||
Object? companyName = null,
|
||||
Object? expiryDate = null,
|
||||
Object? daysRemaining = null,
|
||||
Object? licenseType = null,
|
||||
Object? daysUntilExpiry = null,
|
||||
Object? renewalCost = null,
|
||||
Object? autoRenew = null,
|
||||
}) {
|
||||
return _then(_$ExpiringLicenseImpl(
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
licenseName: null == licenseName
|
||||
? _value.licenseName
|
||||
: licenseName // ignore: cast_nullable_to_non_nullable
|
||||
licenseKey: null == licenseKey
|
||||
? _value.licenseKey
|
||||
: licenseKey // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
softwareName: null == softwareName
|
||||
? _value.softwareName
|
||||
: softwareName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
companyName: null == companyName
|
||||
? _value.companyName
|
||||
@@ -162,14 +186,18 @@ class __$$ExpiringLicenseImplCopyWithImpl<$Res>
|
||||
? _value.expiryDate
|
||||
: expiryDate // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
daysRemaining: null == daysRemaining
|
||||
? _value.daysRemaining
|
||||
: daysRemaining // ignore: cast_nullable_to_non_nullable
|
||||
daysUntilExpiry: null == daysUntilExpiry
|
||||
? _value.daysUntilExpiry
|
||||
: daysUntilExpiry // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
licenseType: null == licenseType
|
||||
? _value.licenseType
|
||||
: licenseType // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
renewalCost: null == renewalCost
|
||||
? _value.renewalCost
|
||||
: renewalCost // ignore: cast_nullable_to_non_nullable
|
||||
as double,
|
||||
autoRenew: null == autoRenew
|
||||
? _value.autoRenew
|
||||
: autoRenew // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -179,11 +207,13 @@ class __$$ExpiringLicenseImplCopyWithImpl<$Res>
|
||||
class _$ExpiringLicenseImpl implements _ExpiringLicense {
|
||||
const _$ExpiringLicenseImpl(
|
||||
{required this.id,
|
||||
@JsonKey(name: 'license_name') required this.licenseName,
|
||||
@JsonKey(name: 'license_key') required this.licenseKey,
|
||||
@JsonKey(name: 'software_name') required this.softwareName,
|
||||
@JsonKey(name: 'company_name') required this.companyName,
|
||||
@JsonKey(name: 'expiry_date') required this.expiryDate,
|
||||
@JsonKey(name: 'days_remaining') required this.daysRemaining,
|
||||
@JsonKey(name: 'license_type') required this.licenseType});
|
||||
@JsonKey(name: 'days_until_expiry') required this.daysUntilExpiry,
|
||||
@JsonKey(name: 'renewal_cost') required this.renewalCost,
|
||||
@JsonKey(name: 'auto_renew') required this.autoRenew});
|
||||
|
||||
factory _$ExpiringLicenseImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$ExpiringLicenseImplFromJson(json);
|
||||
@@ -191,8 +221,11 @@ class _$ExpiringLicenseImpl implements _ExpiringLicense {
|
||||
@override
|
||||
final int id;
|
||||
@override
|
||||
@JsonKey(name: 'license_name')
|
||||
final String licenseName;
|
||||
@JsonKey(name: 'license_key')
|
||||
final String licenseKey;
|
||||
@override
|
||||
@JsonKey(name: 'software_name')
|
||||
final String softwareName;
|
||||
@override
|
||||
@JsonKey(name: 'company_name')
|
||||
final String companyName;
|
||||
@@ -200,15 +233,18 @@ class _$ExpiringLicenseImpl implements _ExpiringLicense {
|
||||
@JsonKey(name: 'expiry_date')
|
||||
final DateTime expiryDate;
|
||||
@override
|
||||
@JsonKey(name: 'days_remaining')
|
||||
final int daysRemaining;
|
||||
@JsonKey(name: 'days_until_expiry')
|
||||
final int daysUntilExpiry;
|
||||
@override
|
||||
@JsonKey(name: 'license_type')
|
||||
final String licenseType;
|
||||
@JsonKey(name: 'renewal_cost')
|
||||
final double renewalCost;
|
||||
@override
|
||||
@JsonKey(name: 'auto_renew')
|
||||
final bool autoRenew;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ExpiringLicense(id: $id, licenseName: $licenseName, companyName: $companyName, expiryDate: $expiryDate, daysRemaining: $daysRemaining, licenseType: $licenseType)';
|
||||
return 'ExpiringLicense(id: $id, licenseKey: $licenseKey, softwareName: $softwareName, companyName: $companyName, expiryDate: $expiryDate, daysUntilExpiry: $daysUntilExpiry, renewalCost: $renewalCost, autoRenew: $autoRenew)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -217,22 +253,26 @@ class _$ExpiringLicenseImpl implements _ExpiringLicense {
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ExpiringLicenseImpl &&
|
||||
(identical(other.id, id) || other.id == id) &&
|
||||
(identical(other.licenseName, licenseName) ||
|
||||
other.licenseName == licenseName) &&
|
||||
(identical(other.licenseKey, licenseKey) ||
|
||||
other.licenseKey == licenseKey) &&
|
||||
(identical(other.softwareName, softwareName) ||
|
||||
other.softwareName == softwareName) &&
|
||||
(identical(other.companyName, companyName) ||
|
||||
other.companyName == companyName) &&
|
||||
(identical(other.expiryDate, expiryDate) ||
|
||||
other.expiryDate == expiryDate) &&
|
||||
(identical(other.daysRemaining, daysRemaining) ||
|
||||
other.daysRemaining == daysRemaining) &&
|
||||
(identical(other.licenseType, licenseType) ||
|
||||
other.licenseType == licenseType));
|
||||
(identical(other.daysUntilExpiry, daysUntilExpiry) ||
|
||||
other.daysUntilExpiry == daysUntilExpiry) &&
|
||||
(identical(other.renewalCost, renewalCost) ||
|
||||
other.renewalCost == renewalCost) &&
|
||||
(identical(other.autoRenew, autoRenew) ||
|
||||
other.autoRenew == autoRenew));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, id, licenseName, companyName,
|
||||
expiryDate, daysRemaining, licenseType);
|
||||
int get hashCode => Object.hash(runtimeType, id, licenseKey, softwareName,
|
||||
companyName, expiryDate, daysUntilExpiry, renewalCost, autoRenew);
|
||||
|
||||
/// Create a copy of ExpiringLicense
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -253,13 +293,15 @@ class _$ExpiringLicenseImpl implements _ExpiringLicense {
|
||||
|
||||
abstract class _ExpiringLicense implements ExpiringLicense {
|
||||
const factory _ExpiringLicense(
|
||||
{required final int id,
|
||||
@JsonKey(name: 'license_name') required final String licenseName,
|
||||
@JsonKey(name: 'company_name') required final String companyName,
|
||||
@JsonKey(name: 'expiry_date') required final DateTime expiryDate,
|
||||
@JsonKey(name: 'days_remaining') required final int daysRemaining,
|
||||
@JsonKey(name: 'license_type') required final String licenseType}) =
|
||||
_$ExpiringLicenseImpl;
|
||||
{required final int id,
|
||||
@JsonKey(name: 'license_key') required final String licenseKey,
|
||||
@JsonKey(name: 'software_name') required final String softwareName,
|
||||
@JsonKey(name: 'company_name') required final String companyName,
|
||||
@JsonKey(name: 'expiry_date') required final DateTime expiryDate,
|
||||
@JsonKey(name: 'days_until_expiry') required final int daysUntilExpiry,
|
||||
@JsonKey(name: 'renewal_cost') required final double renewalCost,
|
||||
@JsonKey(name: 'auto_renew')
|
||||
required final bool autoRenew}) = _$ExpiringLicenseImpl;
|
||||
|
||||
factory _ExpiringLicense.fromJson(Map<String, dynamic> json) =
|
||||
_$ExpiringLicenseImpl.fromJson;
|
||||
@@ -267,8 +309,11 @@ abstract class _ExpiringLicense implements ExpiringLicense {
|
||||
@override
|
||||
int get id;
|
||||
@override
|
||||
@JsonKey(name: 'license_name')
|
||||
String get licenseName;
|
||||
@JsonKey(name: 'license_key')
|
||||
String get licenseKey;
|
||||
@override
|
||||
@JsonKey(name: 'software_name')
|
||||
String get softwareName;
|
||||
@override
|
||||
@JsonKey(name: 'company_name')
|
||||
String get companyName;
|
||||
@@ -276,11 +321,14 @@ abstract class _ExpiringLicense implements ExpiringLicense {
|
||||
@JsonKey(name: 'expiry_date')
|
||||
DateTime get expiryDate;
|
||||
@override
|
||||
@JsonKey(name: 'days_remaining')
|
||||
int get daysRemaining;
|
||||
@JsonKey(name: 'days_until_expiry')
|
||||
int get daysUntilExpiry;
|
||||
@override
|
||||
@JsonKey(name: 'license_type')
|
||||
String get licenseType;
|
||||
@JsonKey(name: 'renewal_cost')
|
||||
double get renewalCost;
|
||||
@override
|
||||
@JsonKey(name: 'auto_renew')
|
||||
bool get autoRenew;
|
||||
|
||||
/// Create a copy of ExpiringLicense
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
|
||||
@@ -10,20 +10,24 @@ _$ExpiringLicenseImpl _$$ExpiringLicenseImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$ExpiringLicenseImpl(
|
||||
id: (json['id'] as num).toInt(),
|
||||
licenseName: json['license_name'] as String,
|
||||
licenseKey: json['license_key'] as String,
|
||||
softwareName: json['software_name'] as String,
|
||||
companyName: json['company_name'] as String,
|
||||
expiryDate: DateTime.parse(json['expiry_date'] as String),
|
||||
daysRemaining: (json['days_remaining'] as num).toInt(),
|
||||
licenseType: json['license_type'] as String,
|
||||
daysUntilExpiry: (json['days_until_expiry'] as num).toInt(),
|
||||
renewalCost: (json['renewal_cost'] as num).toDouble(),
|
||||
autoRenew: json['auto_renew'] as bool,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ExpiringLicenseImplToJson(
|
||||
_$ExpiringLicenseImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'license_name': instance.licenseName,
|
||||
'license_key': instance.licenseKey,
|
||||
'software_name': instance.softwareName,
|
||||
'company_name': instance.companyName,
|
||||
'expiry_date': instance.expiryDate.toIso8601String(),
|
||||
'days_remaining': instance.daysRemaining,
|
||||
'license_type': instance.licenseType,
|
||||
'days_until_expiry': instance.daysUntilExpiry,
|
||||
'renewal_cost': instance.renewalCost,
|
||||
'auto_renew': instance.autoRenew,
|
||||
};
|
||||
|
||||
@@ -6,16 +6,23 @@ part 'overview_stats.g.dart';
|
||||
@freezed
|
||||
class OverviewStats with _$OverviewStats {
|
||||
const factory OverviewStats({
|
||||
@JsonKey(name: 'total_companies') required int totalCompanies,
|
||||
@JsonKey(name: 'active_companies') required int activeCompanies,
|
||||
@JsonKey(name: 'total_users') required int totalUsers,
|
||||
@JsonKey(name: 'active_users') required int activeUsers,
|
||||
@JsonKey(name: 'total_equipment') required int totalEquipment,
|
||||
@JsonKey(name: 'available_equipment') required int availableEquipment,
|
||||
@JsonKey(name: 'in_use_equipment') required int inUseEquipment,
|
||||
@JsonKey(name: 'maintenance_equipment') required int maintenanceEquipment,
|
||||
@JsonKey(name: 'total_companies') required int totalCompanies,
|
||||
@JsonKey(name: 'total_users') required int totalUsers,
|
||||
@JsonKey(name: 'total_licenses') required int totalLicenses,
|
||||
@JsonKey(name: 'active_licenses') required int activeLicenses,
|
||||
@JsonKey(name: 'expiring_licenses') required int expiringLicenses,
|
||||
@JsonKey(name: 'total_rentals') required int totalRentals,
|
||||
@JsonKey(name: 'active_rentals') required int activeRentals,
|
||||
@JsonKey(name: 'expiring_licenses_count') required int expiringLicensesCount,
|
||||
@JsonKey(name: 'expired_licenses_count') required int expiredLicensesCount,
|
||||
@JsonKey(name: 'total_warehouse_locations') required int totalWarehouseLocations,
|
||||
@JsonKey(name: 'active_warehouse_locations') required int activeWarehouseLocations,
|
||||
// 다음 필드들은 백엔드에 없으므로 선택적으로 만듭니다
|
||||
@JsonKey(name: 'total_rentals', defaultValue: 0) int? totalRentals,
|
||||
@JsonKey(name: 'active_rentals', defaultValue: 0) int? activeRentals,
|
||||
}) = _OverviewStats;
|
||||
|
||||
factory OverviewStats.fromJson(Map<String, dynamic> json) =>
|
||||
|
||||
@@ -20,6 +20,14 @@ OverviewStats _$OverviewStatsFromJson(Map<String, dynamic> json) {
|
||||
|
||||
/// @nodoc
|
||||
mixin _$OverviewStats {
|
||||
@JsonKey(name: 'total_companies')
|
||||
int get totalCompanies => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'active_companies')
|
||||
int get activeCompanies => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'total_users')
|
||||
int get totalUsers => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'active_users')
|
||||
int get activeUsers => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'total_equipment')
|
||||
int get totalEquipment => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'available_equipment')
|
||||
@@ -28,18 +36,23 @@ mixin _$OverviewStats {
|
||||
int get inUseEquipment => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'maintenance_equipment')
|
||||
int get maintenanceEquipment => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'total_companies')
|
||||
int get totalCompanies => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'total_users')
|
||||
int get totalUsers => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'total_licenses')
|
||||
int get totalLicenses => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'active_licenses')
|
||||
int get activeLicenses => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'expiring_licenses')
|
||||
int get expiringLicenses => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'total_rentals')
|
||||
int get totalRentals => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'active_rentals')
|
||||
int get activeRentals => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'expiring_licenses_count')
|
||||
int get expiringLicensesCount => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'expired_licenses_count')
|
||||
int get expiredLicensesCount => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'total_warehouse_locations')
|
||||
int get totalWarehouseLocations => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'active_warehouse_locations')
|
||||
int get activeWarehouseLocations =>
|
||||
throw _privateConstructorUsedError; // 다음 필드들은 백엔드에 없으므로 선택적으로 만듭니다
|
||||
@JsonKey(name: 'total_rentals', defaultValue: 0)
|
||||
int? get totalRentals => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'active_rentals', defaultValue: 0)
|
||||
int? get activeRentals => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this OverviewStats to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@@ -58,16 +71,22 @@ abstract class $OverviewStatsCopyWith<$Res> {
|
||||
_$OverviewStatsCopyWithImpl<$Res, OverviewStats>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{@JsonKey(name: 'total_equipment') int totalEquipment,
|
||||
{@JsonKey(name: 'total_companies') int totalCompanies,
|
||||
@JsonKey(name: 'active_companies') int activeCompanies,
|
||||
@JsonKey(name: 'total_users') int totalUsers,
|
||||
@JsonKey(name: 'active_users') int activeUsers,
|
||||
@JsonKey(name: 'total_equipment') int totalEquipment,
|
||||
@JsonKey(name: 'available_equipment') int availableEquipment,
|
||||
@JsonKey(name: 'in_use_equipment') int inUseEquipment,
|
||||
@JsonKey(name: 'maintenance_equipment') int maintenanceEquipment,
|
||||
@JsonKey(name: 'total_companies') int totalCompanies,
|
||||
@JsonKey(name: 'total_users') int totalUsers,
|
||||
@JsonKey(name: 'total_licenses') int totalLicenses,
|
||||
@JsonKey(name: 'active_licenses') int activeLicenses,
|
||||
@JsonKey(name: 'expiring_licenses') int expiringLicenses,
|
||||
@JsonKey(name: 'total_rentals') int totalRentals,
|
||||
@JsonKey(name: 'active_rentals') int activeRentals});
|
||||
@JsonKey(name: 'expiring_licenses_count') int expiringLicensesCount,
|
||||
@JsonKey(name: 'expired_licenses_count') int expiredLicensesCount,
|
||||
@JsonKey(name: 'total_warehouse_locations') int totalWarehouseLocations,
|
||||
@JsonKey(name: 'active_warehouse_locations') int activeWarehouseLocations,
|
||||
@JsonKey(name: 'total_rentals', defaultValue: 0) int? totalRentals,
|
||||
@JsonKey(name: 'active_rentals', defaultValue: 0) int? activeRentals});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -85,18 +104,40 @@ class _$OverviewStatsCopyWithImpl<$Res, $Val extends OverviewStats>
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? totalCompanies = null,
|
||||
Object? activeCompanies = null,
|
||||
Object? totalUsers = null,
|
||||
Object? activeUsers = null,
|
||||
Object? totalEquipment = null,
|
||||
Object? availableEquipment = null,
|
||||
Object? inUseEquipment = null,
|
||||
Object? maintenanceEquipment = null,
|
||||
Object? totalCompanies = null,
|
||||
Object? totalUsers = null,
|
||||
Object? totalLicenses = null,
|
||||
Object? activeLicenses = null,
|
||||
Object? expiringLicenses = null,
|
||||
Object? totalRentals = null,
|
||||
Object? activeRentals = null,
|
||||
Object? expiringLicensesCount = null,
|
||||
Object? expiredLicensesCount = null,
|
||||
Object? totalWarehouseLocations = null,
|
||||
Object? activeWarehouseLocations = null,
|
||||
Object? totalRentals = freezed,
|
||||
Object? activeRentals = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
totalCompanies: null == totalCompanies
|
||||
? _value.totalCompanies
|
||||
: totalCompanies // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
activeCompanies: null == activeCompanies
|
||||
? _value.activeCompanies
|
||||
: activeCompanies // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalUsers: null == totalUsers
|
||||
? _value.totalUsers
|
||||
: totalUsers // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
activeUsers: null == activeUsers
|
||||
? _value.activeUsers
|
||||
: activeUsers // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalEquipment: null == totalEquipment
|
||||
? _value.totalEquipment
|
||||
: totalEquipment // ignore: cast_nullable_to_non_nullable
|
||||
@@ -113,30 +154,38 @@ class _$OverviewStatsCopyWithImpl<$Res, $Val extends OverviewStats>
|
||||
? _value.maintenanceEquipment
|
||||
: maintenanceEquipment // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalCompanies: null == totalCompanies
|
||||
? _value.totalCompanies
|
||||
: totalCompanies // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalUsers: null == totalUsers
|
||||
? _value.totalUsers
|
||||
: totalUsers // ignore: cast_nullable_to_non_nullable
|
||||
totalLicenses: null == totalLicenses
|
||||
? _value.totalLicenses
|
||||
: totalLicenses // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
activeLicenses: null == activeLicenses
|
||||
? _value.activeLicenses
|
||||
: activeLicenses // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
expiringLicenses: null == expiringLicenses
|
||||
? _value.expiringLicenses
|
||||
: expiringLicenses // ignore: cast_nullable_to_non_nullable
|
||||
expiringLicensesCount: null == expiringLicensesCount
|
||||
? _value.expiringLicensesCount
|
||||
: expiringLicensesCount // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalRentals: null == totalRentals
|
||||
expiredLicensesCount: null == expiredLicensesCount
|
||||
? _value.expiredLicensesCount
|
||||
: expiredLicensesCount // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalWarehouseLocations: null == totalWarehouseLocations
|
||||
? _value.totalWarehouseLocations
|
||||
: totalWarehouseLocations // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
activeWarehouseLocations: null == activeWarehouseLocations
|
||||
? _value.activeWarehouseLocations
|
||||
: activeWarehouseLocations // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalRentals: freezed == totalRentals
|
||||
? _value.totalRentals
|
||||
: totalRentals // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
activeRentals: null == activeRentals
|
||||
as int?,
|
||||
activeRentals: freezed == activeRentals
|
||||
? _value.activeRentals
|
||||
: activeRentals // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
as int?,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
@@ -150,16 +199,22 @@ abstract class _$$OverviewStatsImplCopyWith<$Res>
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{@JsonKey(name: 'total_equipment') int totalEquipment,
|
||||
{@JsonKey(name: 'total_companies') int totalCompanies,
|
||||
@JsonKey(name: 'active_companies') int activeCompanies,
|
||||
@JsonKey(name: 'total_users') int totalUsers,
|
||||
@JsonKey(name: 'active_users') int activeUsers,
|
||||
@JsonKey(name: 'total_equipment') int totalEquipment,
|
||||
@JsonKey(name: 'available_equipment') int availableEquipment,
|
||||
@JsonKey(name: 'in_use_equipment') int inUseEquipment,
|
||||
@JsonKey(name: 'maintenance_equipment') int maintenanceEquipment,
|
||||
@JsonKey(name: 'total_companies') int totalCompanies,
|
||||
@JsonKey(name: 'total_users') int totalUsers,
|
||||
@JsonKey(name: 'total_licenses') int totalLicenses,
|
||||
@JsonKey(name: 'active_licenses') int activeLicenses,
|
||||
@JsonKey(name: 'expiring_licenses') int expiringLicenses,
|
||||
@JsonKey(name: 'total_rentals') int totalRentals,
|
||||
@JsonKey(name: 'active_rentals') int activeRentals});
|
||||
@JsonKey(name: 'expiring_licenses_count') int expiringLicensesCount,
|
||||
@JsonKey(name: 'expired_licenses_count') int expiredLicensesCount,
|
||||
@JsonKey(name: 'total_warehouse_locations') int totalWarehouseLocations,
|
||||
@JsonKey(name: 'active_warehouse_locations') int activeWarehouseLocations,
|
||||
@JsonKey(name: 'total_rentals', defaultValue: 0) int? totalRentals,
|
||||
@JsonKey(name: 'active_rentals', defaultValue: 0) int? activeRentals});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -175,18 +230,40 @@ class __$$OverviewStatsImplCopyWithImpl<$Res>
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? totalCompanies = null,
|
||||
Object? activeCompanies = null,
|
||||
Object? totalUsers = null,
|
||||
Object? activeUsers = null,
|
||||
Object? totalEquipment = null,
|
||||
Object? availableEquipment = null,
|
||||
Object? inUseEquipment = null,
|
||||
Object? maintenanceEquipment = null,
|
||||
Object? totalCompanies = null,
|
||||
Object? totalUsers = null,
|
||||
Object? totalLicenses = null,
|
||||
Object? activeLicenses = null,
|
||||
Object? expiringLicenses = null,
|
||||
Object? totalRentals = null,
|
||||
Object? activeRentals = null,
|
||||
Object? expiringLicensesCount = null,
|
||||
Object? expiredLicensesCount = null,
|
||||
Object? totalWarehouseLocations = null,
|
||||
Object? activeWarehouseLocations = null,
|
||||
Object? totalRentals = freezed,
|
||||
Object? activeRentals = freezed,
|
||||
}) {
|
||||
return _then(_$OverviewStatsImpl(
|
||||
totalCompanies: null == totalCompanies
|
||||
? _value.totalCompanies
|
||||
: totalCompanies // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
activeCompanies: null == activeCompanies
|
||||
? _value.activeCompanies
|
||||
: activeCompanies // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalUsers: null == totalUsers
|
||||
? _value.totalUsers
|
||||
: totalUsers // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
activeUsers: null == activeUsers
|
||||
? _value.activeUsers
|
||||
: activeUsers // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalEquipment: null == totalEquipment
|
||||
? _value.totalEquipment
|
||||
: totalEquipment // ignore: cast_nullable_to_non_nullable
|
||||
@@ -203,30 +280,38 @@ class __$$OverviewStatsImplCopyWithImpl<$Res>
|
||||
? _value.maintenanceEquipment
|
||||
: maintenanceEquipment // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalCompanies: null == totalCompanies
|
||||
? _value.totalCompanies
|
||||
: totalCompanies // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalUsers: null == totalUsers
|
||||
? _value.totalUsers
|
||||
: totalUsers // ignore: cast_nullable_to_non_nullable
|
||||
totalLicenses: null == totalLicenses
|
||||
? _value.totalLicenses
|
||||
: totalLicenses // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
activeLicenses: null == activeLicenses
|
||||
? _value.activeLicenses
|
||||
: activeLicenses // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
expiringLicenses: null == expiringLicenses
|
||||
? _value.expiringLicenses
|
||||
: expiringLicenses // ignore: cast_nullable_to_non_nullable
|
||||
expiringLicensesCount: null == expiringLicensesCount
|
||||
? _value.expiringLicensesCount
|
||||
: expiringLicensesCount // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalRentals: null == totalRentals
|
||||
expiredLicensesCount: null == expiredLicensesCount
|
||||
? _value.expiredLicensesCount
|
||||
: expiredLicensesCount // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalWarehouseLocations: null == totalWarehouseLocations
|
||||
? _value.totalWarehouseLocations
|
||||
: totalWarehouseLocations // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
activeWarehouseLocations: null == activeWarehouseLocations
|
||||
? _value.activeWarehouseLocations
|
||||
: activeWarehouseLocations // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
totalRentals: freezed == totalRentals
|
||||
? _value.totalRentals
|
||||
: totalRentals // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
activeRentals: null == activeRentals
|
||||
as int?,
|
||||
activeRentals: freezed == activeRentals
|
||||
? _value.activeRentals
|
||||
: activeRentals // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -235,21 +320,43 @@ class __$$OverviewStatsImplCopyWithImpl<$Res>
|
||||
@JsonSerializable()
|
||||
class _$OverviewStatsImpl implements _OverviewStats {
|
||||
const _$OverviewStatsImpl(
|
||||
{@JsonKey(name: 'total_equipment') required this.totalEquipment,
|
||||
{@JsonKey(name: 'total_companies') required this.totalCompanies,
|
||||
@JsonKey(name: 'active_companies') required this.activeCompanies,
|
||||
@JsonKey(name: 'total_users') required this.totalUsers,
|
||||
@JsonKey(name: 'active_users') required this.activeUsers,
|
||||
@JsonKey(name: 'total_equipment') required this.totalEquipment,
|
||||
@JsonKey(name: 'available_equipment') required this.availableEquipment,
|
||||
@JsonKey(name: 'in_use_equipment') required this.inUseEquipment,
|
||||
@JsonKey(name: 'maintenance_equipment')
|
||||
required this.maintenanceEquipment,
|
||||
@JsonKey(name: 'total_companies') required this.totalCompanies,
|
||||
@JsonKey(name: 'total_users') required this.totalUsers,
|
||||
@JsonKey(name: 'total_licenses') required this.totalLicenses,
|
||||
@JsonKey(name: 'active_licenses') required this.activeLicenses,
|
||||
@JsonKey(name: 'expiring_licenses') required this.expiringLicenses,
|
||||
@JsonKey(name: 'total_rentals') required this.totalRentals,
|
||||
@JsonKey(name: 'active_rentals') required this.activeRentals});
|
||||
@JsonKey(name: 'expiring_licenses_count')
|
||||
required this.expiringLicensesCount,
|
||||
@JsonKey(name: 'expired_licenses_count')
|
||||
required this.expiredLicensesCount,
|
||||
@JsonKey(name: 'total_warehouse_locations')
|
||||
required this.totalWarehouseLocations,
|
||||
@JsonKey(name: 'active_warehouse_locations')
|
||||
required this.activeWarehouseLocations,
|
||||
@JsonKey(name: 'total_rentals', defaultValue: 0) this.totalRentals,
|
||||
@JsonKey(name: 'active_rentals', defaultValue: 0) this.activeRentals});
|
||||
|
||||
factory _$OverviewStatsImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$OverviewStatsImplFromJson(json);
|
||||
|
||||
@override
|
||||
@JsonKey(name: 'total_companies')
|
||||
final int totalCompanies;
|
||||
@override
|
||||
@JsonKey(name: 'active_companies')
|
||||
final int activeCompanies;
|
||||
@override
|
||||
@JsonKey(name: 'total_users')
|
||||
final int totalUsers;
|
||||
@override
|
||||
@JsonKey(name: 'active_users')
|
||||
final int activeUsers;
|
||||
@override
|
||||
@JsonKey(name: 'total_equipment')
|
||||
final int totalEquipment;
|
||||
@@ -263,27 +370,34 @@ class _$OverviewStatsImpl implements _OverviewStats {
|
||||
@JsonKey(name: 'maintenance_equipment')
|
||||
final int maintenanceEquipment;
|
||||
@override
|
||||
@JsonKey(name: 'total_companies')
|
||||
final int totalCompanies;
|
||||
@override
|
||||
@JsonKey(name: 'total_users')
|
||||
final int totalUsers;
|
||||
@JsonKey(name: 'total_licenses')
|
||||
final int totalLicenses;
|
||||
@override
|
||||
@JsonKey(name: 'active_licenses')
|
||||
final int activeLicenses;
|
||||
@override
|
||||
@JsonKey(name: 'expiring_licenses')
|
||||
final int expiringLicenses;
|
||||
@JsonKey(name: 'expiring_licenses_count')
|
||||
final int expiringLicensesCount;
|
||||
@override
|
||||
@JsonKey(name: 'total_rentals')
|
||||
final int totalRentals;
|
||||
@JsonKey(name: 'expired_licenses_count')
|
||||
final int expiredLicensesCount;
|
||||
@override
|
||||
@JsonKey(name: 'active_rentals')
|
||||
final int activeRentals;
|
||||
@JsonKey(name: 'total_warehouse_locations')
|
||||
final int totalWarehouseLocations;
|
||||
@override
|
||||
@JsonKey(name: 'active_warehouse_locations')
|
||||
final int activeWarehouseLocations;
|
||||
// 다음 필드들은 백엔드에 없으므로 선택적으로 만듭니다
|
||||
@override
|
||||
@JsonKey(name: 'total_rentals', defaultValue: 0)
|
||||
final int? totalRentals;
|
||||
@override
|
||||
@JsonKey(name: 'active_rentals', defaultValue: 0)
|
||||
final int? activeRentals;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'OverviewStats(totalEquipment: $totalEquipment, availableEquipment: $availableEquipment, inUseEquipment: $inUseEquipment, maintenanceEquipment: $maintenanceEquipment, totalCompanies: $totalCompanies, totalUsers: $totalUsers, activeLicenses: $activeLicenses, expiringLicenses: $expiringLicenses, totalRentals: $totalRentals, activeRentals: $activeRentals)';
|
||||
return 'OverviewStats(totalCompanies: $totalCompanies, activeCompanies: $activeCompanies, totalUsers: $totalUsers, activeUsers: $activeUsers, totalEquipment: $totalEquipment, availableEquipment: $availableEquipment, inUseEquipment: $inUseEquipment, maintenanceEquipment: $maintenanceEquipment, totalLicenses: $totalLicenses, activeLicenses: $activeLicenses, expiringLicensesCount: $expiringLicensesCount, expiredLicensesCount: $expiredLicensesCount, totalWarehouseLocations: $totalWarehouseLocations, activeWarehouseLocations: $activeWarehouseLocations, totalRentals: $totalRentals, activeRentals: $activeRentals)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -291,6 +405,14 @@ class _$OverviewStatsImpl implements _OverviewStats {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$OverviewStatsImpl &&
|
||||
(identical(other.totalCompanies, totalCompanies) ||
|
||||
other.totalCompanies == totalCompanies) &&
|
||||
(identical(other.activeCompanies, activeCompanies) ||
|
||||
other.activeCompanies == activeCompanies) &&
|
||||
(identical(other.totalUsers, totalUsers) ||
|
||||
other.totalUsers == totalUsers) &&
|
||||
(identical(other.activeUsers, activeUsers) ||
|
||||
other.activeUsers == activeUsers) &&
|
||||
(identical(other.totalEquipment, totalEquipment) ||
|
||||
other.totalEquipment == totalEquipment) &&
|
||||
(identical(other.availableEquipment, availableEquipment) ||
|
||||
@@ -299,14 +421,20 @@ class _$OverviewStatsImpl implements _OverviewStats {
|
||||
other.inUseEquipment == inUseEquipment) &&
|
||||
(identical(other.maintenanceEquipment, maintenanceEquipment) ||
|
||||
other.maintenanceEquipment == maintenanceEquipment) &&
|
||||
(identical(other.totalCompanies, totalCompanies) ||
|
||||
other.totalCompanies == totalCompanies) &&
|
||||
(identical(other.totalUsers, totalUsers) ||
|
||||
other.totalUsers == totalUsers) &&
|
||||
(identical(other.totalLicenses, totalLicenses) ||
|
||||
other.totalLicenses == totalLicenses) &&
|
||||
(identical(other.activeLicenses, activeLicenses) ||
|
||||
other.activeLicenses == activeLicenses) &&
|
||||
(identical(other.expiringLicenses, expiringLicenses) ||
|
||||
other.expiringLicenses == expiringLicenses) &&
|
||||
(identical(other.expiringLicensesCount, expiringLicensesCount) ||
|
||||
other.expiringLicensesCount == expiringLicensesCount) &&
|
||||
(identical(other.expiredLicensesCount, expiredLicensesCount) ||
|
||||
other.expiredLicensesCount == expiredLicensesCount) &&
|
||||
(identical(
|
||||
other.totalWarehouseLocations, totalWarehouseLocations) ||
|
||||
other.totalWarehouseLocations == totalWarehouseLocations) &&
|
||||
(identical(
|
||||
other.activeWarehouseLocations, activeWarehouseLocations) ||
|
||||
other.activeWarehouseLocations == activeWarehouseLocations) &&
|
||||
(identical(other.totalRentals, totalRentals) ||
|
||||
other.totalRentals == totalRentals) &&
|
||||
(identical(other.activeRentals, activeRentals) ||
|
||||
@@ -317,14 +445,20 @@ class _$OverviewStatsImpl implements _OverviewStats {
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
totalCompanies,
|
||||
activeCompanies,
|
||||
totalUsers,
|
||||
activeUsers,
|
||||
totalEquipment,
|
||||
availableEquipment,
|
||||
inUseEquipment,
|
||||
maintenanceEquipment,
|
||||
totalCompanies,
|
||||
totalUsers,
|
||||
totalLicenses,
|
||||
activeLicenses,
|
||||
expiringLicenses,
|
||||
expiringLicensesCount,
|
||||
expiredLicensesCount,
|
||||
totalWarehouseLocations,
|
||||
activeWarehouseLocations,
|
||||
totalRentals,
|
||||
activeRentals);
|
||||
|
||||
@@ -346,23 +480,45 @@ class _$OverviewStatsImpl implements _OverviewStats {
|
||||
|
||||
abstract class _OverviewStats implements OverviewStats {
|
||||
const factory _OverviewStats(
|
||||
{@JsonKey(name: 'total_equipment') required final int totalEquipment,
|
||||
{@JsonKey(name: 'total_companies') required final int totalCompanies,
|
||||
@JsonKey(name: 'active_companies') required final int activeCompanies,
|
||||
@JsonKey(name: 'total_users') required final int totalUsers,
|
||||
@JsonKey(name: 'active_users') required final int activeUsers,
|
||||
@JsonKey(name: 'total_equipment') required final int totalEquipment,
|
||||
@JsonKey(name: 'available_equipment')
|
||||
required final int availableEquipment,
|
||||
@JsonKey(name: 'in_use_equipment') required final int inUseEquipment,
|
||||
@JsonKey(name: 'maintenance_equipment')
|
||||
required final int maintenanceEquipment,
|
||||
@JsonKey(name: 'total_companies') required final int totalCompanies,
|
||||
@JsonKey(name: 'total_users') required final int totalUsers,
|
||||
@JsonKey(name: 'total_licenses') required final int totalLicenses,
|
||||
@JsonKey(name: 'active_licenses') required final int activeLicenses,
|
||||
@JsonKey(name: 'expiring_licenses') required final int expiringLicenses,
|
||||
@JsonKey(name: 'total_rentals') required final int totalRentals,
|
||||
@JsonKey(name: 'active_rentals')
|
||||
required final int activeRentals}) = _$OverviewStatsImpl;
|
||||
@JsonKey(name: 'expiring_licenses_count')
|
||||
required final int expiringLicensesCount,
|
||||
@JsonKey(name: 'expired_licenses_count')
|
||||
required final int expiredLicensesCount,
|
||||
@JsonKey(name: 'total_warehouse_locations')
|
||||
required final int totalWarehouseLocations,
|
||||
@JsonKey(name: 'active_warehouse_locations')
|
||||
required final int activeWarehouseLocations,
|
||||
@JsonKey(name: 'total_rentals', defaultValue: 0) final int? totalRentals,
|
||||
@JsonKey(name: 'active_rentals', defaultValue: 0)
|
||||
final int? activeRentals}) = _$OverviewStatsImpl;
|
||||
|
||||
factory _OverviewStats.fromJson(Map<String, dynamic> json) =
|
||||
_$OverviewStatsImpl.fromJson;
|
||||
|
||||
@override
|
||||
@JsonKey(name: 'total_companies')
|
||||
int get totalCompanies;
|
||||
@override
|
||||
@JsonKey(name: 'active_companies')
|
||||
int get activeCompanies;
|
||||
@override
|
||||
@JsonKey(name: 'total_users')
|
||||
int get totalUsers;
|
||||
@override
|
||||
@JsonKey(name: 'active_users')
|
||||
int get activeUsers;
|
||||
@override
|
||||
@JsonKey(name: 'total_equipment')
|
||||
int get totalEquipment;
|
||||
@@ -376,23 +532,29 @@ abstract class _OverviewStats implements OverviewStats {
|
||||
@JsonKey(name: 'maintenance_equipment')
|
||||
int get maintenanceEquipment;
|
||||
@override
|
||||
@JsonKey(name: 'total_companies')
|
||||
int get totalCompanies;
|
||||
@override
|
||||
@JsonKey(name: 'total_users')
|
||||
int get totalUsers;
|
||||
@JsonKey(name: 'total_licenses')
|
||||
int get totalLicenses;
|
||||
@override
|
||||
@JsonKey(name: 'active_licenses')
|
||||
int get activeLicenses;
|
||||
@override
|
||||
@JsonKey(name: 'expiring_licenses')
|
||||
int get expiringLicenses;
|
||||
@JsonKey(name: 'expiring_licenses_count')
|
||||
int get expiringLicensesCount;
|
||||
@override
|
||||
@JsonKey(name: 'total_rentals')
|
||||
int get totalRentals;
|
||||
@JsonKey(name: 'expired_licenses_count')
|
||||
int get expiredLicensesCount;
|
||||
@override
|
||||
@JsonKey(name: 'active_rentals')
|
||||
int get activeRentals;
|
||||
@JsonKey(name: 'total_warehouse_locations')
|
||||
int get totalWarehouseLocations;
|
||||
@override
|
||||
@JsonKey(name: 'active_warehouse_locations')
|
||||
int get activeWarehouseLocations; // 다음 필드들은 백엔드에 없으므로 선택적으로 만듭니다
|
||||
@override
|
||||
@JsonKey(name: 'total_rentals', defaultValue: 0)
|
||||
int? get totalRentals;
|
||||
@override
|
||||
@JsonKey(name: 'active_rentals', defaultValue: 0)
|
||||
int? get activeRentals;
|
||||
|
||||
/// Create a copy of OverviewStats
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
|
||||
@@ -8,28 +8,42 @@ part of 'overview_stats.dart';
|
||||
|
||||
_$OverviewStatsImpl _$$OverviewStatsImplFromJson(Map<String, dynamic> json) =>
|
||||
_$OverviewStatsImpl(
|
||||
totalCompanies: (json['total_companies'] as num).toInt(),
|
||||
activeCompanies: (json['active_companies'] as num).toInt(),
|
||||
totalUsers: (json['total_users'] as num).toInt(),
|
||||
activeUsers: (json['active_users'] as num).toInt(),
|
||||
totalEquipment: (json['total_equipment'] as num).toInt(),
|
||||
availableEquipment: (json['available_equipment'] as num).toInt(),
|
||||
inUseEquipment: (json['in_use_equipment'] as num).toInt(),
|
||||
maintenanceEquipment: (json['maintenance_equipment'] as num).toInt(),
|
||||
totalCompanies: (json['total_companies'] as num).toInt(),
|
||||
totalUsers: (json['total_users'] as num).toInt(),
|
||||
totalLicenses: (json['total_licenses'] as num).toInt(),
|
||||
activeLicenses: (json['active_licenses'] as num).toInt(),
|
||||
expiringLicenses: (json['expiring_licenses'] as num).toInt(),
|
||||
totalRentals: (json['total_rentals'] as num).toInt(),
|
||||
activeRentals: (json['active_rentals'] as num).toInt(),
|
||||
expiringLicensesCount: (json['expiring_licenses_count'] as num).toInt(),
|
||||
expiredLicensesCount: (json['expired_licenses_count'] as num).toInt(),
|
||||
totalWarehouseLocations:
|
||||
(json['total_warehouse_locations'] as num).toInt(),
|
||||
activeWarehouseLocations:
|
||||
(json['active_warehouse_locations'] as num).toInt(),
|
||||
totalRentals: (json['total_rentals'] as num?)?.toInt() ?? 0,
|
||||
activeRentals: (json['active_rentals'] as num?)?.toInt() ?? 0,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$OverviewStatsImplToJson(_$OverviewStatsImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'total_companies': instance.totalCompanies,
|
||||
'active_companies': instance.activeCompanies,
|
||||
'total_users': instance.totalUsers,
|
||||
'active_users': instance.activeUsers,
|
||||
'total_equipment': instance.totalEquipment,
|
||||
'available_equipment': instance.availableEquipment,
|
||||
'in_use_equipment': instance.inUseEquipment,
|
||||
'maintenance_equipment': instance.maintenanceEquipment,
|
||||
'total_companies': instance.totalCompanies,
|
||||
'total_users': instance.totalUsers,
|
||||
'total_licenses': instance.totalLicenses,
|
||||
'active_licenses': instance.activeLicenses,
|
||||
'expiring_licenses': instance.expiringLicenses,
|
||||
'expiring_licenses_count': instance.expiringLicensesCount,
|
||||
'expired_licenses_count': instance.expiredLicensesCount,
|
||||
'total_warehouse_locations': instance.totalWarehouseLocations,
|
||||
'active_warehouse_locations': instance.activeWarehouseLocations,
|
||||
'total_rentals': instance.totalRentals,
|
||||
'active_rentals': instance.activeRentals,
|
||||
};
|
||||
|
||||
@@ -8,9 +8,13 @@ class RecentActivity with _$RecentActivity {
|
||||
const factory RecentActivity({
|
||||
required int id,
|
||||
@JsonKey(name: 'activity_type') required String activityType,
|
||||
@JsonKey(name: 'entity_type') required String entityType,
|
||||
@JsonKey(name: 'entity_id') required int entityId,
|
||||
@JsonKey(name: 'entity_name') required String entityName,
|
||||
required String description,
|
||||
@JsonKey(name: 'user_name') required String userName,
|
||||
@JsonKey(name: 'created_at') required DateTime createdAt,
|
||||
@JsonKey(name: 'user_id') int? userId,
|
||||
@JsonKey(name: 'user_name') String? userName,
|
||||
required DateTime timestamp,
|
||||
Map<String, dynamic>? metadata,
|
||||
}) = _RecentActivity;
|
||||
|
||||
|
||||
@@ -23,11 +23,18 @@ mixin _$RecentActivity {
|
||||
int get id => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'activity_type')
|
||||
String get activityType => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'entity_type')
|
||||
String get entityType => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'entity_id')
|
||||
int get entityId => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'entity_name')
|
||||
String get entityName => throw _privateConstructorUsedError;
|
||||
String get description => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'user_id')
|
||||
int? get userId => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'user_name')
|
||||
String get userName => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime get createdAt => throw _privateConstructorUsedError;
|
||||
String? get userName => throw _privateConstructorUsedError;
|
||||
DateTime get timestamp => throw _privateConstructorUsedError;
|
||||
Map<String, dynamic>? get metadata => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this RecentActivity to a JSON map.
|
||||
@@ -49,9 +56,13 @@ abstract class $RecentActivityCopyWith<$Res> {
|
||||
$Res call(
|
||||
{int id,
|
||||
@JsonKey(name: 'activity_type') String activityType,
|
||||
@JsonKey(name: 'entity_type') String entityType,
|
||||
@JsonKey(name: 'entity_id') int entityId,
|
||||
@JsonKey(name: 'entity_name') String entityName,
|
||||
String description,
|
||||
@JsonKey(name: 'user_name') String userName,
|
||||
@JsonKey(name: 'created_at') DateTime createdAt,
|
||||
@JsonKey(name: 'user_id') int? userId,
|
||||
@JsonKey(name: 'user_name') String? userName,
|
||||
DateTime timestamp,
|
||||
Map<String, dynamic>? metadata});
|
||||
}
|
||||
|
||||
@@ -72,9 +83,13 @@ class _$RecentActivityCopyWithImpl<$Res, $Val extends RecentActivity>
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? activityType = null,
|
||||
Object? entityType = null,
|
||||
Object? entityId = null,
|
||||
Object? entityName = null,
|
||||
Object? description = null,
|
||||
Object? userName = null,
|
||||
Object? createdAt = null,
|
||||
Object? userId = freezed,
|
||||
Object? userName = freezed,
|
||||
Object? timestamp = null,
|
||||
Object? metadata = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
@@ -86,17 +101,33 @@ class _$RecentActivityCopyWithImpl<$Res, $Val extends RecentActivity>
|
||||
? _value.activityType
|
||||
: activityType // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
entityType: null == entityType
|
||||
? _value.entityType
|
||||
: entityType // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
entityId: null == entityId
|
||||
? _value.entityId
|
||||
: entityId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
entityName: null == entityName
|
||||
? _value.entityName
|
||||
: entityName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
description: null == description
|
||||
? _value.description
|
||||
: description // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
userName: null == userName
|
||||
userId: freezed == userId
|
||||
? _value.userId
|
||||
: userId // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
userName: freezed == userName
|
||||
? _value.userName
|
||||
: userName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
createdAt: null == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
timestamp: null == timestamp
|
||||
? _value.timestamp
|
||||
: timestamp // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
metadata: freezed == metadata
|
||||
? _value.metadata
|
||||
@@ -117,9 +148,13 @@ abstract class _$$RecentActivityImplCopyWith<$Res>
|
||||
$Res call(
|
||||
{int id,
|
||||
@JsonKey(name: 'activity_type') String activityType,
|
||||
@JsonKey(name: 'entity_type') String entityType,
|
||||
@JsonKey(name: 'entity_id') int entityId,
|
||||
@JsonKey(name: 'entity_name') String entityName,
|
||||
String description,
|
||||
@JsonKey(name: 'user_name') String userName,
|
||||
@JsonKey(name: 'created_at') DateTime createdAt,
|
||||
@JsonKey(name: 'user_id') int? userId,
|
||||
@JsonKey(name: 'user_name') String? userName,
|
||||
DateTime timestamp,
|
||||
Map<String, dynamic>? metadata});
|
||||
}
|
||||
|
||||
@@ -138,9 +173,13 @@ class __$$RecentActivityImplCopyWithImpl<$Res>
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? activityType = null,
|
||||
Object? entityType = null,
|
||||
Object? entityId = null,
|
||||
Object? entityName = null,
|
||||
Object? description = null,
|
||||
Object? userName = null,
|
||||
Object? createdAt = null,
|
||||
Object? userId = freezed,
|
||||
Object? userName = freezed,
|
||||
Object? timestamp = null,
|
||||
Object? metadata = freezed,
|
||||
}) {
|
||||
return _then(_$RecentActivityImpl(
|
||||
@@ -152,17 +191,33 @@ class __$$RecentActivityImplCopyWithImpl<$Res>
|
||||
? _value.activityType
|
||||
: activityType // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
entityType: null == entityType
|
||||
? _value.entityType
|
||||
: entityType // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
entityId: null == entityId
|
||||
? _value.entityId
|
||||
: entityId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
entityName: null == entityName
|
||||
? _value.entityName
|
||||
: entityName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
description: null == description
|
||||
? _value.description
|
||||
: description // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
userName: null == userName
|
||||
userId: freezed == userId
|
||||
? _value.userId
|
||||
: userId // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
userName: freezed == userName
|
||||
? _value.userName
|
||||
: userName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
createdAt: null == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
timestamp: null == timestamp
|
||||
? _value.timestamp
|
||||
: timestamp // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
metadata: freezed == metadata
|
||||
? _value._metadata
|
||||
@@ -178,9 +233,13 @@ class _$RecentActivityImpl implements _RecentActivity {
|
||||
const _$RecentActivityImpl(
|
||||
{required this.id,
|
||||
@JsonKey(name: 'activity_type') required this.activityType,
|
||||
@JsonKey(name: 'entity_type') required this.entityType,
|
||||
@JsonKey(name: 'entity_id') required this.entityId,
|
||||
@JsonKey(name: 'entity_name') required this.entityName,
|
||||
required this.description,
|
||||
@JsonKey(name: 'user_name') required this.userName,
|
||||
@JsonKey(name: 'created_at') required this.createdAt,
|
||||
@JsonKey(name: 'user_id') this.userId,
|
||||
@JsonKey(name: 'user_name') this.userName,
|
||||
required this.timestamp,
|
||||
final Map<String, dynamic>? metadata})
|
||||
: _metadata = metadata;
|
||||
|
||||
@@ -193,13 +252,24 @@ class _$RecentActivityImpl implements _RecentActivity {
|
||||
@JsonKey(name: 'activity_type')
|
||||
final String activityType;
|
||||
@override
|
||||
@JsonKey(name: 'entity_type')
|
||||
final String entityType;
|
||||
@override
|
||||
@JsonKey(name: 'entity_id')
|
||||
final int entityId;
|
||||
@override
|
||||
@JsonKey(name: 'entity_name')
|
||||
final String entityName;
|
||||
@override
|
||||
final String description;
|
||||
@override
|
||||
@JsonKey(name: 'user_name')
|
||||
final String userName;
|
||||
@JsonKey(name: 'user_id')
|
||||
final int? userId;
|
||||
@override
|
||||
@JsonKey(name: 'created_at')
|
||||
final DateTime createdAt;
|
||||
@JsonKey(name: 'user_name')
|
||||
final String? userName;
|
||||
@override
|
||||
final DateTime timestamp;
|
||||
final Map<String, dynamic>? _metadata;
|
||||
@override
|
||||
Map<String, dynamic>? get metadata {
|
||||
@@ -212,7 +282,7 @@ class _$RecentActivityImpl implements _RecentActivity {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'RecentActivity(id: $id, activityType: $activityType, description: $description, userName: $userName, createdAt: $createdAt, metadata: $metadata)';
|
||||
return 'RecentActivity(id: $id, activityType: $activityType, entityType: $entityType, entityId: $entityId, entityName: $entityName, description: $description, userId: $userId, userName: $userName, timestamp: $timestamp, metadata: $metadata)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -223,19 +293,36 @@ class _$RecentActivityImpl implements _RecentActivity {
|
||||
(identical(other.id, id) || other.id == id) &&
|
||||
(identical(other.activityType, activityType) ||
|
||||
other.activityType == activityType) &&
|
||||
(identical(other.entityType, entityType) ||
|
||||
other.entityType == entityType) &&
|
||||
(identical(other.entityId, entityId) ||
|
||||
other.entityId == entityId) &&
|
||||
(identical(other.entityName, entityName) ||
|
||||
other.entityName == entityName) &&
|
||||
(identical(other.description, description) ||
|
||||
other.description == description) &&
|
||||
(identical(other.userId, userId) || other.userId == userId) &&
|
||||
(identical(other.userName, userName) ||
|
||||
other.userName == userName) &&
|
||||
(identical(other.createdAt, createdAt) ||
|
||||
other.createdAt == createdAt) &&
|
||||
(identical(other.timestamp, timestamp) ||
|
||||
other.timestamp == timestamp) &&
|
||||
const DeepCollectionEquality().equals(other._metadata, _metadata));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, id, activityType, description,
|
||||
userName, createdAt, const DeepCollectionEquality().hash(_metadata));
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
id,
|
||||
activityType,
|
||||
entityType,
|
||||
entityId,
|
||||
entityName,
|
||||
description,
|
||||
userId,
|
||||
userName,
|
||||
timestamp,
|
||||
const DeepCollectionEquality().hash(_metadata));
|
||||
|
||||
/// Create a copy of RecentActivity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -258,9 +345,13 @@ abstract class _RecentActivity implements RecentActivity {
|
||||
const factory _RecentActivity(
|
||||
{required final int id,
|
||||
@JsonKey(name: 'activity_type') required final String activityType,
|
||||
@JsonKey(name: 'entity_type') required final String entityType,
|
||||
@JsonKey(name: 'entity_id') required final int entityId,
|
||||
@JsonKey(name: 'entity_name') required final String entityName,
|
||||
required final String description,
|
||||
@JsonKey(name: 'user_name') required final String userName,
|
||||
@JsonKey(name: 'created_at') required final DateTime createdAt,
|
||||
@JsonKey(name: 'user_id') final int? userId,
|
||||
@JsonKey(name: 'user_name') final String? userName,
|
||||
required final DateTime timestamp,
|
||||
final Map<String, dynamic>? metadata}) = _$RecentActivityImpl;
|
||||
|
||||
factory _RecentActivity.fromJson(Map<String, dynamic> json) =
|
||||
@@ -272,13 +363,24 @@ abstract class _RecentActivity implements RecentActivity {
|
||||
@JsonKey(name: 'activity_type')
|
||||
String get activityType;
|
||||
@override
|
||||
@JsonKey(name: 'entity_type')
|
||||
String get entityType;
|
||||
@override
|
||||
@JsonKey(name: 'entity_id')
|
||||
int get entityId;
|
||||
@override
|
||||
@JsonKey(name: 'entity_name')
|
||||
String get entityName;
|
||||
@override
|
||||
String get description;
|
||||
@override
|
||||
@JsonKey(name: 'user_name')
|
||||
String get userName;
|
||||
@JsonKey(name: 'user_id')
|
||||
int? get userId;
|
||||
@override
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime get createdAt;
|
||||
@JsonKey(name: 'user_name')
|
||||
String? get userName;
|
||||
@override
|
||||
DateTime get timestamp;
|
||||
@override
|
||||
Map<String, dynamic>? get metadata;
|
||||
|
||||
|
||||
@@ -10,9 +10,13 @@ _$RecentActivityImpl _$$RecentActivityImplFromJson(Map<String, dynamic> json) =>
|
||||
_$RecentActivityImpl(
|
||||
id: (json['id'] as num).toInt(),
|
||||
activityType: json['activity_type'] as String,
|
||||
entityType: json['entity_type'] as String,
|
||||
entityId: (json['entity_id'] as num).toInt(),
|
||||
entityName: json['entity_name'] as String,
|
||||
description: json['description'] as String,
|
||||
userName: json['user_name'] as String,
|
||||
createdAt: DateTime.parse(json['created_at'] as String),
|
||||
userId: (json['user_id'] as num?)?.toInt(),
|
||||
userName: json['user_name'] as String?,
|
||||
timestamp: DateTime.parse(json['timestamp'] as String),
|
||||
metadata: json['metadata'] as Map<String, dynamic>?,
|
||||
);
|
||||
|
||||
@@ -21,8 +25,12 @@ Map<String, dynamic> _$$RecentActivityImplToJson(
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'activity_type': instance.activityType,
|
||||
'entity_type': instance.entityType,
|
||||
'entity_id': instance.entityId,
|
||||
'entity_name': instance.entityName,
|
||||
'description': instance.description,
|
||||
'user_id': instance.userId,
|
||||
'user_name': instance.userName,
|
||||
'created_at': instance.createdAt.toIso8601String(),
|
||||
'timestamp': instance.timestamp.toIso8601String(),
|
||||
'metadata': instance.metadata,
|
||||
};
|
||||
|
||||
@@ -7,19 +7,19 @@ part 'equipment_list_dto.g.dart';
|
||||
class EquipmentListDto with _$EquipmentListDto {
|
||||
const factory EquipmentListDto({
|
||||
required int id,
|
||||
required String equipmentNumber,
|
||||
@JsonKey(name: 'equipment_number') required String equipmentNumber,
|
||||
required String manufacturer,
|
||||
String? modelName,
|
||||
String? serialNumber,
|
||||
@JsonKey(name: 'model_name') String? modelName,
|
||||
@JsonKey(name: 'serial_number') String? serialNumber,
|
||||
required String status,
|
||||
int? currentCompanyId,
|
||||
int? currentBranchId,
|
||||
int? warehouseLocationId,
|
||||
required DateTime createdAt,
|
||||
@JsonKey(name: 'current_company_id') int? currentCompanyId,
|
||||
@JsonKey(name: 'current_branch_id') int? currentBranchId,
|
||||
@JsonKey(name: 'warehouse_location_id') int? warehouseLocationId,
|
||||
@JsonKey(name: 'created_at') required DateTime createdAt,
|
||||
// 추가 필드 (조인된 데이터)
|
||||
String? companyName,
|
||||
String? branchName,
|
||||
String? warehouseName,
|
||||
@JsonKey(name: 'company_name') String? companyName,
|
||||
@JsonKey(name: 'branch_name') String? branchName,
|
||||
@JsonKey(name: 'warehouse_name') String? warehouseName,
|
||||
}) = _EquipmentListDto;
|
||||
|
||||
factory EquipmentListDto.fromJson(Map<String, dynamic> json) =>
|
||||
|
||||
@@ -21,18 +21,28 @@ EquipmentListDto _$EquipmentListDtoFromJson(Map<String, dynamic> json) {
|
||||
/// @nodoc
|
||||
mixin _$EquipmentListDto {
|
||||
int get id => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'equipment_number')
|
||||
String get equipmentNumber => throw _privateConstructorUsedError;
|
||||
String get manufacturer => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'model_name')
|
||||
String? get modelName => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'serial_number')
|
||||
String? get serialNumber => throw _privateConstructorUsedError;
|
||||
String get status => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'current_company_id')
|
||||
int? get currentCompanyId => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'current_branch_id')
|
||||
int? get currentBranchId => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'warehouse_location_id')
|
||||
int? get warehouseLocationId => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime get createdAt =>
|
||||
throw _privateConstructorUsedError; // 추가 필드 (조인된 데이터)
|
||||
@JsonKey(name: 'company_name')
|
||||
String? get companyName => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'branch_name')
|
||||
String? get branchName => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'warehouse_name')
|
||||
String? get warehouseName => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this EquipmentListDto to a JSON map.
|
||||
@@ -53,18 +63,18 @@ abstract class $EquipmentListDtoCopyWith<$Res> {
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
String equipmentNumber,
|
||||
@JsonKey(name: 'equipment_number') String equipmentNumber,
|
||||
String manufacturer,
|
||||
String? modelName,
|
||||
String? serialNumber,
|
||||
@JsonKey(name: 'model_name') String? modelName,
|
||||
@JsonKey(name: 'serial_number') String? serialNumber,
|
||||
String status,
|
||||
int? currentCompanyId,
|
||||
int? currentBranchId,
|
||||
int? warehouseLocationId,
|
||||
DateTime createdAt,
|
||||
String? companyName,
|
||||
String? branchName,
|
||||
String? warehouseName});
|
||||
@JsonKey(name: 'current_company_id') int? currentCompanyId,
|
||||
@JsonKey(name: 'current_branch_id') int? currentBranchId,
|
||||
@JsonKey(name: 'warehouse_location_id') int? warehouseLocationId,
|
||||
@JsonKey(name: 'created_at') DateTime createdAt,
|
||||
@JsonKey(name: 'company_name') String? companyName,
|
||||
@JsonKey(name: 'branch_name') String? branchName,
|
||||
@JsonKey(name: 'warehouse_name') String? warehouseName});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -163,18 +173,18 @@ abstract class _$$EquipmentListDtoImplCopyWith<$Res>
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
String equipmentNumber,
|
||||
@JsonKey(name: 'equipment_number') String equipmentNumber,
|
||||
String manufacturer,
|
||||
String? modelName,
|
||||
String? serialNumber,
|
||||
@JsonKey(name: 'model_name') String? modelName,
|
||||
@JsonKey(name: 'serial_number') String? serialNumber,
|
||||
String status,
|
||||
int? currentCompanyId,
|
||||
int? currentBranchId,
|
||||
int? warehouseLocationId,
|
||||
DateTime createdAt,
|
||||
String? companyName,
|
||||
String? branchName,
|
||||
String? warehouseName});
|
||||
@JsonKey(name: 'current_company_id') int? currentCompanyId,
|
||||
@JsonKey(name: 'current_branch_id') int? currentBranchId,
|
||||
@JsonKey(name: 'warehouse_location_id') int? warehouseLocationId,
|
||||
@JsonKey(name: 'created_at') DateTime createdAt,
|
||||
@JsonKey(name: 'company_name') String? companyName,
|
||||
@JsonKey(name: 'branch_name') String? branchName,
|
||||
@JsonKey(name: 'warehouse_name') String? warehouseName});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -266,18 +276,18 @@ class __$$EquipmentListDtoImplCopyWithImpl<$Res>
|
||||
class _$EquipmentListDtoImpl implements _EquipmentListDto {
|
||||
const _$EquipmentListDtoImpl(
|
||||
{required this.id,
|
||||
required this.equipmentNumber,
|
||||
@JsonKey(name: 'equipment_number') required this.equipmentNumber,
|
||||
required this.manufacturer,
|
||||
this.modelName,
|
||||
this.serialNumber,
|
||||
@JsonKey(name: 'model_name') this.modelName,
|
||||
@JsonKey(name: 'serial_number') this.serialNumber,
|
||||
required this.status,
|
||||
this.currentCompanyId,
|
||||
this.currentBranchId,
|
||||
this.warehouseLocationId,
|
||||
required this.createdAt,
|
||||
this.companyName,
|
||||
this.branchName,
|
||||
this.warehouseName});
|
||||
@JsonKey(name: 'current_company_id') this.currentCompanyId,
|
||||
@JsonKey(name: 'current_branch_id') this.currentBranchId,
|
||||
@JsonKey(name: 'warehouse_location_id') this.warehouseLocationId,
|
||||
@JsonKey(name: 'created_at') required this.createdAt,
|
||||
@JsonKey(name: 'company_name') this.companyName,
|
||||
@JsonKey(name: 'branch_name') this.branchName,
|
||||
@JsonKey(name: 'warehouse_name') this.warehouseName});
|
||||
|
||||
factory _$EquipmentListDtoImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$EquipmentListDtoImplFromJson(json);
|
||||
@@ -285,29 +295,39 @@ class _$EquipmentListDtoImpl implements _EquipmentListDto {
|
||||
@override
|
||||
final int id;
|
||||
@override
|
||||
@JsonKey(name: 'equipment_number')
|
||||
final String equipmentNumber;
|
||||
@override
|
||||
final String manufacturer;
|
||||
@override
|
||||
@JsonKey(name: 'model_name')
|
||||
final String? modelName;
|
||||
@override
|
||||
@JsonKey(name: 'serial_number')
|
||||
final String? serialNumber;
|
||||
@override
|
||||
final String status;
|
||||
@override
|
||||
@JsonKey(name: 'current_company_id')
|
||||
final int? currentCompanyId;
|
||||
@override
|
||||
@JsonKey(name: 'current_branch_id')
|
||||
final int? currentBranchId;
|
||||
@override
|
||||
@JsonKey(name: 'warehouse_location_id')
|
||||
final int? warehouseLocationId;
|
||||
@override
|
||||
@JsonKey(name: 'created_at')
|
||||
final DateTime createdAt;
|
||||
// 추가 필드 (조인된 데이터)
|
||||
@override
|
||||
@JsonKey(name: 'company_name')
|
||||
final String? companyName;
|
||||
@override
|
||||
@JsonKey(name: 'branch_name')
|
||||
final String? branchName;
|
||||
@override
|
||||
@JsonKey(name: 'warehouse_name')
|
||||
final String? warehouseName;
|
||||
|
||||
@override
|
||||
@@ -384,17 +404,18 @@ class _$EquipmentListDtoImpl implements _EquipmentListDto {
|
||||
abstract class _EquipmentListDto implements EquipmentListDto {
|
||||
const factory _EquipmentListDto(
|
||||
{required final int id,
|
||||
required final String equipmentNumber,
|
||||
@JsonKey(name: 'equipment_number') required final String equipmentNumber,
|
||||
required final String manufacturer,
|
||||
final String? modelName,
|
||||
final String? serialNumber,
|
||||
@JsonKey(name: 'model_name') final String? modelName,
|
||||
@JsonKey(name: 'serial_number') final String? serialNumber,
|
||||
required final String status,
|
||||
final int? currentCompanyId,
|
||||
final int? currentBranchId,
|
||||
final int? warehouseLocationId,
|
||||
required final DateTime createdAt,
|
||||
final String? companyName,
|
||||
final String? branchName,
|
||||
@JsonKey(name: 'current_company_id') final int? currentCompanyId,
|
||||
@JsonKey(name: 'current_branch_id') final int? currentBranchId,
|
||||
@JsonKey(name: 'warehouse_location_id') final int? warehouseLocationId,
|
||||
@JsonKey(name: 'created_at') required final DateTime createdAt,
|
||||
@JsonKey(name: 'company_name') final String? companyName,
|
||||
@JsonKey(name: 'branch_name') final String? branchName,
|
||||
@JsonKey(name: 'warehouse_name')
|
||||
final String? warehouseName}) = _$EquipmentListDtoImpl;
|
||||
|
||||
factory _EquipmentListDto.fromJson(Map<String, dynamic> json) =
|
||||
@@ -403,28 +424,38 @@ abstract class _EquipmentListDto implements EquipmentListDto {
|
||||
@override
|
||||
int get id;
|
||||
@override
|
||||
@JsonKey(name: 'equipment_number')
|
||||
String get equipmentNumber;
|
||||
@override
|
||||
String get manufacturer;
|
||||
@override
|
||||
@JsonKey(name: 'model_name')
|
||||
String? get modelName;
|
||||
@override
|
||||
@JsonKey(name: 'serial_number')
|
||||
String? get serialNumber;
|
||||
@override
|
||||
String get status;
|
||||
@override
|
||||
@JsonKey(name: 'current_company_id')
|
||||
int? get currentCompanyId;
|
||||
@override
|
||||
@JsonKey(name: 'current_branch_id')
|
||||
int? get currentBranchId;
|
||||
@override
|
||||
@JsonKey(name: 'warehouse_location_id')
|
||||
int? get warehouseLocationId;
|
||||
@override
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime get createdAt; // 추가 필드 (조인된 데이터)
|
||||
@override
|
||||
@JsonKey(name: 'company_name')
|
||||
String? get companyName;
|
||||
@override
|
||||
@JsonKey(name: 'branch_name')
|
||||
String? get branchName;
|
||||
@override
|
||||
@JsonKey(name: 'warehouse_name')
|
||||
String? get warehouseName;
|
||||
|
||||
/// Create a copy of EquipmentListDto
|
||||
|
||||
@@ -10,34 +10,34 @@ _$EquipmentListDtoImpl _$$EquipmentListDtoImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$EquipmentListDtoImpl(
|
||||
id: (json['id'] as num).toInt(),
|
||||
equipmentNumber: json['equipmentNumber'] as String,
|
||||
equipmentNumber: json['equipment_number'] as String,
|
||||
manufacturer: json['manufacturer'] as String,
|
||||
modelName: json['modelName'] as String?,
|
||||
serialNumber: json['serialNumber'] as String?,
|
||||
modelName: json['model_name'] as String?,
|
||||
serialNumber: json['serial_number'] as String?,
|
||||
status: json['status'] as String,
|
||||
currentCompanyId: (json['currentCompanyId'] as num?)?.toInt(),
|
||||
currentBranchId: (json['currentBranchId'] as num?)?.toInt(),
|
||||
warehouseLocationId: (json['warehouseLocationId'] as num?)?.toInt(),
|
||||
createdAt: DateTime.parse(json['createdAt'] as String),
|
||||
companyName: json['companyName'] as String?,
|
||||
branchName: json['branchName'] as String?,
|
||||
warehouseName: json['warehouseName'] as String?,
|
||||
currentCompanyId: (json['current_company_id'] as num?)?.toInt(),
|
||||
currentBranchId: (json['current_branch_id'] as num?)?.toInt(),
|
||||
warehouseLocationId: (json['warehouse_location_id'] as num?)?.toInt(),
|
||||
createdAt: DateTime.parse(json['created_at'] as String),
|
||||
companyName: json['company_name'] as String?,
|
||||
branchName: json['branch_name'] as String?,
|
||||
warehouseName: json['warehouse_name'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$EquipmentListDtoImplToJson(
|
||||
_$EquipmentListDtoImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'equipmentNumber': instance.equipmentNumber,
|
||||
'equipment_number': instance.equipmentNumber,
|
||||
'manufacturer': instance.manufacturer,
|
||||
'modelName': instance.modelName,
|
||||
'serialNumber': instance.serialNumber,
|
||||
'model_name': instance.modelName,
|
||||
'serial_number': instance.serialNumber,
|
||||
'status': instance.status,
|
||||
'currentCompanyId': instance.currentCompanyId,
|
||||
'currentBranchId': instance.currentBranchId,
|
||||
'warehouseLocationId': instance.warehouseLocationId,
|
||||
'createdAt': instance.createdAt.toIso8601String(),
|
||||
'companyName': instance.companyName,
|
||||
'branchName': instance.branchName,
|
||||
'warehouseName': instance.warehouseName,
|
||||
'current_company_id': instance.currentCompanyId,
|
||||
'current_branch_id': instance.currentBranchId,
|
||||
'warehouse_location_id': instance.warehouseLocationId,
|
||||
'created_at': instance.createdAt.toIso8601String(),
|
||||
'company_name': instance.companyName,
|
||||
'branch_name': instance.branchName,
|
||||
'warehouse_name': instance.warehouseName,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:superport/core/utils/equipment_status_converter.dart';
|
||||
|
||||
part 'equipment_request.freezed.dart';
|
||||
part 'equipment_request.g.dart';
|
||||
@@ -34,7 +35,7 @@ class UpdateEquipmentRequest with _$UpdateEquipmentRequest {
|
||||
String? barcode,
|
||||
DateTime? purchaseDate,
|
||||
double? purchasePrice,
|
||||
String? status,
|
||||
@EquipmentStatusJsonConverter() String? status,
|
||||
int? currentCompanyId,
|
||||
int? currentBranchId,
|
||||
int? warehouseLocationId,
|
||||
|
||||
@@ -389,6 +389,7 @@ mixin _$UpdateEquipmentRequest {
|
||||
String? get barcode => throw _privateConstructorUsedError;
|
||||
DateTime? get purchaseDate => throw _privateConstructorUsedError;
|
||||
double? get purchasePrice => throw _privateConstructorUsedError;
|
||||
@EquipmentStatusJsonConverter()
|
||||
String? get status => throw _privateConstructorUsedError;
|
||||
int? get currentCompanyId => throw _privateConstructorUsedError;
|
||||
int? get currentBranchId => throw _privateConstructorUsedError;
|
||||
@@ -423,7 +424,7 @@ abstract class $UpdateEquipmentRequestCopyWith<$Res> {
|
||||
String? barcode,
|
||||
DateTime? purchaseDate,
|
||||
double? purchasePrice,
|
||||
String? status,
|
||||
@EquipmentStatusJsonConverter() String? status,
|
||||
int? currentCompanyId,
|
||||
int? currentBranchId,
|
||||
int? warehouseLocationId,
|
||||
@@ -553,7 +554,7 @@ abstract class _$$UpdateEquipmentRequestImplCopyWith<$Res>
|
||||
String? barcode,
|
||||
DateTime? purchaseDate,
|
||||
double? purchasePrice,
|
||||
String? status,
|
||||
@EquipmentStatusJsonConverter() String? status,
|
||||
int? currentCompanyId,
|
||||
int? currentBranchId,
|
||||
int? warehouseLocationId,
|
||||
@@ -676,7 +677,7 @@ class _$UpdateEquipmentRequestImpl implements _UpdateEquipmentRequest {
|
||||
this.barcode,
|
||||
this.purchaseDate,
|
||||
this.purchasePrice,
|
||||
this.status,
|
||||
@EquipmentStatusJsonConverter() this.status,
|
||||
this.currentCompanyId,
|
||||
this.currentBranchId,
|
||||
this.warehouseLocationId,
|
||||
@@ -706,6 +707,7 @@ class _$UpdateEquipmentRequestImpl implements _UpdateEquipmentRequest {
|
||||
@override
|
||||
final double? purchasePrice;
|
||||
@override
|
||||
@EquipmentStatusJsonConverter()
|
||||
final String? status;
|
||||
@override
|
||||
final int? currentCompanyId;
|
||||
@@ -810,7 +812,7 @@ abstract class _UpdateEquipmentRequest implements UpdateEquipmentRequest {
|
||||
final String? barcode,
|
||||
final DateTime? purchaseDate,
|
||||
final double? purchasePrice,
|
||||
final String? status,
|
||||
@EquipmentStatusJsonConverter() final String? status,
|
||||
final int? currentCompanyId,
|
||||
final int? currentBranchId,
|
||||
final int? warehouseLocationId,
|
||||
@@ -840,6 +842,7 @@ abstract class _UpdateEquipmentRequest implements UpdateEquipmentRequest {
|
||||
@override
|
||||
double? get purchasePrice;
|
||||
@override
|
||||
@EquipmentStatusJsonConverter()
|
||||
String? get status;
|
||||
@override
|
||||
int? get currentCompanyId;
|
||||
|
||||
@@ -52,7 +52,8 @@ _$UpdateEquipmentRequestImpl _$$UpdateEquipmentRequestImplFromJson(
|
||||
? null
|
||||
: DateTime.parse(json['purchaseDate'] as String),
|
||||
purchasePrice: (json['purchasePrice'] as num?)?.toDouble(),
|
||||
status: json['status'] as String?,
|
||||
status: _$JsonConverterFromJson<String, String>(
|
||||
json['status'], const EquipmentStatusJsonConverter().fromJson),
|
||||
currentCompanyId: (json['currentCompanyId'] as num?)?.toInt(),
|
||||
currentBranchId: (json['currentBranchId'] as num?)?.toInt(),
|
||||
warehouseLocationId: (json['warehouseLocationId'] as num?)?.toInt(),
|
||||
@@ -77,7 +78,8 @@ Map<String, dynamic> _$$UpdateEquipmentRequestImplToJson(
|
||||
'barcode': instance.barcode,
|
||||
'purchaseDate': instance.purchaseDate?.toIso8601String(),
|
||||
'purchasePrice': instance.purchasePrice,
|
||||
'status': instance.status,
|
||||
'status': _$JsonConverterToJson<String, String>(
|
||||
instance.status, const EquipmentStatusJsonConverter().toJson),
|
||||
'currentCompanyId': instance.currentCompanyId,
|
||||
'currentBranchId': instance.currentBranchId,
|
||||
'warehouseLocationId': instance.warehouseLocationId,
|
||||
@@ -85,3 +87,15 @@ Map<String, dynamic> _$$UpdateEquipmentRequestImplToJson(
|
||||
'nextInspectionDate': instance.nextInspectionDate?.toIso8601String(),
|
||||
'remark': instance.remark,
|
||||
};
|
||||
|
||||
Value? _$JsonConverterFromJson<Json, Value>(
|
||||
Object? json,
|
||||
Value? Function(Json json) fromJson,
|
||||
) =>
|
||||
json == null ? null : fromJson(json as Json);
|
||||
|
||||
Json? _$JsonConverterToJson<Json, Value>(
|
||||
Value? value,
|
||||
Json? Function(Value value) toJson,
|
||||
) =>
|
||||
value == null ? null : toJson(value);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:superport/core/utils/equipment_status_converter.dart';
|
||||
|
||||
part 'equipment_response.freezed.dart';
|
||||
part 'equipment_response.g.dart';
|
||||
@@ -17,7 +18,7 @@ class EquipmentResponse with _$EquipmentResponse {
|
||||
String? barcode,
|
||||
DateTime? purchaseDate,
|
||||
double? purchasePrice,
|
||||
required String status,
|
||||
@EquipmentStatusJsonConverter() required String status,
|
||||
int? currentCompanyId,
|
||||
int? currentBranchId,
|
||||
int? warehouseLocationId,
|
||||
|
||||
@@ -31,6 +31,7 @@ mixin _$EquipmentResponse {
|
||||
String? get barcode => throw _privateConstructorUsedError;
|
||||
DateTime? get purchaseDate => throw _privateConstructorUsedError;
|
||||
double? get purchasePrice => throw _privateConstructorUsedError;
|
||||
@EquipmentStatusJsonConverter()
|
||||
String get status => throw _privateConstructorUsedError;
|
||||
int? get currentCompanyId => throw _privateConstructorUsedError;
|
||||
int? get currentBranchId => throw _privateConstructorUsedError;
|
||||
@@ -73,7 +74,7 @@ abstract class $EquipmentResponseCopyWith<$Res> {
|
||||
String? barcode,
|
||||
DateTime? purchaseDate,
|
||||
double? purchasePrice,
|
||||
String status,
|
||||
@EquipmentStatusJsonConverter() String status,
|
||||
int? currentCompanyId,
|
||||
int? currentBranchId,
|
||||
int? warehouseLocationId,
|
||||
@@ -243,7 +244,7 @@ abstract class _$$EquipmentResponseImplCopyWith<$Res>
|
||||
String? barcode,
|
||||
DateTime? purchaseDate,
|
||||
double? purchasePrice,
|
||||
String status,
|
||||
@EquipmentStatusJsonConverter() String status,
|
||||
int? currentCompanyId,
|
||||
int? currentBranchId,
|
||||
int? warehouseLocationId,
|
||||
@@ -406,7 +407,7 @@ class _$EquipmentResponseImpl implements _EquipmentResponse {
|
||||
this.barcode,
|
||||
this.purchaseDate,
|
||||
this.purchasePrice,
|
||||
required this.status,
|
||||
@EquipmentStatusJsonConverter() required this.status,
|
||||
this.currentCompanyId,
|
||||
this.currentBranchId,
|
||||
this.warehouseLocationId,
|
||||
@@ -445,6 +446,7 @@ class _$EquipmentResponseImpl implements _EquipmentResponse {
|
||||
@override
|
||||
final double? purchasePrice;
|
||||
@override
|
||||
@EquipmentStatusJsonConverter()
|
||||
final String status;
|
||||
@override
|
||||
final int? currentCompanyId;
|
||||
@@ -583,7 +585,7 @@ abstract class _EquipmentResponse implements EquipmentResponse {
|
||||
final String? barcode,
|
||||
final DateTime? purchaseDate,
|
||||
final double? purchasePrice,
|
||||
required final String status,
|
||||
@EquipmentStatusJsonConverter() required final String status,
|
||||
final int? currentCompanyId,
|
||||
final int? currentBranchId,
|
||||
final int? warehouseLocationId,
|
||||
@@ -622,6 +624,7 @@ abstract class _EquipmentResponse implements EquipmentResponse {
|
||||
@override
|
||||
double? get purchasePrice;
|
||||
@override
|
||||
@EquipmentStatusJsonConverter()
|
||||
String get status;
|
||||
@override
|
||||
int? get currentCompanyId;
|
||||
|
||||
@@ -22,7 +22,8 @@ _$EquipmentResponseImpl _$$EquipmentResponseImplFromJson(
|
||||
? null
|
||||
: DateTime.parse(json['purchaseDate'] as String),
|
||||
purchasePrice: (json['purchasePrice'] as num?)?.toDouble(),
|
||||
status: json['status'] as String,
|
||||
status: const EquipmentStatusJsonConverter()
|
||||
.fromJson(json['status'] as String),
|
||||
currentCompanyId: (json['currentCompanyId'] as num?)?.toInt(),
|
||||
currentBranchId: (json['currentBranchId'] as num?)?.toInt(),
|
||||
warehouseLocationId: (json['warehouseLocationId'] as num?)?.toInt(),
|
||||
@@ -54,7 +55,7 @@ Map<String, dynamic> _$$EquipmentResponseImplToJson(
|
||||
'barcode': instance.barcode,
|
||||
'purchaseDate': instance.purchaseDate?.toIso8601String(),
|
||||
'purchasePrice': instance.purchasePrice,
|
||||
'status': instance.status,
|
||||
'status': const EquipmentStatusJsonConverter().toJson(instance.status),
|
||||
'currentCompanyId': instance.currentCompanyId,
|
||||
'currentBranchId': instance.currentBranchId,
|
||||
'warehouseLocationId': instance.warehouseLocationId,
|
||||
|
||||
@@ -46,18 +46,20 @@ class WarehouseLocationDto with _$WarehouseLocationDto {
|
||||
const factory WarehouseLocationDto({
|
||||
required int id,
|
||||
required String name,
|
||||
String? code,
|
||||
@JsonKey(name: 'manager_name') String? managerName,
|
||||
@JsonKey(name: 'manager_phone') String? managerPhone,
|
||||
int? capacity,
|
||||
@JsonKey(name: 'is_active') required bool isActive,
|
||||
@JsonKey(name: 'created_at') required DateTime createdAt,
|
||||
// API에 없는 필드들은 nullable로 변경
|
||||
String? address,
|
||||
String? city,
|
||||
String? state,
|
||||
@JsonKey(name: 'postal_code') String? postalCode,
|
||||
String? country,
|
||||
int? capacity,
|
||||
@JsonKey(name: 'manager_id') int? managerId,
|
||||
@JsonKey(name: 'manager_name') String? managerName,
|
||||
@JsonKey(name: 'is_active') required bool isActive,
|
||||
@JsonKey(name: 'created_at') required DateTime createdAt,
|
||||
@JsonKey(name: 'updated_at') required DateTime updatedAt,
|
||||
// 추가 정보
|
||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
||||
@JsonKey(name: 'current_stock') int? currentStock,
|
||||
@JsonKey(name: 'available_capacity') int? availableCapacity,
|
||||
}) = _WarehouseLocationDto;
|
||||
|
||||
@@ -680,23 +680,27 @@ WarehouseLocationDto _$WarehouseLocationDtoFromJson(Map<String, dynamic> json) {
|
||||
mixin _$WarehouseLocationDto {
|
||||
int get id => throw _privateConstructorUsedError;
|
||||
String get name => throw _privateConstructorUsedError;
|
||||
String? get code => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'manager_name')
|
||||
String? get managerName => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'manager_phone')
|
||||
String? get managerPhone => throw _privateConstructorUsedError;
|
||||
int? get capacity => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'is_active')
|
||||
bool get isActive => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime get createdAt =>
|
||||
throw _privateConstructorUsedError; // API에 없는 필드들은 nullable로 변경
|
||||
String? get address => throw _privateConstructorUsedError;
|
||||
String? get city => throw _privateConstructorUsedError;
|
||||
String? get state => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'postal_code')
|
||||
String? get postalCode => throw _privateConstructorUsedError;
|
||||
String? get country => throw _privateConstructorUsedError;
|
||||
int? get capacity => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'manager_id')
|
||||
int? get managerId => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'manager_name')
|
||||
String? get managerName => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'is_active')
|
||||
bool get isActive => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime get createdAt => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'updated_at')
|
||||
DateTime get updatedAt => throw _privateConstructorUsedError; // 추가 정보
|
||||
DateTime? get updatedAt => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'current_stock')
|
||||
int? get currentStock => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'available_capacity')
|
||||
@@ -721,17 +725,19 @@ abstract class $WarehouseLocationDtoCopyWith<$Res> {
|
||||
$Res call(
|
||||
{int id,
|
||||
String name,
|
||||
String? code,
|
||||
@JsonKey(name: 'manager_name') String? managerName,
|
||||
@JsonKey(name: 'manager_phone') String? managerPhone,
|
||||
int? capacity,
|
||||
@JsonKey(name: 'is_active') bool isActive,
|
||||
@JsonKey(name: 'created_at') DateTime createdAt,
|
||||
String? address,
|
||||
String? city,
|
||||
String? state,
|
||||
@JsonKey(name: 'postal_code') String? postalCode,
|
||||
String? country,
|
||||
int? capacity,
|
||||
@JsonKey(name: 'manager_id') int? managerId,
|
||||
@JsonKey(name: 'manager_name') String? managerName,
|
||||
@JsonKey(name: 'is_active') bool isActive,
|
||||
@JsonKey(name: 'created_at') DateTime createdAt,
|
||||
@JsonKey(name: 'updated_at') DateTime updatedAt,
|
||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
||||
@JsonKey(name: 'current_stock') int? currentStock,
|
||||
@JsonKey(name: 'available_capacity') int? availableCapacity});
|
||||
}
|
||||
@@ -754,17 +760,19 @@ class _$WarehouseLocationDtoCopyWithImpl<$Res,
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? name = null,
|
||||
Object? code = freezed,
|
||||
Object? managerName = freezed,
|
||||
Object? managerPhone = freezed,
|
||||
Object? capacity = freezed,
|
||||
Object? isActive = null,
|
||||
Object? createdAt = null,
|
||||
Object? address = freezed,
|
||||
Object? city = freezed,
|
||||
Object? state = freezed,
|
||||
Object? postalCode = freezed,
|
||||
Object? country = freezed,
|
||||
Object? capacity = freezed,
|
||||
Object? managerId = freezed,
|
||||
Object? managerName = freezed,
|
||||
Object? isActive = null,
|
||||
Object? createdAt = null,
|
||||
Object? updatedAt = null,
|
||||
Object? updatedAt = freezed,
|
||||
Object? currentStock = freezed,
|
||||
Object? availableCapacity = freezed,
|
||||
}) {
|
||||
@@ -777,6 +785,30 @@ class _$WarehouseLocationDtoCopyWithImpl<$Res,
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
code: freezed == code
|
||||
? _value.code
|
||||
: code // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
managerName: freezed == managerName
|
||||
? _value.managerName
|
||||
: managerName // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
managerPhone: freezed == managerPhone
|
||||
? _value.managerPhone
|
||||
: managerPhone // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
capacity: freezed == capacity
|
||||
? _value.capacity
|
||||
: capacity // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
isActive: null == isActive
|
||||
? _value.isActive
|
||||
: isActive // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
createdAt: null == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
address: freezed == address
|
||||
? _value.address
|
||||
: address // ignore: cast_nullable_to_non_nullable
|
||||
@@ -797,30 +829,14 @@ class _$WarehouseLocationDtoCopyWithImpl<$Res,
|
||||
? _value.country
|
||||
: country // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
capacity: freezed == capacity
|
||||
? _value.capacity
|
||||
: capacity // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
managerId: freezed == managerId
|
||||
? _value.managerId
|
||||
: managerId // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
managerName: freezed == managerName
|
||||
? _value.managerName
|
||||
: managerName // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
isActive: null == isActive
|
||||
? _value.isActive
|
||||
: isActive // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
createdAt: null == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
updatedAt: null == updatedAt
|
||||
updatedAt: freezed == updatedAt
|
||||
? _value.updatedAt
|
||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
as DateTime?,
|
||||
currentStock: freezed == currentStock
|
||||
? _value.currentStock
|
||||
: currentStock // ignore: cast_nullable_to_non_nullable
|
||||
@@ -844,17 +860,19 @@ abstract class _$$WarehouseLocationDtoImplCopyWith<$Res>
|
||||
$Res call(
|
||||
{int id,
|
||||
String name,
|
||||
String? code,
|
||||
@JsonKey(name: 'manager_name') String? managerName,
|
||||
@JsonKey(name: 'manager_phone') String? managerPhone,
|
||||
int? capacity,
|
||||
@JsonKey(name: 'is_active') bool isActive,
|
||||
@JsonKey(name: 'created_at') DateTime createdAt,
|
||||
String? address,
|
||||
String? city,
|
||||
String? state,
|
||||
@JsonKey(name: 'postal_code') String? postalCode,
|
||||
String? country,
|
||||
int? capacity,
|
||||
@JsonKey(name: 'manager_id') int? managerId,
|
||||
@JsonKey(name: 'manager_name') String? managerName,
|
||||
@JsonKey(name: 'is_active') bool isActive,
|
||||
@JsonKey(name: 'created_at') DateTime createdAt,
|
||||
@JsonKey(name: 'updated_at') DateTime updatedAt,
|
||||
@JsonKey(name: 'updated_at') DateTime? updatedAt,
|
||||
@JsonKey(name: 'current_stock') int? currentStock,
|
||||
@JsonKey(name: 'available_capacity') int? availableCapacity});
|
||||
}
|
||||
@@ -874,17 +892,19 @@ class __$$WarehouseLocationDtoImplCopyWithImpl<$Res>
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? name = null,
|
||||
Object? code = freezed,
|
||||
Object? managerName = freezed,
|
||||
Object? managerPhone = freezed,
|
||||
Object? capacity = freezed,
|
||||
Object? isActive = null,
|
||||
Object? createdAt = null,
|
||||
Object? address = freezed,
|
||||
Object? city = freezed,
|
||||
Object? state = freezed,
|
||||
Object? postalCode = freezed,
|
||||
Object? country = freezed,
|
||||
Object? capacity = freezed,
|
||||
Object? managerId = freezed,
|
||||
Object? managerName = freezed,
|
||||
Object? isActive = null,
|
||||
Object? createdAt = null,
|
||||
Object? updatedAt = null,
|
||||
Object? updatedAt = freezed,
|
||||
Object? currentStock = freezed,
|
||||
Object? availableCapacity = freezed,
|
||||
}) {
|
||||
@@ -897,6 +917,30 @@ class __$$WarehouseLocationDtoImplCopyWithImpl<$Res>
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
code: freezed == code
|
||||
? _value.code
|
||||
: code // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
managerName: freezed == managerName
|
||||
? _value.managerName
|
||||
: managerName // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
managerPhone: freezed == managerPhone
|
||||
? _value.managerPhone
|
||||
: managerPhone // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
capacity: freezed == capacity
|
||||
? _value.capacity
|
||||
: capacity // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
isActive: null == isActive
|
||||
? _value.isActive
|
||||
: isActive // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
createdAt: null == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
address: freezed == address
|
||||
? _value.address
|
||||
: address // ignore: cast_nullable_to_non_nullable
|
||||
@@ -917,30 +961,14 @@ class __$$WarehouseLocationDtoImplCopyWithImpl<$Res>
|
||||
? _value.country
|
||||
: country // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
capacity: freezed == capacity
|
||||
? _value.capacity
|
||||
: capacity // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
managerId: freezed == managerId
|
||||
? _value.managerId
|
||||
: managerId // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
managerName: freezed == managerName
|
||||
? _value.managerName
|
||||
: managerName // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
isActive: null == isActive
|
||||
? _value.isActive
|
||||
: isActive // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
createdAt: null == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
updatedAt: null == updatedAt
|
||||
updatedAt: freezed == updatedAt
|
||||
? _value.updatedAt
|
||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
as DateTime?,
|
||||
currentStock: freezed == currentStock
|
||||
? _value.currentStock
|
||||
: currentStock // ignore: cast_nullable_to_non_nullable
|
||||
@@ -959,17 +987,19 @@ class _$WarehouseLocationDtoImpl implements _WarehouseLocationDto {
|
||||
const _$WarehouseLocationDtoImpl(
|
||||
{required this.id,
|
||||
required this.name,
|
||||
this.code,
|
||||
@JsonKey(name: 'manager_name') this.managerName,
|
||||
@JsonKey(name: 'manager_phone') this.managerPhone,
|
||||
this.capacity,
|
||||
@JsonKey(name: 'is_active') required this.isActive,
|
||||
@JsonKey(name: 'created_at') required this.createdAt,
|
||||
this.address,
|
||||
this.city,
|
||||
this.state,
|
||||
@JsonKey(name: 'postal_code') this.postalCode,
|
||||
this.country,
|
||||
this.capacity,
|
||||
@JsonKey(name: 'manager_id') this.managerId,
|
||||
@JsonKey(name: 'manager_name') this.managerName,
|
||||
@JsonKey(name: 'is_active') required this.isActive,
|
||||
@JsonKey(name: 'created_at') required this.createdAt,
|
||||
@JsonKey(name: 'updated_at') required this.updatedAt,
|
||||
@JsonKey(name: 'updated_at') this.updatedAt,
|
||||
@JsonKey(name: 'current_stock') this.currentStock,
|
||||
@JsonKey(name: 'available_capacity') this.availableCapacity});
|
||||
|
||||
@@ -980,6 +1010,23 @@ class _$WarehouseLocationDtoImpl implements _WarehouseLocationDto {
|
||||
final int id;
|
||||
@override
|
||||
final String name;
|
||||
@override
|
||||
final String? code;
|
||||
@override
|
||||
@JsonKey(name: 'manager_name')
|
||||
final String? managerName;
|
||||
@override
|
||||
@JsonKey(name: 'manager_phone')
|
||||
final String? managerPhone;
|
||||
@override
|
||||
final int? capacity;
|
||||
@override
|
||||
@JsonKey(name: 'is_active')
|
||||
final bool isActive;
|
||||
@override
|
||||
@JsonKey(name: 'created_at')
|
||||
final DateTime createdAt;
|
||||
// API에 없는 필드들은 nullable로 변경
|
||||
@override
|
||||
final String? address;
|
||||
@override
|
||||
@@ -992,23 +1039,11 @@ class _$WarehouseLocationDtoImpl implements _WarehouseLocationDto {
|
||||
@override
|
||||
final String? country;
|
||||
@override
|
||||
final int? capacity;
|
||||
@override
|
||||
@JsonKey(name: 'manager_id')
|
||||
final int? managerId;
|
||||
@override
|
||||
@JsonKey(name: 'manager_name')
|
||||
final String? managerName;
|
||||
@override
|
||||
@JsonKey(name: 'is_active')
|
||||
final bool isActive;
|
||||
@override
|
||||
@JsonKey(name: 'created_at')
|
||||
final DateTime createdAt;
|
||||
@override
|
||||
@JsonKey(name: 'updated_at')
|
||||
final DateTime updatedAt;
|
||||
// 추가 정보
|
||||
final DateTime? updatedAt;
|
||||
@override
|
||||
@JsonKey(name: 'current_stock')
|
||||
final int? currentStock;
|
||||
@@ -1018,7 +1053,7 @@ class _$WarehouseLocationDtoImpl implements _WarehouseLocationDto {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'WarehouseLocationDto(id: $id, name: $name, address: $address, city: $city, state: $state, postalCode: $postalCode, country: $country, capacity: $capacity, managerId: $managerId, managerName: $managerName, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt, currentStock: $currentStock, availableCapacity: $availableCapacity)';
|
||||
return 'WarehouseLocationDto(id: $id, name: $name, code: $code, managerName: $managerName, managerPhone: $managerPhone, capacity: $capacity, isActive: $isActive, createdAt: $createdAt, address: $address, city: $city, state: $state, postalCode: $postalCode, country: $country, managerId: $managerId, updatedAt: $updatedAt, currentStock: $currentStock, availableCapacity: $availableCapacity)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1028,22 +1063,25 @@ class _$WarehouseLocationDtoImpl implements _WarehouseLocationDto {
|
||||
other is _$WarehouseLocationDtoImpl &&
|
||||
(identical(other.id, id) || other.id == id) &&
|
||||
(identical(other.name, name) || other.name == name) &&
|
||||
(identical(other.code, code) || other.code == code) &&
|
||||
(identical(other.managerName, managerName) ||
|
||||
other.managerName == managerName) &&
|
||||
(identical(other.managerPhone, managerPhone) ||
|
||||
other.managerPhone == managerPhone) &&
|
||||
(identical(other.capacity, capacity) ||
|
||||
other.capacity == capacity) &&
|
||||
(identical(other.isActive, isActive) ||
|
||||
other.isActive == isActive) &&
|
||||
(identical(other.createdAt, createdAt) ||
|
||||
other.createdAt == createdAt) &&
|
||||
(identical(other.address, address) || other.address == address) &&
|
||||
(identical(other.city, city) || other.city == city) &&
|
||||
(identical(other.state, state) || other.state == state) &&
|
||||
(identical(other.postalCode, postalCode) ||
|
||||
other.postalCode == postalCode) &&
|
||||
(identical(other.country, country) || other.country == country) &&
|
||||
(identical(other.capacity, capacity) ||
|
||||
other.capacity == capacity) &&
|
||||
(identical(other.managerId, managerId) ||
|
||||
other.managerId == managerId) &&
|
||||
(identical(other.managerName, managerName) ||
|
||||
other.managerName == managerName) &&
|
||||
(identical(other.isActive, isActive) ||
|
||||
other.isActive == isActive) &&
|
||||
(identical(other.createdAt, createdAt) ||
|
||||
other.createdAt == createdAt) &&
|
||||
(identical(other.updatedAt, updatedAt) ||
|
||||
other.updatedAt == updatedAt) &&
|
||||
(identical(other.currentStock, currentStock) ||
|
||||
@@ -1058,16 +1096,18 @@ class _$WarehouseLocationDtoImpl implements _WarehouseLocationDto {
|
||||
runtimeType,
|
||||
id,
|
||||
name,
|
||||
code,
|
||||
managerName,
|
||||
managerPhone,
|
||||
capacity,
|
||||
isActive,
|
||||
createdAt,
|
||||
address,
|
||||
city,
|
||||
state,
|
||||
postalCode,
|
||||
country,
|
||||
capacity,
|
||||
managerId,
|
||||
managerName,
|
||||
isActive,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
currentStock,
|
||||
availableCapacity);
|
||||
@@ -1094,17 +1134,19 @@ abstract class _WarehouseLocationDto implements WarehouseLocationDto {
|
||||
const factory _WarehouseLocationDto(
|
||||
{required final int id,
|
||||
required final String name,
|
||||
final String? code,
|
||||
@JsonKey(name: 'manager_name') final String? managerName,
|
||||
@JsonKey(name: 'manager_phone') final String? managerPhone,
|
||||
final int? capacity,
|
||||
@JsonKey(name: 'is_active') required final bool isActive,
|
||||
@JsonKey(name: 'created_at') required final DateTime createdAt,
|
||||
final String? address,
|
||||
final String? city,
|
||||
final String? state,
|
||||
@JsonKey(name: 'postal_code') final String? postalCode,
|
||||
final String? country,
|
||||
final int? capacity,
|
||||
@JsonKey(name: 'manager_id') final int? managerId,
|
||||
@JsonKey(name: 'manager_name') final String? managerName,
|
||||
@JsonKey(name: 'is_active') required final bool isActive,
|
||||
@JsonKey(name: 'created_at') required final DateTime createdAt,
|
||||
@JsonKey(name: 'updated_at') required final DateTime updatedAt,
|
||||
@JsonKey(name: 'updated_at') final DateTime? updatedAt,
|
||||
@JsonKey(name: 'current_stock') final int? currentStock,
|
||||
@JsonKey(name: 'available_capacity') final int? availableCapacity}) =
|
||||
_$WarehouseLocationDtoImpl;
|
||||
@@ -1117,6 +1159,22 @@ abstract class _WarehouseLocationDto implements WarehouseLocationDto {
|
||||
@override
|
||||
String get name;
|
||||
@override
|
||||
String? get code;
|
||||
@override
|
||||
@JsonKey(name: 'manager_name')
|
||||
String? get managerName;
|
||||
@override
|
||||
@JsonKey(name: 'manager_phone')
|
||||
String? get managerPhone;
|
||||
@override
|
||||
int? get capacity;
|
||||
@override
|
||||
@JsonKey(name: 'is_active')
|
||||
bool get isActive;
|
||||
@override
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime get createdAt; // API에 없는 필드들은 nullable로 변경
|
||||
@override
|
||||
String? get address;
|
||||
@override
|
||||
String? get city;
|
||||
@@ -1128,22 +1186,11 @@ abstract class _WarehouseLocationDto implements WarehouseLocationDto {
|
||||
@override
|
||||
String? get country;
|
||||
@override
|
||||
int? get capacity;
|
||||
@override
|
||||
@JsonKey(name: 'manager_id')
|
||||
int? get managerId;
|
||||
@override
|
||||
@JsonKey(name: 'manager_name')
|
||||
String? get managerName;
|
||||
@override
|
||||
@JsonKey(name: 'is_active')
|
||||
bool get isActive;
|
||||
@override
|
||||
@JsonKey(name: 'created_at')
|
||||
DateTime get createdAt;
|
||||
@override
|
||||
@JsonKey(name: 'updated_at')
|
||||
DateTime get updatedAt; // 추가 정보
|
||||
DateTime? get updatedAt;
|
||||
@override
|
||||
@JsonKey(name: 'current_stock')
|
||||
int? get currentStock;
|
||||
|
||||
@@ -65,17 +65,21 @@ _$WarehouseLocationDtoImpl _$$WarehouseLocationDtoImplFromJson(
|
||||
_$WarehouseLocationDtoImpl(
|
||||
id: (json['id'] as num).toInt(),
|
||||
name: json['name'] as String,
|
||||
code: json['code'] as String?,
|
||||
managerName: json['manager_name'] as String?,
|
||||
managerPhone: json['manager_phone'] as String?,
|
||||
capacity: (json['capacity'] as num?)?.toInt(),
|
||||
isActive: json['is_active'] as bool,
|
||||
createdAt: DateTime.parse(json['created_at'] as String),
|
||||
address: json['address'] as String?,
|
||||
city: json['city'] as String?,
|
||||
state: json['state'] as String?,
|
||||
postalCode: json['postal_code'] as String?,
|
||||
country: json['country'] as String?,
|
||||
capacity: (json['capacity'] as num?)?.toInt(),
|
||||
managerId: (json['manager_id'] as num?)?.toInt(),
|
||||
managerName: json['manager_name'] as String?,
|
||||
isActive: json['is_active'] as bool,
|
||||
createdAt: DateTime.parse(json['created_at'] as String),
|
||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||
updatedAt: json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String),
|
||||
currentStock: (json['current_stock'] as num?)?.toInt(),
|
||||
availableCapacity: (json['available_capacity'] as num?)?.toInt(),
|
||||
);
|
||||
@@ -85,17 +89,19 @@ Map<String, dynamic> _$$WarehouseLocationDtoImplToJson(
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'code': instance.code,
|
||||
'manager_name': instance.managerName,
|
||||
'manager_phone': instance.managerPhone,
|
||||
'capacity': instance.capacity,
|
||||
'is_active': instance.isActive,
|
||||
'created_at': instance.createdAt.toIso8601String(),
|
||||
'address': instance.address,
|
||||
'city': instance.city,
|
||||
'state': instance.state,
|
||||
'postal_code': instance.postalCode,
|
||||
'country': instance.country,
|
||||
'capacity': instance.capacity,
|
||||
'manager_id': instance.managerId,
|
||||
'manager_name': instance.managerName,
|
||||
'is_active': instance.isActive,
|
||||
'created_at': instance.createdAt.toIso8601String(),
|
||||
'updated_at': instance.updatedAt.toIso8601String(),
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'current_stock': instance.currentStock,
|
||||
'available_capacity': instance.availableCapacity,
|
||||
};
|
||||
|
||||
@@ -227,7 +227,6 @@ class SuperportApp extends StatelessWidget {
|
||||
return MaterialPageRoute(
|
||||
builder: (context) => WarehouseLocationFormScreen(id: id),
|
||||
);
|
||||
|
||||
default:
|
||||
return MaterialPageRoute(
|
||||
builder:
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:superport/screens/license/license_list_redesign.dart';
|
||||
import 'package:superport/screens/warehouse_location/warehouse_location_list_redesign.dart';
|
||||
import 'package:superport/services/auth_service.dart';
|
||||
import 'package:superport/utils/constants.dart';
|
||||
import 'package:superport/data/models/auth/auth_user.dart';
|
||||
|
||||
/// Microsoft Dynamics 365 스타일의 메인 레이아웃
|
||||
/// 상단 헤더 + 좌측 사이드바 + 메인 콘텐츠 구조
|
||||
@@ -28,6 +29,8 @@ class _AppLayoutRedesignState extends State<AppLayoutRedesign>
|
||||
late String _currentRoute;
|
||||
bool _sidebarCollapsed = false;
|
||||
late AnimationController _sidebarAnimationController;
|
||||
AuthUser? _currentUser;
|
||||
late final AuthService _authService;
|
||||
late Animation<double> _sidebarAnimation;
|
||||
|
||||
@override
|
||||
@@ -35,6 +38,17 @@ class _AppLayoutRedesignState extends State<AppLayoutRedesign>
|
||||
super.initState();
|
||||
_currentRoute = widget.initialRoute;
|
||||
_setupAnimations();
|
||||
_authService = GetIt.instance<AuthService>();
|
||||
_loadCurrentUser();
|
||||
}
|
||||
|
||||
Future<void> _loadCurrentUser() async {
|
||||
final user = await _authService.getCurrentUser();
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_currentUser = user;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _setupAnimations() {
|
||||
@@ -74,6 +88,12 @@ class _AppLayoutRedesignState extends State<AppLayoutRedesign>
|
||||
return const LicenseListRedesign();
|
||||
case Routes.warehouseLocation:
|
||||
return const WarehouseLocationListRedesign();
|
||||
case '/test/api':
|
||||
// Navigator를 사용하여 별도 화면으로 이동
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
Navigator.pushNamed(context, '/test/api');
|
||||
});
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
default:
|
||||
return const OverviewScreenRedesign();
|
||||
}
|
||||
@@ -115,6 +135,8 @@ class _AppLayoutRedesignState extends State<AppLayoutRedesign>
|
||||
return '유지보수 관리';
|
||||
case Routes.warehouseLocation:
|
||||
return '입고지 관리';
|
||||
case '/test/api':
|
||||
return 'API 테스트';
|
||||
default:
|
||||
return '대시보드';
|
||||
}
|
||||
@@ -139,6 +161,8 @@ class _AppLayoutRedesignState extends State<AppLayoutRedesign>
|
||||
return ['홈', '유지보수 관리'];
|
||||
case Routes.warehouseLocation:
|
||||
return ['홈', '입고지 관리'];
|
||||
case '/test/api':
|
||||
return ['홈', '개발자 도구', 'API 테스트'];
|
||||
default:
|
||||
return ['홈', '대시보드'];
|
||||
}
|
||||
@@ -330,7 +354,10 @@ class _AppLayoutRedesignState extends State<AppLayoutRedesign>
|
||||
onTap: () {
|
||||
_showProfileMenu(context);
|
||||
},
|
||||
child: ShadcnAvatar(initials: 'A', size: 36),
|
||||
child: ShadcnAvatar(
|
||||
initials: _currentUser != null ? _currentUser!.name.substring(0, 1).toUpperCase() : 'U',
|
||||
size: 36,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -410,14 +437,20 @@ class _AppLayoutRedesignState extends State<AppLayoutRedesign>
|
||||
// 프로필 정보
|
||||
Row(
|
||||
children: [
|
||||
ShadcnAvatar(initials: 'A', size: 48),
|
||||
ShadcnAvatar(
|
||||
initials: _currentUser != null ? _currentUser!.name.substring(0, 1).toUpperCase() : 'U',
|
||||
size: 48,
|
||||
),
|
||||
const SizedBox(width: ShadcnTheme.spacing4),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('관리자', style: ShadcnTheme.headingH4),
|
||||
Text(
|
||||
'admin@superport.com',
|
||||
_currentUser?.name ?? '사용자',
|
||||
style: ShadcnTheme.headingH4,
|
||||
),
|
||||
Text(
|
||||
_currentUser?.email ?? '',
|
||||
style: ShadcnTheme.bodyMuted,
|
||||
),
|
||||
],
|
||||
@@ -551,6 +584,17 @@ class SidebarMenuRedesign extends StatelessWidget {
|
||||
isActive: currentRoute == Routes.license,
|
||||
),
|
||||
|
||||
const SizedBox(height: ShadcnTheme.spacing4),
|
||||
const Divider(),
|
||||
const SizedBox(height: ShadcnTheme.spacing4),
|
||||
|
||||
_buildMenuItem(
|
||||
icon: Icons.bug_report,
|
||||
title: 'API 테스트',
|
||||
route: '/test/api',
|
||||
isActive: currentRoute == '/test/api',
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -184,6 +184,7 @@ class _CompanyListRedesignState extends State<CompanyListRedesign> {
|
||||
'mainCompanyName': null,
|
||||
});
|
||||
if (company.branches != null) {
|
||||
print('[CompanyListRedesign] Company ${company.name} has ${company.branches!.length} branches');
|
||||
for (final branch in company.branches!) {
|
||||
displayCompanies.add({
|
||||
'branch': branch,
|
||||
@@ -192,10 +193,13 @@ class _CompanyListRedesignState extends State<CompanyListRedesign> {
|
||||
'mainCompanyName': company.name,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
print('[CompanyListRedesign] Company ${company.name} has no branches');
|
||||
}
|
||||
}
|
||||
|
||||
final int totalCount = displayCompanies.length;
|
||||
print('[CompanyListRedesign] Total display items: $totalCount (companies + branches)');
|
||||
|
||||
return SingleChildScrollView(
|
||||
controller: _scrollController,
|
||||
|
||||
@@ -43,6 +43,8 @@ class CompanyListController extends ChangeNotifier {
|
||||
|
||||
// 데이터 로드 및 필터 적용
|
||||
Future<void> loadData({bool isRefresh = false}) async {
|
||||
print('[CompanyListController] loadData called - isRefresh: $isRefresh');
|
||||
|
||||
if (isRefresh) {
|
||||
_currentPage = 1;
|
||||
_hasMore = true;
|
||||
@@ -59,12 +61,14 @@ class CompanyListController extends ChangeNotifier {
|
||||
try {
|
||||
if (_useApi) {
|
||||
// API 호출
|
||||
print('[CompanyListController] Using API to fetch companies');
|
||||
final apiCompanies = await _companyService.getCompanies(
|
||||
page: _currentPage,
|
||||
perPage: _perPage,
|
||||
search: searchKeyword.isNotEmpty ? searchKeyword : null,
|
||||
isActive: _isActiveFilter,
|
||||
);
|
||||
print('[CompanyListController] API returned ${apiCompanies.length} companies');
|
||||
|
||||
if (isRefresh) {
|
||||
companies = apiCompanies;
|
||||
@@ -76,16 +80,23 @@ class CompanyListController extends ChangeNotifier {
|
||||
if (_hasMore) _currentPage++;
|
||||
} else {
|
||||
// Mock 데이터 사용
|
||||
print('[CompanyListController] Using Mock data');
|
||||
companies = dataService.getAllCompanies();
|
||||
print('[CompanyListController] Mock returned ${companies.length} companies');
|
||||
_hasMore = false;
|
||||
}
|
||||
|
||||
// 필터 적용
|
||||
applyFilters();
|
||||
print('[CompanyListController] After filtering: ${filteredCompanies.length} companies shown');
|
||||
selectedCompanyIds.clear();
|
||||
} on Failure catch (e) {
|
||||
print('[CompanyListController] Failure loading companies: ${e.message}');
|
||||
_error = e.message;
|
||||
} catch (e) {
|
||||
} catch (e, stackTrace) {
|
||||
print('[CompanyListController] Error loading companies: $e');
|
||||
print('[CompanyListController] Error type: ${e.runtimeType}');
|
||||
print('[CompanyListController] Stack trace: $stackTrace');
|
||||
_error = '회사 목록을 불러오는 중 오류가 발생했습니다: $e';
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
|
||||
@@ -6,12 +6,14 @@ import 'package:superport/services/mock_data_service.dart';
|
||||
import 'package:superport/utils/constants.dart';
|
||||
import 'package:superport/core/errors/failures.dart';
|
||||
import 'package:superport/models/equipment_unified_model.dart' as legacy;
|
||||
import 'package:superport/core/utils/debug_logger.dart';
|
||||
|
||||
// companyTypeToString 함수 import
|
||||
import 'package:superport/utils/constants.dart'
|
||||
show companyTypeToString, CompanyType;
|
||||
import 'package:superport/models/company_model.dart';
|
||||
import 'package:superport/models/address_model.dart';
|
||||
import 'package:superport/core/utils/equipment_status_converter.dart';
|
||||
|
||||
// 장비 목록 화면의 상태 및 비즈니스 로직을 담당하는 컨트롤러
|
||||
class EquipmentListController extends ChangeNotifier {
|
||||
@@ -56,19 +58,48 @@ class EquipmentListController extends ChangeNotifier {
|
||||
try {
|
||||
if (_useApi) {
|
||||
// API 호출
|
||||
final apiEquipments = await _equipmentService.getEquipments(
|
||||
DebugLogger.log('장비 목록 API 호출 시작', tag: 'EQUIPMENT', data: {
|
||||
'page': _currentPage,
|
||||
'perPage': _perPage,
|
||||
'statusFilter': selectedStatusFilter,
|
||||
});
|
||||
|
||||
// DTO 형태로 가져와서 status 정보 유지
|
||||
final apiEquipmentDtos = await _equipmentService.getEquipmentsWithStatus(
|
||||
page: _currentPage,
|
||||
perPage: _perPage,
|
||||
status: selectedStatusFilter,
|
||||
status: selectedStatusFilter != null ? EquipmentStatusConverter.clientToServer(selectedStatusFilter) : null,
|
||||
);
|
||||
|
||||
// API 모델을 UnifiedEquipment로 변환
|
||||
final List<UnifiedEquipment> unifiedEquipments = apiEquipments.map((equipment) {
|
||||
DebugLogger.log('장비 목록 API 응답', tag: 'EQUIPMENT', data: {
|
||||
'count': apiEquipmentDtos.length,
|
||||
'firstItem': apiEquipmentDtos.isNotEmpty ? {
|
||||
'id': apiEquipmentDtos.first.id,
|
||||
'equipmentNumber': apiEquipmentDtos.first.equipmentNumber,
|
||||
'manufacturer': apiEquipmentDtos.first.manufacturer,
|
||||
'status': apiEquipmentDtos.first.status,
|
||||
} : null,
|
||||
});
|
||||
|
||||
// DTO를 UnifiedEquipment로 변환 (status 정보 포함)
|
||||
final List<UnifiedEquipment> unifiedEquipments = apiEquipmentDtos.map((dto) {
|
||||
final equipment = Equipment(
|
||||
id: dto.id,
|
||||
manufacturer: dto.manufacturer,
|
||||
name: dto.modelName ?? dto.equipmentNumber,
|
||||
category: '', // 세부 정보는 상세 조회에서 가져와야 함
|
||||
subCategory: '',
|
||||
subSubCategory: '',
|
||||
serialNumber: dto.serialNumber,
|
||||
quantity: 1,
|
||||
inDate: dto.createdAt,
|
||||
);
|
||||
|
||||
return UnifiedEquipment(
|
||||
id: equipment.id,
|
||||
id: dto.id,
|
||||
equipment: equipment,
|
||||
date: DateTime.now(), // 실제로는 API에서 날짜 정보를 가져와야 함
|
||||
status: EquipmentStatus.in_, // 기본값, 실제로는 API에서 가져와야 함
|
||||
date: dto.createdAt,
|
||||
status: EquipmentStatusConverter.serverToClient(dto.status), // 서버 status를 클라이언트 status로 변환
|
||||
);
|
||||
}).toList();
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:superport/core/errors/failures.dart';
|
||||
import 'package:superport/data/models/auth/login_request.dart';
|
||||
import 'package:superport/di/injection_container.dart';
|
||||
import 'package:superport/services/auth_service.dart';
|
||||
import 'package:superport/services/health_test_service.dart';
|
||||
|
||||
/// 로그인 화면의 상태 및 비즈니스 로직을 담당하는 ChangeNotifier 기반 컨트롤러
|
||||
class LoginController extends ChangeNotifier {
|
||||
@@ -40,7 +42,7 @@ class LoginController extends ChangeNotifier {
|
||||
Future<bool> login() async {
|
||||
// 입력값 검증
|
||||
if (idController.text.trim().isEmpty) {
|
||||
_errorMessage = '이메일을 입력해주세요.';
|
||||
_errorMessage = '아이디 또는 이메일을 입력해주세요.';
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
@@ -51,13 +53,10 @@ class LoginController extends ChangeNotifier {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 이메일 형식 검증
|
||||
// 입력값이 이메일인지 username인지 판단
|
||||
final inputValue = idController.text.trim();
|
||||
final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
|
||||
if (!emailRegex.hasMatch(idController.text.trim())) {
|
||||
_errorMessage = '올바른 이메일 형식이 아닙니다.';
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
final isEmail = emailRegex.hasMatch(inputValue);
|
||||
|
||||
// 로딩 시작
|
||||
_isLoading = true;
|
||||
@@ -65,29 +64,103 @@ class LoginController extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
// 로그인 요청
|
||||
// 로그인 요청 (이메일 또는 username으로)
|
||||
final request = LoginRequest(
|
||||
email: idController.text.trim(),
|
||||
email: isEmail ? inputValue : null,
|
||||
username: !isEmail ? inputValue : null,
|
||||
password: pwController.text,
|
||||
);
|
||||
|
||||
final result = await _authService.login(request);
|
||||
print('[LoginController] 로그인 요청 시작: ${isEmail ? 'email: ${request.email}' : 'username: ${request.username}'}');
|
||||
print('[LoginController] 요청 데이터: ${request.toJson()}');
|
||||
|
||||
final result = await _authService.login(request).timeout(
|
||||
const Duration(seconds: 10),
|
||||
onTimeout: () async {
|
||||
print('[LoginController] 로그인 요청 타임아웃 (10초)');
|
||||
return Left(NetworkFailure(message: '요청 시간이 초과되었습니다. 네트워크 연결을 확인해주세요.'));
|
||||
},
|
||||
);
|
||||
|
||||
print('[LoginController] 로그인 결과 수신: ${result.isRight() ? '성공' : '실패'}');
|
||||
|
||||
return result.fold(
|
||||
(failure) {
|
||||
print('[LoginController] 로그인 실패: ${failure.message}');
|
||||
_errorMessage = failure.message;
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
return false;
|
||||
},
|
||||
(loginResponse) {
|
||||
(loginResponse) async {
|
||||
print('[LoginController] 로그인 성공: ${loginResponse.user.email}');
|
||||
|
||||
// Health Test 실행
|
||||
try {
|
||||
print('[LoginController] ========== Health Test 시작 ==========');
|
||||
final healthTestService = HealthTestService();
|
||||
final testResults = await healthTestService.checkAllEndpoints();
|
||||
|
||||
// 상세한 결과 출력
|
||||
print('\n[LoginController] === 인증 상태 ===');
|
||||
print('인증됨: ${testResults['auth']?['success']}');
|
||||
print('Access Token: ${testResults['auth']?['accessToken'] == true ? '있음' : '없음'}');
|
||||
print('Refresh Token: ${testResults['auth']?['refreshToken'] == true ? '있음' : '없음'}');
|
||||
|
||||
print('\n[LoginController] === 대시보드 API ===');
|
||||
print('Overview Stats: ${testResults['dashboard_stats']?['success'] == true ? '✅ 성공' : '❌ 실패'}');
|
||||
if (testResults['dashboard_stats']?['error'] != null) {
|
||||
print(' 에러: ${testResults['dashboard_stats']['error']}');
|
||||
}
|
||||
if (testResults['dashboard_stats']?['data'] != null) {
|
||||
print(' 데이터: ${testResults['dashboard_stats']['data']}');
|
||||
}
|
||||
|
||||
print('\n[LoginController] === 장비 상태 분포 ===');
|
||||
print('Equipment Status: ${testResults['equipment_status_distribution']?['success'] == true ? '✅ 성공' : '❌ 실패'}');
|
||||
if (testResults['equipment_status_distribution']?['error'] != null) {
|
||||
print(' 에러: ${testResults['equipment_status_distribution']['error']}');
|
||||
}
|
||||
if (testResults['equipment_status_distribution']?['data'] != null) {
|
||||
print(' 데이터: ${testResults['equipment_status_distribution']['data']}');
|
||||
}
|
||||
|
||||
print('\n[LoginController] === 장비 목록 ===');
|
||||
print('Equipments: ${testResults['equipments']?['success'] == true ? '✅ 성공' : '❌ 실패'}');
|
||||
if (testResults['equipments']?['error'] != null) {
|
||||
print(' 에러: ${testResults['equipments']['error']}');
|
||||
}
|
||||
if (testResults['equipments']?['sample'] != null) {
|
||||
print(' 샘플: ${testResults['equipments']['sample']}');
|
||||
}
|
||||
|
||||
print('\n[LoginController] === 입고지 ===');
|
||||
print('Warehouses: ${testResults['warehouses']?['success'] == true ? '✅ 성공' : '❌ 실패'}');
|
||||
if (testResults['warehouses']?['error'] != null) {
|
||||
print(' 에러: ${testResults['warehouses']['error']}');
|
||||
}
|
||||
|
||||
print('\n[LoginController] === 회사 ===');
|
||||
print('Companies: ${testResults['companies']?['success'] == true ? '✅ 성공' : '❌ 실패'}');
|
||||
if (testResults['companies']?['error'] != null) {
|
||||
print(' 에러: ${testResults['companies']['error']}');
|
||||
}
|
||||
|
||||
print('\n[LoginController] ========== Health Test 완료 ==========\n');
|
||||
} catch (e, stackTrace) {
|
||||
print('[LoginController] Health Test 오류: $e');
|
||||
print('[LoginController] Stack Trace: $stackTrace');
|
||||
}
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
return true;
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
_errorMessage = '로그인 중 오류가 발생했습니다.';
|
||||
} catch (e, stackTrace) {
|
||||
print('[LoginController] 로그인 예외 발생: $e');
|
||||
print('[LoginController] 스택 트레이스: $stackTrace');
|
||||
_errorMessage = '로그인 중 오류가 발생했습니다: ${e.toString()}';
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
return false;
|
||||
|
||||
@@ -130,7 +130,7 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: ShadcnTheme.gradient1.withOpacity(0.3),
|
||||
color: ShadcnTheme.gradient1.withValues(alpha: 0.3),
|
||||
blurRadius: 20,
|
||||
offset: const Offset(0, 10),
|
||||
),
|
||||
@@ -186,10 +186,10 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
||||
),
|
||||
const SizedBox(height: ShadcnTheme.spacing8),
|
||||
|
||||
// 사용자명 입력
|
||||
// 아이디/이메일 입력
|
||||
ShadcnInput(
|
||||
label: '사용자명',
|
||||
placeholder: '사용자명을 입력하세요',
|
||||
label: '아이디/이메일',
|
||||
placeholder: '아이디 또는 이메일을 입력하세요',
|
||||
controller: controller.idController,
|
||||
prefixIcon: const Icon(Icons.person_outline),
|
||||
keyboardType: TextInputType.text,
|
||||
@@ -229,10 +229,10 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
||||
padding: const EdgeInsets.all(ShadcnTheme.spacing3),
|
||||
margin: const EdgeInsets.only(bottom: ShadcnTheme.spacing4),
|
||||
decoration: BoxDecoration(
|
||||
color: ShadcnTheme.destructive.withOpacity(0.1),
|
||||
color: ShadcnTheme.destructive.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(ShadcnTheme.radiusMd),
|
||||
border: Border.all(
|
||||
color: ShadcnTheme.destructive.withOpacity(0.3),
|
||||
color: ShadcnTheme.destructive.withValues(alpha: 0.3),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
@@ -270,8 +270,13 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
||||
// 테스트 로그인 버튼
|
||||
ShadcnButton(
|
||||
text: '테스트 로그인',
|
||||
onPressed: () {
|
||||
widget.onLoginSuccess();
|
||||
onPressed: () async {
|
||||
// 테스트 계정 정보 자동 입력
|
||||
widget.controller.idController.text = 'admin@superport.kr';
|
||||
widget.controller.pwController.text = 'admin123!';
|
||||
|
||||
// 실제 로그인 프로세스 실행
|
||||
await _handleLogin();
|
||||
},
|
||||
variant: ShadcnButtonVariant.secondary,
|
||||
size: ShadcnButtonSize.medium,
|
||||
@@ -298,7 +303,7 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
||||
Container(
|
||||
padding: const EdgeInsets.all(ShadcnTheme.spacing2),
|
||||
decoration: BoxDecoration(
|
||||
color: ShadcnTheme.info.withOpacity(0.1),
|
||||
color: ShadcnTheme.info.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(ShadcnTheme.radiusMd),
|
||||
),
|
||||
child: Icon(
|
||||
@@ -323,7 +328,7 @@ class _LoginViewRedesignState extends State<LoginViewRedesign>
|
||||
Text(
|
||||
'Copyright 2025 NatureBridgeAI. All rights reserved.',
|
||||
style: ShadcnTheme.bodySmall.copyWith(
|
||||
color: ShadcnTheme.foreground.withOpacity(0.7),
|
||||
color: ShadcnTheme.foreground.withValues(alpha: 0.7),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:superport/data/models/dashboard/overview_stats.dart';
|
||||
import 'package:superport/data/models/dashboard/recent_activity.dart';
|
||||
import 'package:superport/services/dashboard_service.dart';
|
||||
import 'package:superport/screens/common/theme_tailwind.dart';
|
||||
import 'package:superport/core/utils/debug_logger.dart';
|
||||
|
||||
// 대시보드(Overview) 화면의 상태 및 비즈니스 로직을 담답하는 컨트롤러
|
||||
class OverviewController extends ChangeNotifier {
|
||||
@@ -110,14 +111,23 @@ class OverviewController extends ChangeNotifier {
|
||||
_equipmentStatusError = null;
|
||||
notifyListeners();
|
||||
|
||||
DebugLogger.log('장비 상태 분포 로드 시작', tag: 'DASHBOARD');
|
||||
|
||||
final result = await _dashboardService.getEquipmentStatusDistribution();
|
||||
|
||||
result.fold(
|
||||
(failure) {
|
||||
_equipmentStatusError = failure.message;
|
||||
DebugLogger.logError('장비 상태 분포 로드 실패', error: failure.message);
|
||||
},
|
||||
(status) {
|
||||
_equipmentStatus = status;
|
||||
DebugLogger.log('장비 상태 분포 로드 성공', tag: 'DASHBOARD', data: {
|
||||
'available': status.available,
|
||||
'inUse': status.inUse,
|
||||
'maintenance': status.maintenance,
|
||||
'disposed': status.disposed,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:get_it/get_it.dart';
|
||||
import 'package:superport/models/warehouse_location_model.dart';
|
||||
import 'package:superport/services/warehouse_service.dart';
|
||||
import 'package:superport/services/mock_data_service.dart';
|
||||
import 'package:superport/core/errors/failures.dart';
|
||||
|
||||
/// 입고지 리스트 상태 및 CRUD만 담당하는 컨트롤러 클래스 (SRP 적용)
|
||||
/// UI, 네비게이션, 다이얼로그 등은 포함하지 않음
|
||||
@@ -45,6 +46,8 @@ class WarehouseLocationListController extends ChangeNotifier {
|
||||
Future<void> loadWarehouseLocations({bool isInitialLoad = true}) async {
|
||||
if (_isLoading) return;
|
||||
|
||||
print('[WarehouseLocationListController] loadWarehouseLocations started - isInitialLoad: $isInitialLoad');
|
||||
|
||||
_isLoading = true;
|
||||
_error = null;
|
||||
|
||||
@@ -59,12 +62,15 @@ class WarehouseLocationListController extends ChangeNotifier {
|
||||
try {
|
||||
if (useApi && GetIt.instance.isRegistered<WarehouseService>()) {
|
||||
// API 사용
|
||||
print('[WarehouseLocationListController] Using API to fetch warehouse locations');
|
||||
final fetchedLocations = await _warehouseService.getWarehouseLocations(
|
||||
page: _currentPage,
|
||||
perPage: _pageSize,
|
||||
isActive: _isActive,
|
||||
);
|
||||
|
||||
print('[WarehouseLocationListController] API returned ${fetchedLocations.length} locations');
|
||||
|
||||
if (isInitialLoad) {
|
||||
_warehouseLocations = fetchedLocations;
|
||||
} else {
|
||||
@@ -77,9 +83,12 @@ class WarehouseLocationListController extends ChangeNotifier {
|
||||
_total = await _warehouseService.getTotalWarehouseLocations(
|
||||
isActive: _isActive,
|
||||
);
|
||||
print('[WarehouseLocationListController] Total warehouse locations: $_total');
|
||||
} else {
|
||||
// Mock 데이터 사용
|
||||
print('[WarehouseLocationListController] Using Mock data');
|
||||
final allLocations = mockDataService?.getAllWarehouseLocations() ?? [];
|
||||
print('[WarehouseLocationListController] Mock data has ${allLocations.length} locations');
|
||||
|
||||
// 필터링 적용
|
||||
var filtered = allLocations;
|
||||
@@ -113,12 +122,21 @@ class WarehouseLocationListController extends ChangeNotifier {
|
||||
}
|
||||
|
||||
_applySearchFilter();
|
||||
print('[WarehouseLocationListController] After filtering: ${_filteredLocations.length} locations shown');
|
||||
|
||||
if (!isInitialLoad) {
|
||||
_currentPage++;
|
||||
}
|
||||
} catch (e) {
|
||||
_error = e.toString();
|
||||
} catch (e, stackTrace) {
|
||||
print('[WarehouseLocationListController] Error loading warehouse locations: $e');
|
||||
print('[WarehouseLocationListController] Error type: ${e.runtimeType}');
|
||||
print('[WarehouseLocationListController] Stack trace: $stackTrace');
|
||||
|
||||
if (e is ServerFailure) {
|
||||
_error = e.message;
|
||||
} else {
|
||||
_error = '오류 발생: ${e.toString()}';
|
||||
}
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:superport/models/warehouse_location_model.dart';
|
||||
import 'package:superport/screens/common/theme_shadcn.dart';
|
||||
import 'package:superport/screens/common/components/shadcn_components.dart';
|
||||
@@ -16,23 +17,30 @@ class WarehouseLocationListRedesign extends StatefulWidget {
|
||||
|
||||
class _WarehouseLocationListRedesignState
|
||||
extends State<WarehouseLocationListRedesign> {
|
||||
final WarehouseLocationListController _controller =
|
||||
WarehouseLocationListController();
|
||||
late WarehouseLocationListController _controller;
|
||||
int _currentPage = 1;
|
||||
final int _pageSize = 10;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller.loadWarehouseLocations();
|
||||
_controller = WarehouseLocationListController();
|
||||
// 초기 데이터 로드
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_controller.loadWarehouseLocations();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// 리스트 새로고침
|
||||
void _reload() {
|
||||
setState(() {
|
||||
_controller.loadWarehouseLocations();
|
||||
_currentPage = 1;
|
||||
});
|
||||
_currentPage = 1;
|
||||
_controller.loadWarehouseLocations();
|
||||
}
|
||||
|
||||
/// 입고지 추가 폼으로 이동
|
||||
@@ -72,11 +80,9 @@ class _WarehouseLocationListRedesignState
|
||||
child: const Text('취소'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_controller.deleteWarehouseLocation(id);
|
||||
});
|
||||
onPressed: () async {
|
||||
Navigator.of(context).pop();
|
||||
await _controller.deleteWarehouseLocation(id);
|
||||
},
|
||||
child: const Text('삭제'),
|
||||
),
|
||||
@@ -87,17 +93,52 @@ class _WarehouseLocationListRedesignState
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final int totalCount = _controller.warehouseLocations.length;
|
||||
final int startIndex = (_currentPage - 1) * _pageSize;
|
||||
final int endIndex =
|
||||
(startIndex + _pageSize) > totalCount
|
||||
? totalCount
|
||||
: (startIndex + _pageSize);
|
||||
final List<WarehouseLocation> pagedLocations = _controller
|
||||
.warehouseLocations
|
||||
.sublist(startIndex, endIndex);
|
||||
return ChangeNotifierProvider.value(
|
||||
value: _controller,
|
||||
child: Consumer<WarehouseLocationListController>(
|
||||
builder: (context, controller, child) {
|
||||
// 로딩 중일 때
|
||||
if (controller.isLoading && controller.warehouseLocations.isEmpty) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
return SingleChildScrollView(
|
||||
// 에러가 있을 때
|
||||
if (controller.error != null) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.error_outline, size: 48, color: Colors.red),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
'오류가 발생했습니다',
|
||||
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text(controller.error!),
|
||||
SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: _reload,
|
||||
child: Text('다시 시도'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final int totalCount = controller.warehouseLocations.length;
|
||||
final int startIndex = (_currentPage - 1) * _pageSize;
|
||||
final int endIndex =
|
||||
(startIndex + _pageSize) > totalCount
|
||||
? totalCount
|
||||
: (startIndex + _pageSize);
|
||||
final List<WarehouseLocation> pagedLocations = totalCount > 0 && startIndex < totalCount
|
||||
? controller.warehouseLocations.sublist(startIndex, endIndex)
|
||||
: [];
|
||||
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(ShadcnTheme.spacing6),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -106,7 +147,17 @@ class _WarehouseLocationListRedesignState
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('총 ${totalCount}개 입고지', style: ShadcnTheme.bodyMuted),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('총 ${totalCount}개 입고지', style: ShadcnTheme.bodyMuted),
|
||||
if (controller.searchQuery.isNotEmpty)
|
||||
Text(
|
||||
'"${controller.searchQuery}" 검색 결과',
|
||||
style: ShadcnTheme.bodyMuted.copyWith(fontSize: 12),
|
||||
),
|
||||
],
|
||||
),
|
||||
ShadcnButton(
|
||||
text: '입고지 추가',
|
||||
onPressed: _navigateToAdd,
|
||||
@@ -168,12 +219,27 @@ class _WarehouseLocationListRedesignState
|
||||
),
|
||||
|
||||
// 테이블 데이터
|
||||
if (pagedLocations.isEmpty)
|
||||
if (controller.isLoading)
|
||||
Container(
|
||||
padding: const EdgeInsets.all(ShadcnTheme.spacing8),
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
CircularProgressIndicator(),
|
||||
SizedBox(height: 8),
|
||||
Text('데이터를 불러오는 중...', style: ShadcnTheme.bodyMuted),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
else if (pagedLocations.isEmpty)
|
||||
Container(
|
||||
padding: const EdgeInsets.all(ShadcnTheme.spacing8),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'등록된 입고지가 없습니다.',
|
||||
controller.searchQuery.isNotEmpty
|
||||
? '검색 결과가 없습니다.'
|
||||
: '등록된 입고지가 없습니다.',
|
||||
style: ShadcnTheme.bodyMuted,
|
||||
),
|
||||
),
|
||||
@@ -306,7 +372,10 @@ class _WarehouseLocationListRedesignState
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,8 @@ import 'package:superport/data/models/auth/login_response.dart';
|
||||
import 'package:superport/data/models/auth/logout_request.dart';
|
||||
import 'package:superport/data/models/auth/refresh_token_request.dart';
|
||||
import 'package:superport/data/models/auth/token_response.dart';
|
||||
import 'package:superport/core/config/environment.dart' as env;
|
||||
import 'package:superport/services/mock_data_service.dart';
|
||||
|
||||
abstract class AuthService {
|
||||
Future<Either<Failure, LoginResponse>> login(LoginRequest request);
|
||||
@@ -45,6 +47,16 @@ class AuthServiceImpl implements AuthService {
|
||||
@override
|
||||
Future<Either<Failure, LoginResponse>> login(LoginRequest request) async {
|
||||
try {
|
||||
print('[AuthService] login 시작 - useApi: ${env.Environment.useApi}');
|
||||
|
||||
// Mock 모드일 때
|
||||
if (!env.Environment.useApi) {
|
||||
print('[AuthService] Mock 모드로 로그인 처리');
|
||||
return _mockLogin(request);
|
||||
}
|
||||
|
||||
// API 모드일 때
|
||||
print('[AuthService] API 모드로 로그인 처리');
|
||||
final result = await _authRemoteDataSource.login(request);
|
||||
|
||||
return await result.fold(
|
||||
@@ -68,6 +80,61 @@ class AuthServiceImpl implements AuthService {
|
||||
return Left(ServerFailure(message: '로그인 처리 중 오류가 발생했습니다.'));
|
||||
}
|
||||
}
|
||||
|
||||
Future<Either<Failure, LoginResponse>> _mockLogin(LoginRequest request) async {
|
||||
try {
|
||||
// Mock 데이터 서비스의 사용자 확인
|
||||
final mockService = MockDataService();
|
||||
final users = mockService.getAllUsers();
|
||||
|
||||
// 사용자 찾기
|
||||
final user = users.firstWhere(
|
||||
(u) => u.email == request.email,
|
||||
orElse: () => throw Exception('사용자를 찾을 수 없습니다.'),
|
||||
);
|
||||
|
||||
// 비밀번호 확인 (Mock에서는 간단하게 처리)
|
||||
if (request.password != 'admin123' && request.password != 'password123') {
|
||||
return Left(AuthenticationFailure(message: '잘못된 비밀번호입니다.'));
|
||||
}
|
||||
|
||||
// Mock 토큰 생성
|
||||
final mockAccessToken = 'mock_access_token_${DateTime.now().millisecondsSinceEpoch}';
|
||||
final mockRefreshToken = 'mock_refresh_token_${DateTime.now().millisecondsSinceEpoch}';
|
||||
|
||||
// Mock 로그인 응답 생성
|
||||
final loginResponse = LoginResponse(
|
||||
accessToken: mockAccessToken,
|
||||
refreshToken: mockRefreshToken,
|
||||
tokenType: 'Bearer',
|
||||
expiresIn: 3600,
|
||||
user: AuthUser(
|
||||
id: user.id ?? 0,
|
||||
username: user.username ?? '',
|
||||
email: user.email ?? request.email ?? '',
|
||||
name: user.name,
|
||||
role: user.role,
|
||||
),
|
||||
);
|
||||
|
||||
// 토큰 및 사용자 정보 저장
|
||||
await _saveTokens(
|
||||
loginResponse.accessToken,
|
||||
loginResponse.refreshToken,
|
||||
loginResponse.expiresIn,
|
||||
);
|
||||
await _saveUser(loginResponse.user);
|
||||
|
||||
// 인증 상태 변경 알림
|
||||
_authStateController.add(true);
|
||||
|
||||
print('[AuthService] Mock 로그인 성공');
|
||||
return Right(loginResponse);
|
||||
} catch (e) {
|
||||
print('[AuthService] Mock 로그인 실패: $e');
|
||||
return Left(ServerFailure(message: '로그인 처리 중 오류가 발생했습니다.'));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, void>> logout() async {
|
||||
@@ -164,8 +231,17 @@ class AuthServiceImpl implements AuthService {
|
||||
@override
|
||||
Future<String?> getAccessToken() async {
|
||||
try {
|
||||
return await _secureStorage.read(key: _accessTokenKey);
|
||||
final token = await _secureStorage.read(key: _accessTokenKey);
|
||||
if (token != null && token.length > 20) {
|
||||
print('[AuthService] getAccessToken: Found (${token.substring(0, 20)}...)');
|
||||
} else if (token != null) {
|
||||
print('[AuthService] getAccessToken: Found (${token})');
|
||||
} else {
|
||||
print('[AuthService] getAccessToken: Not found');
|
||||
}
|
||||
return token;
|
||||
} catch (e) {
|
||||
print('[AuthService] getAccessToken error: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -199,6 +275,13 @@ class AuthServiceImpl implements AuthService {
|
||||
String refreshToken,
|
||||
int expiresIn,
|
||||
) async {
|
||||
print('[AuthService] Saving tokens...');
|
||||
final accessTokenPreview = accessToken.length > 20 ? '${accessToken.substring(0, 20)}...' : accessToken;
|
||||
final refreshTokenPreview = refreshToken.length > 20 ? '${refreshToken.substring(0, 20)}...' : refreshToken;
|
||||
print('[AuthService] Access token: $accessTokenPreview');
|
||||
print('[AuthService] Refresh token: $refreshTokenPreview');
|
||||
print('[AuthService] Expires in: $expiresIn seconds');
|
||||
|
||||
await _secureStorage.write(key: _accessTokenKey, value: accessToken);
|
||||
await _secureStorage.write(key: _refreshTokenKey, value: refreshToken);
|
||||
|
||||
@@ -208,6 +291,8 @@ class AuthServiceImpl implements AuthService {
|
||||
key: _tokenExpiryKey,
|
||||
value: expiry.toIso8601String(),
|
||||
);
|
||||
|
||||
print('[AuthService] Tokens saved successfully');
|
||||
}
|
||||
|
||||
Future<void> _saveUser(AuthUser user) async {
|
||||
|
||||
@@ -31,8 +31,11 @@ class CompanyService {
|
||||
|
||||
return response.items.map((dto) => _convertListDtoToCompany(dto)).toList();
|
||||
} on ApiException catch (e) {
|
||||
print('[CompanyService] ApiException: ${e.message}');
|
||||
throw ServerFailure(message: e.message);
|
||||
} catch (e) {
|
||||
} catch (e, stackTrace) {
|
||||
print('[CompanyService] Error loading companies: $e');
|
||||
print('[CompanyService] Stack trace: $stackTrace');
|
||||
throw ServerFailure(message: 'Failed to fetch company list: $e');
|
||||
}
|
||||
}
|
||||
@@ -263,6 +266,7 @@ class CompanyService {
|
||||
contactName: dto.contactName,
|
||||
contactPhone: dto.contactPhone,
|
||||
companyTypes: [CompanyType.customer], // 기본값, 실제로는 API에서 받아와야 함
|
||||
branches: [], // branches는 빈 배열로 초기화
|
||||
);
|
||||
}
|
||||
|
||||
@@ -282,6 +286,7 @@ class CompanyService {
|
||||
contactEmail: dto.contactEmail,
|
||||
companyTypes: companyTypes.isEmpty ? [CompanyType.customer] : companyTypes,
|
||||
remark: dto.remark,
|
||||
branches: [], // branches는 빈 배열로 초기화
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,31 @@ import 'package:superport/models/equipment_unified_model.dart';
|
||||
class EquipmentService {
|
||||
final EquipmentRemoteDataSource _remoteDataSource = GetIt.instance<EquipmentRemoteDataSource>();
|
||||
|
||||
// 장비 목록 조회 (DTO 형태로 반환하여 status 정보 유지)
|
||||
Future<List<EquipmentListDto>> getEquipmentsWithStatus({
|
||||
int page = 1,
|
||||
int perPage = 20,
|
||||
String? status,
|
||||
int? companyId,
|
||||
int? warehouseLocationId,
|
||||
}) async {
|
||||
try {
|
||||
final dtoList = await _remoteDataSource.getEquipments(
|
||||
page: page,
|
||||
perPage: perPage,
|
||||
status: status,
|
||||
companyId: companyId,
|
||||
warehouseLocationId: warehouseLocationId,
|
||||
);
|
||||
|
||||
return dtoList;
|
||||
} on ServerException catch (e) {
|
||||
throw ServerFailure(message: e.message);
|
||||
} catch (e) {
|
||||
throw ServerFailure(message: 'Failed to fetch equipment list: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 장비 목록 조회
|
||||
Future<List<Equipment>> getEquipments({
|
||||
int page = 1,
|
||||
|
||||
99
lib/services/health_check_service.dart
Normal file
99
lib/services/health_check_service.dart
Normal file
@@ -0,0 +1,99 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import '../core/config/environment.dart';
|
||||
import '../data/datasources/remote/api_client.dart';
|
||||
|
||||
/// API 헬스체크 테스트를 위한 서비스
|
||||
class HealthCheckService {
|
||||
final ApiClient _apiClient;
|
||||
|
||||
HealthCheckService({ApiClient? apiClient})
|
||||
: _apiClient = apiClient ?? ApiClient();
|
||||
|
||||
/// 헬스체크 API 호출
|
||||
Future<Map<String, dynamic>> checkHealth() async {
|
||||
try {
|
||||
print('=== 헬스체크 시작 ===');
|
||||
print('API Base URL: ${Environment.apiBaseUrl}');
|
||||
print('Full URL: ${Environment.apiBaseUrl}/health');
|
||||
|
||||
final response = await _apiClient.get('/health');
|
||||
|
||||
print('응답 상태 코드: ${response.statusCode}');
|
||||
print('응답 데이터: ${response.data}');
|
||||
|
||||
return {
|
||||
'success': true,
|
||||
'data': response.data,
|
||||
'statusCode': response.statusCode,
|
||||
};
|
||||
} on DioException catch (e) {
|
||||
print('=== DioException 발생 ===');
|
||||
print('에러 타입: ${e.type}');
|
||||
print('에러 메시지: ${e.message}');
|
||||
print('에러 응답: ${e.response?.data}');
|
||||
print('에러 상태 코드: ${e.response?.statusCode}');
|
||||
|
||||
// CORS 에러인지 확인
|
||||
if (e.type == DioExceptionType.connectionError ||
|
||||
e.type == DioExceptionType.unknown) {
|
||||
print('⚠️ CORS 또는 네트워크 연결 문제일 가능성이 있습니다.');
|
||||
}
|
||||
|
||||
return {
|
||||
'success': false,
|
||||
'error': e.message ?? '알 수 없는 에러',
|
||||
'errorType': e.type.toString(),
|
||||
'statusCode': e.response?.statusCode,
|
||||
'responseData': e.response?.data,
|
||||
};
|
||||
} catch (e) {
|
||||
print('=== 일반 에러 발생 ===');
|
||||
print('에러: $e');
|
||||
|
||||
return {
|
||||
'success': false,
|
||||
'error': e.toString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// 직접 Dio로 테스트 (인터셉터 없이)
|
||||
Future<Map<String, dynamic>> checkHealthDirect() async {
|
||||
try {
|
||||
print('=== 직접 Dio 헬스체크 시작 ===');
|
||||
|
||||
final dio = Dio(BaseOptions(
|
||||
baseUrl: Environment.apiBaseUrl,
|
||||
connectTimeout: const Duration(seconds: 10),
|
||||
receiveTimeout: const Duration(seconds: 10),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
));
|
||||
|
||||
// 로깅 인터셉터만 추가
|
||||
dio.interceptors.add(LogInterceptor(
|
||||
requestBody: true,
|
||||
responseBody: true,
|
||||
requestHeader: true,
|
||||
responseHeader: true,
|
||||
error: true,
|
||||
));
|
||||
|
||||
final response = await dio.get('/health');
|
||||
|
||||
return {
|
||||
'success': true,
|
||||
'data': response.data,
|
||||
'statusCode': response.statusCode,
|
||||
};
|
||||
} catch (e) {
|
||||
print('직접 Dio 에러: $e');
|
||||
return {
|
||||
'success': false,
|
||||
'error': e.toString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
193
lib/services/health_test_service.dart
Normal file
193
lib/services/health_test_service.dart
Normal file
@@ -0,0 +1,193 @@
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:superport/services/auth_service.dart';
|
||||
import 'package:superport/services/dashboard_service.dart';
|
||||
import 'package:superport/services/equipment_service.dart';
|
||||
import 'package:superport/services/warehouse_service.dart';
|
||||
import 'package:superport/services/company_service.dart';
|
||||
import 'package:superport/core/utils/debug_logger.dart';
|
||||
import 'package:superport/models/company_model.dart';
|
||||
|
||||
/// API 상태 테스트 서비스
|
||||
class HealthTestService {
|
||||
final AuthService _authService = GetIt.instance<AuthService>();
|
||||
final DashboardService _dashboardService = GetIt.instance<DashboardService>();
|
||||
final EquipmentService _equipmentService = GetIt.instance<EquipmentService>();
|
||||
final WarehouseService _warehouseService = GetIt.instance<WarehouseService>();
|
||||
final CompanyService _companyService = GetIt.instance<CompanyService>();
|
||||
|
||||
/// 모든 주요 API 엔드포인트 테스트
|
||||
Future<Map<String, dynamic>> checkAllEndpoints() async {
|
||||
final results = <String, dynamic>{};
|
||||
|
||||
// 1. 인증 상태 확인
|
||||
try {
|
||||
final isAuthenticated = await _authService.isLoggedIn();
|
||||
final accessToken = await _authService.getAccessToken();
|
||||
final refreshToken = await _authService.getRefreshToken();
|
||||
|
||||
results['auth'] = {
|
||||
'success': isAuthenticated,
|
||||
'accessToken': accessToken != null,
|
||||
'refreshToken': refreshToken != null,
|
||||
};
|
||||
DebugLogger.log('인증 상태', tag: 'HEALTH_TEST', data: results['auth']);
|
||||
} catch (e) {
|
||||
results['auth'] = {'success': false, 'error': e.toString()};
|
||||
}
|
||||
|
||||
// 2. 대시보드 API 체크
|
||||
try {
|
||||
DebugLogger.log('대시보드 API 체크 시작', tag: 'HEALTH_TEST');
|
||||
|
||||
// Overview Stats
|
||||
final statsResult = await _dashboardService.getOverviewStats();
|
||||
results['dashboard_stats'] = {
|
||||
'success': statsResult.isRight(),
|
||||
'error': statsResult.fold((l) => l.message, (r) => null),
|
||||
'data': statsResult.fold((l) => null, (r) => {
|
||||
'totalEquipment': r.totalEquipment,
|
||||
'totalCompanies': r.totalCompanies,
|
||||
'totalUsers': r.totalUsers,
|
||||
'availableEquipment': r.availableEquipment,
|
||||
}),
|
||||
};
|
||||
|
||||
// Equipment Status Distribution
|
||||
final statusResult = await _dashboardService.getEquipmentStatusDistribution();
|
||||
results['equipment_status_distribution'] = {
|
||||
'success': statusResult.isRight(),
|
||||
'error': statusResult.fold((l) => l.message, (r) => null),
|
||||
'data': statusResult.fold((l) => null, (r) => {
|
||||
'available': r.available,
|
||||
'inUse': r.inUse,
|
||||
'maintenance': r.maintenance,
|
||||
'disposed': r.disposed,
|
||||
}),
|
||||
};
|
||||
|
||||
DebugLogger.log('대시보드 API 결과', tag: 'HEALTH_TEST', data: results);
|
||||
} catch (e) {
|
||||
results['dashboard'] = {'success': false, 'error': e.toString()};
|
||||
}
|
||||
|
||||
// 3. 장비 API 체크
|
||||
try {
|
||||
DebugLogger.log('장비 API 체크 시작', tag: 'HEALTH_TEST');
|
||||
|
||||
final equipments = await _equipmentService.getEquipments(page: 1, perPage: 5);
|
||||
results['equipments'] = {
|
||||
'success': true,
|
||||
'count': equipments.length,
|
||||
'sample': equipments.take(2).map((e) => {
|
||||
'id': e.id,
|
||||
'name': e.name,
|
||||
'manufacturer': e.manufacturer,
|
||||
'category': e.category,
|
||||
}).toList(),
|
||||
};
|
||||
|
||||
DebugLogger.log('장비 API 결과', tag: 'HEALTH_TEST', data: results['equipments']);
|
||||
} catch (e) {
|
||||
results['equipments'] = {'success': false, 'error': e.toString()};
|
||||
}
|
||||
|
||||
// 4. 입고지 API 체크
|
||||
try {
|
||||
DebugLogger.log('입고지 API 체크 시작', tag: 'HEALTH_TEST');
|
||||
|
||||
final warehouses = await _warehouseService.getWarehouseLocations();
|
||||
results['warehouses'] = {
|
||||
'success': true,
|
||||
'count': warehouses.length,
|
||||
'sample': warehouses.take(2).map((w) => {
|
||||
'id': w.id,
|
||||
'name': w.name,
|
||||
'address': w.address.toString(),
|
||||
}).toList(),
|
||||
};
|
||||
|
||||
DebugLogger.log('입고지 API 결과', tag: 'HEALTH_TEST', data: results['warehouses']);
|
||||
} catch (e) {
|
||||
results['warehouses'] = {'success': false, 'error': e.toString()};
|
||||
}
|
||||
|
||||
// 5. 회사 API 체크
|
||||
try {
|
||||
DebugLogger.log('회사 API 체크 시작', tag: 'HEALTH_TEST');
|
||||
|
||||
final companies = await _companyService.getCompanies();
|
||||
results['companies'] = {
|
||||
'success': true,
|
||||
'count': companies.length,
|
||||
'sample': companies.take(2).map((c) => {
|
||||
'id': c.id,
|
||||
'name': c.name,
|
||||
'companyTypes': c.companyTypes.map((t) => companyTypeToString(t)).toList(),
|
||||
}).toList(),
|
||||
};
|
||||
|
||||
DebugLogger.log('회사 API 결과', tag: 'HEALTH_TEST', data: results['companies']);
|
||||
} catch (e) {
|
||||
results['companies'] = {'success': false, 'error': e.toString()};
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// 특정 엔드포인트만 체크
|
||||
Future<Map<String, dynamic>> checkEndpoint(String endpoint) async {
|
||||
switch (endpoint) {
|
||||
case 'dashboard':
|
||||
final result = await _dashboardService.getOverviewStats();
|
||||
return {
|
||||
'success': result.isRight(),
|
||||
'error': result.fold((l) => l.message, (r) => null),
|
||||
'data': result.fold((l) => null, (r) => r.toJson()),
|
||||
};
|
||||
|
||||
case 'equipments':
|
||||
try {
|
||||
final equipments = await _equipmentService.getEquipments(page: 1, perPage: 10);
|
||||
return {
|
||||
'success': true,
|
||||
'count': equipments.length,
|
||||
'data': equipments.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
} catch (e) {
|
||||
return {'success': false, 'error': e.toString()};
|
||||
}
|
||||
|
||||
case 'warehouses':
|
||||
try {
|
||||
final warehouses = await _warehouseService.getWarehouseLocations();
|
||||
return {
|
||||
'success': true,
|
||||
'count': warehouses.length,
|
||||
'data': warehouses.map((w) => {
|
||||
'id': w.id,
|
||||
'name': w.name,
|
||||
'address': w.address.toString(),
|
||||
'remark': w.remark,
|
||||
}).toList(),
|
||||
};
|
||||
} catch (e) {
|
||||
return {'success': false, 'error': e.toString()};
|
||||
}
|
||||
|
||||
case 'companies':
|
||||
try {
|
||||
final companies = await _companyService.getCompanies();
|
||||
return {
|
||||
'success': true,
|
||||
'count': companies.length,
|
||||
'data': companies.map((c) => c.toJson()).toList(),
|
||||
};
|
||||
} catch (e) {
|
||||
return {'success': false, 'error': e.toString()};
|
||||
}
|
||||
|
||||
default:
|
||||
return {'success': false, 'error': 'Unknown endpoint: $endpoint'};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -273,6 +273,7 @@ class MockDataService {
|
||||
companyId: 1,
|
||||
name: '홍길동',
|
||||
role: 'S', // 관리자
|
||||
email: 'admin@superport.com',
|
||||
),
|
||||
);
|
||||
|
||||
@@ -281,6 +282,7 @@ class MockDataService {
|
||||
companyId: 1,
|
||||
name: '김철수',
|
||||
role: 'M', // 멤버
|
||||
email: 'kim.cs@samsung.com',
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -26,8 +26,11 @@ class WarehouseService {
|
||||
|
||||
return response.items.map((dto) => _convertDtoToWarehouseLocation(dto)).toList();
|
||||
} on ApiException catch (e) {
|
||||
print('[WarehouseService] ApiException: ${e.message}');
|
||||
throw ServerFailure(message: e.message);
|
||||
} catch (e) {
|
||||
} catch (e, stackTrace) {
|
||||
print('[WarehouseService] Error loading warehouse locations: $e');
|
||||
print('[WarehouseService] Stack trace: $stackTrace');
|
||||
throw ServerFailure(message: '창고 위치 목록을 불러오는 데 실패했습니다: $e');
|
||||
}
|
||||
}
|
||||
@@ -149,29 +152,30 @@ class WarehouseService {
|
||||
|
||||
// DTO를 Flutter 모델로 변환
|
||||
WarehouseLocation _convertDtoToWarehouseLocation(WarehouseLocationDto dto) {
|
||||
// 주소 조합
|
||||
final addressParts = <String>[];
|
||||
if (dto.address != null && dto.address!.isNotEmpty) {
|
||||
addressParts.add(dto.address!);
|
||||
}
|
||||
if (dto.city != null && dto.city!.isNotEmpty) {
|
||||
addressParts.add(dto.city!);
|
||||
}
|
||||
if (dto.state != null && dto.state!.isNotEmpty) {
|
||||
addressParts.add(dto.state!);
|
||||
}
|
||||
|
||||
// API에 주소 정보가 없으므로 기본값 사용
|
||||
final address = Address(
|
||||
zipCode: dto.postalCode ?? '',
|
||||
region: dto.city ?? '',
|
||||
detailAddress: addressParts.join(' '),
|
||||
detailAddress: dto.address ?? '주소 정보 없음',
|
||||
);
|
||||
|
||||
// 담당자 정보 조합
|
||||
final remarkParts = <String>[];
|
||||
if (dto.code != null) {
|
||||
remarkParts.add('코드: ${dto.code}');
|
||||
}
|
||||
if (dto.managerName != null) {
|
||||
remarkParts.add('담당자: ${dto.managerName}');
|
||||
}
|
||||
if (dto.managerPhone != null) {
|
||||
remarkParts.add('연락처: ${dto.managerPhone}');
|
||||
}
|
||||
|
||||
return WarehouseLocation(
|
||||
id: dto.id,
|
||||
name: dto.name,
|
||||
address: address,
|
||||
remark: dto.managerName != null ? '담당자: ${dto.managerName}' : null,
|
||||
remark: remarkParts.isNotEmpty ? remarkParts.join(', ') : null,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user