aboutsummaryrefslogtreecommitdiff
path: root/src/commands.c
diff options
context:
space:
mode:
authorAnders Betts <anders.betts@gmail.com>2026-09-19 20:13:02 +0200
committerAnders Betts <anders.betts@gmail.com>2026-09-19 20:13:02 +0200
commit77c298b3b64f2493e509734df0084068ad24441f (patch)
tree8a8182fbecdb0dc63cdc71842511cc6d00e21716 /src/commands.c
parent30c309e15d3211e7d0e8a8a2752c3e9afa0a0638 (diff)
downloadbokf-0.1.33.tar.gz
bokf-0.1.33.zip
bokslut: TUI screen, K2 årsredovisning draft, storable dividend (schema v4)v0.1.33
Diffstat (limited to 'src/commands.c')
-rw-r--r--src/commands.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/src/commands.c b/src/commands.c
index f03e0e4..62de0be 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -1696,10 +1696,12 @@ static yyjson_mut_val *fy_json(struct req *r, sqlite3_stmt *st)
else
yyjson_mut_obj_add_strcpy(r->rdoc, o, "locked_until",
sq(sqlite3_column_text(st, 5)));
+ yyjson_mut_obj_add_int(r->rdoc, o, "dividend_ore",
+ sqlite3_column_int64(st, 6));
return o;
}
-#define FY_COLUMNS "id,label,start_date,end_date,status,locked_until"
+#define FY_COLUMNS "id,label,start_date,end_date,status,locked_until,dividend_ore"
static yyjson_mut_val *h_fiscal_year_list(struct req *r)
{
@@ -1878,6 +1880,70 @@ static yyjson_mut_val *h_fiscal_year_reopen(struct req *r)
return yyjson_mut_obj(r->rdoc);
}
+/* Fiscal-year metadata that is not a posting: today only the board's
+ proposed dividend, kept for the årsredovisning draft. */
+static yyjson_mut_val *h_fiscal_year_update(struct req *r)
+{
+ int64_t id = 0, dividend = 0;
+ if (!arg_int(r->args, "id", &id) || id <= 0)
+ return fail(r, "INVALID_ARGS", "id is required");
+ if (!arg_int(r->args, "dividend_ore", &dividend))
+ return fail(r, "INVALID_ARGS", "dividend_ore is required");
+ if (dividend < 0)
+ return fail(r, "INVALID_ARGS", "dividend_ore must be >= 0");
+ sqlite3_stmt *st = NULL;
+ if (sqlite3_prepare_v2(r->db,
+ "SELECT count(*) FROM fiscal_years"
+ " WHERE org_id=?1 AND id=?2",
+ -1, &st, NULL) != SQLITE_OK)
+ return fail(r, "INTERNAL", "database error");
+ sqlite3_bind_int64(st, 1, r->org_id);
+ sqlite3_bind_int64(st, 2, id);
+ int64_t exists = 0;
+ if (sqlite3_step(st) == SQLITE_ROW)
+ exists = sqlite3_column_int64(st, 0);
+ sqlite3_finalize(st);
+ if (!exists)
+ return fail(r, "NOT_FOUND", "fiscal year not found");
+ if (r->dry_run) {
+ yyjson_mut_val *o = yyjson_mut_obj(r->rdoc);
+ yyjson_mut_obj_add_bool(r->rdoc, o, "dry_run", true);
+ yyjson_mut_obj_add_int(r->rdoc, o, "id", id);
+ yyjson_mut_obj_add_int(r->rdoc, o, "dividend_ore", dividend);
+ return o;
+ }
+ if (sqlite3_prepare_v2(r->db,
+ "UPDATE fiscal_years SET dividend_ore=?3"
+ " WHERE org_id=?1 AND id=?2",
+ -1, &st, NULL) != SQLITE_OK)
+ return fail(r, "INTERNAL", "database error");
+ sqlite3_bind_int64(st, 1, r->org_id);
+ sqlite3_bind_int64(st, 2, id);
+ sqlite3_bind_int64(st, 3, dividend);
+ int rc = sqlite3_step(st);
+ sqlite3_finalize(st);
+ if (rc != SQLITE_DONE)
+ return fail(r, "INTERNAL", sqlite3_errmsg(r->db));
+ char *reqjson = audit_args_json(r->args);
+ audit_append(r->db, r->org_id, r->sess->user_id, r->sess->token_id,
+ "fiscal_year.update", reqjson, "OK", NULL);
+ free(reqjson);
+ if (sqlite3_prepare_v2(r->db,
+ "SELECT " FY_COLUMNS " FROM fiscal_years"
+ " WHERE org_id=?1 AND id=?2",
+ -1, &st, NULL) != SQLITE_OK)
+ return fail(r, "INTERNAL", "database error");
+ sqlite3_bind_int64(st, 1, r->org_id);
+ sqlite3_bind_int64(st, 2, id);
+ yyjson_mut_val *o = NULL;
+ if (sqlite3_step(st) == SQLITE_ROW)
+ o = fy_json(r, st);
+ sqlite3_finalize(st);
+ if (!o)
+ return fail(r, "NOT_FOUND", "fiscal year not found");
+ return o;
+}
+
static yyjson_mut_val *h_period_lock(struct req *r)
{
int64_t fy = 0;
@@ -4119,6 +4185,8 @@ const struct command g_commands[] = {
h_fiscal_year_close },
{ "fiscal_year.reopen", "Reopen a closed fiscal year", PERM_OWNER, 1, 1, 1,
h_fiscal_year_reopen },
+ { "fiscal_year.update", "Update fiscal-year metadata (dividend)",
+ PERM_WRITE, 1, 1, 1, h_fiscal_year_update },
{ "period.lock", "Lock a period through a date", PERM_OWNER, 1, 1, 1,
h_period_lock },
{ "period.unlock", "Remove a period lock", PERM_OWNER, 1, 1, 1,