summaryrefslogtreecommitdiff
path: root/src/reports.c
diff options
context:
space:
mode:
authorAnders Betts <anders.betts@gmail.com>2026-09-22 19:53:19 +0200
committerAnders Betts <anders.betts@gmail.com>2026-09-22 19:55:47 +0200
commit3f07edf64f74cab68cb379e49841fdf6b24674e9 (patch)
tree125a350247d421b3dbac11d56c25bdf189af2656 /src/reports.c
parent6e0e96cfc74b129950002456e21d401dd07e10fd (diff)
parente1a24f6250f5e498e524ce14a5acbed5fc5c2a91 (diff)
downloadbokf-3f07edf64f74cab68cb379e49841fdf6b24674e9.tar.gz
bokf-3f07edf64f74cab68cb379e49841fdf6b24674e9.zip
Merge eff/imported-closings; skip only SIE-imported Stäng closings
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'src/reports.c')
-rw-r--r--src/reports.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/src/reports.c b/src/reports.c
index d8ed0d2..96b1344 100644
--- a/src/reports.c
+++ b/src/reports.c
@@ -59,12 +59,16 @@ static yyjson_mut_val *fy_json(yyjson_mut_doc *doc, const struct fy_info *fy)
}
/* One row per account with IB and period movements; IB as defined by
- REPORT_IB_ROW_SQL.
- Amounts signed: debit positive. */
+ REPORT_IB_ROW_SQL. skip_closings drops the source system's "Stäng ..."
+ closing vouchers (SIE-imported only) from the period movements: imported
+ years close the P&L accounts straight to 2099, so the year otherwise nets
+ to zero; the TUI årsredovisning uses the same convention. Amounts signed:
+ debit positive. */
static yyjson_mut_val *balance_query(yyjson_mut_doc *doc, sqlite3 *db,
int64_t org_id, int64_t fy_id,
const char *from, const char *to,
- const char *types_filter, char **err)
+ const char *types_filter,
+ int skip_closings, char **err)
{
char ib_series[16];
db_setting_copy(db, org_id, "series_ib", "IB", ib_series,
@@ -73,8 +77,12 @@ static yyjson_mut_val *balance_query(yyjson_mut_doc *doc, sqlite3 *db,
snprintf(sql, sizeof sql,
"SELECT a.number,a.name,a.type,"
" COALESCE(SUM(CASE WHEN v.series <> 'IB' AND v.series <> ?5"
+ " AND (?6 = 0 OR v.source <> 'sie_import'"
+ " OR COALESCE(v.description,'') NOT LIKE 'Stäng%%')"
" AND v.date BETWEEN ?2 AND ?3 THEN r.debit_ore END),0),"
" COALESCE(SUM(CASE WHEN v.series <> 'IB' AND v.series <> ?5"
+ " AND (?6 = 0 OR v.source <> 'sie_import'"
+ " OR COALESCE(v.description,'') NOT LIKE 'Stäng%%')"
" AND v.date BETWEEN ?2 AND ?3 THEN r.credit_ore END),0),"
" COALESCE(SUM(CASE WHEN " REPORT_IB_ROW_SQL
" THEN r.debit_ore END),0),"
@@ -97,6 +105,7 @@ static yyjson_mut_val *balance_query(yyjson_mut_doc *doc, sqlite3 *db,
sqlite3_bind_text(st, 3, to, -1, SQLITE_TRANSIENT);
sqlite3_bind_int64(st, 4, fy_id);
sqlite3_bind_text(st, 5, ib_series, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_int(st, 6, skip_closings);
yyjson_mut_val *arr = yyjson_mut_arr(doc);
while (sqlite3_step(st) == SQLITE_ROW) {
const char *number = (const char *)sqlite3_column_text(st, 0);
@@ -131,7 +140,8 @@ yyjson_mut_val *report_trial_balance(yyjson_mut_doc *doc, sqlite3 *db,
if (!to)
to = fy.end;
- yyjson_mut_val *rows = balance_query(doc, db, org_id, fy.id, from, to, NULL, err);
+ yyjson_mut_val *rows = balance_query(doc, db, org_id, fy.id, from, to, NULL,
+ 0, err);
if (!rows)
return NULL;
@@ -190,7 +200,7 @@ yyjson_mut_val *report_income_statement(yyjson_mut_doc *doc, sqlite3 *db,
yyjson_mut_val *rows = balance_query(
doc, db, org_id, fy.id, from, to,
- " AND a.type IN ('revenue','expense')", err);
+ " AND a.type IN ('revenue','expense')", 1, err);
if (!rows)
return NULL;
@@ -247,7 +257,7 @@ yyjson_mut_val *report_balance_sheet(yyjson_mut_doc *doc, sqlite3 *db,
yyjson_mut_val *rows = balance_query(
doc, db, org_id, fy.id, fy.start, to,
- " AND a.type IN ('asset','liability','equity')", err);
+ " AND a.type IN ('asset','liability','equity')", 0, err);
if (!rows)
return NULL;
@@ -283,10 +293,11 @@ yyjson_mut_val *report_balance_sheet(yyjson_mut_doc *doc, sqlite3 *db,
yyjson_mut_arr_add_val(*target, copy);
}
- /* current year result belongs to equity */
+ /* current year result belongs to equity; the closings stay included so a
+ transferred result (2099) does not get counted twice */
yyjson_mut_val *inc = balance_query(
doc, db, org_id, fy.id, fy.start, to,
- " AND a.type IN ('revenue','expense')", err);
+ " AND a.type IN ('revenue','expense')", 0, err);
int64_t result = 0;
if (inc) {
size_t m = yyjson_mut_arr_size(inc);
@@ -541,7 +552,7 @@ yyjson_mut_val *report_general_ledger(yyjson_mut_doc *doc, sqlite3 *db,
if (!to)
to = fy.end;
yyjson_mut_val *bal =
- balance_query(doc, db, org_id, fy.id, from, to, NULL, err);
+ balance_query(doc, db, org_id, fy.id, from, to, NULL, 0, err);
if (!bal)
return NULL;
sqlite3_stmt *rs = NULL;