// 테스트용 SMS 데이터 // 실제 SMS를 스캔하는 대신 이 테스트 데이터를 사용합니다. class TestSmsData { static List> getTestData() { // 현재 날짜 기준으로 미래 날짜 계산 final now = DateTime.now(); final nextMonth = DateTime(now.year, now.month + 1, now.day); final prevMonth = DateTime(now.year, now.month - 1, now.day); final String formattedNextMonth = '${nextMonth.year}-${nextMonth.month.toString().padLeft(2, '0')}-${nextMonth.day.toString().padLeft(2, '0')}'; final String formattedPrevMonth = '${prevMonth.year}-${prevMonth.month.toString().padLeft(2, '0')}-${prevMonth.day.toString().padLeft(2, '0')}'; final String formattedNow = '${now.year}-${now.month.toString().padLeft(2, '0')}-${now.day.toString().padLeft(2, '0')}'; // 1년 후 날짜 계산 (연간 구독용) final nextYear = DateTime(now.year + 1, now.month, now.day); final prevYear = DateTime(now.year - 1, now.month, now.day); final String formattedNextYear = '${nextYear.year}-${nextYear.month.toString().padLeft(2, '0')}-${nextYear.day.toString().padLeft(2, '0')}'; final String formattedPrevYear = '${prevYear.year}-${prevYear.month.toString().padLeft(2, '0')}-${prevYear.day.toString().padLeft(2, '0')}'; // 기본 테스트 데이터 정의 final baseTestData = [ { 'serviceName': '넷플릭스', 'monthlyCost': 9900.0, 'billingCycle': '월간', 'nextBillingDate': formattedNextMonth, 'isRecurring': true, 'repeatCount': 5, 'sender': '15885000', 'messageDate': formattedNow, 'previousPaymentDate': formattedPrevMonth, 'message': '[넷플릭스] 정기 결제 완료: 9,900원이 결제되었습니다. 다음 결제일: ${nextMonth.day}일' }, { 'serviceName': '유튜브프리미엄', 'monthlyCost': 14900.0, 'billingCycle': '월간', 'nextBillingDate': '${DateTime(now.year, now.month + 1, 20).year}-${DateTime(now.year, now.month + 1, 20).month.toString().padLeft(2, '0')}-20', 'isRecurring': true, 'repeatCount': 7, 'sender': '15882018', 'messageDate': formattedNow, 'previousPaymentDate': '${DateTime(now.year, now.month - 1, 20).year}-${DateTime(now.year, now.month - 1, 20).month.toString().padLeft(2, '0')}-20', 'message': '[Google] 유튜브프리미엄 구독료 14,900원이 자동 결제되었습니다.' }, { 'serviceName': '디즈니플러스', 'monthlyCost': 8900.0, 'billingCycle': '월간', 'nextBillingDate': '${DateTime(now.year, now.month + 1, 10).year}-${DateTime(now.year, now.month + 1, 10).month.toString().padLeft(2, '0')}-10', 'isRecurring': true, 'repeatCount': 3, 'sender': '15771055', 'messageDate': formattedNow, 'previousPaymentDate': '${DateTime(now.year, now.month - 1, 10).year}-${DateTime(now.year, now.month - 1, 10).month.toString().padLeft(2, '0')}-10', 'message': '[디즈니플러스] 8,900원 정기결제가 완료되었습니다.' }, { 'serviceName': '애플 iCloud', 'monthlyCost': 2900.0, 'billingCycle': '월간', 'nextBillingDate': '${DateTime(now.year, now.month + 1, 5).year}-${DateTime(now.year, now.month + 1, 5).month.toString().padLeft(2, '0')}-05', 'isRecurring': true, 'repeatCount': 12, 'sender': '0802011900', 'messageDate': formattedNow, 'previousPaymentDate': '${DateTime(now.year, now.month - 1, 5).year}-${DateTime(now.year, now.month - 1, 5).month.toString().padLeft(2, '0')}-05', 'message': 'Apple: iCloud+ 50GB 월 구독(₩2,900)이 자동으로 갱신되었습니다.' }, { 'serviceName': '멜론', 'monthlyCost': 10900.0, 'billingCycle': '월간', 'nextBillingDate': '${DateTime(now.year, now.month + 1, 22).year}-${DateTime(now.year, now.month + 1, 22).month.toString().padLeft(2, '0')}-22', 'isRecurring': true, 'repeatCount': 4, 'sender': '16001950', 'messageDate': formattedNow, 'previousPaymentDate': '${DateTime(now.year, now.month - 1, 22).year}-${DateTime(now.year, now.month - 1, 22).month.toString().padLeft(2, '0')}-22', 'message': '[멜론] 스트리밍클럽 정기결제 10,900원 완료. 다음 결제일: ${DateTime(now.year, now.month + 1, 22).day}일' }, { 'serviceName': 'Microsoft 365', 'monthlyCost': 12800.0, 'billingCycle': '연간', 'nextBillingDate': formattedNextYear, 'isRecurring': true, 'repeatCount': 2, 'sender': '0801136532', 'messageDate': formattedNow, 'previousPaymentDate': formattedPrevYear, 'message': '[Microsoft] Microsoft 365 연간 구독료 12,800원이 결제되었습니다.' }, { 'serviceName': '웨이브', 'monthlyCost': 7900.0, 'billingCycle': '월간', 'nextBillingDate': '${DateTime(now.year, now.month + 1, 15).year}-${DateTime(now.year, now.month + 1, 15).month.toString().padLeft(2, '0')}-15', 'isRecurring': true, 'repeatCount': 2, 'sender': '1800-1234', 'messageDate': formattedNow, 'previousPaymentDate': '${DateTime(now.year, now.month - 1, 15).year}-${DateTime(now.year, now.month - 1, 15).month.toString().padLeft(2, '0')}-15', 'message': '[웨이브] 구독료 7,900원이 정기결제 되었습니다. 감사합니다.' }, // 달러 결제 서비스 추가 { 'serviceName': 'Netflix US', 'monthlyCost': 9.99, 'billingCycle': '월간', 'nextBillingDate': '${DateTime(now.year, now.month + 1, 7).year}-${DateTime(now.year, now.month + 1, 7).month.toString().padLeft(2, '0')}-07', 'isRecurring': true, 'repeatCount': 6, 'sender': '334455', 'messageDate': formattedNow, 'previousPaymentDate': '${DateTime(now.year, now.month - 1, 7).year}-${DateTime(now.year, now.month - 1, 7).month.toString().padLeft(2, '0')}-07', 'message': '[Netflix US] Your subscription has been renewed. \$9.99 has been charged to your account. Next billing date: ${DateTime(now.year, now.month + 1, 7).day}' }, { 'serviceName': 'Spotify Premium', 'monthlyCost': 10.99, 'billingCycle': '월간', 'nextBillingDate': '${DateTime(now.year, now.month + 1, 12).year}-${DateTime(now.year, now.month + 1, 12).month.toString().padLeft(2, '0')}-12', 'isRecurring': true, 'repeatCount': 4, 'sender': '223344', 'messageDate': formattedNow, 'previousPaymentDate': '${DateTime(now.year, now.month - 1, 12).year}-${DateTime(now.year, now.month - 1, 12).month.toString().padLeft(2, '0')}-12', 'message': '[Spotify] Your premium subscription was automatically renewed. USD 10.99 charged to your card. Your next payment will be on ${DateTime(now.year, now.month + 1, 12).day}' }, { 'serviceName': 'GitHub Pro', 'monthlyCost': 4.00, 'billingCycle': '월간', 'nextBillingDate': '${DateTime(now.year, now.month + 1, 3).year}-${DateTime(now.year, now.month + 1, 3).month.toString().padLeft(2, '0')}-03', 'isRecurring': true, 'repeatCount': 8, 'sender': '112233', 'messageDate': formattedNow, 'previousPaymentDate': '${DateTime(now.year, now.month - 1, 3).year}-${DateTime(now.year, now.month - 1, 3).month.toString().padLeft(2, '0')}-03', 'message': '[GitHub] Your Pro plan has been renewed for \$4.00 USD. View your receipt at github.com/receipt. Next bill on ${DateTime(now.year, now.month + 1, 3).day}' }, ]; // 각 서비스별로 여러 개의 메시지 생성 (그룹화를 위해) final List> resultData = []; // 각 기본 데이터를 복제하여 여러 개의 메시지 생성 for (final service in baseTestData) { // 원본 메시지 추가 resultData.add(Map.from(service)); // 각 서비스에 대해 과거 메시지 추가 (2개 이상의 메시지가 있어야 반복 구독으로 인식) for (int i = 2; i <= (service['repeatCount'] as int); i++) { // 과거 결제일 계산 final pastMonth = DateTime( now.year, now.month - i + 1 > 0 ? now.month - i + 1 : now.month - i + 1 + 12, service['billingCycle'] == '월간' ? now.day : now.day); final formattedPastMonth = '${pastMonth.year}-${pastMonth.month.toString().padLeft(2, '0')}-${pastMonth.day.toString().padLeft(2, '0')}'; // 과거 메시지 생성 final pastMessage = Map.from(service); pastMessage['messageDate'] = formattedPastMonth; pastMessage['nextBillingDate'] = service['previousPaymentDate']; // 이전 메시지의 다음 결제일은 현재의 이전 결제일 // 과거 메시지의 이전 결제일 계산 final veryPastMonth = DateTime( pastMonth.year, pastMonth.month - 1 > 0 ? pastMonth.month - 1 : pastMonth.month - 1 + 12, pastMonth.day); final formattedVeryPastMonth = '${veryPastMonth.year}-${veryPastMonth.month.toString().padLeft(2, '0')}-${veryPastMonth.day.toString().padLeft(2, '0')}'; pastMessage['previousPaymentDate'] = formattedVeryPastMonth; resultData.add(pastMessage); } } print('TestSmsData: 생성된 테스트 메시지 수: ${resultData.length}개'); return resultData; } // 최근 6개월의 월간 지출 데이터를 반환하는 메서드 static List> getMonthlyExpenseData() { final now = DateTime.now(); final List> monthlyData = []; // 기본 구독 서비스와 금액 (현재 구독 중인 서비스) final baseServices = [ {'serviceName': '넷플릭스', 'cost': 9900.0}, {'serviceName': '유튜브프리미엄', 'cost': 14900.0}, {'serviceName': '디즈니플러스', 'cost': 8900.0}, {'serviceName': '애플 iCloud', 'cost': 2900.0}, {'serviceName': '멜론', 'cost': 10900.0}, {'serviceName': '웨이브', 'cost': 7900.0}, {'serviceName': 'Netflix US', 'cost': 9.99}, // 달러 결제 서비스 추가 {'serviceName': 'Spotify Premium', 'cost': 10.99}, // 달러 결제 서비스 추가 {'serviceName': 'GitHub Pro', 'cost': 4.00}, // 달러 결제 서비스 추가 ]; // Microsoft 365는 연간 구독이므로 월별 비용으로 환산 (1년에 1번만 결제) final microsoftMonthlyCost = 12800.0 / 12; // 최근 6개월 데이터 생성 for (int i = 0; i < 6; i++) { // i개월 전 날짜 final targetMonth = DateTime(now.month - i <= 0 ? now.year - 1 : now.year, now.month - i <= 0 ? now.month - i + 12 : now.month - i, 1); // 해당 월의 모든 서비스 데이터 리스트 final List> servicesForMonth = []; // 해당 월의 총 지출 double totalExpense = 0.0; // 기본 서비스 추가 (일부 서비스는 구독 시작 시점이 다를 수 있음) for (final service in baseServices) { // 3개월 전부터 웨이브 구독 시작 if (service['serviceName'] == '웨이브' && i > 3) { continue; } // 2개월 전부터 디즈니플러스 구독 시작 if (service['serviceName'] == '디즈니플러스' && i > 2) { continue; } // 서비스 정보 추가 final Map serviceData = { 'serviceName': service['serviceName'], 'cost': service['cost'], 'date': '${targetMonth.year}-${targetMonth.month.toString().padLeft(2, '0')}-15', }; servicesForMonth.add(serviceData); totalExpense += service['cost'] as double; } // Microsoft 365는 정확히 4개월 전에 결제됨 if (i == 4) { servicesForMonth.add({ 'serviceName': 'Microsoft 365', 'cost': 12800.0, // 연간 결제 비용 'date': '${targetMonth.year}-${targetMonth.month.toString().padLeft(2, '0')}-10', }); totalExpense += 12800.0; } else { // 다른 달에는 월 환산 비용으로 계산 totalExpense += microsoftMonthlyCost; } // 3개월 전에는 Spotify를 일시적으로 구독했다가 해지 if (i == 3) { servicesForMonth.add({ 'serviceName': 'Spotify', 'cost': 10900.0, 'date': '${targetMonth.year}-${targetMonth.month.toString().padLeft(2, '0')}-05', }); totalExpense += 10900.0; } // 5개월 전과 4개월 전에는 쿠팡플레이를 구독했다가 해지 if (i == 4 || i == 5) { servicesForMonth.add({ 'serviceName': '쿠팡플레이', 'cost': 4990.0, 'date': '${targetMonth.year}-${targetMonth.month.toString().padLeft(2, '0')}-18', }); totalExpense += 4990.0; } // 월별 총 지출 데이터 추가 monthlyData.add({ 'year': targetMonth.year, 'month': targetMonth.month, 'totalExpense': totalExpense, 'services': servicesForMonth, 'monthName': _getMonthName(targetMonth.month), }); } // 최신 달이 먼저 오도록 reverse return monthlyData.reversed.toList(); } // 월 숫자를 한글 월 이름으로 변환 static String _getMonthName(int month) { const monthNames = [ '1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월' ]; return monthNames[month - 1]; } }