From f16386810f151c600f6689729f6cba826781fd95 Mon Sep 17 00:00:00 2001 From: Christian Oswald Date: Tue, 28 Apr 2026 11:36:11 +0200 Subject: [PATCH] Die Umsatztabelle zeigt jetzt unbekannte bvbs an und man kann auch eine bvb den contacts zuordnern oder einen neuen contacct erstellen --- R/umsatz/module_umsatz.R | 103 ++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 38 deletions(-) diff --git a/R/umsatz/module_umsatz.R b/R/umsatz/module_umsatz.R index bba7c52..6dd6a33 100755 --- a/R/umsatz/module_umsatz.R +++ b/R/umsatz/module_umsatz.R @@ -51,8 +51,11 @@ umsatzServer <- function(id, conn, r_global) { }) }) - # ── Tabelle ──────────────────────────────────────────────────────────────── + # ── Tabelle ---- output$umsatz_table <- renderReactable({ + # remote_names einmal laden + known_names <- dbGetQuery(conn, "SELECT contact_text FROM bank_connections")$contact_text + reactable( umsatz_data() %>% select(id, valuta, empfaenger_name, empfaenger_konto, @@ -61,19 +64,19 @@ umsatzServer <- function(id, conn, r_global) { highlight = TRUE, searchable = T, searchMethod = JS("function(rows, columnIds, filterValue) { - var filter = filterValue.toLowerCase().replace(',', '.').replace(/\\s/g, ''); - return rows.filter(function(row) { - return columnIds.some(function(col) { - var val = row.values[col]; - var str = val === null || val === undefined ? '' : String(val); - var strNorm = str.toLowerCase().replace(',', '.').replace(/\\s/g, ''); - return strNorm.includes(filter) || - (typeof val === 'number' && - String(Math.abs(val)).includes(filter)); - }); - }); - }"), - filterable = F, # ← das reicht + var filter = filterValue.toLowerCase().replace(',', '.').replace(/\\s/g, ''); + return rows.filter(function(row) { + return columnIds.some(function(col) { + var val = row.values[col]; + var str = val === null || val === undefined ? '' : String(val); + var strNorm = str.toLowerCase().replace(',', '.').replace(/\\s/g, ''); + return strNorm.includes(filter) || + (typeof val === 'number' && + String(Math.abs(val)).includes(filter)); + }); + }); + }"), + filterable = F, pagination = F, selection = "single", onClick = "select", @@ -83,7 +86,15 @@ umsatzServer <- function(id, conn, r_global) { posting_id = colDef(show = FALSE), entry_id = colDef(show = FALSE), valuta = colDef(name = "Datum", maxWidth = 120), - empfaenger_name = colDef(name = "Empfänger", minWidth = 150), + empfaenger_name = colDef( + name = "Empfänger", + minWidth = 150, + style = function(value) { + if (!is.na(value) && !(value %in% known_names)) { + list(color = "red", fontWeight = "bold") + } + } + ), empfaenger_konto = colDef(name = "IBAN", minWidth = 150), betrag = colDef( name = "Betrag", @@ -106,7 +117,7 @@ umsatzServer <- function(id, conn, r_global) { ) }) - # ── Selektierter Umsatz ──────────────────────────────────────────────────── + # ── Selektierter Umsatz ---- sel <- reactive(getReactableState("umsatz_table", "selected")) selected_umsatz <- reactive({ @@ -114,7 +125,7 @@ umsatzServer <- function(id, conn, r_global) { umsatz_data()[sel(), ] }) - # ── Buchungs-Panel ───────────────────────────────────────────────────────── + # ── Buchungs-Panel ---- output$buchungs_panel <- renderUI({ req(selected_umsatz()) u <- selected_umsatz() @@ -165,7 +176,7 @@ umsatzServer <- function(id, conn, r_global) { } }) - # ── Zur Buchung springen ─────────────────────────────────────────────────── + # ── Zur Buchung springen ---- observeEvent(input$goto_buchung, { req(selected_umsatz()) r_global$nav_history <- c(r_global$nav_history, list(list(tab = "umsatz"))) @@ -173,7 +184,7 @@ umsatzServer <- function(id, conn, r_global) { r_global$active_tab <- "buchungen" }) - # ── Buchen ──────────────────────────────────────────────────────────────── + # ── Buchen ---- observeEvent(input$buchen, { req(selected_umsatz(), input$konto) u <- selected_umsatz() @@ -207,14 +218,24 @@ umsatzServer <- function(id, conn, r_global) { showNotification("✓ Gebucht", type = "message") }) - # ── Neuer Kontakt ────────────────────────────────────────────────────────── + # ── Neuer Kontakt / Bankverbindung ---- observeEvent(input$new_contact, { req(selected_umsatz()) u <- selected_umsatz() - + contact_choices <- get_contact_choices(conn) showModal(modalDialog( title = "Neuer Kontakt", - textInput(ns("new_contact_name"), "Name", value = u$empfaenger_name), + selectizeInput(ns("existing_contact_id"), + "Vorhandenen Kontakt verknüpfen (optional)", + choices = contact_choices, + selected = 0, + options = list(placeholder = "Kontakt suchen...") + ), + hr(), + conditionalPanel( + condition = paste0("input['", ns("existing_contact_id"), "'] == '0'"), + textInput(ns("new_contact_name"), "Name", value = u$empfaenger_name) + ), textInput(ns("new_contact_iban"), "IBAN", value = u$empfaenger_konto), footer = tagList( modalButton("Abbrechen"), @@ -223,33 +244,39 @@ umsatzServer <- function(id, conn, r_global) { ) )) }) - + # ** Neuen Kontakt/Bvb speichern observeEvent(input$save_contact, { - req(input$new_contact_name) u <- selected_umsatz() - - new_c_id <- max_id(conn, "contacts") + 1L - dbxInsert(conn, "contacts", data.frame( - id = new_c_id, - display_name = input$new_contact_name - )) - + existing_id <- as.integer(input$existing_contact_id) + if (!is.na(existing_id) && existing_id != 0L) { + # ── Nur bank_connection anlegen ---- + target_contact_id <- existing_id + + } else { + # ── Neuen Kontakt + bank_connection anlegen ---- + req(input$new_contact_name) + target_contact_id <- max_id(conn, "contacts") + 1L + dbxInsert(conn, "contacts", data.frame( + id = target_contact_id, + display_name = input$new_contact_name + )) + } new_bc_id <- max_id(conn, "bank_connections") + 1L dbxInsert(conn, "bank_connections", data.frame( id = new_bc_id, - contact_id = new_c_id, + contact_id = target_contact_id, iban = input$new_contact_iban, - remote_name = u$empfaenger_name + contact_text = u$empfaenger_name )) - removeModal() - updateSelectizeInput(session, "kontakt", choices = get_contact_choices(conn), - selected = new_c_id + selected = target_contact_id ) - - showNotification("✓ Kontakt angelegt", type = "message") + msg <- if (existing_id != 0L) "✓ Bankverbindung verknüpft" else "✓ Kontakt angelegt" + showNotification(msg, type = "message") }) + + }) }