From ba1019728de2ee5d76a86b34ea87421635b216c9 Mon Sep 17 00:00:00 2001 From: jbergner Date: Fri, 29 May 2026 10:34:04 +0200 Subject: [PATCH] update mit archiv --- .env.example | 10 +++++----- README.md | 6 +++++- db.go | 18 +++++++++++++++++- discord.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 75 insertions(+), 10 deletions(-) diff --git a/.env.example b/.env.example index b4d31ef..7e2961e 100644 --- a/.env.example +++ b/.env.example @@ -7,18 +7,18 @@ DISCORD_APP_ID=ApplicationIDHere DISCORD_GUILD_ID=OptionalTestGuildIDForFastCommandRegistration # Public channel for sanitized order overview. Leave empty if only the internal team should see order posts. -DISCORD_PUBLIC_ORDER_CHANNEL_ID=PublicOrderChannelIDOptional +DISCORD_PUBLIC_ORDER_CHANNEL_ID=PublicOrderChannelIDOptional # 1509819718922670271 # Private/internal channel for team operations. The bot posts buttons and warehouse checks here. -DISCORD_INTERNAL_ORDER_CHANNEL_ID=PrivateTeamOrderChannelIDRequired +DISCORD_INTERNAL_ORDER_CHANNEL_ID=PrivateTeamOrderChannelIDRequired # 1509819679487688817 # Optional audit/log channel for admin traceability. -DISCORD_AUDIT_CHANNEL_ID=AuditLogChannelIDOptional +DISCORD_AUDIT_CHANNEL_ID=AuditLogChannelIDOptional # 1509819633551802409 # Comma-separated role IDs. Admin role can modify inventory and force status changes. -DISCORD_ADMIN_ROLE_IDS=123456789012345678,234567890123456789 +DISCORD_ADMIN_ROLE_IDS=123456789012345678,234567890123456789 # 1509819305188003931 # Comma-separated role IDs. Team role can see internal orders, accept/decline, check warehouse. -DISCORD_TEAM_ROLE_IDS=345678901234567890 +DISCORD_TEAM_ROLE_IDS=345678901234567890 # 1509819434330755233 DATABASE_PATH=orders.db diff --git a/README.md b/README.md index e35d72f..93a5fc4 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,11 @@ Zeigt den Auftrag. Team/Admin sieht die interne Ansicht inklusive Lagerprüfung, ### `/auftrag_liste status: limit:` -Listet Aufträge. Team/Admin sieht zusätzlich interne Zuordnungen. +Listet nur aktive Aufträge. Standardmäßig werden `open`, `accepted`, `in_delivery` und `delivered` angezeigt. Abgeschlossene, abgelehnte und abgebrochene Aufträge erscheinen hier nicht mehr. + +### `/auftrag_archiv status: limit:` + +Listet archivierte Aufträge mit den Statuswerten `completed`, `declined` und `cancelled`. Team/Admin sieht zusätzlich interne Zuordnungen. ### `/auftrag_abschliessen id:` diff --git a/db.go b/db.go index 804a058..8574242 100644 --- a/db.go +++ b/db.go @@ -178,16 +178,32 @@ func scanOrder(scanner interface{ Scan(dest ...any) error }) (*Order, error) { } func (s *Store) ListOrders(status string, limit int) ([]Order, error) { + return s.listOrders(status, limit, false) +} + +func (s *Store) ListArchivedOrders(status string, limit int) ([]Order, error) { + return s.listOrders(status, limit, true) +} + +func (s *Store) listOrders(status string, limit int, archived bool) ([]Order, error) { if limit <= 0 || limit > 50 { limit = 10 } query := `SELECT id, submitter_id, submitter_name, acceptor_id, acceptor_name, commodity, quality, quantity_amount, quantity_unit, deadline, delivery_place, max_budget_auec, status, public_channel_id, public_message_id, internal_channel_id, internal_message_id, thread_id, created_at, updated_at, last_feedback FROM orders` args := []any{} + if status != "" { query += ` WHERE status=?` args = append(args, status) + } else if archived { + query += ` WHERE status IN (?, ?, ?)` + args = append(args, StatusCompleted, StatusDeclined, StatusCancelled) + } else { + query += ` WHERE status NOT IN (?, ?, ?)` + args = append(args, StatusCompleted, StatusDeclined, StatusCancelled) } - query += ` ORDER BY created_at DESC LIMIT ?` + + query += ` ORDER BY updated_at DESC LIMIT ?` args = append(args, limit) rows, err := s.db.Query(query, args...) if err != nil { diff --git a/discord.go b/discord.go index 13c31ef..ec484f4 100644 --- a/discord.go +++ b/discord.go @@ -58,7 +58,8 @@ func (b *Bot) registerCommands() error { }, }, {Name: "auftrag_status", Description: "Zeigt einen Auftrag", Options: []*discordgo.ApplicationCommandOption{{Name: "id", Description: "Auftrags-ID", Type: discordgo.ApplicationCommandOptionInteger, Required: true}}}, - {Name: "auftrag_liste", Description: "Listet Aufträge", Options: []*discordgo.ApplicationCommandOption{{Name: "status", Description: "Optionaler Status", Type: discordgo.ApplicationCommandOptionString, Required: false, Choices: statusChoices()}, {Name: "limit", Description: "Maximal 50", Type: discordgo.ApplicationCommandOptionInteger, Required: false, MinValue: ptrFloat(1), MaxValue: float64(50)}}}, + {Name: "auftrag_liste", Description: "Listet aktive Aufträge", Options: []*discordgo.ApplicationCommandOption{{Name: "status", Description: "Optionaler aktiver Status", Type: discordgo.ApplicationCommandOptionString, Required: false, Choices: activeStatusChoices()}, {Name: "limit", Description: "Maximal 50", Type: discordgo.ApplicationCommandOptionInteger, Required: false, MinValue: ptrFloat(1), MaxValue: float64(50)}}}, + {Name: "auftrag_archiv", Description: "Listet abgeschlossene, abgelehnte und abgebrochene Aufträge", Options: []*discordgo.ApplicationCommandOption{{Name: "status", Description: "Optionaler Archiv-Status", Type: discordgo.ApplicationCommandOptionString, Required: false, Choices: archivedStatusChoices()}, {Name: "limit", Description: "Maximal 50", Type: discordgo.ApplicationCommandOptionInteger, Required: false, MinValue: ptrFloat(1), MaxValue: float64(50)}}}, {Name: "auftrag_abschliessen", Description: "Markiert einen Auftrag als abgeschlossen", Options: []*discordgo.ApplicationCommandOption{{Name: "id", Description: "Auftrags-ID", Type: discordgo.ApplicationCommandOptionInteger, Required: true}}}, {Name: "auftrag_status_setzen", Description: "Admin/Team: setzt den Status eines Auftrags", Options: []*discordgo.ApplicationCommandOption{{Name: "id", Description: "Auftrags-ID", Type: discordgo.ApplicationCommandOptionInteger, Required: true}, {Name: "status", Description: "Neuer Status", Type: discordgo.ApplicationCommandOptionString, Required: true, Choices: statusChoices()}, {Name: "notiz", Description: "Interne Notiz", Type: discordgo.ApplicationCommandOptionString, Required: false}}}, {Name: "auftrag_abbrechen", Description: "Bricht einen Auftrag ab", Options: []*discordgo.ApplicationCommandOption{{Name: "id", Description: "Auftrags-ID", Type: discordgo.ApplicationCommandOptionInteger, Required: true}, {Name: "grund", Description: "Optionaler Grund", Type: discordgo.ApplicationCommandOptionString, Required: false}}}, @@ -81,6 +82,18 @@ func statusChoices() []*discordgo.ApplicationCommandOptionChoice { return []*discordgo.ApplicationCommandOptionChoice{{Name: StatusOpen, Value: StatusOpen}, {Name: StatusAccepted, Value: StatusAccepted}, {Name: StatusInDelivery, Value: StatusInDelivery}, {Name: StatusDelivered, Value: StatusDelivered}, {Name: StatusCompleted, Value: StatusCompleted}, {Name: StatusDeclined, Value: StatusDeclined}, {Name: StatusCancelled, Value: StatusCancelled}} } +func activeStatusChoices() []*discordgo.ApplicationCommandOptionChoice { + return []*discordgo.ApplicationCommandOptionChoice{{Name: StatusOpen, Value: StatusOpen}, {Name: StatusAccepted, Value: StatusAccepted}, {Name: StatusInDelivery, Value: StatusInDelivery}, {Name: StatusDelivered, Value: StatusDelivered}} +} + +func archivedStatusChoices() []*discordgo.ApplicationCommandOptionChoice { + return []*discordgo.ApplicationCommandOptionChoice{{Name: StatusCompleted, Value: StatusCompleted}, {Name: StatusDeclined, Value: StatusDeclined}, {Name: StatusCancelled, Value: StatusCancelled}} +} + +func isArchivedStatus(status string) bool { + return status == StatusCompleted || status == StatusDeclined || status == StatusCancelled +} + func (b *Bot) onInteraction(s *discordgo.Session, i *discordgo.InteractionCreate) { switch i.Type { case discordgo.InteractionApplicationCommand: @@ -103,6 +116,8 @@ func (b *Bot) handleCommand(s *discordgo.Session, i *discordgo.InteractionCreate b.cmdStatus(s, i, optInt(i, "id")) case "auftrag_liste": b.cmdList(s, i) + case "auftrag_archiv": + b.cmdArchive(s, i) case "auftrag_abschliessen": b.cmdFinish(s, i, optInt(i, "id")) case "auftrag_status_setzen": @@ -186,15 +201,45 @@ func (b *Bot) cmdStatus(s *discordgo.Session, i *discordgo.InteractionCreate, id } func (b *Bot) cmdList(s *discordgo.Session, i *discordgo.InteractionCreate) { + b.cmdListOrders(s, i, false) +} + +func (b *Bot) cmdArchive(s *discordgo.Session, i *discordgo.InteractionCreate) { + b.cmdListOrders(s, i, true) +} + +func (b *Bot) cmdListOrders(s *discordgo.Session, i *discordgo.InteractionCreate, archived bool) { status := optString(i, "status") limit := int(optIntDefault(i, "limit", 10)) - orders, err := b.store.ListOrders(status, limit) + + if status != "" && isArchivedStatus(status) != archived { + if archived { + b.replyEphemeral(s, i, "`/auftrag_archiv` zeigt nur completed, declined und cancelled. Aktive Aufträge findest du mit `/auftrag_liste`.") + } else { + b.replyEphemeral(s, i, "`/auftrag_liste` zeigt nur aktive Aufträge. Abgeschlossene/abgelehnte/abgebrochene Aufträge findest du mit `/auftrag_archiv`.") + } + return + } + + var ( + orders []Order + err error + ) + if archived { + orders, err = b.store.ListArchivedOrders(status, limit) + } else { + orders, err = b.store.ListOrders(status, limit) + } if err != nil { b.replyEphemeral(s, i, err.Error()) return } if len(orders) == 0 { - b.replyEphemeral(s, i, "Keine Aufträge gefunden.") + if archived { + b.replyEphemeral(s, i, "Keine archivierten Aufträge gefunden.") + } else { + b.replyEphemeral(s, i, "Keine aktiven Aufträge gefunden.") + } return } var lines []string