# module_posting.R postingModuleUI <- function(id) { ns <- NS(id) tagList() # Das UI wird dynamisch via showModal erzeugt } postingModuleServer <- function(id, conn, r_trans_id, r_trigger_list) { moduleServer(id, function(input, output, session) { ns <- session$ns # Dieser Trigger signalisiert dem Hauptmodul: "Daten haben sich geändert!" db_updated <- reactiveVal(0) # Hilfsvariablen für den aktuellen Edit-Status current_record <- reactiveVal() current_trans <- reactiveVal() # Beobachte den Trigger aus dem Hauptmodul observeEvent(r_trigger_list(), { req(r_trans_id()) # 1. Daten laden t_id <- r_trans_id() p_id <- r_trigger_list()$post_id trans_data <- dbxSelect(conn, paste0("SELECT * FROM entries WHERE id=", t_id)) current_trans(trans_data) if (!is.null(p_id)) { record <- read_posting(conn, p_id) } else { # Logik für neuen Eintrag new_p_id <- max_id(conn, "postings") + 1 wertstellung <- dbxSelect(conn, paste0("SELECT max(valuta) from Postings WHERE entry_id=", t_id)) %>% pull() record <- leer_df_from_table(conn, "postings") record[1, "id"] <- new_p_id record$entry_id <- t_id record$account_id <- 0 record$valuta <- wertstellung record$booking_date <- wertstellung } current_record(record) # 2. Modal anzeigen showModal(modalDialog( title = paste("Buchung bearbeiten - Transaktion", t_id), f_airdatepicker_UI(ns("valuta"), "Wertstellung", record$valuta), f_airdatepicker_UI(ns("buchungsdatum"), "Buchungsdatum", record$booking_date), selectizeInput(ns("kontakt"), "Kontakt:", selected = trans_data$contact_id, choices = get_contact_choices(conn), width = "100%"), selectizeInput(ns("konto"), "Kontoname:", selected = record$account_id, choices = get_account_choices(conn), width = "100%"), selectizeInput(ns("projekt"), "Projektname", selected = record$project_id, choices = get_project_choices(conn), width = "100%"), splitLayout(cellWidths = c("70%", "30%"), numericInput(ns("amount"), "Betrag:", value = record$amount, width = "100%"), numericInput(ns("coin_share_amount"), "Münzen:", value = record$coin_share_amount, width = "100%") ), textAreaInput(ns("trans_notiz"), label = "Notiz (Transaktion)", value = trans_data$note, width = "100%"), footer = tagList( modalButton("Abbrechen"), actionBttn(ns("delete"), "Löschen", style = "minimal", color = "danger"), actionBttn(ns("confirm"), "Bestätigen", style = "minimal", color = "success") ), easyClose = TRUE )) }) # Speichern observeEvent(input$confirm, { req(current_record(), current_trans()) # Daten aus UI einsammeln rec <- current_record() tra <- current_trans() tra$contact_id <- input$kontakt tra$note <- input$trans_notiz rec$amount <- input$amount rec$account_id <- input$konto rec$project_id <- input$projekt rec$valuta <- as.character(input$valuta) rec$booking_date <- as.character(input$buchungsdatum) rec$coin_share_amount <- input$coin_share_amount # Validierung ok <- !is.na(rec$amount) && rec$account_id > 0 if (ok) { dbxUpsert(conn, "postings", records = rec, where_cols = "id") dbxUpsert(conn, "entries", records = tra, where_cols = "id") removeModal() db_updated(db_updated() + 1) # Hauptmodul triggern } else { showNotification("Eingabe ungültig", type = "error") } }) # Löschen observeEvent(input$delete, { rec <- current_record() anz <- dbxSelect(conn, paste0("SELECT count(*) FROM postings WHERE entry_id=", rec$entry_id)) %>% pull() if (anz > 1) { dbxDelete(conn, "postings", where = data.frame(id = rec$id)) removeModal() db_updated(db_updated() + 1) } else { showNotification("Letzter Teil kann nicht gelöscht werden.", type = "error") } }) return(db_updated) }) }