mirror of
https://git.hiabuto.net/C3MA/CCMA.git
synced 2026-08-25 06:55:17 +02:00
Import payments per member from a GnuCash file
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>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
e7a18b5cde
commit
745e634a8b
@@ -7,6 +7,7 @@ from decimal import Decimal
|
||||
from pathlib import Path
|
||||
from tkinter import messagebox, ttk
|
||||
|
||||
from ccma.config import AppConfig
|
||||
from ccma.domain.contributions import (
|
||||
CLAIM_STATUS_LABELS,
|
||||
DONATION_STATUS_LABELS,
|
||||
@@ -30,6 +31,7 @@ from ccma.ui.donation_dialog import (
|
||||
DonationPaymentDialog,
|
||||
)
|
||||
from ccma.ui.file_open import open_path
|
||||
from ccma.ui.gnucash_import_dialog import GnuCashImportDialog
|
||||
from ccma.ui.labels import display_label, storage_key
|
||||
from ccma.ui.messages import MessageAction, MessageBannerList, TabMessage
|
||||
from ccma.ui.payment_dialog import PaymentCreateDialog, PaymentEditDialog
|
||||
@@ -62,6 +64,7 @@ class MemberTab(ttk.Frame):
|
||||
master: tk.Misc,
|
||||
repository: MemberRepository,
|
||||
member_id: str,
|
||||
config: AppConfig,
|
||||
on_close: Callable[[], None],
|
||||
on_changed: Callable[[], None],
|
||||
on_open_claim: Callable[[str, str], None],
|
||||
@@ -72,6 +75,7 @@ class MemberTab(ttk.Frame):
|
||||
super().__init__(master, padding=12)
|
||||
self.repository = repository
|
||||
self.member_id = member_id
|
||||
self.config = config
|
||||
self.on_close = on_close
|
||||
self.on_changed = on_changed
|
||||
self.on_open_claim = on_open_claim
|
||||
@@ -325,6 +329,10 @@ class MemberTab(ttk.Frame):
|
||||
ttk.Button(payment_actions, text="Zahlung löschen", command=self._delete_selected_payment).pack(
|
||||
side="left"
|
||||
)
|
||||
ttk.Separator(payment_actions, orient="vertical").pack(side="left", fill="y", padx=10)
|
||||
ttk.Button(
|
||||
payment_actions, text="Zahlungen importieren", command=self._import_payments
|
||||
).pack(side="left")
|
||||
|
||||
donations_tab.columnconfigure(0, weight=1)
|
||||
donations_tab.rowconfigure(1, weight=1)
|
||||
@@ -733,6 +741,11 @@ class MemberTab(ttk.Frame):
|
||||
def _create_payment(self) -> None:
|
||||
PaymentCreateDialog(self, self.repository, self.member_id, self._payment_changed)
|
||||
|
||||
def _import_payments(self) -> None:
|
||||
GnuCashImportDialog(
|
||||
self, self.repository, self.member_id, self.config, self._payment_changed
|
||||
)
|
||||
|
||||
def _payment_changed(self) -> None:
|
||||
self.refresh()
|
||||
self.on_changed()
|
||||
|
||||
Reference in New Issue
Block a user