financial page with bank data
All checks were successful
Deploy / build-deploy (push) Successful in 1m48s

This commit is contained in:
Jorijn van der Graaf 2026-08-14 04:14:13 +02:00
commit 33c68c2f44
11 changed files with 394 additions and 87 deletions

View file

@ -179,9 +179,9 @@ std::string SerialiseFinancials(const Financials& f) {
return std::format(
R"({{"as_of":"{}",)"
R"("donations":{{"count":{},"total_minor":{}}},)"
R"("recurring":{},"single":{}}})",
R"("expenses":{}}})",
JsonEscapeF(f.asOf), f.donationCount, f.donationsMinor,
categories(f.recurring), categories(f.single));
categories(f.expenses));
}
// ── crypto ────────────────────────────────────────────────────────────
@ -378,12 +378,12 @@ FinancialRules LoadFinancialRules(std::string_view json) {
// silently become a published category.
const bool hasCriterion = !r.iban.empty() || !r.descriptionContains.empty()
|| !r.account.empty();
const bool knownGroup = r.group == "donations" || r.group == "recurring"
|| r.group == "single" || r.group == "ignore";
const bool knownGroup = r.group == "donations" || r.group == "expense"
|| r.group == "ignore";
if (!hasCriterion || !knownGroup) continue;
// Expense groups need a label to render under; donations and
// ignore do not have one.
if ((r.group == "recurring" || r.group == "single") && r.label.empty()) continue;
// An expense needs a label to render under; donations and ignore
// do not have one.
if (r.group == "expense" && r.label.empty()) continue;
out.rules.push_back(std::move(r));
}
}
@ -444,10 +444,8 @@ void ApplyMutation(Financials& fin, const MutationClass& cls, const BankMutation
// The count follows money in, not money out: a refunded donation
// reduces the total without pretending the gift never happened.
if (m.amountMinor > 0) ++fin.donationCount;
} else if (cls.group == "recurring") {
bump(fin.recurring);
} else if (cls.group == "single") {
bump(fin.single);
} else if (cls.group == "expense") {
bump(fin.expenses);
} else {
return; // "ignore" and unclassified touch nothing
}