mirror of
https://git.hiabuto.net/C3MA/CCMA.git
synced 2026-08-25 23:15:18 +02:00
feat: extend inventory and administration workflows
This commit is contained in:
+139
-19
@@ -124,13 +124,31 @@ class NewAssetDialog(tk.Toplevel):
|
||||
super().__init__(master)
|
||||
self.repository = repository
|
||||
self.on_created = on_created
|
||||
self.members = repository.list_members()
|
||||
self.member_labels = {
|
||||
f"{member.member_number or member.member_id} · {member.display_name}": member.member_id
|
||||
for member in self.members
|
||||
}
|
||||
self.title("Neues Asset")
|
||||
self.transient(master.winfo_toplevel())
|
||||
self.resizable(False, False)
|
||||
self.variables = {
|
||||
name: tk.StringVar()
|
||||
for name in ("label", "category", "inventory_number", "serial_number", "deposit_amount_default")
|
||||
for name in (
|
||||
"label",
|
||||
"category",
|
||||
"inventory_number",
|
||||
"serial_number",
|
||||
"deposit_amount_default",
|
||||
"location",
|
||||
"handed_over_at",
|
||||
"condition",
|
||||
"estimated_value",
|
||||
"owner_name",
|
||||
)
|
||||
}
|
||||
self.owner_type_var = tk.StringVar(value="VEREIN")
|
||||
self.owner_member_var = tk.StringVar()
|
||||
self._build_ui()
|
||||
self.bind("<Escape>", lambda _event: self.destroy())
|
||||
self.bind("<Return>", lambda _event: self._create())
|
||||
@@ -145,6 +163,10 @@ class NewAssetDialog(tk.Toplevel):
|
||||
("Inventarnummer", "inventory_number"),
|
||||
("Seriennummer", "serial_number"),
|
||||
("Kaution (EUR)", "deposit_amount_default"),
|
||||
("Standort", "location"),
|
||||
("Übergabedatum", "handed_over_at"),
|
||||
("Zustand bei Übergabe", "condition"),
|
||||
("Wert / Kaufpreis", "estimated_value"),
|
||||
]
|
||||
self.entries: dict[str, ttk.Entry] = {}
|
||||
for row, (label, key) in enumerate(fields):
|
||||
@@ -152,17 +174,42 @@ class NewAssetDialog(tk.Toplevel):
|
||||
entry = ttk.Entry(frame, textvariable=self.variables[key], width=38)
|
||||
entry.grid(row=row, column=1, sticky="ew", pady=5)
|
||||
self.entries[key] = entry
|
||||
owner_row = len(fields)
|
||||
ttk.Label(frame, text="Eigentümer").grid(row=owner_row, column=0, sticky="w", pady=5, padx=(0, 12))
|
||||
ttk.Combobox(
|
||||
frame,
|
||||
textvariable=self.owner_type_var,
|
||||
values=("VEREIN", "MITGLIED", "EXTERN"),
|
||||
state="readonly",
|
||||
width=35,
|
||||
).grid(row=owner_row, column=1, sticky="ew", pady=5)
|
||||
ttk.Label(frame, text="Eigentümer-Mitglied").grid(
|
||||
row=owner_row + 1, column=0, sticky="w", pady=5, padx=(0, 12)
|
||||
)
|
||||
ttk.Combobox(
|
||||
frame,
|
||||
textvariable=self.owner_member_var,
|
||||
values=list(self.member_labels),
|
||||
state="readonly",
|
||||
width=35,
|
||||
).grid(row=owner_row + 1, column=1, sticky="ew", pady=5)
|
||||
ttk.Label(frame, text="Externer Eigentümer").grid(
|
||||
row=owner_row + 2, column=0, sticky="w", pady=5, padx=(0, 12)
|
||||
)
|
||||
ttk.Entry(frame, textvariable=self.variables["owner_name"], width=38).grid(
|
||||
row=owner_row + 2, column=1, sticky="ew", pady=5
|
||||
)
|
||||
ttk.Label(frame, text="Interne Notiz").grid(
|
||||
row=len(fields),
|
||||
row=owner_row + 3,
|
||||
column=0,
|
||||
sticky="nw",
|
||||
pady=5,
|
||||
padx=(0, 12),
|
||||
)
|
||||
self.notes_text = tk.Text(frame, width=38, height=5, wrap="word")
|
||||
self.notes_text.grid(row=len(fields), column=1, sticky="ew", pady=5)
|
||||
self.notes_text.grid(row=owner_row + 3, column=1, sticky="ew", pady=5)
|
||||
buttons = ttk.Frame(frame)
|
||||
buttons.grid(row=len(fields) + 1, column=0, columnspan=2, sticky="e", pady=(16, 0))
|
||||
buttons.grid(row=owner_row + 4, column=0, columnspan=2, sticky="e", pady=(16, 0))
|
||||
ttk.Button(buttons, text="Abbrechen", command=self.destroy).pack(side="left", padx=(0, 8))
|
||||
ttk.Button(
|
||||
buttons,
|
||||
@@ -176,9 +223,15 @@ class NewAssetDialog(tk.Toplevel):
|
||||
_activate_modal_window(self, self.entries.get("label"))
|
||||
|
||||
def _create(self) -> None:
|
||||
owner_type = {"VEREIN": "club", "MITGLIED": "member", "EXTERN": "external"}[self.owner_type_var.get()]
|
||||
try:
|
||||
asset = self.repository.create_asset(
|
||||
**{key: variable.get() for key, variable in self.variables.items()},
|
||||
**{key: variable.get() for key, variable in self.variables.items() if key != "owner_name"},
|
||||
owner_type=owner_type,
|
||||
owner_member_id=(
|
||||
self.member_labels.get(self.owner_member_var.get(), "") if owner_type == "member" else ""
|
||||
),
|
||||
owner_name=self.variables["owner_name"].get() if owner_type == "external" else "",
|
||||
notes=self.notes_text.get("1.0", "end-1c"),
|
||||
)
|
||||
except RepositoryError as exc:
|
||||
@@ -201,6 +254,19 @@ class EditAssetDialog(tk.Toplevel):
|
||||
self.asset_id = asset_id
|
||||
self.on_saved = on_saved
|
||||
self.asset = repository.get_asset(asset_id)
|
||||
self.members = repository.list_members()
|
||||
self.member_labels = {
|
||||
f"{member.member_number or member.member_id} · {member.display_name}": member.member_id
|
||||
for member in self.members
|
||||
}
|
||||
owner_member_label = next(
|
||||
(
|
||||
label
|
||||
for label, member_id in self.member_labels.items()
|
||||
if member_id == self.asset.owner_member_id
|
||||
),
|
||||
"",
|
||||
)
|
||||
self.title("Asset bearbeiten")
|
||||
self.transient(master.winfo_toplevel())
|
||||
self.resizable(False, False)
|
||||
@@ -211,7 +277,18 @@ class EditAssetDialog(tk.Toplevel):
|
||||
"serial_number": tk.StringVar(value=self.asset.serial_number),
|
||||
"deposit_amount_default": tk.StringVar(value=self.asset.deposit_amount_default),
|
||||
"status": tk.StringVar(value=self.asset.status),
|
||||
"location": tk.StringVar(value=self.asset.location),
|
||||
"handed_over_at": tk.StringVar(value=self.asset.handed_over_at),
|
||||
"condition": tk.StringVar(value=self.asset.condition),
|
||||
"estimated_value": tk.StringVar(value=self.asset.estimated_value),
|
||||
"owner_name": tk.StringVar(value=self.asset.owner_name),
|
||||
}
|
||||
self.owner_type_var = tk.StringVar(
|
||||
value={"club": "VEREIN", "member": "MITGLIED", "external": "EXTERN"}.get(
|
||||
self.asset.owner_type, "VEREIN"
|
||||
)
|
||||
)
|
||||
self.owner_member_var = tk.StringVar(value=owner_member_label)
|
||||
self._build_ui()
|
||||
self.bind("<Escape>", lambda _event: self.destroy())
|
||||
self.bind("<Return>", lambda _event: self._save())
|
||||
@@ -227,6 +304,10 @@ class EditAssetDialog(tk.Toplevel):
|
||||
("Inventarnummer", "inventory_number"),
|
||||
("Seriennummer", "serial_number"),
|
||||
("Kaution (EUR)", "deposit_amount_default"),
|
||||
("Standort", "location"),
|
||||
("Übergabedatum", "handed_over_at"),
|
||||
("Zustand bei Übergabe", "condition"),
|
||||
("Wert / Kaufpreis", "estimated_value"),
|
||||
]
|
||||
self.entries: dict[str, ttk.Entry] = {}
|
||||
for row, (label, key) in enumerate(fields):
|
||||
@@ -235,12 +316,40 @@ class EditAssetDialog(tk.Toplevel):
|
||||
entry = ttk.Entry(frame, textvariable=self.variables[key], width=38, state=state)
|
||||
entry.grid(row=row, column=1, sticky="ew", pady=5)
|
||||
self.entries[key] = entry
|
||||
ttk.Label(frame, text="Status").grid(row=len(fields), column=0, sticky="w", pady=5, padx=(0, 12))
|
||||
status_values = [value for key, value in (
|
||||
("available", "VERFUEGBAR"),
|
||||
("lost", "VERLOREN"),
|
||||
("retired", "AUSGEMUSTERT"),
|
||||
)]
|
||||
owner_row = len(fields)
|
||||
ttk.Label(frame, text="Eigentümer").grid(row=owner_row, column=0, sticky="w", pady=5, padx=(0, 12))
|
||||
ttk.Combobox(
|
||||
frame,
|
||||
textvariable=self.owner_type_var,
|
||||
values=("VEREIN", "MITGLIED", "EXTERN"),
|
||||
state="readonly",
|
||||
width=35,
|
||||
).grid(row=owner_row, column=1, sticky="ew", pady=5)
|
||||
ttk.Label(frame, text="Eigentümer-Mitglied").grid(
|
||||
row=owner_row + 1, column=0, sticky="w", pady=5, padx=(0, 12)
|
||||
)
|
||||
ttk.Combobox(
|
||||
frame,
|
||||
textvariable=self.owner_member_var,
|
||||
values=list(self.member_labels),
|
||||
state="readonly",
|
||||
width=35,
|
||||
).grid(row=owner_row + 1, column=1, sticky="ew", pady=5)
|
||||
ttk.Label(frame, text="Externer Eigentümer").grid(
|
||||
row=owner_row + 2, column=0, sticky="w", pady=5, padx=(0, 12)
|
||||
)
|
||||
ttk.Entry(frame, textvariable=self.variables["owner_name"], width=38).grid(
|
||||
row=owner_row + 2, column=1, sticky="ew", pady=5
|
||||
)
|
||||
ttk.Label(frame, text="Status").grid(row=owner_row + 3, column=0, sticky="w", pady=5, padx=(0, 12))
|
||||
status_values = [
|
||||
value
|
||||
for key, value in (
|
||||
("available", "VERFUEGBAR"),
|
||||
("lost", "VERLOREN"),
|
||||
("retired", "AUSGEMUSTERT"),
|
||||
)
|
||||
]
|
||||
self.status_map = {
|
||||
"VERFUEGBAR": "available",
|
||||
"VERLOREN": "lost",
|
||||
@@ -260,8 +369,8 @@ class EditAssetDialog(tk.Toplevel):
|
||||
state="readonly" if not issued else "disabled",
|
||||
width=35,
|
||||
)
|
||||
self.status_box.grid(row=len(fields), column=1, sticky="ew", pady=5)
|
||||
note_row = len(fields) + 1
|
||||
self.status_box.grid(row=owner_row + 3, column=1, sticky="ew", pady=5)
|
||||
note_row = owner_row + 4
|
||||
ttk.Label(frame, text="Interne Notiz").grid(row=note_row, column=0, sticky="nw", pady=5, padx=(0, 12))
|
||||
self.notes_text = tk.Text(frame, width=38, height=5, wrap="word")
|
||||
self.notes_text.grid(row=note_row, column=1, sticky="ew", pady=5)
|
||||
@@ -290,6 +399,21 @@ class EditAssetDialog(tk.Toplevel):
|
||||
self.asset.inventory_number = self.variables["inventory_number"].get()
|
||||
self.asset.serial_number = self.variables["serial_number"].get()
|
||||
self.asset.notes = self.notes_text.get("1.0", "end-1c")
|
||||
self.asset.location = self.variables["location"].get()
|
||||
self.asset.handed_over_at = self.variables["handed_over_at"].get()
|
||||
self.asset.condition = self.variables["condition"].get()
|
||||
self.asset.estimated_value = self.variables["estimated_value"].get()
|
||||
self.asset.owner_type = {"VEREIN": "club", "MITGLIED": "member", "EXTERN": "external"}[
|
||||
self.owner_type_var.get()
|
||||
]
|
||||
self.asset.owner_member_id = (
|
||||
self.member_labels.get(self.owner_member_var.get(), "")
|
||||
if self.asset.owner_type == "member"
|
||||
else ""
|
||||
)
|
||||
self.asset.owner_name = (
|
||||
self.variables["owner_name"].get() if self.asset.owner_type == "external" else ""
|
||||
)
|
||||
if not self.asset.current_holder_member_id:
|
||||
self.asset.deposit_amount_default = self.variables["deposit_amount_default"].get()
|
||||
self.asset.status = self.status_map.get(self.status_var.get(), self.asset.status)
|
||||
@@ -394,9 +518,7 @@ class IssueAssetDialog(tk.Toplevel):
|
||||
self.member_tree.delete(*self.member_tree.get_children())
|
||||
query = self.search_var.get().strip().casefold()
|
||||
filtered = [
|
||||
member
|
||||
for member in self.members
|
||||
if not query or query in self._member_search_text(member)
|
||||
member for member in self.members if not query or query in self._member_search_text(member)
|
||||
]
|
||||
for member in filtered:
|
||||
self.member_tree.insert(
|
||||
@@ -599,9 +721,7 @@ class IntegrityWarningDialog(tk.Toplevel):
|
||||
text="\n".join(f"• {item}" for item in self.warnings),
|
||||
style="Warning.TLabel",
|
||||
justify="left",
|
||||
).grid(
|
||||
row=1, column=0, sticky="w", pady=(12, 0)
|
||||
)
|
||||
).grid(row=1, column=0, sticky="w", pady=(12, 0))
|
||||
buttons = ttk.Frame(frame)
|
||||
buttons.grid(row=2, column=0, sticky="e", pady=(18, 0))
|
||||
ttk.Button(buttons, text="Nein", command=self.destroy).pack(side="left", padx=(0, 8))
|
||||
|
||||
Reference in New Issue
Block a user