look ahead
This commit is contained in:
@@ -325,6 +325,126 @@ class TxExactTemplate {
|
||||
}
|
||||
}
|
||||
|
||||
/// How a [RecurringTemplate] resolves its projected amount.
|
||||
enum RecurringAmountRule {
|
||||
lastValue,
|
||||
avgLastTxs,
|
||||
labelAvgMonths,
|
||||
}
|
||||
|
||||
/// What a recurring template is anchored to.
|
||||
enum RecurringTemplateSource {
|
||||
transaction,
|
||||
label,
|
||||
}
|
||||
|
||||
/// First-class look-ahead recurring template (manual or auto from marked txs).
|
||||
class RecurringTemplate {
|
||||
const RecurringTemplate({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.dayOfMonth,
|
||||
required this.currency,
|
||||
required this.source,
|
||||
required this.amountRule,
|
||||
this.merchantKey = '',
|
||||
this.sourceTxId,
|
||||
this.labelId,
|
||||
this.avgCount = 5,
|
||||
this.autoFromRecurring = false,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final String name;
|
||||
final int dayOfMonth;
|
||||
final String currency;
|
||||
final RecurringTemplateSource source;
|
||||
final RecurringAmountRule amountRule;
|
||||
final String merchantKey;
|
||||
final String? sourceTxId;
|
||||
final String? labelId;
|
||||
final int avgCount;
|
||||
final bool autoFromRecurring;
|
||||
|
||||
RecurringTemplate copyWith({
|
||||
String? id,
|
||||
String? name,
|
||||
int? dayOfMonth,
|
||||
String? currency,
|
||||
RecurringTemplateSource? source,
|
||||
RecurringAmountRule? amountRule,
|
||||
String? merchantKey,
|
||||
String? sourceTxId,
|
||||
bool clearSourceTxId = false,
|
||||
String? labelId,
|
||||
bool clearLabelId = false,
|
||||
int? avgCount,
|
||||
bool? autoFromRecurring,
|
||||
}) {
|
||||
return RecurringTemplate(
|
||||
id: id ?? this.id,
|
||||
name: name ?? this.name,
|
||||
dayOfMonth: dayOfMonth ?? this.dayOfMonth,
|
||||
currency: currency ?? this.currency,
|
||||
source: source ?? this.source,
|
||||
amountRule: amountRule ?? this.amountRule,
|
||||
merchantKey: merchantKey ?? this.merchantKey,
|
||||
sourceTxId: clearSourceTxId ? null : (sourceTxId ?? this.sourceTxId),
|
||||
labelId: clearLabelId ? null : (labelId ?? this.labelId),
|
||||
avgCount: avgCount ?? this.avgCount,
|
||||
autoFromRecurring: autoFromRecurring ?? this.autoFromRecurring,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'dayOfMonth': dayOfMonth,
|
||||
'currency': currency,
|
||||
'source': source.name,
|
||||
'amountRule': amountRule.name,
|
||||
'merchantKey': merchantKey,
|
||||
'sourceTxId': sourceTxId,
|
||||
'labelId': labelId,
|
||||
'avgCount': avgCount,
|
||||
'autoFromRecurring': autoFromRecurring,
|
||||
};
|
||||
|
||||
factory RecurringTemplate.fromJson(Map<String, dynamic> json) {
|
||||
return RecurringTemplate(
|
||||
id: json['id'] as String? ?? '',
|
||||
name: json['name'] as String? ?? 'Recurring',
|
||||
dayOfMonth: (json['dayOfMonth'] as num?)?.toInt().clamp(1, 28) ?? 1,
|
||||
currency: json['currency'] as String? ?? 'EUR',
|
||||
source: _parseTemplateSource(json['source'] as String?),
|
||||
amountRule: _parseAmountRule(json['amountRule'] as String?),
|
||||
merchantKey: json['merchantKey'] as String? ?? '',
|
||||
sourceTxId: json['sourceTxId'] as String?,
|
||||
labelId: json['labelId'] as String?,
|
||||
avgCount: (json['avgCount'] as num?)?.toInt().clamp(1, 36) ?? 5,
|
||||
autoFromRecurring: json['autoFromRecurring'] as bool? ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
/// Stable id for auto templates linked to a bank transaction.
|
||||
static String autoIdForTx(String txId) => 'auto_${txId.hashCode.toRadixString(16)}';
|
||||
}
|
||||
|
||||
RecurringTemplateSource _parseTemplateSource(String? raw) {
|
||||
return switch (raw) {
|
||||
'label' => RecurringTemplateSource.label,
|
||||
_ => RecurringTemplateSource.transaction,
|
||||
};
|
||||
}
|
||||
|
||||
RecurringAmountRule _parseAmountRule(String? raw) {
|
||||
return switch (raw) {
|
||||
'avgLastTxs' => RecurringAmountRule.avgLastTxs,
|
||||
'labelAvgMonths' => RecurringAmountRule.labelAvgMonths,
|
||||
_ => RecurringAmountRule.lastValue,
|
||||
};
|
||||
}
|
||||
|
||||
/// Strip bank noise so supermarket / POS lines group by merchant stem.
|
||||
///
|
||||
/// Example: `BCK*AH CAMPUS DIEMEN ZUID NLD Pasvolgnr:…` → `ah campus`
|
||||
|
||||
Reference in New Issue
Block a user