Add asset records, claims, and credit workflows

This commit is contained in:
Marcel Peterkau
2026-06-26 23:03:06 +02:00
parent 30b6d253b2
commit d1dab793a6
11 changed files with 2060 additions and 10 deletions
+71 -1
View File
@@ -8,7 +8,7 @@ from tkinter import messagebox, ttk
from ccma.domain.contributions import CLAIM_STATUS_LABELS, claim_status, claim_total, money_text
from ccma.domain.dates import age_label, date_input_hint, format_date_for_display
from ccma.domain.models import MEMBERSHIP_STATUS_LABELS as STATUS_LABELS
from ccma.domain.models import ASSET_STATUS_LABELS, MEMBERSHIP_STATUS_LABELS as STATUS_LABELS
from ccma.domain.models import Event
from ccma.storage.repository import MemberRepository, RepositoryError
from ccma.ui.document_dialog import DocumentTemplateDialog
@@ -46,6 +46,9 @@ class MemberTab(ttk.Frame):
on_close: Callable[[], None],
on_changed: Callable[[], None],
on_open_claim: Callable[[str, str], None],
on_open_assets: Callable[[], None],
on_open_asset: Callable[[str], None],
on_return_asset: Callable[[str], None],
):
super().__init__(master, padding=12)
self.repository = repository
@@ -53,6 +56,9 @@ class MemberTab(ttk.Frame):
self.on_close = on_close
self.on_changed = on_changed
self.on_open_claim = on_open_claim
self.on_open_assets = on_open_assets
self.on_open_asset = on_open_asset
self.on_return_asset = on_return_asset
self.member = repository.get_member(member_id)
self.variables: dict[str, tk.Variable] = {}
self.notes_text: tk.Text | None = None
@@ -108,11 +114,13 @@ class MemberTab(ttk.Frame):
address_tab = ttk.Frame(notebook, padding=16)
banking_tab = ttk.Frame(notebook, padding=16)
contribution_tab = ttk.Frame(notebook, padding=16)
assets_tab = ttk.Frame(notebook, padding=16)
documents_tab = ttk.Frame(notebook, padding=16)
notebook.add(data_tab, text="Stammdaten")
notebook.add(address_tab, text="Anschrift")
notebook.add(banking_tab, text="Bank / SEPA")
notebook.add(contribution_tab, text="Forderungen")
notebook.add(assets_tab, text="Assets")
notebook.add(documents_tab, text="Dokumente")
fields = [
@@ -228,6 +236,40 @@ class MemberTab(ttk.Frame):
self.claims.bind("<Double-1>", lambda _event: self._open_selected_claim())
self.claims.bind("<Return>", lambda _event: self._open_selected_claim())
assets_tab.columnconfigure(0, weight=1)
assets_tab.rowconfigure(1, weight=1)
self.assets_summary = tk.StringVar()
ttk.Label(assets_tab, textvariable=self.assets_summary, style="Mono.TLabel").grid(
row=0, column=0, sticky="w", pady=(0, 10)
)
self.assets_tree = ttk.Treeview(
assets_tab,
columns=("label", "category", "inventory_number", "status"),
show="headings",
)
for key, title, width in (
("label", "Bezeichnung", 240),
("category", "Kategorie", 140),
("inventory_number", "Inventarnummer", 140),
("status", "Status", 140),
):
self.assets_tree.heading(key, text=title)
self.assets_tree.column(key, width=width, anchor="w")
self.assets_tree.grid(row=1, column=0, sticky="nsew")
self.assets_tree.bind("<Double-1>", lambda _event: self._open_selected_asset())
self.assets_tree.bind("<Return>", lambda _event: self._open_selected_asset())
asset_actions = ttk.Frame(assets_tab)
asset_actions.grid(row=2, column=0, sticky="e", pady=(10, 0))
ttk.Button(asset_actions, text="Inventar öffnen", command=self.on_open_assets).pack(
side="left", padx=(0, 8)
)
ttk.Button(asset_actions, text="Asset öffnen", command=self._open_selected_asset).pack(
side="left", padx=(0, 8)
)
ttk.Button(asset_actions, text="Ausgewähltes Asset zurücknehmen", command=self._return_selected_asset).pack(
side="left"
)
documents_tab.columnconfigure(0, weight=1)
documents_tab.rowconfigure(1, weight=1)
document_buttons = ttk.Frame(documents_tab)
@@ -311,6 +353,7 @@ class MemberTab(ttk.Frame):
self.notes_text.insert("1.0", self.member.notes)
self._refresh_events()
self._refresh_contributions()
self._refresh_assets()
self._refresh_documents()
def _refresh_events(self) -> None:
@@ -399,6 +442,23 @@ class MemberTab(ttk.Frame):
),
)
def _refresh_assets(self) -> None:
self.assets_tree.delete(*self.assets_tree.get_children())
assets = self.repository.list_member_assets(self.member_id)
self.assets_summary.set(f"{len(assets)} ausgegebene Assets")
for asset in assets:
self.assets_tree.insert(
"",
"end",
iid=asset.asset_id,
values=(
asset.label,
asset.category,
asset.inventory_number,
ASSET_STATUS_LABELS.get(asset.status, asset.status),
),
)
def _save(self) -> None:
for key, variable in self.variables.items():
raw_value = variable.get()
@@ -434,6 +494,16 @@ class MemberTab(ttk.Frame):
path = self.repository.members_root / self.member_id / "files"
self._open_path(path)
def _return_selected_asset(self) -> None:
selected = self.assets_tree.selection()
if selected:
self.on_return_asset(selected[0])
def _open_selected_asset(self) -> None:
selected = self.assets_tree.selection()
if selected:
self.on_open_asset(selected[0])
def _open_selected_document(self) -> None:
selected = self.documents.selection()
if selected and selected[0] in self.document_paths: