diff options
| author | Anders Betts <anders.betts@gmail.com> | 2026-09-18 21:35:10 +0200 |
|---|---|---|
| committer | Anders Betts <anders.betts@gmail.com> | 2026-09-18 21:35:10 +0200 |
| commit | 251eb8c54c77029f0b43aa987ea50c44016147f3 (patch) | |
| tree | 2bf4284ce2daab191d48579a6c5a84882060d398 /clients/bokftui.c | |
| parent | 64c0d5d79b31dafcbdb68ff938a92bd6f136d4a7 (diff) | |
| download | bokf-0.1.28.tar.gz bokf-0.1.28.zip | |
eskd: generate the momsdeklaration file (eSKDUpload 6.0)v0.1.28
report.vat_eskd builds the ISO-8859-1 XML from report.vat: whole
kronor with öre truncated like the blankett, box 48 positive as filed,
MomsBetala computed from the whole-krona boxes, and an optional
upplysning converted from UTF-8, XML-escaped and capped at 300
characters. The TUI momsrapport gains "s = spara eSKD", prompting for a
path and writing the bytes verbatim.
Verified against the FY2027 Kapitas report: 05=703200, 10=175800,
20=1453, 30=851, 48=1030, 49=175621.
Diffstat (limited to 'clients/bokftui.c')
| -rw-r--r-- | clients/bokftui.c | 77 |
1 files changed, 72 insertions, 5 deletions
diff --git a/clients/bokftui.c b/clients/bokftui.c index eedf5fc..ddff00b 100644 --- a/clients/bokftui.c +++ b/clients/bokftui.c @@ -540,7 +540,8 @@ static char *prompt(const char *label, const char *def, int mask) return buf; } -static int text_view(const char *title, const char *text) +static int text_view(const char *title, const char *text, + const char *action_hint) { int ret = 0; int nlines = 0; @@ -570,7 +571,17 @@ static int text_view(const char *title, const char *text) if (top + i < n) mvaddnstr(2 + i, 2, lines[top + i], COLS - 4); } - hints("piltangenter/PgUp/PgDn rullar F5 = uppdatera q = tillbaka"); + char hint[256]; + if (action_hint) + snprintf(hint, sizeof hint, + "piltangenter/PgUp/PgDn rullar F5 = uppdatera %s " + "q = tillbaka", + action_hint); + else + snprintf(hint, sizeof hint, + "piltangenter/PgUp/PgDn rullar F5 = uppdatera " + "q = tillbaka"); + hints(hint); refresh(); int ch = ui_getch(); if (ch == 'q' || ch == 27) @@ -579,6 +590,10 @@ static int text_view(const char *title, const char *text) ret = 1; break; } + if (ch == 's' && action_hint) { + ret = 2; + break; + } if (ch == KEY_DOWN && top + view < n) top++; else if (ch == KEY_UP && top > 0) @@ -2590,7 +2605,7 @@ static void accounts_report(struct app *a) (long long)n, (long long)active_count); buf_append(&text, line, strlen(line)); buf_append(&text, "\0", 1); - int again = text_view("Kontolista", (char *)text.p); + int again = text_view("Kontolista", (char *)text.p, NULL); buf_free(&text); free(resp); if (!again) @@ -3358,6 +3373,50 @@ static void fmt_verifikationslista(struct buf *t, const struct app *a, buf_line(t, "\n%-69s %14s %14s\n", "Omslutning:", s1, s2); } +static void eskd_save(struct app *a, const char *from, const char *to) +{ + const char *home = getenv("HOME"); + char period[8], def[512], full[512]; + snprintf(period, sizeof period, "%.4s%.2s", to, to + 5); + snprintf(def, sizeof def, "%s/eskd_%s.xml", home && *home ? home : ".", + period); + char *path = prompt("Spara eSKD-fil: ", def, 0); + if (!path || !*path) + return; + if (path[0] == '~' && (path[1] == '/' || path[1] == '\0')) + snprintf(full, sizeof full, "%s%s", home ? home : "", path + 1); + else + snprintf(full, sizeof full, "%s", path); + char args[64]; + snprintf(args, sizeof args, "{\"from\":\"%s\",\"to\":\"%s\"}", from, to); + char *resp = + client_rpc(&a->conn, "report.vat_eskd", a->session, a->org, args); + if (!resp || !client_ok(resp)) { + show_error("Kunde inte skapa eSKD", resp); + free(resp); + return; + } + char *b64 = jstr_dup(resp, "result.content_base64"); + unsigned char *data = NULL; + size_t n = 0; + if (!b64 || util_b64_decode(b64, strlen(b64), &data, &n) != 0) { + message("eSKD", "Kunde inte avkoda filen från servern."); + } else { + FILE *f = fopen(full, "wb"); + if (!f || fwrite(data, 1, n, f) != n) { + message("eSKD", "Kunde inte skriva %s: %s", full, strerror(errno)); + if (f) + fclose(f); + } else { + fclose(f); + message("eSKD", "Sparat: %s\n(%zu byte, ISO-8859-1)", full, n); + } + } + free(data); + free(b64); + free(resp); +} + static void reports_screen(struct app *a) { static const char *const report_items[] = { @@ -3381,6 +3440,7 @@ static void reports_screen(struct app *a) continue; } char args[256]; + char vat_from[16] = "", vat_to[16] = ""; const char *cmd = NULL; switch (sel) { case 0: @@ -3419,6 +3479,8 @@ static void reports_screen(struct app *a) char *to = date_prompt("Till (YYYY-MM-DD): ", a->fy_end); if (!to) continue; + snprintf(vat_from, sizeof vat_from, "%s", f); + snprintf(vat_to, sizeof vat_to, "%s", to); snprintf(args, sizeof args, "{\"from\":\"%s\",\"to\":\"%s\"}", f, to); break; @@ -3470,10 +3532,15 @@ static void reports_screen(struct app *a) fmt_moms(&out, a, res); } buf_append(&out, "", 1); - int again = text_view("Rapport", (const char *)out.p); + int again = text_view("Rapport", (const char *)out.p, + sel == 5 ? "s = spara eSKD" : NULL); buf_free(&out); yyjson_doc_free(d); free(resp); + if (again == 2 && sel == 5) { + eskd_save(a, vat_from, vat_to); + break; + } if (!again) break; } @@ -3648,7 +3715,7 @@ static void audit_screen(struct app *a) free(code); } buf_append(&text, "\0", 1); - int again = text_view("Behandlingshistorik", (char *)text.p); + int again = text_view("Behandlingshistorik", (char *)text.p, NULL); buf_free(&text); free(resp); if (!again) |
