diff options
Diffstat (limited to 'clients')
| -rw-r--r-- | clients/bokftui.c | 161 |
1 files changed, 158 insertions, 3 deletions
diff --git a/clients/bokftui.c b/clients/bokftui.c index 16c9941..ccbce14 100644 --- a/clients/bokftui.c +++ b/clients/bokftui.c @@ -3606,6 +3606,157 @@ static void ib_screen(struct app *a) } } +struct company_field { + const char *key; + const char *label; + int numeric; +}; + +static const struct company_field COMPANY_FIELDS[] = { + { "name", "Företagsnamn", 0 }, + { "org_nr", "Organisationsnummer", 0 }, + { "vat_nr", "Momsregistreringsnummer", 0 }, + { "address", "Adress", 0 }, + { "postal_code", "Postnummer", 0 }, + { "city", "Ort", 0 }, + { "country", "Land", 0 }, + { "email", "E-post", 0 }, + { "phone", "Telefon", 0 }, + { "moms_period", "Momsperiod (month/quarter/year)", 0 }, + { "framework", "Regelverk (K2/K3)", 0 }, + { "fiscal_year_start_month", "Startmånad räkenskapsår (1-12)", 1 }, +}; + +static int company_field_valid(const struct company_field *f, const char *v) +{ + if (f->numeric) { + char *end = NULL; + long n = strtol(v, &end, 10); + return end && *end == '\0' && n >= 1 && n <= 12; + } + if (strcmp(f->key, "moms_period") == 0) + return strcmp(v, "month") == 0 || strcmp(v, "quarter") == 0 || + strcmp(v, "year") == 0; + if (strcmp(f->key, "framework") == 0) + return strcmp(v, "K2") == 0 || strcmp(v, "K3") == 0; + return 1; +} + +static void company_screen(struct app *a) +{ + const int nf = (int)(sizeof COMPANY_FIELDS / sizeof COMPANY_FIELDS[0]); + int owner = a->role[0] && strcmp(a->role, "owner") == 0; + for (;;) { + if (g_quit) + return; + char *resp = client_rpc(&a->conn, "org.get", a->session, a->org, "{}"); + if (!resp || !client_ok(resp)) { + show_error("Företagsuppgifter", resp); + free(resp); + return; + } + char **vals = xcalloc(nf, sizeof(char *)); + for (int i = 0; i < nf; i++) { + char path[64]; + snprintf(path, sizeof path, "result.%s", COMPANY_FIELDS[i].key); + if (COMPANY_FIELDS[i].numeric) { + char tmp[32]; + snprintf(tmp, sizeof tmp, "%lld", + (long long)jint_val(resp, path, 0)); + vals[i] = xstrdup(tmp); + } else { + char *v = jstr_dup(resp, path); + vals[i] = v ? v : xstrdup(""); + } + } + free(resp); + + int sel = 0; + int back = 0; + for (;;) { + frame("Företagsuppgifter"); + attron(A_BOLD); + mvaddstr(3, 2, "Uppgift"); + mvaddstr(3, 34, "Värde"); + attroff(A_BOLD); + for (int i = 0; i < nf; i++) { + char lbl[128], line[512]; + snprintf(lbl, sizeof lbl, "%s", COMPANY_FIELDS[i].label); + pad_field(lbl, sizeof lbl, 31); + snprintf(line, sizeof line, "%s %s", lbl, vals[i]); + if (i == sel) { + attron(A_REVERSE); + mvaddnstr(5 + i, 2, line, COLS - 4); + attroff(A_REVERSE); + } else { + if (!owner) + attron(A_DIM); + mvaddnstr(5 + i, 2, line, COLS - 4); + if (!owner) + attroff(A_DIM); + } + } + hints(owner + ? "upp/ned Enter = ändra F5 = uppdatera" + " Esc/q = tillbaka Ctrl+C = avsluta" + : "upp/ned F5 = uppdatera Esc/q = tillbaka" + " Ctrl+C = avsluta (endast ägare kan ändra)"); + refresh(); + int ch = ui_getch(); + if (ch == KEY_UP && sel > 0) + sel--; + else if (ch == KEY_DOWN && sel < nf - 1) + sel++; + else if (ch == KEY_F(5)) + break; /* reload */ + else if (ch == '\n' || ch == '\r' || ch == KEY_ENTER) { + if (!owner) { + message("Företagsuppgifter", + "Endast ägare kan ändra företagsuppgifterna."); + continue; + } + char label[160]; + snprintf(label, sizeof label, "%s: ", + COMPANY_FIELDS[sel].label); + char *val = prompt(label, vals[sel], 0); + if (!val) + continue; + if (!company_field_valid(&COMPANY_FIELDS[sel], val)) { + message("Ogiltigt värde", "%s", + COMPANY_FIELDS[sel].label); + continue; + } + yyjson_mut_doc *d = yyjson_mut_doc_new(NULL); + yyjson_mut_val *o = yyjson_mut_obj(d); + yyjson_mut_doc_set_root(d, o); + if (COMPANY_FIELDS[sel].numeric) + yyjson_mut_obj_add_int(d, o, COMPANY_FIELDS[sel].key, + strtoll(val, NULL, 10)); + else + yyjson_mut_obj_add_strcpy(d, o, COMPANY_FIELDS[sel].key, + val); + char *args = yyjson_mut_write(d, 0, NULL); + yyjson_mut_doc_free(d); + char *r = client_rpc(&a->conn, "org.update", a->session, + a->org, args); + free(args); + if (!r || !client_ok(r)) + show_error("Kunde inte spara", r); + free(r); + break; /* reload from the server */ + } else if (ch == 27 || ch == 'q') { + back = 1; + break; + } + } + for (int i = 0; i < nf; i++) + free(vals[i]); + free(vals); + if (back || g_quit) + return; + } +} + static const char *const SETTING_KEYS[] = { "default_series", "attachment_dir" }; static const char *const SETTING_LABELS[] = { "Standardserie", @@ -3785,13 +3936,14 @@ static void templates_screen(struct app *a) static const char *const MAIN_ITEMS[] = { "Verifikat", "Underlag (inkorg)", "Ingående balans", "Mallar", "Rapporter", "Revision", - "Inställningar", "Byt räkenskapsår", "Logga ut / avsluta", + "Inställningar", "Företagsuppgifter", "Byt räkenskapsår", + "Logga ut / avsluta", }; static void dashboard(struct app *a) { for (;;) { - int sel = menu("Bokf", MAIN_ITEMS, 9, 1); + int sel = menu("Bokf", MAIN_ITEMS, 10, 1); if (g_quit) return; if (sel == -4) { @@ -3825,9 +3977,12 @@ static void dashboard(struct app *a) settings_screen(a); break; case 7: - select_fiscal_year(a); + company_screen(a); break; case 8: + select_fiscal_year(a); + break; + case 9: return; } } |
