feat: adopt material 3 theme and billing adjustments
This commit is contained in:
@@ -5,6 +5,7 @@ import '../utils/logger.dart';
|
||||
import '../temp/test_sms_data.dart';
|
||||
import '../services/subscription_url_matcher.dart';
|
||||
import '../utils/platform_helper.dart';
|
||||
import '../utils/business_day_util.dart';
|
||||
|
||||
class SmsScanner {
|
||||
final SmsQuery _query = SmsQuery();
|
||||
@@ -56,7 +57,61 @@ class SmsScanner {
|
||||
|
||||
// 2회 이상 반복된 서비스만 구독으로 간주
|
||||
if (entry.value.length >= 2) {
|
||||
final serviceSms = entry.value[0]; // 가장 최근 SMS 사용
|
||||
// 결제일 패턴 유추를 위해 최근 2개의 결제일을 사용
|
||||
final messages = [...entry.value];
|
||||
messages.sort((a, b) {
|
||||
final da = DateTime.tryParse(a['previousPaymentDate'] ?? '') ??
|
||||
DateTime(1970);
|
||||
final db = DateTime.tryParse(b['previousPaymentDate'] ?? '') ??
|
||||
DateTime(1970);
|
||||
return db.compareTo(da); // desc
|
||||
});
|
||||
|
||||
final mostRecent = messages.first;
|
||||
DateTime? recentDate =
|
||||
DateTime.tryParse(mostRecent['previousPaymentDate'] ?? '');
|
||||
DateTime? prevDate = messages.length > 1
|
||||
? DateTime.tryParse(messages[1]['previousPaymentDate'] ?? '')
|
||||
: null;
|
||||
|
||||
// 기본 결제 일자(일단위) 추정: 가장 최근 결제의 일자
|
||||
int baseDay = recentDate?.day ?? DateTime.now().day;
|
||||
|
||||
// 이전 결제가 주말 이월로 보이는 패턴인지 검사하여 baseDay 보정
|
||||
if (recentDate != null && prevDate != null) {
|
||||
final candidate = DateTime(prevDate.year, prevDate.month, baseDay);
|
||||
if (BusinessDayUtil.isWeekend(candidate)) {
|
||||
final diff = prevDate.difference(candidate).inDays;
|
||||
if (diff >= 1 && diff <= 3) {
|
||||
// 예: 12일(토)→14일(월)
|
||||
baseDay = baseDay; // 유지
|
||||
} else {
|
||||
// 차이가 크면 이전 달의 일자를 채택
|
||||
baseDay = prevDate.day;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 다음 결제일 계산: 기준 일자를 바탕으로 다음 달 또는 이번 달로 설정 후 영업일 보정
|
||||
final DateTime now = DateTime.now();
|
||||
int year = now.year;
|
||||
int month = now.month;
|
||||
if (now.day >= baseDay) {
|
||||
month += 1;
|
||||
if (month > 12) {
|
||||
month = 1;
|
||||
year += 1;
|
||||
}
|
||||
}
|
||||
final dim = BusinessDayUtil.daysInMonth(year, month);
|
||||
final day = baseDay.clamp(1, dim);
|
||||
DateTime nextBilling = DateTime(year, month, day);
|
||||
nextBilling = BusinessDayUtil.nextBusinessDay(nextBilling);
|
||||
|
||||
// 가장 최근 SMS 맵에 override 값으로 주입
|
||||
final serviceSms = Map<String, dynamic>.from(mostRecent);
|
||||
serviceSms['overrideNextBillingDate'] = nextBilling.toIso8601String();
|
||||
|
||||
final subscription = _parseSms(serviceSms, entry.value.length);
|
||||
if (subscription != null) {
|
||||
Log.i(
|
||||
@@ -134,7 +189,11 @@ class SmsScanner {
|
||||
}
|
||||
|
||||
DateTime? nextBillingDate;
|
||||
if (nextBillingDateStr != null) {
|
||||
// 외부에서 계산된 다음 결제일이 있으면 우선 사용
|
||||
final overrideNext = sms['overrideNextBillingDate'] as String?;
|
||||
if (overrideNext != null) {
|
||||
nextBillingDate = DateTime.tryParse(overrideNext);
|
||||
} else if (nextBillingDateStr != null) {
|
||||
nextBillingDate = DateTime.tryParse(nextBillingDateStr);
|
||||
}
|
||||
|
||||
@@ -146,8 +205,12 @@ class SmsScanner {
|
||||
|
||||
// 결제일 계산 로직 추가 - 미래 날짜가 아니면 조정
|
||||
DateTime adjustedNextBillingDate = _calculateNextBillingDate(
|
||||
nextBillingDate ?? DateTime.now().add(const Duration(days: 30)),
|
||||
billingCycle);
|
||||
nextBillingDate ?? DateTime.now().add(const Duration(days: 30)),
|
||||
billingCycle,
|
||||
);
|
||||
// 주말/공휴일 보정
|
||||
adjustedNextBillingDate =
|
||||
BusinessDayUtil.nextBusinessDay(adjustedNextBillingDate);
|
||||
|
||||
return SubscriptionModel(
|
||||
id: DateTime.now().millisecondsSinceEpoch.toString(),
|
||||
@@ -190,7 +253,9 @@ class SmsScanner {
|
||||
}
|
||||
}
|
||||
|
||||
return DateTime(year, month, billingDate.day);
|
||||
final dim = BusinessDayUtil.daysInMonth(year, month);
|
||||
final day = billingDate.day.clamp(1, dim);
|
||||
return DateTime(year, month, day);
|
||||
} else if (billingCycle == 'yearly') {
|
||||
// 올해의 결제일이 지났는지 확인
|
||||
final thisYearBilling =
|
||||
|
||||
Reference in New Issue
Block a user