Buchungen-popup funktioniert
This commit is contained in:
+4
-48
@@ -1,50 +1,6 @@
|
||||
# These are some examples of commonly ignored file patterns.
|
||||
# You should customize this list as applicable to your project.
|
||||
# Learn more about .gitignore:
|
||||
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore
|
||||
|
||||
# Node artifact files
|
||||
node_modules/
|
||||
dist/
|
||||
|
||||
# Compiled Java class files
|
||||
*.class
|
||||
|
||||
# Compiled Python bytecode
|
||||
*.py[cod]
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
|
||||
# Package files
|
||||
*.jar
|
||||
|
||||
# Maven
|
||||
target/
|
||||
dist/
|
||||
|
||||
# JetBrains IDE
|
||||
.idea/
|
||||
|
||||
# Unit test reports
|
||||
TEST*.xml
|
||||
|
||||
# Generated by MacOS
|
||||
.DS_Store
|
||||
|
||||
# Generated by Windows
|
||||
Thumbs.db
|
||||
|
||||
# Applications
|
||||
*.app
|
||||
*.exe
|
||||
*.war
|
||||
|
||||
# Large media files
|
||||
*.mp4
|
||||
*.tiff
|
||||
*.avi
|
||||
*.flv
|
||||
*.mov
|
||||
*.wmv
|
||||
.Rproj.user
|
||||
.Rhistory
|
||||
.RData
|
||||
.Ruserdata
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
read_accounts <- function(conn){
|
||||
tbl(conn, "accounts")
|
||||
|
||||
}
|
||||
|
||||
|
||||
get_account_choices <- function(conn) {
|
||||
tbl(conn, "accounts") |>
|
||||
select(id, konto) |>
|
||||
collect() |>
|
||||
arrange(konto) |>
|
||||
(\(df) setNames(df$id, df$konto))()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
read_buch_tabelle <- function(conn){
|
||||
postings <- tbl(conn, "postings")
|
||||
entries <- tbl(conn, "entries")
|
||||
accounts <- tbl(conn, "accounts")
|
||||
projects <- tbl(conn, "projects")
|
||||
contacts <- tbl(conn, "contacts")
|
||||
result <- postings |>
|
||||
left_join(entries, by = c("entry_id" = "id")) |>
|
||||
left_join(contacts, by = c("contact_id" = "id")) |> # contact_id jetzt verfügbar
|
||||
left_join(accounts, by = c("account_id" = "id")) |>
|
||||
left_join(projects, by = c("project_id" = "id")) |>
|
||||
select(id, valuta, konto, projektname, display_name, amount, entry_id) |>
|
||||
collect()
|
||||
}
|
||||
|
||||
read_posting <- function(conn, id){
|
||||
dbxSelect(conn, paste0("SELECT * FROM postings WHERE id =", id))
|
||||
}
|
||||
read_postings_by_entry <- function(conn, id){
|
||||
dbxSelect(conn, paste0("SELECT * FROM postings WHERE entry_id =", id))
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
buchungenUI <- function(id) {
|
||||
ns <- NS(id)
|
||||
tagList(
|
||||
reactableOutput(ns("buchungen_table"))
|
||||
)
|
||||
}
|
||||
|
||||
buchungenServer <- function(id) {
|
||||
moduleServer( id, function(input, output, session) {
|
||||
ns <- session$ns
|
||||
|
||||
postings <- reactiveVal(read_buch_tabelle(conn))
|
||||
|
||||
|
||||
output$buchungen_table <- renderReactable({
|
||||
reactable(
|
||||
postings(),
|
||||
onClick = "expand",
|
||||
selection = "single",
|
||||
details = function(index) {
|
||||
entry_id <- postings()$entry_id[index]
|
||||
detail_rows <- postings()[postings()$entry_id == entry_id, ]
|
||||
|
||||
div(
|
||||
style = "padding: 10px; background: #f4f4f4; border-left: 4px solid #3c8dbc; max-width: 800px; margin-left: auto",
|
||||
|
||||
reactable(
|
||||
dplyr::select(detail_rows, konto, projektname, amount),
|
||||
fullWidth = TRUE,
|
||||
columns = list(
|
||||
konto = colDef(name = "Konto", minWidth = 150),
|
||||
projektname = colDef(name = "Projekt", minWidth = 150),
|
||||
amount = colDef(name = "Betrag", minWidth = 80)
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
columns = list(
|
||||
id = colDef(name = "ID", minWidth = 80),
|
||||
valuta = colDef(name = "Wertstellung", minWidth = 80),
|
||||
konto = colDef(name = "Kontoname", minWidth = 200),
|
||||
entry_id = colDef(show = FALSE)
|
||||
)
|
||||
)
|
||||
})
|
||||
|
||||
# Modal zum editieren
|
||||
selected <- reactive(getReactableState("buchungen_table", "selected"))
|
||||
observeEvent(selected(),{
|
||||
idwert <- postings()[selected(), "id"]
|
||||
selected_row <- read_posting(conn, idwert) %>%
|
||||
mutate(verzicht = ifelse(is.na(verzicht), F, verzicht))
|
||||
showModal(modalDialog(
|
||||
title = "Buchung bearbeiten",
|
||||
size = "l",
|
||||
tags$style(HTML(".modal-dialog { max-width: 90% !important; width: 90% !important; }")),
|
||||
|
||||
entryEditUI(ns("entry_edit")),
|
||||
footer = tagList(
|
||||
modalButton("Abbrechen"),
|
||||
actionButton(ns("speichern"), "Speichern")
|
||||
)
|
||||
))
|
||||
|
||||
entryEditServer("entry_edit", entry_id = selected_row$entry_id, conn = conn)
|
||||
|
||||
}, ignoreInit = TRUE)
|
||||
|
||||
observeEvent(input$speichern, {
|
||||
browser()
|
||||
dbExecute(conn, "UPDATE postings SET
|
||||
account_id = ?, project_id = ?, amount = ?, valuta = ?,
|
||||
notiz = ?, rechnungsnummer = ?, betrag_muenzen = ?, verzicht = ?
|
||||
WHERE id = ?",
|
||||
params = list(
|
||||
input$account_id, input$project_id, input$amount, input$valuta,
|
||||
input$notiz, input$rechnungsnummer, input$betrag_muenzen, input$verzicht,
|
||||
selected_row$id
|
||||
)
|
||||
)
|
||||
|
||||
removeModal()
|
||||
buchungen(read_buch_tabelle(conn)) # Tabelle neu laden
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
get_contact_choices <- function(conn) {
|
||||
tbl(conn, "contacts") |>
|
||||
select(id, display_name) |>
|
||||
collect() |>
|
||||
arrange(display_name) |>
|
||||
(\(df) setNames(df$id, df$display_name))()
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
read_entry <- function(conn, idwert) {
|
||||
dbxSelect(conn, paste0("SELECT * FROM entries WHERE id=", idwert))
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
# entry_edit_mod.R
|
||||
entryEditUI <- function(id) {
|
||||
ns <- NS(id)
|
||||
tagList(
|
||||
|
||||
uiOutput(ns("entry_ui")),
|
||||
uiOutput(ns("postings_ui"))
|
||||
)
|
||||
}
|
||||
|
||||
entryEditServer <- function(id, entry_id, conn) {
|
||||
moduleServer(id, function(input, output, session) {
|
||||
ns <- session$ns
|
||||
|
||||
entry_postings <- reactiveVal(read_postings_by_entry(conn, entry_id))
|
||||
entry_data <- reactiveVal(read_entry(conn, entry_id))
|
||||
|
||||
output$entry_ui <- renderUI({
|
||||
e <- entry_data()
|
||||
tagList(
|
||||
fluidRow(
|
||||
column(6, selectizeInput(ns("contact_id"), "Kontakt",
|
||||
choices = get_contact_choices(conn),
|
||||
selected = e$contact_id)),
|
||||
column(6, textInput(ns("purpose"), "Verwendungszweck", value = e$purpose))
|
||||
),
|
||||
hr()
|
||||
)
|
||||
})
|
||||
|
||||
# Choices für contact nach dem Flush setzen
|
||||
|
||||
|
||||
output$postings_ui <- renderUI({
|
||||
alle <- entry_postings()
|
||||
lapply(seq_len(nrow(alle)), function(i) {
|
||||
print(paste("project selected:", alle$project_id[i]))
|
||||
print(head(get_project_choices(conn)))
|
||||
print(class(get_project_choices(conn)))
|
||||
div(
|
||||
style = "border-left: 3px solid #3c8dbc; padding: 5px; margin-bottom: 5px",
|
||||
fluidRow(
|
||||
column(3,
|
||||
selectInput(ns(paste0("account_id_", i)), "Konto",
|
||||
choices = get_account_choices(conn),
|
||||
selected = as.character(alle$account_id[i]))
|
||||
),
|
||||
column(3, selectizeInput(ns(paste0("project_id_", i)), "Projekt",
|
||||
choices = get_project_choices(conn),
|
||||
selected = ifelse(is.na(alle$project_id[i]), "", as.character(alle$project_id[i])))
|
||||
),
|
||||
column(2, numericInput(ns(paste0("amount_", i)), "Betrag", value = alle$amount[i])),
|
||||
column(3, textInput(ns(paste0("notiz_", i)), "Notiz", value = alle$notiz[i])),
|
||||
column(1, actionButton(ns(paste0("delete_", i)), "", icon = icon("trash"), class = "btn-danger btn-sm"))
|
||||
)
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
# Choices befüllen nachdem renderUI fertig ist
|
||||
observe({
|
||||
alle <- entry_postings()
|
||||
e <- entry_data()
|
||||
req(nrow(alle) > 0, nrow(e) > 0)
|
||||
|
||||
session$onFlushed(function() {
|
||||
# Contact
|
||||
updateSelectizeInput(session, "contact_id",
|
||||
choices = get_contact_choices(conn),
|
||||
selected = e$contact_id)
|
||||
|
||||
# Postings
|
||||
lapply(seq_len(nrow(alle)), function(i) {
|
||||
updateSelectizeInput(session, paste0("account_id_", i),
|
||||
choices = get_account_choices(conn),
|
||||
selected = alle$account_id[i])
|
||||
updateSelectizeInput(session, paste0("project_id_", i),
|
||||
choices = get_project_choices(conn),
|
||||
selected = alle$project_id[i])
|
||||
})
|
||||
}, once = TRUE)
|
||||
})
|
||||
|
||||
# Speichern-Logik
|
||||
observeEvent(input$speichern, {
|
||||
alle <- entry_postings()
|
||||
lapply(seq_len(nrow(alle)), function(i) {
|
||||
# update posting i in DB
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
get_project_choices <- function(conn) {
|
||||
projekte <- tbl(conn, "projects") |>
|
||||
select(id, projektname) |>
|
||||
collect() |>
|
||||
arrange(projektname)
|
||||
|
||||
choices <- setNames(as.character(projekte$id), projekte$projektname)
|
||||
c("-" = "", choices)
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,13 @@
|
||||
Version: 1.0
|
||||
|
||||
RestoreWorkspace: Default
|
||||
SaveWorkspace: Default
|
||||
AlwaysSaveHistory: Default
|
||||
|
||||
EnableCodeIndexing: Yes
|
||||
UseSpacesForTab: Yes
|
||||
NumSpacesForTab: 2
|
||||
Encoding: UTF-8
|
||||
|
||||
RnwWeave: Sweave
|
||||
LaTeX: pdfLaTeX
|
||||
@@ -0,0 +1,19 @@
|
||||
library("dbplyr")
|
||||
library("tidyverse")
|
||||
library("shiny")
|
||||
library("DBI")
|
||||
library("RSQLite")
|
||||
library("dbx")
|
||||
library("shinydashboard")
|
||||
library("reactable")
|
||||
library("conflicted")
|
||||
library("R.utils")
|
||||
|
||||
conflicts_prefer(dplyr::select)
|
||||
conflicts_prefer(dplyr::filter)
|
||||
|
||||
options(shiny.reactlog = TRUE)
|
||||
options(shiny.error = browser)
|
||||
|
||||
conn <- dbConnect(RSQLite::SQLite(), "db/development.sqlite3")
|
||||
sourceDirectory("R/")
|
||||
@@ -0,0 +1,5 @@
|
||||
server <- function(input, output) {
|
||||
|
||||
buchungenServer("buchungen_tab")
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
## ui.R ##
|
||||
dashboardPage(
|
||||
dashboardHeader(),
|
||||
## Sidebar content
|
||||
dashboardSidebar(
|
||||
sidebarMenu(
|
||||
menuItem("buchungen", tabName = "buchungen", icon = icon("dashboard")),
|
||||
menuItem("konten", tabName = "Konten", icon = icon("th"))
|
||||
)
|
||||
),
|
||||
dashboardBody(
|
||||
tabItems(
|
||||
# First tab content
|
||||
tabItem(tabName = "buchungen",
|
||||
buchungenUI("buchungen_tab")
|
||||
),
|
||||
|
||||
# Second tab content
|
||||
tabItem(tabName = "widgets",
|
||||
h2("Widgets tab content")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
Reference in New Issue
Block a user