Compare commits
17 Commits
089a930488
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 479f455f86 | |||
| f960e390d9 | |||
| dc7effe9b7 | |||
| e28c8b6a9c | |||
| e27ee5fd0b | |||
| 2e7933ad58 | |||
| 88de12e0b0 | |||
| 6ae86577aa | |||
| b5d7e435c1 | |||
| f52d5fa3dd | |||
| 4175690455 | |||
| 12ef7693d5 | |||
| 0bbb656d22 | |||
| 1f0b9eb214 | |||
| 23e3c3d4fb | |||
| a0e2fb986d | |||
| db63fecded |
@@ -5,3 +5,4 @@
|
|||||||
.Ruserdata
|
.Ruserdata
|
||||||
www/attachments/
|
www/attachments/
|
||||||
|
|
||||||
|
.positai
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>gemfin-shiny</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.statet.r.resourceProjects.RBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.statet.ide.resourceProjects.Statet</nature>
|
||||||
|
<nature>org.eclipse.statet.r.resourceProjects.R</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
num_inp <- function(id, betrag, ro = FALSE){
|
||||||
|
autonumericInput(
|
||||||
|
inputId = id,
|
||||||
|
label = NULL,
|
||||||
|
width = "100%",
|
||||||
|
value = betrag,
|
||||||
|
currencySymbol = "",
|
||||||
|
currencySymbolPlacement = "s",
|
||||||
|
align = "right",
|
||||||
|
readOnly = ro,
|
||||||
|
style = "height: 15px !important; padding: 1px 1px;"
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
f_reactable <- function(daten, coldefs = NULL, selection = "single",
|
f_reactable <- function(daten, coldefs = NULL, selection = "single",
|
||||||
defaultSelected = NULL, hoehe = NULL, highlight_valuta = NULL) {
|
defaultSelected = NULL, hoehe = NULL, highlight_valuta = NULL, filterable = T) {
|
||||||
reactable(
|
reactable(
|
||||||
daten,
|
daten,
|
||||||
selection = selection,
|
selection = selection,
|
||||||
@@ -7,7 +7,8 @@ f_reactable <- function(daten, coldefs = NULL, selection = "single",
|
|||||||
pagination = F,
|
pagination = F,
|
||||||
defaultPageSize = 17,
|
defaultPageSize = 17,
|
||||||
showPageSizeOptions = TRUE,
|
showPageSizeOptions = TRUE,
|
||||||
filterable = TRUE,
|
defaultSorted = list(valuta = "desc"),
|
||||||
|
filterable = filterable,
|
||||||
highlight = TRUE,
|
highlight = TRUE,
|
||||||
height = hoehe, # <--- FIXIERT DEN HEADER und macht den Body scrollbar
|
height = hoehe, # <--- FIXIERT DEN HEADER und macht den Body scrollbar
|
||||||
bordered = TRUE,
|
bordered = TRUE,
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ accountsServer <- function(id, conn, r_global) {
|
|||||||
# ── Gewähltes Konto ────────────────────────────────────────────────────────
|
# ── Gewähltes Konto ────────────────────────────────────────────────────────
|
||||||
selected_name <- reactive({
|
selected_name <- reactive({
|
||||||
sel <- get_selected(input$account_tree, format = "names")
|
sel <- get_selected(input$account_tree, format = "names")
|
||||||
cat("raw selected:", paste(sel, collapse=", "), "\n")
|
|
||||||
if (length(sel) == 0) return(NULL)
|
if (length(sel) == 0) return(NULL)
|
||||||
name <- sub(" \\(\\d+\\)$", "", sel[[1]])
|
name <- sub(" \\(\\d+\\)$", "", sel[[1]])
|
||||||
cat("cleaned name:", name, "\n")
|
cat("cleaned name:", name, "\n")
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ contactsUI <- function(id) {
|
|||||||
),
|
),
|
||||||
fluidRow(
|
fluidRow(
|
||||||
column(4, actionBttn(ns("add"), "Neu", size = "sm", style = "material-flat", color = "warning", icon = icon("plus"), block = T)),
|
column(4, actionBttn(ns("add"), "Neu", size = "sm", style = "material-flat", color = "warning", icon = icon("plus"), block = T)),
|
||||||
column(4, actionBttn(ns("del"), "Löschen", size = "sm", style = "material-flat", color = "danger", icon = icon("thrash"), block = T)),
|
column(4, actionBttn(ns("del"), "Löschen", size = "sm", style = "material-flat", color = "danger", icon = icon("trash"), block = T)),
|
||||||
column(4, actionBttn(ns("save"), "Speichern", size = "sm", style = "material-flat", color = "success", icon = icon("floppy-disk"), block = T)),
|
column(4, actionBttn(ns("save"), "Speichern", size = "sm", style = "material-flat", color = "success", icon = icon("floppy-disk"), block = T)),
|
||||||
),
|
),
|
||||||
br(),
|
br(),
|
||||||
@@ -119,6 +119,7 @@ contactsServer <- function(id, conn, r_global) {
|
|||||||
valuta = colDef(name = "Wertstellung", minWidth = 80),
|
valuta = colDef(name = "Wertstellung", minWidth = 80),
|
||||||
account_name = colDef( name = "Konto", minWidth = 150 ),
|
account_name = colDef( name = "Konto", minWidth = 150 ),
|
||||||
projektname = colDef(name = "Projekt", minWidth = 150),
|
projektname = colDef(name = "Projekt", minWidth = 150),
|
||||||
|
|
||||||
amount = colDef(name = "Betrag", minWidth = 150)
|
amount = colDef(name = "Betrag", minWidth = 150)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ read_posting <- function(conn, id){
|
|||||||
dbxSelect(conn, paste0("SELECT * FROM postings WHERE id =", id))
|
dbxSelect(conn, paste0("SELECT * FROM postings WHERE id =", id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
read_buch_entries <- function(conn, idwert){
|
||||||
|
dbxSelect(conn, paste0("SELECT id, entry_id, valuta, account_id, project_id, amount FROM postings WHERE entry_id=", idwert))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
coldef_entries_tabelle <-
|
coldef_entries_tabelle <-
|
||||||
list(
|
list(
|
||||||
|
|||||||
+147
-146
@@ -1,26 +1,60 @@
|
|||||||
# module_buchungen.R
|
##
|
||||||
|
## Datum : 2026-04-29_08-17
|
||||||
|
## Name : Christian Oswald
|
||||||
|
## Datei : buchungen_mod.R
|
||||||
|
## Projekt : gemfin-shiny
|
||||||
|
## Kommentar: Modul für die Anzeige der Buchungen - praktisch Hauptformular
|
||||||
|
##
|
||||||
|
|
||||||
|
## * UI ----
|
||||||
buchungenUI <- function(id) {
|
buchungenUI <- function(id) {
|
||||||
ns <- NS(id)
|
ns <- NS(id)
|
||||||
tagList(
|
tagList(
|
||||||
useShinyjs(),
|
useShinyjs(),
|
||||||
|
## ** Tabelle ----
|
||||||
h3("Hauptbuchungen"),
|
h3("Hauptbuchungen"),
|
||||||
reactableOutput(ns("buchungen_table")),
|
fluidRow(
|
||||||
hr(),
|
column(8, reactableOutput(ns("buchungen_table")),
|
||||||
h3("Details / Gegenbuchungen"),
|
num_inp(ns("saldo"), 0, ro = T),
|
||||||
reactableOutput(ns("details_table")),
|
div(
|
||||||
h3("Anhänge"),
|
style = "display: flex; justify-content: flex-end; margin-top: 5px;",
|
||||||
uiOutput(ns("attachments_ui")),
|
|
||||||
fileInput(ns("anhang"), NULL, multiple = TRUE,
|
|
||||||
accept = c(".pdf", ".jpg", ".png", ".xlsx", ".docx"),
|
|
||||||
width = "100%"),
|
|
||||||
br(),
|
|
||||||
actionBttn(ns("add_trans"), "Transaktion hinzu", size = "sm", style = "material-flat", color = "warning"),
|
|
||||||
actionBttn(ns("del_trans"), "Transaktion Löschen", size = "sm", style = "material-flat", color = "danger"),
|
|
||||||
actionBttn(ns("add_detail"), "Detail hinzu", size = "sm", style = "material-flat", color = "success"),
|
|
||||||
|
|
||||||
# Das UI-Element des Moduls (auch wenn es leer ist)
|
),
|
||||||
postingModuleUI(ns("posting_modal"))
|
hr(),
|
||||||
|
## ** Gegenbuchungen ----
|
||||||
|
h3("Details / Gegenbuchungen"),
|
||||||
|
uiOutput(ns("details_table")) ,
|
||||||
|
),
|
||||||
|
## ** Eingabefelder ----
|
||||||
|
column(4,
|
||||||
|
selectizeInput(ns("contact"), label = "Kontakt", choices = get_contact_choices(conn),
|
||||||
|
selected = NA, width = "100%"),
|
||||||
|
textAreaInput(ns("note"), label = "Verwendungszweck", value = NA, width = "100%"),
|
||||||
|
|
||||||
|
## ** Anhänge ----
|
||||||
|
h3("Dateien"),
|
||||||
|
uiOutput(ns("attachments_ui")),
|
||||||
|
fileInput(ns("anhang"), NULL, multiple = TRUE,
|
||||||
|
accept = c(".pdf", ".jpg", ".png", ".xlsx", ".docx"),
|
||||||
|
width = "100%"),
|
||||||
|
## ** Buttons ----
|
||||||
|
div(
|
||||||
|
style = "display: flex; flex-direction: column; gap: 10px; align-items: flex-start;",
|
||||||
|
|
||||||
|
actionBttn(ns("add_detail"), "Detail hinzu",
|
||||||
|
size = "sm", style = "material-flat", color = "default", block = TRUE),
|
||||||
|
actionBttn(ns("del_detail"), "Detail Löschen",
|
||||||
|
size = "sm", style = "material-flat", color = "danger", block = TRUE),
|
||||||
|
actionBttn(ns("add_trans"), "Transaktion hinzu",
|
||||||
|
size = "sm", style = "material-flat", color = "default", block = TRUE),
|
||||||
|
|
||||||
|
actionBttn(ns("del_trans"), "Transaktion Löschen",
|
||||||
|
size = "sm", style = "material-flat", color = "danger", block = TRUE),
|
||||||
|
actionBttn(ns("save_trans"), "Transaktion speichern",
|
||||||
|
size = "sm", style = "material-flat", color = "success", block = TRUE, icon = icon("floppy-disk")),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,22 +62,18 @@ buchungenServer <- function(id, conn, r_global) {
|
|||||||
moduleServer(id, function(input, output, session) {
|
moduleServer(id, function(input, output, session) {
|
||||||
ns <- session$ns
|
ns <- session$ns
|
||||||
|
|
||||||
# ── Reactive Variablen ----
|
## ** Reactive Variablen ----
|
||||||
postings_data <- reactiveVal(read_buch_tabelle(conn))
|
postings_data <- reactiveVal(read_buch_tabelle(conn))
|
||||||
details_data <- reactiveVal(NULL)
|
sel_details <- reactiveVal(NULL)
|
||||||
selected_trans_id <- reactiveVal(NULL)
|
selected_entry_id <- reactiveVal(NULL)
|
||||||
current_main_idx <- reactiveVal(NULL)
|
reset_trigger <- reactiveVal(NULL)
|
||||||
reset_trigger <- reactiveVal(0)
|
current_main_idx <- reactiveVal(NULL)
|
||||||
modal_trigger <- reactiveVal(list(post_id = NULL, counter = 0))
|
|
||||||
highlighted_valuta <- reactiveVal(NULL)
|
|
||||||
|
|
||||||
update_db_trigger <- postingModuleServer(
|
|
||||||
"posting_modal", conn, selected_trans_id, modal_trigger
|
|
||||||
)
|
|
||||||
|
|
||||||
# ── Filter ----
|
|
||||||
|
|
||||||
|
## ** Filter ----
|
||||||
aktiver_filter <- reactive(r_global$buchungen_filter)
|
aktiver_filter <- reactive(r_global$buchungen_filter)
|
||||||
|
|
||||||
gefilterte_daten <- reactive({
|
gefilterte_daten <- reactive({
|
||||||
d <- postings_data()
|
d <- postings_data()
|
||||||
f <- aktiver_filter()
|
f <- aktiver_filter()
|
||||||
@@ -58,37 +88,7 @@ buchungenServer <- function(id, conn, r_global) {
|
|||||||
else d
|
else d
|
||||||
})
|
})
|
||||||
|
|
||||||
observeEvent(aktiver_filter(), {
|
## ** Haupttabelle rendern ----
|
||||||
current_main_idx(NULL)
|
|
||||||
selected_trans_id(NULL)
|
|
||||||
details_data(NULL)
|
|
||||||
})
|
|
||||||
|
|
||||||
# ── Sprung von anderem Modul ----
|
|
||||||
observeEvent(r_global$jump_to_entry_id, ignoreInit = TRUE, {
|
|
||||||
req(r_global$jump_to_entry_id)
|
|
||||||
t_id <- r_global$jump_to_entry_id
|
|
||||||
|
|
||||||
# Daten neu laden
|
|
||||||
postings_data(read_buch_tabelle(conn))
|
|
||||||
|
|
||||||
# Zeile suchen
|
|
||||||
idx <- which(gefilterte_daten()$entry_id == t_id)[1]
|
|
||||||
req(!is.na(idx))
|
|
||||||
|
|
||||||
current_main_idx(idx)
|
|
||||||
selected_trans_id(t_id)
|
|
||||||
details_data(read_buch_tabelle(conn, trans_id = t_id))
|
|
||||||
highlighted_valuta(gefilterte_daten()[idx, "valuta"])
|
|
||||||
|
|
||||||
reset_trigger(isolate(reset_trigger()) + 1)
|
|
||||||
scroll_to_row(ns("buchungen_table"), idx)
|
|
||||||
|
|
||||||
# Sprungziel zurücksetzen
|
|
||||||
r_global$jump_to_entry_id <- NULL
|
|
||||||
})
|
|
||||||
|
|
||||||
# ── Haupttabelle rendern ----
|
|
||||||
output$buchungen_table <- renderReactable({
|
output$buchungen_table <- renderReactable({
|
||||||
reset_trigger()
|
reset_trigger()
|
||||||
f_reactable(
|
f_reactable(
|
||||||
@@ -96,106 +96,106 @@ buchungenServer <- function(id, conn, r_global) {
|
|||||||
coldefs = coldef_entries_tabelle,
|
coldefs = coldef_entries_tabelle,
|
||||||
selection = "single",
|
selection = "single",
|
||||||
hoehe = "60vh",
|
hoehe = "60vh",
|
||||||
defaultSelected = current_main_idx(),
|
filterable = TRUE,
|
||||||
highlight_valuta = highlighted_valuta()
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
## ** Auswahl anzeigen ----
|
||||||
|
sel <- reactive(getReactableState("buchungen_table", "selected"))
|
||||||
|
observeEvent(sel(), ignoreInit = T, {
|
||||||
|
idwert <- gefilterte_daten()$id[sel()]
|
||||||
|
record <- read_posting(conn, idwert)
|
||||||
|
record_entry <- read_entry(conn, record$entry_id)
|
||||||
|
updateSelectizeInput(session, "contact", selected = record_entry$contact_id)
|
||||||
|
updateTextAreaInput(session, "note", value = record_entry$purpose)
|
||||||
|
|
||||||
# ── Details laden ──────────────────────────────────────────────────────────
|
|
||||||
sel_details <- reactive(getReactableState("buchungen_table", "selected"))
|
|
||||||
|
|
||||||
observeEvent(sel_details(), ignoreInit = TRUE, {
|
|
||||||
|
|
||||||
|
output$details_table <- renderUI({
|
||||||
|
req(sel())
|
||||||
|
## *** Daten-Gegenbuchungen laden ----
|
||||||
|
df <- read_buch_entries(conn, gefilterte_daten()$entry_id[sel()])
|
||||||
|
sel_details(df)
|
||||||
|
## *** Gegenbuchungen rendern ----
|
||||||
|
rows <- lapply(1:nrow(df), function(ind) {
|
||||||
|
fluidRow(class = "details-row",
|
||||||
|
# HIER: Index an die ID hängen!
|
||||||
|
column(1, numericInput(ns(paste0("id_", ind)), label = NULL, width = "100%", value = df$id[ind])),
|
||||||
|
column(2, dateInput(ns(paste0("valuta_", ind)), label = NULL, width = "100%", value = df$valuta[ind])),
|
||||||
|
column(3, selectizeInput(ns(paste0("account_", ind)), label = NULL,
|
||||||
|
choices = get_account_choices(conn),
|
||||||
|
selected = df$account_id[ind], width = "100%")),
|
||||||
|
column(3, selectizeInput(ns(paste0("projekt_", ind)), label = NULL,
|
||||||
|
choices = get_project_choices(conn),
|
||||||
|
selected = df$projekt_id[ind], width = "100%")),
|
||||||
|
column(2, numericInput(ns(paste0("betrag_", ind)), label = NULL, width = "100%", value = df$amount[ind]))
|
||||||
|
)
|
||||||
|
})
|
||||||
|
tagList(rows)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
observeEvent(input$save_trans, {
|
||||||
req(sel_details())
|
req(sel_details())
|
||||||
highlighted_valuta(gefilterte_daten()[sel_details(), "valuta"])
|
n_rows <- nrow(sel_details())
|
||||||
current_main_idx(sel_details())
|
# Alle Zeilen in einer Liste sammeln
|
||||||
t_id <- gefilterte_daten()[sel_details(), "entry_id"] |> pull()
|
all_records <- lapply(1:n_rows, function(ind) {
|
||||||
selected_trans_id(t_id)
|
data.frame(
|
||||||
details_data(read_buch_tabelle(conn, trans_id = t_id))
|
id = as.integer(input[[paste0("id_", ind)]]),
|
||||||
|
valuta = as.Date(input[[paste0("valuta_", ind)]]),
|
||||||
|
amount = as.numeric(input[[paste0("betrag_", ind)]]),
|
||||||
|
account_id = input[[paste0("account_", ind)]],
|
||||||
|
projekt_id = input[[paste0("projekt_", ind)]],
|
||||||
|
stringsAsFactors = FALSE
|
||||||
|
)
|
||||||
|
})
|
||||||
|
# Zu einem großen Dataframe zusammenfügen
|
||||||
|
final_df <- do.call(rbind, all_records)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Datenbank-Update-Logik
|
||||||
|
tryCatch({
|
||||||
|
# Beispiel: Für jede Zeile ein Update ausführen
|
||||||
|
for(i in 1:nrow(final_df)) {
|
||||||
|
update_buchung_detail(conn, final_df[i, ]) # Deine DB-Funktion
|
||||||
|
}
|
||||||
|
|
||||||
|
showNotification("Daten erfolgreich gespeichert", type = "message")
|
||||||
|
|
||||||
|
# Optional: Haupttabelle aktualisieren, falls sich Summen geändert haben
|
||||||
|
# trigger_refresh(trigger_refresh() + 1)
|
||||||
|
|
||||||
|
}, error = function(e) {
|
||||||
|
showNotification(paste("Fehler beim Speichern:", e$message), type = "error")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
output$details_table <- renderReactable({
|
|
||||||
req(details_data())
|
|
||||||
f_reactable(
|
|
||||||
details_data(),
|
|
||||||
coldefs = coldef_entries_tabelle,
|
|
||||||
selection = "single",
|
|
||||||
hoehe = NULL
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
# ── Detail hinzufügen ----
|
## ** Anhänge ----
|
||||||
observeEvent(input$add_detail, {
|
|
||||||
req(selected_trans_id())
|
|
||||||
modal_trigger(list(post_id = NULL, counter = modal_trigger()$counter + 1))
|
|
||||||
})
|
|
||||||
|
|
||||||
# ── Detail editieren ----
|
|
||||||
sel_detail <- reactive(getReactableState("details_table", "selected"))
|
|
||||||
|
|
||||||
observeEvent(sel_detail(), ignoreInit = TRUE, {
|
|
||||||
p_id <- details_data()$id[sel_detail()]
|
|
||||||
modal_trigger(list(post_id = p_id, counter = modal_trigger()$counter + 1))
|
|
||||||
})
|
|
||||||
|
|
||||||
# ── DB-Update durch Modal ----
|
|
||||||
observeEvent(update_db_trigger(), ignoreInit = TRUE, {
|
|
||||||
req(selected_trans_id())
|
|
||||||
details_data(read_buch_tabelle(conn, trans_id = selected_trans_id()))
|
|
||||||
postings_data(read_buch_tabelle(conn))
|
|
||||||
updateReactable("buchungen_table", data = gefilterte_daten())
|
|
||||||
})
|
|
||||||
|
|
||||||
# ── Neue Transaktion ----
|
|
||||||
observeEvent(input$add_trans, {
|
|
||||||
new_t_id <- max_id(conn, "entries") + 1
|
|
||||||
dbxInsert(conn, "entries", data.frame(id = new_t_id))
|
|
||||||
p_id1 <- max_id(conn, "postings") + 1
|
|
||||||
p_id2 <- p_id1 + 1
|
|
||||||
dbxInsert(conn, "postings", data.frame(
|
|
||||||
id = c(p_id1, p_id2),
|
|
||||||
entry_id = c(new_t_id, new_t_id),
|
|
||||||
amount = c(0, 0),
|
|
||||||
account_id = c(0, 0),
|
|
||||||
valuta = c(Sys.Date(), Sys.Date())
|
|
||||||
))
|
|
||||||
|
|
||||||
# Filter zurücksetzen damit neue Transaktion sichtbar ist
|
|
||||||
r_global$buchungen_filter <- "alle"
|
|
||||||
|
|
||||||
postings_data(read_buch_tabelle(conn))
|
|
||||||
selected_trans_id(new_t_id)
|
|
||||||
details_data(read_buch_tabelle(conn, trans_id = new_t_id))
|
|
||||||
|
|
||||||
neue_zeile <- which(postings_data()$id == p_id1)
|
|
||||||
current_main_idx(neue_zeile)
|
|
||||||
reset_trigger(isolate(reset_trigger()) + 1)
|
|
||||||
scroll_to_row(ns("buchungen_table"), neue_zeile)
|
|
||||||
})
|
|
||||||
|
|
||||||
# ── Transaktion löschen ----
|
|
||||||
observeEvent(input$del_trans, ignoreInit = TRUE, {
|
|
||||||
req(selected_trans_id())
|
|
||||||
dbxDelete(conn, "postings", where = data.frame(entry_id = selected_trans_id()))
|
|
||||||
dbxDelete(conn, "entries", where = data.frame(id = selected_trans_id()))
|
|
||||||
postings_data(read_buch_tabelle(conn))
|
|
||||||
current_main_idx(NULL)
|
|
||||||
selected_trans_id(NULL)
|
|
||||||
details_data(NULL)
|
|
||||||
updateReactable("buchungen_table", data = gefilterte_daten())
|
|
||||||
})
|
|
||||||
|
|
||||||
# ── Anhänge ----
|
|
||||||
output$attachments_ui <- renderUI({
|
output$attachments_ui <- renderUI({
|
||||||
req(selected_trans_id())
|
req(sel_details())
|
||||||
att <- dbxSelect(conn, paste0(
|
selected_entry_id(dbxSelect(conn, paste0("SELECT entry_id FROM postings WHERE id=",
|
||||||
"SELECT * FROM attachments WHERE entry_id = ", selected_trans_id()
|
sel_details()$id[1])) %>%
|
||||||
))
|
pull )
|
||||||
|
print(selected_entry_id())
|
||||||
|
att <- dbxSelect(conn, paste0("SELECT * FROM attachments WHERE entry_id = ", selected_entry_id() ))
|
||||||
if (nrow(att) == 0) return(p("Keine Anhänge vorhanden."))
|
if (nrow(att) == 0) return(p("Keine Anhänge vorhanden."))
|
||||||
|
## *** Anhänge anzeigen ----
|
||||||
tagList(lapply(seq_len(nrow(att)), function(i) {
|
tagList(lapply(seq_len(nrow(att)), function(i) {
|
||||||
ext <- tools::file_ext(att$original_name[i])
|
ext <- tools::file_ext(att$original_name[i])
|
||||||
filename <- paste0("attachments/", att$id[i], ".", ext)
|
filename <- paste0("documents/", att$id[i], ".", ext)
|
||||||
|
|
||||||
|
## *** Anhang öffnen ----
|
||||||
observeEvent(input[[paste0("open_att_", att$id[i])]], {
|
observeEvent(input[[paste0("open_att_", att$id[i])]], {
|
||||||
showModal(modalDialog(
|
showModal(modalDialog(
|
||||||
tags$iframe(src = filename, width = "100%", height = "600px",
|
tags$iframe(src = filename, width = "100%", height = "600px",
|
||||||
@@ -207,6 +207,7 @@ buchungenServer <- function(id, conn, r_global) {
|
|||||||
))
|
))
|
||||||
}, ignoreInit = TRUE, once = FALSE)
|
}, ignoreInit = TRUE, once = FALSE)
|
||||||
|
|
||||||
|
## *** Buttons Anhänge ----
|
||||||
div(
|
div(
|
||||||
actionLink(ns(paste0("open_att_", att$id[i])), att$original_name[i]),
|
actionLink(ns(paste0("open_att_", att$id[i])), att$original_name[i]),
|
||||||
actionLink(ns(paste0("del_att_", att$id[i])), "✕",
|
actionLink(ns(paste0("del_att_", att$id[i])), "✕",
|
||||||
|
|||||||
@@ -27,3 +27,4 @@ resolve_contact <- function(conn, empfaenger_name, empfaenger_konto) {
|
|||||||
collect()
|
collect()
|
||||||
if (nrow(bc) > 0) bc$contact_id[1] else NA_integer_
|
if (nrow(bc) > 0) bc$contact_id[1] else NA_integer_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+87
-32
@@ -4,11 +4,15 @@ umsatzUI <- function(id) {
|
|||||||
useShinyjs(),
|
useShinyjs(),
|
||||||
# Sync-Button oben
|
# Sync-Button oben
|
||||||
div(
|
div(
|
||||||
style = "display: flex; justify-content: flex-end; margin-bottom: 8px;",
|
style = "display: flex; justify-content: flex-end; margin-bottom: 8px; gap: 8px;",
|
||||||
|
actionBttn(ns("deselect_all"), "Auswahl aufheben",
|
||||||
|
size = "xs", style = "minimal",
|
||||||
|
icon = icon("xmark"), color = "default"),
|
||||||
actionBttn(ns("sync"), "Sync Hibiscus",
|
actionBttn(ns("sync"), "Sync Hibiscus",
|
||||||
size = "xs", style = "minimal",
|
size = "xs", style = "minimal",
|
||||||
icon = icon("rotate"), color = "primary")
|
icon = icon("rotate"), color = "primary")
|
||||||
),
|
),
|
||||||
|
|
||||||
# Buchungspanel immer sichtbar unten
|
# Buchungspanel immer sichtbar unten
|
||||||
uiOutput(ns("buchungs_panel")),
|
uiOutput(ns("buchungs_panel")),
|
||||||
# Tabelle mit begrenzter Höhe und Scroll
|
# Tabelle mit begrenzter Höhe und Scroll
|
||||||
@@ -78,7 +82,7 @@ umsatzServer <- function(id, conn, r_global) {
|
|||||||
}"),
|
}"),
|
||||||
filterable = F,
|
filterable = F,
|
||||||
pagination = F,
|
pagination = F,
|
||||||
selection = "single",
|
selection = "multiple",
|
||||||
onClick = "select",
|
onClick = "select",
|
||||||
defaultSorted = list(valuta = "desc"),
|
defaultSorted = list(valuta = "desc"),
|
||||||
columns = list(
|
columns = list(
|
||||||
@@ -128,18 +132,46 @@ umsatzServer <- function(id, conn, r_global) {
|
|||||||
# ── Buchungs-Panel ----
|
# ── Buchungs-Panel ----
|
||||||
output$buchungs_panel <- renderUI({
|
output$buchungs_panel <- renderUI({
|
||||||
req(selected_umsatz())
|
req(selected_umsatz())
|
||||||
u <- selected_umsatz()
|
rows <- selected_umsatz()
|
||||||
|
|
||||||
if (u$gebucht) {
|
alle_gebucht <- all(rows$gebucht)
|
||||||
|
manche_gebucht <- any(rows$gebucht) && !alle_gebucht
|
||||||
|
keine_gebucht <- !any(rows$gebucht)
|
||||||
|
|
||||||
|
if (alle_gebucht && nrow(rows) == 1) {
|
||||||
|
# Einzelauswahl, bereits gebucht → Sprung-Button
|
||||||
tagList(
|
tagList(
|
||||||
h4("Bereits gebucht"),
|
h4("Bereits gebucht"),
|
||||||
actionBttn(ns("goto_buchung"),
|
actionBttn(ns("goto_buchung"),
|
||||||
paste0("→ Zur Buchung (Entry #", u$entry_id, ")"),
|
paste0("→ Zur Buchung (Entry #", rows$entry_id, ")"),
|
||||||
size = "sm", style = "minimal", color = "primary")
|
size = "sm", style = "minimal", color = "primary")
|
||||||
)
|
)
|
||||||
|
} else if (manche_gebucht) {
|
||||||
|
div(style = "color: orange;",
|
||||||
|
icon("triangle-exclamation"),
|
||||||
|
strong(paste0(sum(rows$gebucht), " von ", nrow(rows),
|
||||||
|
" Umsätzen bereits gebucht – bitte nur ungebuchte auswählen."))
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
|
# Alle ungebucht → Buchungsformular
|
||||||
|
info_text <- if (nrow(rows) > 1) {
|
||||||
|
tags$p(style = "color: steelblue; font-size: 0.9em;",
|
||||||
|
icon("info-circle"),
|
||||||
|
paste0(nrow(rows), " Umsätze ausgewählt – ",
|
||||||
|
"Konto/Projekt/Kontakt werden für alle verwendet.")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Kontakt: bei Mehrfachauswahl keinen Auto-Resolve
|
||||||
|
kontakt_selected <- if (nrow(rows) == 1) {
|
||||||
|
resolve_contact(conn, rows$empfaenger_name, rows$empfaenger_konto)
|
||||||
|
} else {
|
||||||
|
NULL
|
||||||
|
}
|
||||||
|
|
||||||
tagList(
|
tagList(
|
||||||
h4("Buchen"),
|
h4(if (nrow(rows) == 1) "Buchen" else paste0(nrow(rows), " Umsätze buchen")),
|
||||||
|
info_text,
|
||||||
fluidRow(
|
fluidRow(
|
||||||
column(4,
|
column(4,
|
||||||
selectizeInput(ns("konto"), "Konto:",
|
selectizeInput(ns("konto"), "Konto:",
|
||||||
@@ -155,11 +187,11 @@ umsatzServer <- function(id, conn, r_global) {
|
|||||||
column(3,
|
column(3,
|
||||||
selectizeInput(ns("kontakt"), "Kontakt:",
|
selectizeInput(ns("kontakt"), "Kontakt:",
|
||||||
choices = get_contact_choices(conn),
|
choices = get_contact_choices(conn),
|
||||||
selected = resolve_contact(conn, u$empfaenger_name, u$empfaenger_konto),
|
selected = kontakt_selected,
|
||||||
width = "100%")
|
width = "100%")
|
||||||
),
|
),
|
||||||
column(1,
|
column(1,
|
||||||
div(style = "margin-top: 25px;", # Label-Höhe ausgleichen
|
div(style = "margin-top: 25px;",
|
||||||
actionBttn(ns("new_contact"), "Neuer Kontakt",
|
actionBttn(ns("new_contact"), "Neuer Kontakt",
|
||||||
size = "xs", style = "minimal", icon = icon("plus"), color = "warning")
|
size = "xs", style = "minimal", icon = icon("plus"), color = "warning")
|
||||||
)
|
)
|
||||||
@@ -186,36 +218,55 @@ umsatzServer <- function(id, conn, r_global) {
|
|||||||
|
|
||||||
# ── Buchen ----
|
# ── Buchen ----
|
||||||
observeEvent(input$buchen, {
|
observeEvent(input$buchen, {
|
||||||
req(selected_umsatz(), input$konto)
|
req(selected_umsatz(), input$konto, input$konto != 0)
|
||||||
u <- selected_umsatz()
|
rows <- selected_umsatz()
|
||||||
|
rows <- rows %>% filter(!gebucht)
|
||||||
|
req(nrow(rows) > 0)
|
||||||
|
|
||||||
gegenkonto_id <- dbReadTable(conn, "accounts") %>%
|
bank_connections <- dbReadTable(conn, "bank_connections")
|
||||||
filter(hibiscus_account_id == u$konto_id) %>%
|
|
||||||
pull(id)
|
|
||||||
|
|
||||||
req(length(gegenkonto_id) > 0, input$konto != 0)
|
for (i in seq_len(nrow(rows))) {
|
||||||
|
u <- rows[i, ]
|
||||||
|
gegenkonto_id <- dbReadTable(conn, "accounts") %>%
|
||||||
|
filter(hibiscus_account_id == u$konto_id) %>%
|
||||||
|
pull(id)
|
||||||
|
if (length(gegenkonto_id) == 0) next
|
||||||
|
|
||||||
new_t_id <- max_id(conn, "entries") + 1L
|
# contact_id: manuell gewählt oder aus bank_connections
|
||||||
dbxInsert(conn, "entries", data.frame(
|
contact_id <- if (!is.null(input$kontakt) && as.integer(input$kontakt) != 0) {
|
||||||
id = new_t_id,
|
as.integer(input$kontakt)
|
||||||
contact_id = as.integer(input$kontakt),
|
} else {
|
||||||
note = u$zweck
|
match <- bank_connections %>%
|
||||||
))
|
filter(contact_text == u$empfaenger_name) %>%
|
||||||
|
pull(contact_id)
|
||||||
|
if (length(match) > 0) as.integer(match[[1]]) else NA_integer_
|
||||||
|
}
|
||||||
|
|
||||||
p_id1 <- max_id(conn, "postings") + 1L
|
new_t_id <- max_id(conn, "entries") + 1L
|
||||||
dbxInsert(conn, "postings", data.frame(
|
dbxInsert(conn, "entries", data.frame(
|
||||||
id = c(p_id1, p_id1 + 1L),
|
id = new_t_id,
|
||||||
entry_id = c(new_t_id, new_t_id),
|
contact_id = contact_id,
|
||||||
account_id = c(as.integer(input$konto), gegenkonto_id),
|
note = u$zweck
|
||||||
project_id = c(as.integer(input$projekt), NA_integer_),
|
))
|
||||||
amount = c(u$betrag, -u$betrag),
|
|
||||||
valuta = c(as.character(u$valuta), as.character(u$valuta)),
|
p_id1 <- max_id(conn, "postings") + 1L
|
||||||
booking_date = c(as.character(u$datum), as.character(u$datum)),
|
dbxInsert(conn, "postings", data.frame(
|
||||||
bank_transaction_id = c(u$id, NA_integer_)
|
id = c(p_id1, p_id1 + 1L),
|
||||||
))
|
entry_id = c(new_t_id, new_t_id),
|
||||||
|
account_id = c(as.integer(input$konto), gegenkonto_id),
|
||||||
|
project_id = c(as.integer(input$projekt), NA_integer_),
|
||||||
|
amount = c(u$betrag, -u$betrag),
|
||||||
|
valuta = c(as.character(u$valuta), as.character(u$valuta)),
|
||||||
|
booking_date = c(as.character(u$datum), as.character(u$datum)),
|
||||||
|
bank_transaction_id = c(u$id, NA_integer_)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
refresh(refresh() + 1)
|
refresh(refresh() + 1)
|
||||||
showNotification("✓ Gebucht", type = "message")
|
showNotification(
|
||||||
|
paste0("✓ ", nrow(rows), " Umsatz/Umsätze gebucht"),
|
||||||
|
type = "message"
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
# ── Neuer Kontakt / Bankverbindung ----
|
# ── Neuer Kontakt / Bankverbindung ----
|
||||||
@@ -277,6 +328,10 @@ umsatzServer <- function(id, conn, r_global) {
|
|||||||
showNotification(msg, type = "message")
|
showNotification(msg, type = "message")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
## ** Auswahl aufheben ----
|
||||||
|
observeEvent(input$deselect_all, {
|
||||||
|
updateReactable("umsatz_table", selected = NA, session = session)
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
##
|
||||||
|
## Datum : 2026-05-13_09-37
|
||||||
|
## Name : Christian Oswald
|
||||||
|
## Datei : sync_hibiscus.R
|
||||||
|
## Projekt : gemfin-shiny
|
||||||
|
## Kommentar: Liest Daten aus der Hibiscus Datenbank
|
||||||
|
##
|
||||||
|
|
||||||
|
## * Initialisierung ----
|
||||||
|
|
||||||
|
sync_hibiscus <- function(){
|
||||||
|
if (as.character(Sys.info())[1] == "Linux") {
|
||||||
|
jdbc_url <- "jdbc:h2:/home/cosw/.jameica/hibiscus/h2db/hibiscus;IFEXISTS=TRUE;CIPHER=AES"
|
||||||
|
pw <- "LsOX6Ytldl4lJBcVoA6j+MDLzaA= LsOX6Ytldl4lJBcVoA6j+MDLzaA="
|
||||||
|
}
|
||||||
|
|
||||||
|
if(as.character(Sys.info())[1] == "Windows"){
|
||||||
|
source("c:/Users/chris/R/rfunc/fehler_add.R")
|
||||||
|
url <- "jdbc:h2:~/Insync/Projekte/Gemeindefinanzen/jameica/hibiscus/h2db/hibiscus;IFEXISTS=TRUE;CIPHER=AES"
|
||||||
|
h2jar <- "C:/Users/chris/bin/jameica/lib/h2/migration-h2/disabled/h2-1.4.199.jar"
|
||||||
|
}
|
||||||
|
# JDBC - Verbindung ----
|
||||||
|
if (as.character(Sys.info())[1] == "Darwin") {
|
||||||
|
source("/Users/cosw/R/rfunc/fehler_add.R")
|
||||||
|
h2jar <- "/Users/cosw/bin/jameica.app/lib/h2/migration-h2/disabled/h2-1.4.199.jar"
|
||||||
|
url <- "jdbc:h2:/Users/cosw/insync/Projekte/Gemeindefinanzen/jameica/hibiscus/h2db/hibiscus;IFEXISTS=TRUE;CIPHER=AES"
|
||||||
|
}
|
||||||
|
user <- "hibiscus"
|
||||||
|
pw <- "FbvGoL+yJlH1GtUojnC8ZajYuTA= FbvGoL+yJlH1GtUojnC8ZajYuTA="
|
||||||
|
drv <- JDBC("org.h2.Driver", h2jar, identifier.quote="`")
|
||||||
|
|
||||||
|
con_j <- dbConnect(drv, url, user, pw)
|
||||||
|
originaldaten <- dbReadTable(con_j, "UMSATZ")
|
||||||
|
dbDisconnect(con_j)
|
||||||
|
return(originaldaten)
|
||||||
|
}
|
||||||
+388
-367
@@ -26,30 +26,14 @@ fm_driver_jar <- "~/R/fmjdbc.jar"
|
|||||||
|
|
||||||
sqlite_path <- "db/development.sqlite"
|
sqlite_path <- "db/development.sqlite"
|
||||||
|
|
||||||
# optional future switch
|
|
||||||
USE_CENTS <- FALSE
|
|
||||||
|
|
||||||
# Helpers ----
|
# Helpers ----
|
||||||
|
exec_sql <- function(sql) dbExecute(con_s, sql)
|
||||||
to_cents <- function(x) {
|
f_anzahl <- function(tabelle){
|
||||||
if (is.null(x)) return(NA_integer_)
|
dbxSelect(con_s, paste0("SELECt count(id) FROM ", tabelle)) %>% pull
|
||||||
if (is.factor(x)) x <- as.character(x)
|
|
||||||
|
|
||||||
if (is.character(x)) {
|
|
||||||
x <- trimws(x)
|
|
||||||
x[x == ""] <- NA
|
|
||||||
x <- gsub("\\.", "", x)
|
|
||||||
x <- gsub(",", ".", x)
|
|
||||||
}
|
|
||||||
|
|
||||||
d <- suppressWarnings(as.numeric(x))
|
|
||||||
ifelse(is.na(d), NA_integer_, as.integer(round(d * 100)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exec_sql <- function(sql) dbExecute(con_s, sql)
|
|
||||||
|
|
||||||
# Connections ----
|
# Connections ----
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
drv <- JDBC(fm_driver_class, fm_driver_jar)
|
drv <- JDBC(fm_driver_class, fm_driver_jar)
|
||||||
con_f <- dbConnect(
|
con_f <- dbConnect(
|
||||||
@@ -69,126 +53,395 @@ if (ok) {
|
|||||||
error_f <- fehler_add("SQLite connection established", TRUE, error_f)
|
error_f <- fehler_add("SQLite connection established", TRUE, error_f)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Schema creation ----
|
## * Transfer Accounts ----
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
exec_sql("DROP TABLE IF EXISTS konten;")
|
||||||
exec_sql("CREATE TABLE accounts (
|
exec_sql("CREATE TABLE konten (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
account_name TEXT NOT NULL,
|
kontoname TEXT NOT NULL,
|
||||||
bank_name TEXT,
|
bank_name TEXT,
|
||||||
hibiscus_account_id INTEGER,
|
hibiscus_konto_id INTEGER,
|
||||||
budget_id INTEGER,
|
budget_id INTEGER,
|
||||||
wiso_account TEXT,
|
wiso_kategorie TEXT,
|
||||||
bank_account_no TEXT,
|
bank_konto_nr TEXT,
|
||||||
is_donations INTEGER,
|
ist_spende INTEGER,
|
||||||
notes TEXT,
|
notiz TEXT,
|
||||||
created_at TEXT,
|
created_at TEXT,
|
||||||
updated_at TEXT
|
updated_at TEXT
|
||||||
);")
|
);")
|
||||||
|
|
||||||
|
konten <- dbxSelect(con_f, "
|
||||||
|
SELECT id, konto, budget_id, bankname, updated_at, created_at,
|
||||||
|
konto_hibiscus, konto_wiso, kontonummer_bank, notizen, ist_spende
|
||||||
|
FROM Konten
|
||||||
|
") %>%
|
||||||
|
transmute(
|
||||||
|
id = as.integer(id),
|
||||||
|
kontoname = konto,
|
||||||
|
bank_name = bankname,
|
||||||
|
hibiscus_konto_id = as.integer(konto_hibiscus),
|
||||||
|
budget_id = as.integer(budget_id),
|
||||||
|
wiso_kategorie = konto_wiso,
|
||||||
|
bank_konto_nr = kontonummer_bank,
|
||||||
|
ist_spende = as.integer(ist_spende),
|
||||||
|
notiz = notizen,
|
||||||
|
created_at = created_at,
|
||||||
|
updated_at = updated_at
|
||||||
|
)
|
||||||
|
dbWriteTable(con_s, "konten", konten, append = TRUE)
|
||||||
|
ok <- dbExistsTable(con_s, "konten")
|
||||||
|
ok <- f_anzahl("konten") == nrow(konten) & ok
|
||||||
|
error_f <- fehler_add("Konten übertragen", TRUE, error_f)
|
||||||
|
}
|
||||||
|
|
||||||
|
## * Transfer Projekte ----
|
||||||
|
if (ok) {
|
||||||
|
exec_sql("DROP TABLE IF EXISTS projekte;")
|
||||||
|
exec_sql("CREATE TABLE projekte (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
projektname TEXT NOT NULL,
|
||||||
|
jahr INTEGER,
|
||||||
|
projekt_wiso TEXT,
|
||||||
|
bereich TEXT,
|
||||||
|
notiz TEXT,
|
||||||
|
created_at TEXT,
|
||||||
|
updated_at TEXT
|
||||||
|
);")
|
||||||
|
projekte <- dbxSelect(con_f, "
|
||||||
|
SELECT id, projektname, bereich, notiz, jahr, created_at, updated_at from Projekte") %>%
|
||||||
|
transmute(
|
||||||
|
id = as.integer(id),
|
||||||
|
projektname = projektname,
|
||||||
|
bereich = bereich,
|
||||||
|
notiz = notiz,
|
||||||
|
jahr = as.integer(jahr),
|
||||||
|
created_at = created_at,
|
||||||
|
updated_at = updated_at
|
||||||
|
)
|
||||||
|
|
||||||
|
dbWriteTable(con_s, "projekte", projekte, append = TRUE)
|
||||||
|
ok <- dbExistsTable(con_s, "projekte")
|
||||||
|
ok <- f_anzahl("projekte") == nrow(projekte) & ok
|
||||||
|
error_f <- fehler_add("Projekte übertragen", TRUE, error_f)
|
||||||
|
}
|
||||||
|
|
||||||
|
## * Transfer Budgets ----
|
||||||
|
if (ok) {
|
||||||
|
exec_sql("DROP TABLE IF EXISTS budgets;")
|
||||||
exec_sql("CREATE TABLE budgets (
|
exec_sql("CREATE TABLE budgets (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
row_no INTEGER,
|
reihe INTEGER,
|
||||||
area TEXT,
|
bereich TEXT,
|
||||||
label TEXT,
|
bezeichnung TEXT,
|
||||||
direction TEXT,
|
richtung TEXT,
|
||||||
created_at TEXT,
|
created_at TEXT,
|
||||||
updated_at TEXT
|
updated_at TEXT
|
||||||
);")
|
);")
|
||||||
|
budgets <- dbxSelect(con_f, "
|
||||||
|
SELECT id, richtung, bereich, bezeichnung, reihe
|
||||||
|
FROM Budgets
|
||||||
|
") %>%
|
||||||
|
transmute(
|
||||||
|
id = as.integer(id),
|
||||||
|
reihe = as.integer(reihe),
|
||||||
|
bereich = bereich,
|
||||||
|
bezeichnung = bezeichnung,
|
||||||
|
richtung = richtung,
|
||||||
|
created_at = format(Sys.time(), ""),
|
||||||
|
updated_at = format(Sys.time(), "")
|
||||||
|
)
|
||||||
|
dbWriteTable(con_s, "budgets", budgets, append = TRUE)
|
||||||
|
ok <- dbExistsTable(con_s, "budgets")
|
||||||
|
ok <- f_anzahl("budgets") == nrow(budgets) & ok
|
||||||
|
error_f <- fehler_add("Budgets übertragen", TRUE, error_f)
|
||||||
|
}
|
||||||
|
|
||||||
exec_sql("CREATE TABLE contacts (
|
### ** Transfer Budget-Werte
|
||||||
|
if(ok){
|
||||||
|
exec_sql("DROP TABLE IF EXISTS budget_werte;")
|
||||||
|
exec_sql("CREATE TABLE budget_werte (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
first_name TEXT,
|
budget_id INTEGER,
|
||||||
last_name TEXT,
|
jahr INTEGER,
|
||||||
street TEXT,
|
betrag DECIMAL,
|
||||||
postal_code TEXT,
|
budget_listen_nr INTEGER,
|
||||||
city TEXT,
|
created_at TEXT,
|
||||||
country TEXT,
|
updated_at TEXT
|
||||||
phone TEXT,
|
);")
|
||||||
mobile TEXT,
|
budget_werte <- dbReadTable(con_f, "Budgets_werte") %>%
|
||||||
|
transmute(
|
||||||
|
id = as.integer(id),
|
||||||
|
budget_id = as.integer(budget_id),
|
||||||
|
jahr = as.integer(jahr),
|
||||||
|
betrag = betrag,
|
||||||
|
budget_listen_nr = as.integer(budget_listen_nr),
|
||||||
|
created_at = format(Sys.time(), ""),
|
||||||
|
updated_at = format(Sys.time(), "")
|
||||||
|
)
|
||||||
|
dbWriteTable(con_s, "budget_werte", budget_werte, append = TRUE)
|
||||||
|
ok <- dbExistsTable(con_s, "budget_werte")
|
||||||
|
ok <- f_anzahl("budget_werte") == nrow(budget_werte) & ok
|
||||||
|
error_f <- fehler_add("budget_werte übertragen", TRUE, error_f)
|
||||||
|
} ## ------------------------------------------------------- 2026-06-19 08:52
|
||||||
|
|
||||||
|
|
||||||
|
## * Transfer Adressen ----
|
||||||
|
if (ok) {
|
||||||
|
exec_sql("DROP TABLE IF EXISTS adressen;")
|
||||||
|
exec_sql("CREATE TABLE adressen (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
vorname TEXT,
|
||||||
|
nachname TEXT,
|
||||||
|
strasse TEXT,
|
||||||
|
plz TEXT,
|
||||||
|
ort TEXT,
|
||||||
|
land TEXT,
|
||||||
|
telefon TEXT,
|
||||||
|
mobil TEXT,
|
||||||
email TEXT,
|
email TEXT,
|
||||||
salutation TEXT,
|
anrede TEXT,
|
||||||
gender TEXT,
|
geschlecht TEXT,
|
||||||
donor TEXT,
|
ist_mitglied INTEGER,
|
||||||
member INTEGER,
|
ist_firma INTEGER,
|
||||||
notes TEXT,
|
quittung_anrede TEXT,
|
||||||
receipt_salutation TEXT,
|
quittung_name TEXT,
|
||||||
receipt_name TEXT,
|
|
||||||
display_name TEXT,
|
display_name TEXT,
|
||||||
partner_id INTEGER,
|
partner_id INTEGER,
|
||||||
is_couple INTEGER,
|
notiz TEXT,
|
||||||
is_company INTEGER,
|
|
||||||
created_at TEXT,
|
created_at TEXT,
|
||||||
updated_at TEXT
|
updated_at TEXT
|
||||||
);")
|
);")
|
||||||
|
|
||||||
exec_sql("CREATE TABLE bank_connections (
|
adressen <- dbxSelect(con_f, "
|
||||||
|
SELECT id, vorname, nachname, strasse, plz, ort, Land,
|
||||||
|
telefon, mobil, email, anrede, geschlecht, mitglied, notiz,
|
||||||
|
quittung_anrede, quittung_name, bezeichnung, partner_id, b_paar, b_firma
|
||||||
|
FROM Adressen
|
||||||
|
") %>%
|
||||||
|
as_tibble() %>%
|
||||||
|
transmute(
|
||||||
|
id = as.integer(id),
|
||||||
|
vorname = vorname,
|
||||||
|
nachname = nachname,
|
||||||
|
strasse = strasse,
|
||||||
|
plz = plz,
|
||||||
|
ort = ort,
|
||||||
|
land = Land,
|
||||||
|
telefon = telefon,
|
||||||
|
mobil = mobil,
|
||||||
|
email = email,
|
||||||
|
anrede = anrede,
|
||||||
|
geschlecht = geschlecht,
|
||||||
|
ist_mitglied = as.integer(mitglied),
|
||||||
|
ist_firma = as.integer(b_firma),
|
||||||
|
quittung_anrede = quittung_anrede,
|
||||||
|
quittung_name = quittung_name,
|
||||||
|
display_name = bezeichnung,
|
||||||
|
partner_id = as.integer(partner_id),
|
||||||
|
notiz = notiz,
|
||||||
|
created_at = format(Sys.time(), ""),
|
||||||
|
updated_at = format(Sys.time(), "")
|
||||||
|
)
|
||||||
|
dbWriteTable(con_s, "adressen", adressen, append = TRUE)
|
||||||
|
ok <- dbExistsTable(con_s, "adressen")
|
||||||
|
ok <- f_anzahl("adressen") == nrow(adressen) & ok
|
||||||
|
error_f <- fehler_add("adressen übertragen", TRUE, error_f)
|
||||||
|
}
|
||||||
|
|
||||||
|
## * Transfer Transaktionen ----
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
exec_sql("DROP TABLE IF EXISTS transaktionen;")
|
||||||
|
exec_sql("CREATE TABLE transaktionen (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
contact_id INTEGER,
|
adress_id INTEGER,
|
||||||
contact_text TEXT,
|
vwz TEXT,
|
||||||
|
notiz TEXT,
|
||||||
|
bank_kontakt TEXT,
|
||||||
|
created_at TEXT,
|
||||||
|
updated_at TEXT
|
||||||
|
);")
|
||||||
|
|
||||||
|
transaktionen <- dbxSelect(con_f, "
|
||||||
|
SELECT id, adress_id, verwendungszweck, notiz, kontakt, created_at, updated_at
|
||||||
|
FROM trans
|
||||||
|
") %>%
|
||||||
|
as_tibble() %>%
|
||||||
|
transmute(
|
||||||
|
id = as.integer(id),
|
||||||
|
adress_id = as.integer(adress_id),
|
||||||
|
vwz = verwendungszweck,
|
||||||
|
notiz = notiz,
|
||||||
|
bank_kontakt = kontakt,
|
||||||
|
created_at = created_at,
|
||||||
|
updated_at = updated_at
|
||||||
|
)
|
||||||
|
|
||||||
|
dbWriteTable(con_s, "transaktionen", transaktionen, append = TRUE)
|
||||||
|
ok <- dbExistsTable(con_s, "transaktionen")
|
||||||
|
ok <- f_anzahl("transaktionen") == nrow(transaktionen) & ok
|
||||||
|
error_f <- fehler_add("transaktionen übertragen", TRUE, error_f)
|
||||||
|
}
|
||||||
|
|
||||||
|
## * Transfer Postings ----
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
exec_sql("DROP TABLE IF EXISTS buchungen;")
|
||||||
|
exec_sql("CREATE TABLE buchungen (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
trans_id INTEGER NOT NULL,
|
||||||
|
konto_id INTEGER NOT NULL,
|
||||||
|
valuta TEXT NOT NULL,
|
||||||
|
buchungsdatum TEXT,
|
||||||
|
betrag DECIMAL,
|
||||||
|
rechnungsnummer TEXT,
|
||||||
|
notiz TEXT,
|
||||||
|
status TEXT,
|
||||||
|
ist_verzicht INTEGER,
|
||||||
|
umsatz_id INTEGER,
|
||||||
|
wiso_id INTEGER,
|
||||||
|
quittung_id INTEGER,
|
||||||
|
projekt_id INTEGER,
|
||||||
|
betrag_muenzen DECIMAL,
|
||||||
|
created_at TEXT,
|
||||||
|
updated_at TEXT
|
||||||
|
);")
|
||||||
|
buchungen <- dbxSelect(con_f, "
|
||||||
|
SELECT id, trans_id, konto_id, wertstellung, buchungsdatum, betrag,
|
||||||
|
rechnungsnummer, notiz, status, b_verzicht, umsatz_id, wiso_id,
|
||||||
|
quittung_id, projekt_id, betrag_muenzen, created_at, updated_at
|
||||||
|
FROM buchungen
|
||||||
|
") %>%
|
||||||
|
as_tibble()
|
||||||
|
buchungen <- buchungen %>%
|
||||||
|
transmute(
|
||||||
|
id = as.integer(id),
|
||||||
|
trans_id = as.integer(trans_id),
|
||||||
|
konto_id = as.integer(konto_id),
|
||||||
|
valuta = as.character(wertstellung),
|
||||||
|
buchungsdatum = as.character(buchungsdatum),
|
||||||
|
betrag = betrag,
|
||||||
|
rechnungsnummer = rechnungsnummer,
|
||||||
|
notiz = notiz,
|
||||||
|
status = status,
|
||||||
|
ist_verzicht = as.integer(b_verzicht),
|
||||||
|
umsatz_id = as.integer(umsatz_id),
|
||||||
|
wiso_id = as.integer(wiso_id),
|
||||||
|
quittung_id = as.integer(quittung_id),
|
||||||
|
projekt_id = as.integer(projekt_id),
|
||||||
|
betrag_muenzen = betrag_muenzen,
|
||||||
|
created_at = created_at,
|
||||||
|
updated_at = updated_at
|
||||||
|
)
|
||||||
|
dbWriteTable(con_s, "buchungen", buchungen, append = TRUE)
|
||||||
|
ok <- dbExistsTable(con_s, "buchungen")
|
||||||
|
ok <- f_anzahl("buchungen") == nrow(buchungen) & ok
|
||||||
|
error_f <- fehler_add("buchungen übertragen", TRUE, error_f)
|
||||||
|
}
|
||||||
|
|
||||||
|
## * Transfer Attachments ----
|
||||||
|
if(ok){
|
||||||
|
exec_sql("DROP TABLE IF EXISTS attachments;")
|
||||||
|
exec_sql("CREATE TABLE attachments (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
trans_id INTEGER,
|
||||||
|
quittung_id INTEGER,
|
||||||
|
adress_id INTEGER,
|
||||||
|
wiso_id INTEGER,
|
||||||
|
btisch_id TEXT,
|
||||||
|
original_name TEXT,
|
||||||
|
kategorie TEXT,
|
||||||
|
ext TEXT NOT NULL,
|
||||||
|
notiz TEXT,
|
||||||
|
created_at TEXT DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT DEFAULT (datetime('now'))
|
||||||
|
);")
|
||||||
|
|
||||||
|
att <- dbxSelect(con_f, "SELECT id, trans_id, quittung_id, wiso_id, btisch_id,
|
||||||
|
adress_id, ft_dateiname, beschreibung, created_at, updated_at, ft_extension FROM Dokumente") %>%
|
||||||
|
transmute(
|
||||||
|
id = as.integer(id),
|
||||||
|
trans_id = as.integer(trans_id),
|
||||||
|
quittung_id = as.integer(quittung_id),
|
||||||
|
wiso_id = as.integer(wiso_id),
|
||||||
|
btisch_id = as.integer(btisch_id),
|
||||||
|
adress_id = as.integer(adress_id),
|
||||||
|
created_at = as.character(created_at),
|
||||||
|
updated_at = as.character(updated_at),
|
||||||
|
original_name = ft_dateiname,
|
||||||
|
ext = paste0(id,".", ft_extension)
|
||||||
|
)
|
||||||
|
dbWriteTable(con_s, "attachments", att, append = T)
|
||||||
|
ok <- dbExistsTable(con_s, "attachments")
|
||||||
|
ok <- f_anzahl("attachments") == nrow(att) & ok
|
||||||
|
error_f <- fehler_add("attachments übertragen", TRUE, error_f)
|
||||||
|
|
||||||
|
} ## ------------------------------------------------------- 2026-03-19 16:38
|
||||||
|
|
||||||
|
|
||||||
|
### ** Dateien übertragen ----
|
||||||
|
if(ok){
|
||||||
|
pfad <- "~/Insync/Projekte/Gemeindefinanzen/gemfin-fm/gemfin04/Dokumente/datei/"
|
||||||
|
zielpfad <- "~/Documents/workspace/gemfin-shiny/www/documents/"
|
||||||
|
vorhanden <- list.files(pfad, pattern = "pdf")
|
||||||
|
eintraege <- att$original_name
|
||||||
|
anz <- length(eintraege)
|
||||||
|
for(ind in 1:length(eintraege)){
|
||||||
|
if( exists(paste0(zielpfad, eintraege[ind])) ){
|
||||||
|
cat(ind, " von ", anz, "\n")
|
||||||
|
file.copy(
|
||||||
|
from = paste0(pfad, vorhanden[ind]),
|
||||||
|
to = "~/Documents/workspace/gemfin-shiny/www/documents/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
neue_dateien <- list.files("~/Documents/workspace/gemfin-shiny/www/documents/")
|
||||||
|
length(neue_dateien)
|
||||||
|
eintraege <- att$original_name
|
||||||
|
length(eintraege)
|
||||||
|
nv <- att[-which(eintraege %in% neue_dateien),]
|
||||||
|
error_f <- fehler_add("Alle Dateien übertragen", nrow(nv) == 0, error_f)
|
||||||
|
} ## ------------------------------------------------------- 2026-04-28 18:40
|
||||||
|
|
||||||
|
|
||||||
|
## * Transfer Bankverbindungen ----
|
||||||
|
if (ok) {
|
||||||
|
exec_sql("DROP TABLE IF EXISTS bvb;")
|
||||||
|
exec_sql("CREATE TABLE bvb (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
adress_id INTEGER,
|
||||||
|
remote_name TEXT,
|
||||||
iban TEXT,
|
iban TEXT,
|
||||||
bic TEXT,
|
bic TEXT,
|
||||||
bank_name TEXT,
|
kreditinstitut TEXT,
|
||||||
remote_name TEXT,
|
|
||||||
created_at TEXT,
|
created_at TEXT,
|
||||||
updated_at TEXT
|
updated_at TEXT
|
||||||
);")
|
);")
|
||||||
|
bvb <- dbxSelect(con_f, "
|
||||||
|
SELECT id, adress_id, kontakt, iban, bic, kreditinstitut,
|
||||||
|
created_at, updated_at
|
||||||
|
FROM Bankverbindungen
|
||||||
|
") %>%
|
||||||
|
transmute(
|
||||||
|
id = as.integer(id),
|
||||||
|
adress_id = as.integer(adress_id),
|
||||||
|
remote_name = kontakt,
|
||||||
|
iban = iban,
|
||||||
|
bic = bic,
|
||||||
|
kreditinstitut = kreditinstitut,
|
||||||
|
created_at = as.character(created_at),
|
||||||
|
updated_at = as.character(updated_at)
|
||||||
|
)
|
||||||
|
dbWriteTable(con_s, "bvb", bvb, append = TRUE)
|
||||||
|
ok <- dbExistsTable(con_s, "bvb")
|
||||||
|
ok <- f_anzahl("bvb") == nrow(bvb) & ok
|
||||||
|
error_f <- fehler_add("bvb übertragen", TRUE, error_f)
|
||||||
|
}
|
||||||
|
|
||||||
exec_sql("CREATE TABLE entries (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
contact_id INTEGER,
|
|
||||||
purpose TEXT,
|
|
||||||
note TEXT,
|
|
||||||
remote_name TEXT,
|
|
||||||
created_at TEXT,
|
|
||||||
updated_at TEXT
|
|
||||||
);")
|
|
||||||
|
|
||||||
if (!USE_CENTS) {
|
## * Transfer Hibiscus ----
|
||||||
exec_sql("CREATE TABLE postings (
|
if(ok){
|
||||||
id INTEGER PRIMARY KEY,
|
exec_sql("DROP TABLE IF EXISTS umsatz;")
|
||||||
entry_id INTEGER NOT NULL,
|
exec_sql("CREATE TABLE umsatz (
|
||||||
account_id INTEGER NOT NULL,
|
|
||||||
valuta TEXT NOT NULL,
|
|
||||||
booking_date TEXT,
|
|
||||||
amount NUMERIC NOT NULL,
|
|
||||||
invoice_no TEXT,
|
|
||||||
note TEXT,
|
|
||||||
status TEXT,
|
|
||||||
waived INTEGER,
|
|
||||||
bank_transaction_id INTEGER,
|
|
||||||
wiso_id INTEGER,
|
|
||||||
receipt_id INTEGER,
|
|
||||||
project_id INTEGER,
|
|
||||||
coin_share_amount NUMERIC,
|
|
||||||
created_at TEXT,
|
|
||||||
updated_at TEXT
|
|
||||||
);")
|
|
||||||
} else {
|
|
||||||
exec_sql("CREATE TABLE postings (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
entry_id INTEGER NOT NULL,
|
|
||||||
account_id INTEGER NOT NULL,
|
|
||||||
valuta TEXT NOT NULL,
|
|
||||||
booking_date TEXT,
|
|
||||||
amount_cents INTEGER NOT NULL,
|
|
||||||
invoice_no TEXT,
|
|
||||||
note TEXT,
|
|
||||||
status TEXT,
|
|
||||||
waived INTEGER,
|
|
||||||
bank_transaction_id INTEGER,
|
|
||||||
wiso_id INTEGER,
|
|
||||||
receipt_id INTEGER,
|
|
||||||
project_id INTEGER,
|
|
||||||
coin_share_cents INTEGER,
|
|
||||||
created_at TEXT,
|
|
||||||
updated_at TEXT
|
|
||||||
);")
|
|
||||||
}
|
|
||||||
|
|
||||||
# Hibiscus payload unchanged ----
|
|
||||||
exec_sql("CREATE TABLE hibiscus_transactions (
|
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
konto_id INTEGER,
|
konto_id INTEGER,
|
||||||
empfaenger_konto TEXT,
|
empfaenger_konto TEXT,
|
||||||
@@ -201,275 +454,43 @@ if (ok) {
|
|||||||
datum TEXT,
|
datum TEXT,
|
||||||
valuta TEXT,
|
valuta TEXT,
|
||||||
saldo REAL,
|
saldo REAL,
|
||||||
primanota INTEGER,
|
|
||||||
art TEXT,
|
|
||||||
customerref TEXT,
|
customerref TEXT,
|
||||||
kommentar TEXT,
|
kommentar TEXT,
|
||||||
checksum REAL,
|
endtoendid TEXT
|
||||||
umsatztyp_id INTEGER,
|
|
||||||
flags REAL,
|
|
||||||
gvcode INTEGER,
|
|
||||||
addkey INTEGER,
|
|
||||||
txid TEXT,
|
|
||||||
purposecode TEXT,
|
|
||||||
endtoendid TEXT,
|
|
||||||
mandateid TEXT,
|
|
||||||
empfaenger_name2 TEXT,
|
|
||||||
creditorid TEXT
|
|
||||||
);")
|
);")
|
||||||
|
umsatz <- dbReadTable(con_f, "Umsatz") %>%
|
||||||
# Attachments ----
|
|
||||||
exec_sql("CREATE TABLE attachments (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
entry_id INTEGER,
|
|
||||||
quittung_id INTEGER,
|
|
||||||
adress_id INTEGER,
|
|
||||||
wiso_id INTEGER,
|
|
||||||
btisch_id TEXT,
|
|
||||||
original_name TEXT,
|
|
||||||
kategorie TEXT,
|
|
||||||
path TEXT NOT NULL,
|
|
||||||
note TEXT,
|
|
||||||
created_at TEXT DEFAULT (datetime('now')),
|
|
||||||
updated_at TEXT DEFAULT (datetime('now'))
|
|
||||||
);")
|
|
||||||
|
|
||||||
error_f <- fehler_add("Schema created", TRUE, error_f)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Transfer Accounts ----
|
|
||||||
|
|
||||||
if (ok) {
|
|
||||||
accounts <- dbxSelect(con_f, "
|
|
||||||
SELECT id, konto, budget_id, bankname, updated_at, created_at,
|
|
||||||
konto_hibiscus, konto_wiso, kontonummer_bank, notizen, b_spenden
|
|
||||||
FROM Konten
|
|
||||||
") %>%
|
|
||||||
transmute(
|
|
||||||
id = as.integer(id),
|
|
||||||
account_name = konto,
|
|
||||||
bank_name = bankname,
|
|
||||||
hibiscus_account_id = as.integer(konto_hibiscus),
|
|
||||||
budget_id = as.integer(budget_id),
|
|
||||||
wiso_account = konto_wiso,
|
|
||||||
bank_account_no = kontonummer_bank,
|
|
||||||
is_donations = as.integer(b_spenden),
|
|
||||||
notes = notizen,
|
|
||||||
created_at = created_at,
|
|
||||||
updated_at = updated_at
|
|
||||||
)
|
|
||||||
|
|
||||||
dbWriteTable(con_s, "accounts", accounts, append = TRUE)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok) {
|
|
||||||
projects <- dbxSelect(con_f, "
|
|
||||||
SELECT id, projektname, bereich, notiz, jahr, created_at, updated_at from Projekte") %>%
|
|
||||||
transmute(
|
|
||||||
id = as.integer(id),
|
|
||||||
projektname = projektname,
|
|
||||||
bereich = bereich,
|
|
||||||
notiz = notiz,
|
|
||||||
jahr = as.integer(jahr),
|
|
||||||
created_at = created_at,
|
|
||||||
updated_at = updated_at
|
|
||||||
)
|
|
||||||
|
|
||||||
dbWriteTable(con_s, "projects", projects, append = TRUE)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Transfer Budgets ----
|
|
||||||
|
|
||||||
if (ok) {
|
|
||||||
budgets <- dbxSelect(con_f, "
|
|
||||||
SELECT id, richtung, bereich, bezeichnung, reihe
|
|
||||||
FROM Budgets
|
|
||||||
") %>%
|
|
||||||
transmute(
|
|
||||||
id = as.integer(id),
|
|
||||||
row_no = as.integer(reihe),
|
|
||||||
area = bereich,
|
|
||||||
label = bezeichnung,
|
|
||||||
direction = richtung,
|
|
||||||
created_at = format(Sys.time(), ""),
|
|
||||||
updated_at = format(Sys.time(), "")
|
|
||||||
)
|
|
||||||
|
|
||||||
dbWriteTable(con_s, "budgets", budgets, append = TRUE)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Transfer Contacts
|
|
||||||
|
|
||||||
if (ok) {
|
|
||||||
contacts <- dbxSelect(con_f, "
|
|
||||||
SELECT id, vorname, nachname, strasse, plz, ort, Land,
|
|
||||||
telefon, mobil, email, anrede, geschlecht, spender, mitglied, notiz,
|
|
||||||
quittung_anrede, quittung_name, bezeichnung, partner_id, b_paar, b_firma
|
|
||||||
FROM Adressen
|
|
||||||
") %>%
|
|
||||||
as_tibble() %>%
|
|
||||||
transmute(
|
|
||||||
id = as.integer(id),
|
|
||||||
first_name = vorname,
|
|
||||||
last_name = nachname,
|
|
||||||
street = strasse,
|
|
||||||
postal_code = plz,
|
|
||||||
city = ort,
|
|
||||||
country = Land,
|
|
||||||
phone = telefon,
|
|
||||||
mobile = mobil,
|
|
||||||
email = email,
|
|
||||||
salutation = anrede,
|
|
||||||
gender = geschlecht,
|
|
||||||
donor = spender,
|
|
||||||
member = as.integer(mitglied),
|
|
||||||
notes = notiz,
|
|
||||||
receipt_salutation = quittung_anrede,
|
|
||||||
receipt_name = quittung_name,
|
|
||||||
display_name = bezeichnung,
|
|
||||||
partner_id = as.integer(partner_id),
|
|
||||||
is_couple = as.integer(b_paar),
|
|
||||||
is_company = as.integer(b_firma),
|
|
||||||
created_at = format(Sys.time(), ""),
|
|
||||||
updated_at = format(Sys.time(), "")
|
|
||||||
)
|
|
||||||
|
|
||||||
dbWriteTable(con_s, "contacts", contacts, append = TRUE)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Transfer Entries ----
|
|
||||||
|
|
||||||
if (ok) {
|
|
||||||
entries <- dbxSelect(con_f, "
|
|
||||||
SELECT id, adress_id, verwendungszweck, notiz, kontakt, created_at, updated_at
|
|
||||||
FROM trans
|
|
||||||
") %>%
|
|
||||||
as_tibble() %>%
|
|
||||||
transmute(
|
|
||||||
id = as.integer(id),
|
|
||||||
contact_id = as.integer(adress_id),
|
|
||||||
purpose = verwendungszweck,
|
|
||||||
note = notiz,
|
|
||||||
remote_name = kontakt,
|
|
||||||
created_at = created_at,
|
|
||||||
updated_at = updated_at
|
|
||||||
)
|
|
||||||
|
|
||||||
dbWriteTable(con_s, "entries", entries, append = TRUE)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Transfer Postings ----
|
|
||||||
|
|
||||||
if (ok) {
|
|
||||||
postings <- dbxSelect(con_f, "
|
|
||||||
SELECT id, trans_id, konto_id, wertstellung, buchungsdatum, betrag,
|
|
||||||
rechnungsnummer, notiz, status, b_verzicht, umsatz_id, wiso_id,
|
|
||||||
quittung_id, projekt_id, betrag_muenzen, created_at, updated_at
|
|
||||||
FROM buchungen
|
|
||||||
") %>%
|
|
||||||
as_tibble()
|
|
||||||
|
|
||||||
if (!USE_CENTS) {
|
|
||||||
postings <- postings %>%
|
|
||||||
transmute(
|
transmute(
|
||||||
id = as.integer(id),
|
id = as.integer(id),
|
||||||
entry_id = as.integer(trans_id),
|
konto_id = as.integer(konto_id),
|
||||||
account_id = as.integer(konto_id),
|
empfaenger_konto = empfaenger_konto,
|
||||||
valuta = as.character(wertstellung),
|
empfaenger_blz = empfaenger_blz,
|
||||||
booking_date = as.character(buchungsdatum),
|
empfaenger_name = empfaenger_name,
|
||||||
amount = betrag,
|
betrag = betrag,
|
||||||
invoice_no = rechnungsnummer,
|
zweck = zweck,
|
||||||
note = notiz,
|
zweck2 = zweck2,
|
||||||
status = status,
|
zweck3 = zweck2,
|
||||||
waived = as.integer(b_verzicht),
|
datum = datum,
|
||||||
bank_transaction_id = as.integer(umsatz_id),
|
valuta = valuta,
|
||||||
wiso_id = as.integer(wiso_id),
|
saldo = saldo,
|
||||||
receipt_id = as.integer(quittung_id),
|
kommentar = kommentar,
|
||||||
project_id = as.integer(projekt_id),
|
endtoendid = endtoendid
|
||||||
coin_share_amount = betrag_muenzen,
|
)
|
||||||
created_at = created_at,
|
dbWriteTable(con_s, "umsatz", umsatz, append = TRUE)
|
||||||
updated_at = updated_at
|
ok <- sum(duplicated(umsatz$id)) == 0
|
||||||
)
|
ok <- dbExistsTable(con_s, "umsatz") & ok
|
||||||
} else {
|
ok <- f_anzahl("umsatz") == nrow(umsatz) & ok
|
||||||
postings <- postings %>%
|
error_f <- fehler_add("Tabelle Umsatz existiert", ok, error_f)
|
||||||
transmute(
|
} ## ------------------------------------------------------- 2026-06-19 08:34
|
||||||
id = as.integer(id),
|
|
||||||
entry_id = as.integer(trans_id),
|
|
||||||
account_id = as.integer(konto_id),
|
|
||||||
valuta = as.character(wertstellung),
|
|
||||||
booking_date = as.character(buchungsdatum),
|
|
||||||
amount_cents = to_cents(betrag),
|
|
||||||
invoice_no = rechnungsnummer,
|
|
||||||
note = notiz,
|
|
||||||
status = status,
|
|
||||||
waived = as.integer(b_verzicht),
|
|
||||||
bank_transaction_id = as.integer(umsatz_id),
|
|
||||||
wiso_id = as.integer(wiso_id),
|
|
||||||
receipt_id = as.integer(quittung_id),
|
|
||||||
project_id = as.integer(projekt_id),
|
|
||||||
coin_share_cents = to_cents(betrag_muenzen),
|
|
||||||
created_at = created_at,
|
|
||||||
updated_at = updated_at
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
dbWriteTable(con_s, "postings", postings, append = TRUE)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Daten aus Attachments Tabelle übertragen ----
|
|
||||||
if(ok){
|
|
||||||
att <- dbxSelect(con_f, "SELECT id, trans_id, quittung_id, wiso_id, btisch_id,
|
|
||||||
adress_id, ft_dateiname, beschreibung, created_at, updated_at, ft_extension FROM Attachments") %>%
|
|
||||||
mutate(
|
|
||||||
id = as.integer(id),
|
|
||||||
trans_id = as.integer(trans_id),
|
|
||||||
quittung_id = as.integer(quittung_id),
|
|
||||||
wiso_id = as.integer(wiso_id),
|
|
||||||
btisch_id = as.integer(btisch_id),
|
|
||||||
adress_id = as.integer(adress_id),
|
|
||||||
created_at = as.character(created_at),
|
|
||||||
updated_at = as.character(updated_at),
|
|
||||||
path = paste0(id,".", ft_extension)
|
|
||||||
) %>%
|
|
||||||
rename(
|
|
||||||
entry_id = trans_id,
|
|
||||||
note = beschreibung,
|
|
||||||
original_name = ft_dateiname
|
|
||||||
) %>%
|
|
||||||
select(-ft_extension)
|
|
||||||
dbWriteTable(con_s, "Attachments", att, append = T)
|
|
||||||
} ## ------------------------------------------------------- 2026-03-19 16:38
|
|
||||||
|
|
||||||
|
|
||||||
# Transfer Bankverbindungen ----
|
|
||||||
if (ok) {
|
|
||||||
bank_connections <- dbxSelect(con_f, "
|
|
||||||
SELECT id, adress_id, kontakt, iban, bic, kreditinstitut,
|
|
||||||
remote_name, created_at, updated_at
|
|
||||||
FROM Bankverbindungen
|
|
||||||
") %>%
|
|
||||||
transmute(
|
|
||||||
id = as.integer(id),
|
|
||||||
contact_id = as.integer(adress_id),
|
|
||||||
contact_text = kontakt,
|
|
||||||
iban = iban,
|
|
||||||
bic = bic,
|
|
||||||
bank_name = kreditinstitut,
|
|
||||||
remote_name = remote_name,
|
|
||||||
created_at = as.character(created_at),
|
|
||||||
updated_at = as.character(updated_at)
|
|
||||||
)
|
|
||||||
|
|
||||||
dbWriteTable(con_s, "bank_connections", bank_connections, append = TRUE)
|
|
||||||
error_f <- fehler_add(
|
|
||||||
paste(nrow(bank_connections), "Bankverbindungen übertragen"), TRUE, error_f
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Close ----
|
# Close ----
|
||||||
|
|
||||||
|
dbListTables(con_s)
|
||||||
dbDisconnect(con_s)
|
dbDisconnect(con_s)
|
||||||
dbDisconnect(con_f)
|
dbDisconnect(con_f)
|
||||||
|
|
||||||
print("Migration finished.")
|
print("Migration finished.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -12,8 +12,8 @@ library("conflicted")
|
|||||||
library("R.utils")
|
library("R.utils")
|
||||||
library("shinyjs")
|
library("shinyjs")
|
||||||
|
|
||||||
conflicts_prefer(dplyr::select)
|
conflicts_prefer()
|
||||||
conflicts_prefer(dplyr::filter)
|
conflicts_prefer()
|
||||||
|
|
||||||
|
|
||||||
conn <- dbConnect(RSQLite::SQLite(), "db/development.sqlite")
|
conn <- dbConnect(RSQLite::SQLite(), "db/development.sqlite")
|
||||||
@@ -21,3 +21,25 @@ sourceDirectory("R/")
|
|||||||
source("~/R/rfunc/fehler_add.R")
|
source("~/R/rfunc/fehler_add.R")
|
||||||
|
|
||||||
|
|
||||||
|
conflicts_prefer(
|
||||||
|
ggplot2::`%+%`,
|
||||||
|
shinyjs::alert,
|
||||||
|
shinydashboard::box,
|
||||||
|
rJava::clone,
|
||||||
|
dplyr::select,
|
||||||
|
dplyr::filter,
|
||||||
|
tidyr::extract,
|
||||||
|
shinyjs::hidden,
|
||||||
|
dplyr::ident,
|
||||||
|
dplyr::lag,
|
||||||
|
shiny::printStackTrace,
|
||||||
|
shinyjs::removeClass,
|
||||||
|
shinyjs::reset,
|
||||||
|
shiny::runExample,
|
||||||
|
shiny::setProgress,
|
||||||
|
shinyjs::show,
|
||||||
|
dplyr::sql,
|
||||||
|
shiny::validate,
|
||||||
|
.quiet = TRUE
|
||||||
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ dashboardPage(
|
|||||||
),
|
),
|
||||||
|
|
||||||
dashboardBody(
|
dashboardBody(
|
||||||
|
tags$head(
|
||||||
|
tags$link(rel = "stylesheet", type = "text/css", href = "main.css")
|
||||||
|
),
|
||||||
tabItems(
|
tabItems(
|
||||||
tabItem(tabName = "buchungen",
|
tabItem(tabName = "buchungen",
|
||||||
buchungenUI("buchungen_tab")
|
buchungenUI("buchungen_tab")
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user