summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clients/bokftui.c76
-rw-r--r--docs/PROTOCOL.md7
-rw-r--r--docs/STATE.md6
3 files changed, 33 insertions, 56 deletions
diff --git a/clients/bokftui.c b/clients/bokftui.c
index 15ca335..5daa606 100644
--- a/clients/bokftui.c
+++ b/clients/bokftui.c
@@ -3171,6 +3171,8 @@ static void ibrow_normalize(struct tui_ibrow *rows, int *nrows, int *field)
}
/* Loads the net IB per account for the active fiscal year. */
+/* Effective opening balances of the selected year: the year's IB vouchers
+ plus all earlier movements, exactly what the reports show. */
static int ib_load(struct app *a, char ***out_acc, int64_t **out_amt,
int *out_n)
{
@@ -3178,67 +3180,33 @@ static int ib_load(struct app *a, char ***out_acc, int64_t **out_amt,
*out_amt = NULL;
*out_n = 0;
char args[128];
- snprintf(args, sizeof args, "{\"fiscal_year\":%lld,\"series\":\"IB\","
- "\"limit\":200}",
+ snprintf(args, sizeof args,
+ "{\"fiscal_year\":%lld,\"include_zero\":true}",
(long long)a->fy);
- char *resp =
- client_rpc(&a->conn, "voucher.list", a->session, a->org, args);
+ char *resp = client_rpc(&a->conn, "report.trial_balance", a->session,
+ a->org, args);
if (!resp || !client_ok(resp)) {
show_error("Ingående balans", resp);
free(resp);
return -1;
}
- size_t n = jarr_size(resp, "result.items");
- size_t cap = n ? n : 1;
- char **accs = xcalloc(cap, sizeof(char *));
- int64_t *amts = xcalloc(cap, sizeof(int64_t));
+ size_t n = jarr_size(resp, "result.accounts");
+ char **accs = xcalloc(n ? n : 1, sizeof(char *));
+ int64_t *amts = xcalloc(n ? n : 1, sizeof(int64_t));
int count = 0;
for (size_t i = 0; i < n; i++) {
char path[64];
- snprintf(path, sizeof path, "result.items.%zu.id", i);
- int64_t id = jint_val(resp, path, 0);
- if (id <= 0)
+ snprintf(path, sizeof path, "result.accounts.%zu.ib_ore", i);
+ int64_t ib = jint_val(resp, path, 0);
+ if (ib == 0)
continue;
- char vargs[64];
- snprintf(vargs, sizeof vargs, "{\"id\":%lld}", (long long)id);
- char *v = client_rpc(&a->conn, "voucher.get", a->session, a->org, vargs);
- if (!v || !client_ok(v)) {
- free(v);
+ snprintf(path, sizeof path, "result.accounts.%zu.account", i);
+ char *acc = jstr_dup(resp, path);
+ if (!acc)
continue;
- }
- size_t rn = jarr_size(v, "result.rows");
- for (size_t k = 0; k < rn; k++) {
- char p[64];
- snprintf(p, sizeof p, "result.rows.%zu.account", k);
- char *acc = jstr_dup(v, p);
- snprintf(p, sizeof p, "result.rows.%zu.debit_ore", k);
- int64_t d = jint_val(v, p, 0);
- snprintf(p, sizeof p, "result.rows.%zu.credit_ore", k);
- int64_t c = jint_val(v, p, 0);
- if (acc) {
- int found = -1;
- for (int j = 0; j < count; j++)
- if (strcmp(accs[j], acc) == 0) {
- found = j;
- break;
- }
- if (found >= 0) {
- amts[found] += d - c;
- } else {
- if ((size_t)count == cap) {
- cap *= 2;
- accs = xrealloc(accs, cap * sizeof(char *));
- amts = xrealloc(amts, cap * sizeof(int64_t));
- }
- accs[count] = acc;
- amts[count] = d - c;
- count++;
- }
- if (found >= 0)
- free(acc);
- }
- }
- free(v);
+ accs[count] = acc;
+ amts[count] = ib;
+ count++;
}
free(resp);
*out_acc = accs;
@@ -3259,6 +3227,11 @@ static int64_t ib_old_lookup(char **accs, int64_t *amts, int n,
static int ib_form(struct app *a, char **old_acc, int64_t *old_amt, int nold)
{
static struct tui_ibrow rows[64];
+ if (nold > 63) {
+ message("Ingående balans",
+ "För många konton (%d) för att redigera här.", nold);
+ return 0;
+ }
memset(rows, 0, sizeof rows);
for (int i = 0; i < nold && i < 63; i++) {
snprintf(rows[i].account, sizeof rows[i].account, "%s", old_acc[i]);
@@ -3565,7 +3538,8 @@ static void ib_screen(struct app *a)
top = 0;
frame("Ingående balans");
attron(A_BOLD);
- mvprintw(2, 2, "Räkenskapsår %s serie IB", a->fy_label);
+ mvprintw(2, 2, "Räkenskapsår %s ingående balans (effektiv)",
+ a->fy_label);
mvaddstr(4, 2, "Konto");
mvaddstr(4, 9, "Namn");
mvaddstr(4, 62, "Belopp");
diff --git a/docs/PROTOCOL.md b/docs/PROTOCOL.md
index 009b14e..f282691 100644
--- a/docs/PROTOCOL.md
+++ b/docs/PROTOCOL.md
@@ -404,9 +404,10 @@ commands. Implemented screens (0.1.0-dev):
- **Nytt verifikat** — row editor with live balance display, F5 dry-run
validation and F9 posting; one `client_ref` per form makes retries safe.
F4 applies a konteringsmall (prompts for template and `x`).
-- **Ingående balans** — the series `IB` voucher for the selected fiscal year;
- enter accounts with signed amounts (positive debit, negative credit), the
- editor posts deltas so existing entries are never edited.
+- **Ingående balans** — the effective opening balances of the selected
+ fiscal year (carry-forward plus any `IB` vouchers, as the reports compute
+ them); enter accounts with signed amounts (positive debit, negative
+ credit); the editor posts `IB` deltas so nothing is ever edited.
- **Välj organisation att representera** — login step two: pick which org the
session works in. `--org ID` skips the picker for scripts.
- **Byt räkenskapsår** (dashboard) — pick from the org's fiscal years; shown
diff --git a/docs/STATE.md b/docs/STATE.md
index f130f14..3cbe448 100644
--- a/docs/STATE.md
+++ b/docs/STATE.md
@@ -41,8 +41,10 @@ server/protocol/ledger only.
instead of delete.
9. **Ingående balans**: one series `IB` voucher per fiscal year (dated at
year start). Reports treat series IB as IB, not period movement; SIE
- export/import round-trips without double counting; TUI editor posts only
- deltas so nothing is ever edited.
+ export/import round-trips without double counting; TUI editor shows the
+ year's *effective* opening balances (carry-forward plus IB vouchers) and
+ posts deltas, so nothing is ever edited and a target balance can be
+ entered directly.
10. **Attachments**: content stored in the DB (BLOB), immutable, linked via
append-only `voucher_attachments`. Default limit 10 MiB
(`max_attachment_bytes`); the socket line limit is derived from it