bank tranfer fix
All checks were successful
Deploy / build-deploy (push) Successful in 3m11s

This commit is contained in:
Jorijn van der Graaf 2026-08-20 23:33:50 +02:00
commit aaa7a8ce99
10 changed files with 543 additions and 8 deletions

View file

@ -369,6 +369,37 @@ std::unique_ptr<CreditSource> MakeFileCreditSource(std::filesystem::path path) {
return std::make_unique<FileCreditSource>(std::move(path));
}
bool AppendCreditTo(const std::filesystem::path& creditsPath,
const BankCredit& credit) {
if (credit.id.empty()) return false;
// Deduplicate on the bank's own payment id. bunq retries a callback about
// six times, and a periodic --pull-credits reads an overlapping window, so
// the SAME payment arrives more than once by design. Appending it twice
// would double the money against one reference — enough, on a part-paid
// order, to settle it without the balance ever arriving.
{
std::ifstream in(creditsPath, std::ios::binary);
std::string line;
while (std::getline(in, line)) {
if (line.empty()) continue;
const auto doc = Json::Parse(line);
if (!doc || !doc->IsObject()) continue;
if (doc->Str("id") == credit.id) return false;
}
}
std::ofstream out(creditsPath, std::ios::app | std::ios::binary);
if (!out) {
std::println(std::cerr, "transfer: cannot append to {}", creditsPath.string());
return false;
}
out << std::format(
R"({{"id":"{}","reference":"{}","amount_minor":{},"method":"{}"}})" "\n",
EscT(credit.id), EscT(credit.reference), credit.amountMinor,
EscT(credit.method));
out.flush();
return static_cast<bool>(out);
}
std::optional<int> PullCreditsInto(CreditSource& source,
const std::filesystem::path& creditsPath) {
const std::optional<std::vector<BankCredit>> fresh = source.Recent();