Selecting bookings to import now uses the Treeview's own multi-selection
(click, Ctrl+click, Shift+click for ranges) instead of a dedicated
checkbox column that had to be clicked precisely -- more standard and
much faster for marking many rows at once.
Bookings matching an existing payment's date+amount are no longer
blocked from selection; they're still flagged (red row, "Bereits
vorhanden"). If any selected booking is such a duplicate, importing now
asks whether to skip those or instead adopt the booking's description
onto the already-recorded payment. That relabeling is handled by a new
repository.update_payment_reference, which only touches the reference
and gnucash_transaction_id fields, leaving date/amount/allocations
untouched.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Hausmeister: reorder columns to Level, Fällig, Vorgang, Details. Level,
Fällig and Vorgang get a fixed width; only Details stretches to fill the
remaining space.
GnuCash-Import dialog: opens at 80% of the current monitor's size
(monitor-aware via the existing screeninfo-based helpers, not just the
raw/virtual screen size) instead of a fixed 960x640. In its booking
table, Import, Datum, Betrag and Status get a fixed width; Beschreibung
and Memo share the remaining space.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Forderungen: reorder columns to Fällig, Betrag, Status, Forderung.
Zahlungen and Spenden already had the requested order. Across all three
tables, the date/amount-like columns now share one fixed width, the
status column is a third wider (it tends to hold longer label text),
and only the trailing description/reference column stretches to fill
the remaining space.
The Chronik pane now defaults to a third of the member view's width
instead of three fifths, matching the other panes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The claim-status and reminder-due housekeeper rules used to run
independently, so once a claim was both overdue and past its dunning
grace period, both a generic "überfällig" task and a "Mahnung fällig"
task showed up for the same problem. Rules can't see each other's
output, so the fix is to give reminder-due sole ownership of the whole
overdue lifecycle: a plain overdue notice during the grace period, then
either the dunning escalation or a fallback overdue notice (dunning
hold active, or waiting between reminder levels) -- never both at once.
claim-status now only handles claims that aren't overdue yet ("bald
fällig").
Members with an active SEPA mandate get a new sepa_debit_overdue finding
instead of the postal dunning escalation once a claim is past its grace
period, since mailing a Mahnung makes no sense for a member who pays by
direct debit -- the board needs to check/retrigger the debit instead.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
AppConfig now keeps a gnucash_last_accounts map (file path -> account
guid). When the import dialog opens a file it already knows, it
auto-selects whichever account was picked last time for that specific
file instead of always defaulting to the first one alphabetically;
picking a different account updates and persists the mapping right away.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a "Zahlungen importieren" button to the member Zahlungen tab that opens
a dedicated window: point it at a GnuCash file (plain or gzip-compressed
XML, defaults to the file configured in Optionen), pick one of its accounts,
and narrow the account's bookings down with a description-contains filter
and an optional date range.
Each matching booking gets a checkbox to mark it for import as a payment.
Before anything is ticked, bookings are cross-checked against this member's
existing payments by date + amount; a match is highlighted and its checkbox
is refused, so re-importing the same statement can't create a duplicate
payment. Only bookings with a positive amount on the selected account are
offered, since those are the ones that make sense as an incoming payment.
Parsing lives in ccma.services.gnucash_import, independent of the UI, and
is covered by tests against a synthetic GnuCash XML fixture (plain and
gzip-compressed) -- no gnucash/piecash dependency needed since the native
file format is just XML.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Show a claim or donation in the Zahlung anlegen/bearbeiten allocation
table only if it still has an open balance, or is already linked to this
payment -- fully settled ones no longer clutter the list.
Visibility is decided from a snapshot taken when the dialog opens (or
when a donation is created inline), not recomputed live, so a row never
disappears just because the user temporarily unassigned it with
"Zuordnung lösen" -- it stays there to add back with "Zuordnung setzen"
until the dialog is saved.
Also fixes a capacity display bug this surfaced: "Maximal zuordenbar"
was computed by mixing the persisted claim/donation balance with the
live, currently-edited allocation amount, so it inflated every time the
amount was changed during a session. It's now computed against a fixed
baseline captured at dialog open, so it stays accurate throughout.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Recording a payment previously meant saving it bare, then separately
opening a claim to allocate money to it. Zahlung anlegen now lists a
member's open claims and donations right in the same dialog with a
select + amount field to assign parts of the payment on the spot, and a
"Neue Spende anlegen" button to create a donation inline and allocate to
it immediately -- covering members who pay more than the membership fee
in one transfer.
Shared the same allocation table in the existing payment-edit dialog so
editing a payment shows and preserves donation allocations too; before
this, saving an edited payment silently dropped any donation allocation
because update_payment only round-tripped claim allocations.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claims could previously only be cancelled (stornieren), which blocks once a
payment is allocated. Add a hard delete that releases any linked
payments/credits back to being unallocated instead of destroying them.
Payments could only be created from within a claim, forcing immediate
allocation. Add a bare payment creation flow in the Zahlungen tab so
incoming transfers can be logged first and allocated later.
Add a per-member Spenden tab (donations, backed by a new donations list on
ContributionData) so amounts paid beyond the membership fee can be tracked
and existing free payments allocated to them.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>