Initial commit: SubManager Flutter App
주요 구현 완료 기능: - 구독 관리 (추가/편집/삭제/카테고리 분류) - 이벤트 할인 시스템 (기본값 자동 설정) - SMS 자동 스캔 및 구독 정보 추출 - 알림 시스템 (타임존 처리 안정화) - 환율 변환 지원 (KRW/USD) - 반응형 UI 및 애니메이션 - 다국어 지원 (한국어/영어) 버그 수정: - NotificationService tz.local 초기화 오류 해결 - MainScreenSummaryCard 레이아웃 오버플로우 수정 - 구독 추가 시 LateInitializationError 완전 해결 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
134
lib/services/currency_util.dart
Normal file
134
lib/services/currency_util.dart
Normal file
@@ -0,0 +1,134 @@
|
||||
import 'package:intl/intl.dart';
|
||||
import '../models/subscription_model.dart';
|
||||
import 'exchange_rate_service.dart';
|
||||
|
||||
/// 통화 단위 변환 및 포맷팅을 위한 유틸리티 클래스
|
||||
class CurrencyUtil {
|
||||
static final ExchangeRateService _exchangeRateService = ExchangeRateService();
|
||||
|
||||
/// 구독 목록의 총 월 비용을 계산 (원화로 환산, 이벤트 가격 반영)
|
||||
static Future<double> calculateTotalMonthlyExpense(
|
||||
List<SubscriptionModel> subscriptions) async {
|
||||
double total = 0.0;
|
||||
|
||||
for (var subscription in subscriptions) {
|
||||
// 이벤트 가격이 있으면 currentPrice 사용
|
||||
final price = subscription.currentPrice;
|
||||
|
||||
if (subscription.currency == 'USD') {
|
||||
// USD인 경우 KRW로 변환
|
||||
final krwAmount = await _exchangeRateService
|
||||
.convertUsdToKrw(price);
|
||||
if (krwAmount != null) {
|
||||
total += krwAmount;
|
||||
}
|
||||
} else {
|
||||
// KRW인 경우 그대로 합산
|
||||
total += price;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/// 구독의 월 비용을 표시 형식에 맞게 변환 (원화 변환 포함, 이벤트 가격 반영)
|
||||
static Future<String> formatSubscriptionAmount(
|
||||
SubscriptionModel subscription) async {
|
||||
// 이벤트 가격이 있으면 currentPrice 사용
|
||||
final price = subscription.currentPrice;
|
||||
|
||||
if (subscription.currency == 'USD') {
|
||||
// USD 표시 + 원화 환산 금액
|
||||
final usdFormatted = NumberFormat.currency(
|
||||
locale: 'en_US',
|
||||
symbol: '\$',
|
||||
decimalDigits: 2,
|
||||
).format(price);
|
||||
|
||||
// 원화 환산 금액
|
||||
final krwAmount = await _exchangeRateService
|
||||
.getFormattedKrwAmount(price);
|
||||
|
||||
return '$usdFormatted $krwAmount';
|
||||
} else {
|
||||
// 원화 표시
|
||||
return NumberFormat.currency(
|
||||
locale: 'ko_KR',
|
||||
symbol: '₩',
|
||||
decimalDigits: 0,
|
||||
).format(price);
|
||||
}
|
||||
}
|
||||
|
||||
/// 총액을 원화로 표시
|
||||
static String formatTotalAmount(double amount) {
|
||||
return NumberFormat.currency(
|
||||
locale: 'ko_KR',
|
||||
symbol: '₩',
|
||||
decimalDigits: 0,
|
||||
).format(amount);
|
||||
}
|
||||
|
||||
/// 환율 정보 텍스트 가져오기
|
||||
static Future<String> getExchangeRateInfo() {
|
||||
return _exchangeRateService.getFormattedExchangeRateInfo();
|
||||
}
|
||||
|
||||
/// 이벤트로 인한 총 절약액 계산 (원화로 환산)
|
||||
static Future<double> calculateTotalEventSavings(
|
||||
List<SubscriptionModel> subscriptions) async {
|
||||
double total = 0.0;
|
||||
|
||||
for (var subscription in subscriptions) {
|
||||
if (subscription.isCurrentlyInEvent) {
|
||||
final savings = subscription.eventSavings;
|
||||
|
||||
if (subscription.currency == 'USD') {
|
||||
// USD인 경우 KRW로 변환
|
||||
final krwAmount = await _exchangeRateService
|
||||
.convertUsdToKrw(savings);
|
||||
if (krwAmount != null) {
|
||||
total += krwAmount;
|
||||
}
|
||||
} else {
|
||||
// KRW인 경우 그대로 합산
|
||||
total += savings;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/// 이벤트 절약액을 표시 형식에 맞게 변환
|
||||
static Future<String> formatEventSavings(
|
||||
SubscriptionModel subscription) async {
|
||||
if (!subscription.isCurrentlyInEvent) {
|
||||
return '';
|
||||
}
|
||||
|
||||
final savings = subscription.eventSavings;
|
||||
|
||||
if (subscription.currency == 'USD') {
|
||||
// USD 표시 + 원화 환산 금액
|
||||
final usdFormatted = NumberFormat.currency(
|
||||
locale: 'en_US',
|
||||
symbol: '\$',
|
||||
decimalDigits: 2,
|
||||
).format(savings);
|
||||
|
||||
// 원화 환산 금액
|
||||
final krwAmount = await _exchangeRateService
|
||||
.getFormattedKrwAmount(savings);
|
||||
|
||||
return '$usdFormatted $krwAmount';
|
||||
} else {
|
||||
// 원화 표시
|
||||
return NumberFormat.currency(
|
||||
locale: 'ko_KR',
|
||||
symbol: '₩',
|
||||
decimalDigits: 0,
|
||||
).format(savings);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user