diff options
| author | Anders Betts <anders.betts@gmail.com> | 2026-09-19 23:53:09 +0200 |
|---|---|---|
| committer | Anders Betts <anders.betts@gmail.com> | 2026-09-19 23:53:09 +0200 |
| commit | 1f2d7a8190876e3d1c541251e079a11a2cc637f2 (patch) | |
| tree | 284427385e9c140dddb0c97df318fc85852fe8e1 /clients/bokftui.c | |
| parent | 86c0ef0e30f6cb24db04f20a326cf5fb4b616c3c (diff) | |
| download | bokf-0.1.43.tar.gz bokf-0.1.43.zip | |
tui: bokslut hub with year fields, reports and the posting actionv0.1.43
Diffstat (limited to 'clients/bokftui.c')
| -rw-r--r-- | clients/bokftui.c | 168 |
1 files changed, 109 insertions, 59 deletions
diff --git a/clients/bokftui.c b/clients/bokftui.c index aa7233b..3258f22 100644 --- a/clients/bokftui.c +++ b/clients/bokftui.c @@ -2950,6 +2950,38 @@ static void sru_save(struct app *a) saved[0], saved[1]); } +static void ink2_screen(struct app *a) +{ + char sargs[64]; + snprintf(sargs, sizeof sargs, "{\"fiscal_year\":%lld}", (long long)a->fy); + for (;;) { + char *resp = client_rpc(&a->conn, "sru.export", a->session, a->org, + sargs); + if (!resp || !client_ok(resp)) { + show_error("Inkomstdeklaration", resp); + free(resp); + break; + } + yyjson_doc *sd = parse(resp); + yyjson_val *sres = sd ? jget(yyjson_doc_get_root(sd), "result") : NULL; + struct buf out; + buf_init(&out); + if (sres) + fmt_ink2(&out, a, sres); + else + buf_line(&out, "%s", resp); + buf_append(&out, "", 1); + int sagain = tui_pager("Rapport", (const char *)out.p, "s = spara SRU"); + buf_free(&out); + yyjson_doc_free(sd); + free(resp); + if (sagain == 2) + sru_save(a); + if (!sagain) + break; + } +} + static void reports_screen(struct app *a) { static const char *const report_items[] = { @@ -2959,56 +2991,16 @@ static void reports_screen(struct app *a) "Huvudbok", "Verifikationslista", "Momsdeklaration", - "Inkomstdeklaration (INK2/SRU)", - "Årsredovisning (K2)", "Kontolista (alla konton)", }; static int last_sel = 0; for (;;) { if (g_quit) return; - int sel = tui_menu("Rapporter", report_items, 9, 0, &last_sel); + int sel = tui_menu("Rapporter", report_items, 7, 0, &last_sel); if (sel < 0) return; if (sel == 6) { - char sargs[64]; - snprintf(sargs, sizeof sargs, "{\"fiscal_year\":%lld}", - (long long)a->fy); - for (;;) { - char *resp = client_rpc(&a->conn, "sru.export", a->session, - a->org, sargs); - if (!resp || !client_ok(resp)) { - show_error("Inkomstdeklaration", resp); - free(resp); - break; - } - yyjson_doc *sd = parse(resp); - yyjson_val *sres = - sd ? jget(yyjson_doc_get_root(sd), "result") : NULL; - struct buf out; - buf_init(&out); - if (sres) - fmt_ink2(&out, a, sres); - else - buf_line(&out, "%s", resp); - buf_append(&out, "", 1); - int sagain = tui_pager("Rapport", (const char *)out.p, - "s = spara SRU"); - buf_free(&out); - yyjson_doc_free(sd); - free(resp); - if (sagain == 2) - sru_save(a); - if (!sagain) - break; - } - continue; - } - if (sel == 7) { - arsredovisning_screen(a); - continue; - } - if (sel == 8) { accounts_report(a); continue; } @@ -4474,9 +4466,10 @@ static void bokslut_plan(struct app *a, const char *fond, const char *rate, free(presp); } -/* Bokslut: the per-year årsredovisning details (fields 0-5, saved one by - one with fiscal_year.update) plus the local periodiseringsfond and tax - rate inputs. New years inherit the stable fields. */ +/* Bokslut: the year-end hub. The year's årsredovisning details (fields 0-5, + saved one by one with fiscal_year.update) and the local periodiseringsfond + and tax rate inputs plus a status row and the year-end actions, all in one + view. New years inherit the stable fields. */ static void bokslut_screen(struct app *a) { static const char *const labels[6] = { @@ -4506,6 +4499,9 @@ static void bokslut_screen(struct app *a) free(resp); return; } + char *fystat = jstr_dup(resp, "result.status"); + int closed = fystat && strcmp(fystat, "closed") == 0; + free(fystat); char *vals[6]; struct tui_form_field ff[8]; int64_t div_ore = jint_val(resp, "result.dividend_ore", 0); @@ -4524,6 +4520,41 @@ static void bokslut_screen(struct app *a) ff[i].cap = 512; } free(resp); + + /* A closed year counts as posted; an open one only when the tax + voucher that bokslut.post creates is already in the books. */ + int posted = closed; + if (!closed) { + char vargs[160]; + snprintf(vargs, sizeof vargs, + "{\"fiscal_year\":%lld," + "\"text\":\"Skatt på årets resultat\",\"limit\":1}", + (long long)a->fy); + char *vresp = client_rpc(&a->conn, "voucher.list", a->session, + a->org, vargs); + if (vresp && client_ok(vresp)) + posted = jarr_size(vresp, "result.items") > 0; + free(vresp); + } + + char status_line[96]; + snprintf(status_line, sizeof status_line, "Bokslut bokfört: %s", + posted ? "ja" : "nej"); + const char *reason = NULL; + if (closed) + reason = "året är stängt"; + else if (posted) + reason = "bokslutet är redan bokfört"; + else if (!can_edit) + reason = "du har inte behörighet"; + struct tui_form_action acts[5] = { + { status_line, -1, NULL }, + { "Årsredovisning (K2)", 1, NULL }, + { "Inkomstdeklaration (INK2/SRU)", 1, NULL }, + { "Bokslutsplan (torrkörning)", 1, NULL }, + { "Bokför bokslut", reason ? 0 : 1, reason }, + }; + ff[0].kind = TUI_F_TEXT; ff[1].kind = TUI_F_DATE; ff[2].kind = TUI_F_AMOUNT; @@ -4539,10 +4570,11 @@ static void bokslut_screen(struct app *a) ff[7].value = rate; ff[7].cap = sizeof rate; ff[7].kind = TUI_F_TEXT; - tui_form_hint("upp/ned/Home/End Enter = ändra F5 = visa" + tui_form_hint("upp/ned/Tab = flytta Enter = ändra/utför F5 = visa" " bokslutsplan ^Enter = bokför planen (frågar" " först) Esc/q = tillbaka ^C = avsluta"); - int r = tui_form_run("Bokslut", ff, nf + 2, can_edit); + int r = tui_form_run_actions("Bokslut", ff, nf + 2, can_edit, acts, 5, + NULL); if (r >= 0 && r < nf) { yyjson_mut_doc *d = yyjson_mut_doc_new(NULL); yyjson_mut_val *o = yyjson_mut_obj(d); @@ -4563,6 +4595,22 @@ static void bokslut_screen(struct app *a) } for (int i = 0; i < nf; i++) free(vals[i]); + if (r == TUI_FORM_ACTION + 1) { + arsredovisning_screen(a); + continue; + } + if (r == TUI_FORM_ACTION + 2) { + ink2_screen(a); + continue; + } + if (r == TUI_FORM_ACTION + 3) { + bokslut_plan(a, fond, rate, 0); + continue; + } + if (r == TUI_FORM_ACTION + 4) { + bokslut_plan(a, fond, rate, 1); + continue; + } if (r == TUI_FORM_REFRESH) bokslut_plan(a, fond, rate, 0); else if (r == TUI_FORM_SUBMIT) @@ -5337,13 +5385,15 @@ static void do_reload(struct app *a, const char *self) static const char *const MAIN_ITEMS[] = { MK_SECTION "Bokföring", - "Verifikat", "Underlag (inkorg)", "Ingående balans", + "Verifikat", "Underlag (inkorg)", MK_SECTION "Rapporter & bokslut", "Rapporter", "Bokslut", MK_SECTION "Register", "Mallar", "Företagsuppgifter", "Inställningar", + MK_SECTION "Räkenskapsår", + "Ingående balans", "Räkenskapsår", MK_SECTION "Övrigt", - "Revision", "Räkenskapsår", "Logga ut / avsluta", + "Revision", "Logga ut / avsluta", }; static void dashboard(struct app *a) @@ -5373,31 +5423,31 @@ static void dashboard(struct app *a) case 2: open_scene(a, "inbox"); break; - case 3: - open_scene(a, "ib"); - break; - case 5: + case 4: open_scene(a, "reports"); break; - case 6: + case 5: open_scene(a, "bokslut"); break; - case 8: + case 7: open_scene(a, "templates"); break; - case 9: + case 8: open_scene(a, "company"); break; - case 10: + case 9: open_scene(a, "settings"); break; - case 12: - open_scene(a, "audit"); + case 11: + open_scene(a, "ib"); break; - case 13: + case 12: select_fiscal_year(a); break; case 14: + open_scene(a, "audit"); + break; + case 15: return; default: break; /* section header */ |
