Merge pull request 'Feature/allocation amount prefill' (#16) from feature/allocation-amount-prefill into dev

Reviewed-on: https://git.hiabuto.net/C3MA/CCMA/pulls/16
Reviewed-by: Matcha <20+matcha@noreply.git.hiabuto.net>
This commit is contained in:
Marcel Peterkau
2026-08-14 23:24:56 +00:00
2 changed files with 31 additions and 4 deletions
+2 -1
View File
@@ -26,7 +26,8 @@
"Der Hausmeister meldet eine überfällige Forderung nicht mehr doppelt als eigene Überfällig- und Mahnungsmeldung; bei Mitgliedern mit aktivem Lastschriftmandat erscheint statt einer Mahnung ein Hinweis, dass der Lastschrifteinzug geprüft werden sollte.",
"Die Spaltenbreiten in den Tabellen für Forderungen, Zahlungen, Spenden und Hausmeister-Vorgänge sind jetzt einheitlich: Datum-, Betrag- und Statusspalten haben eine feste Breite, nur die abschließende Beschreibungs- bzw. Referenzspalte passt sich dynamisch an die Fensterbreite an.",
"Die Chronik im Mitgliedsfenster nimmt standardmäßig ein Drittel der Fensterbreite ein.",
"Der GnuCash-Import öffnet sich mit 80 % der Bildschirmgröße und erlaubt die Mehrfachauswahl von Buchungen per Klick, Strg+Klick oder Umschalt+Klick; Buchungen, die einer bereits vorhandenen Zahlung entsprechen, können beim Import übersprungen oder mit der Beschreibung aus GnuCash aktualisiert werden."
"Der GnuCash-Import öffnet sich mit 80 % der Bildschirmgröße und erlaubt die Mehrfachauswahl von Buchungen per Klick, Strg+Klick oder Umschalt+Klick; Buchungen, die einer bereits vorhandenen Zahlung entsprechen, können beim Import übersprungen oder mit der Beschreibung aus GnuCash aktualisiert werden.",
"Beim Anklicken einer noch nicht zugeordneten Forderung oder Spende im Zahlungsfenster wird der Betrag automatisch mit dem sinnvollen Vorschlag vorausgefüllt."
]
},
{
+29 -3
View File
@@ -42,12 +42,14 @@ class _AllocationTable:
claim_allocations: dict[str, str],
donation_allocations: dict[str, str],
on_change: Callable[[], None],
get_payment_amount: Callable[[], Decimal],
):
self.repository = repository
self.member_id = member_id
self.claim_allocations = claim_allocations
self.donation_allocations = donation_allocations
self.on_change = on_change
self.get_payment_amount = get_payment_amount
# Fixed snapshot of what this payment already covered when the dialog opened.
# Capacities are computed against this baseline rather than the live, editable
# dicts above -- otherwise "Maximal zuordenbar" would inflate every time the
@@ -182,7 +184,23 @@ class _AllocationTable:
return
kind, target_id = self._target(selected[0])
allocations = self.claim_allocations if kind == "claim" else self.donation_allocations
self.amount_var.set(allocations.get(target_id, "0.00"))
current = allocations.get(target_id)
if current:
# Already allocated: show the existing amount so it can be reviewed/edited.
self.amount_var.set(current)
return
# Not yet allocated: suggest whichever is smaller -- what this claim/donation
# still needs, or what's left of the payment -- so the common case is just
# "click the row, then Zuordnung setzen".
capacity = (self.claim_capacity if kind == "claim" else self.donation_capacity)[target_id]
free = max(self._payment_amount() - self.total_allocated(), Decimal("0"))
self.amount_var.set(money_text(min(capacity, free)))
def _payment_amount(self) -> Decimal:
try:
return self.get_payment_amount()
except ValueError:
return Decimal("0")
def _set(self) -> None:
selected = self.tree.selection()
@@ -314,6 +332,7 @@ class PaymentCreateDialog(tk.Toplevel):
claim_allocations=self.claim_allocations,
donation_allocations=self.donation_allocations,
on_change=self._refresh_totals,
get_payment_amount=self._current_payment_amount,
)
ttk.Label(self, textvariable=self.total_var, style="Mono.TLabel").grid(
@@ -328,10 +347,13 @@ class PaymentCreateDialog(tk.Toplevel):
).pack(side="left")
self._refresh_totals()
def _current_payment_amount(self) -> Decimal:
return decimal_value(self.variables["amount"].get())
def _refresh_totals(self) -> None:
allocated = self.allocation_table.total_allocated() if self.allocation_table else Decimal("0")
try:
payment_amount = decimal_value(self.variables["amount"].get())
payment_amount = self._current_payment_amount()
free = payment_amount - allocated
self.total_var.set(f"Zugeordnet: {money_text(allocated)} EUR · Frei: {money_text(free)} EUR")
except (ValueError, InvalidOperation):
@@ -448,6 +470,7 @@ class PaymentEditDialog(tk.Toplevel):
claim_allocations=self.claim_allocations,
donation_allocations=self.donation_allocations,
on_change=self._refresh_totals,
get_payment_amount=self._current_payment_amount,
)
ttk.Label(self, textvariable=self.total_var, style="Mono.TLabel").grid(
@@ -474,10 +497,13 @@ class PaymentEditDialog(tk.Toplevel):
except tk.TclError:
return
def _current_payment_amount(self) -> Decimal:
return decimal_value(self.variables["amount"].get())
def _refresh_totals(self) -> None:
allocated = self.allocation_table.total_allocated() if self.allocation_table else Decimal("0")
try:
payment_amount = decimal_value(self.variables["amount"].get())
payment_amount = self._current_payment_amount()
free = payment_amount - allocated
self.total_var.set(
f"Zugeordnet: {money_text(allocated)} EUR · Frei: {money_text(free)} EUR"