From e1a24f6250f5e498e524ce14a5acbed5fc5c2a91 Mon Sep 17 00:00:00 2001 From: Anders Betts Date: Tue, 22 Sep 2026 19:52:19 +0200 Subject: reports: income statement skips imported Stäng closings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- tests/test_core.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) (limited to 'tests') diff --git a/tests/test_core.c b/tests/test_core.c index a000ffe..1d86b2b 100644 --- a/tests/test_core.c +++ b/tests/test_core.c @@ -1561,6 +1561,114 @@ static void test_reports(struct tctx *t) yyjson_doc_free(d); } +static void test_imported_closings(struct tctx *t) +{ + yyjson_doc *d; + int64_t org = 0; + + (void)t; + d = call(reqf("{\"v\":1,\"id\":\"ic1\",\"cmd\":\"org.create\"," + "\"session\":\"%s\",\"args\":{\"name\":\"Import AB\"}}", + g_session)); + CHECK_OK(d); + org = jint(d, "result.id"); + CHECK(org > 0); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"ic2\",\"cmd\":\"voucher.post\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"date\":" + "\"2026-02-01\",\"description\":\"Försäljning\",\"rows\":[" + "{\"account\":\"1930\",\"debit_ore\":125000}," + "{\"account\":\"3001\",\"credit_ore\":100000}," + "{\"account\":\"2611\",\"credit_ore\":25000}]}}", + g_session, (int)org)); + CHECK_OK(d); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"ic3\",\"cmd\":\"voucher.post\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"date\":" + "\"2026-02-02\",\"description\":\"Inköp\",\"rows\":[" + "{\"account\":\"5410\",\"debit_ore\":20000}," + "{\"account\":\"2640\",\"debit_ore\":5000}," + "{\"account\":\"1930\",\"credit_ore\":25000}]}}", + g_session, (int)org)); + CHECK_OK(d); + yyjson_doc_free(d); + + /* The source system closes the P&L accounts straight to 2099; the income + statement must still show the year's real figures. */ + d = call(reqf("{\"v\":1,\"id\":\"ic4\",\"cmd\":\"voucher.post\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"date\":" + "\"2026-04-30\",\"description\":\"Stäng intäktskonton\"," + "\"rows\":[{\"account\":\"3001\",\"debit_ore\":100000}," + "{\"account\":\"2099\",\"credit_ore\":100000}]}}", + g_session, (int)org)); + CHECK_OK(d); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"ic5\",\"cmd\":\"voucher.post\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"date\":" + "\"2026-04-30\",\"description\":\"Stäng kostnadskonton\"," + "\"rows\":[{\"account\":\"2099\",\"debit_ore\":20000}," + "{\"account\":\"5410\",\"credit_ore\":20000}]}}", + g_session, (int)org)); + CHECK_OK(d); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"ic6\",\"cmd\":\"report.income_statement\"," + "\"session\":\"%s\",\"org\":%d}", + g_session, (int)org)); + CHECK_OK(d); + CHECK(jint(d, "result.result_ore") == 80000); + CHECK(find_amount(d, "result.revenue.accounts", "account", "3001", + "amount_ore") == 100000); + CHECK(find_amount(d, "result.expenses.accounts", "account", "5410", + "amount_ore") == 20000); + yyjson_doc_free(d); + + /* The result sits in 2099, so the balance sheet must not count it twice. */ + d = call(reqf("{\"v\":1,\"id\":\"ic7\",\"cmd\":\"report.balance_sheet\"," + "\"session\":\"%s\",\"org\":%d}", + g_session, (int)org)); + CHECK_OK(d); + /* 2640 is chart-typed as a liability (debit balance shows negative) */ + CHECK(jint(d, "result.assets.total_ore") == 100000); + CHECK(jint(d, "result.liabilities.total_ore") == 20000); + CHECK(jint(d, "result.equity.total_ore") == 80000); + CHECK(jint(d, "result.assets.total_ore") == + jint(d, "result.liabilities.total_ore") + + jint(d, "result.equity.total_ore")); + CHECK(find_amount(d, "result.equity.accounts", "account", "2099", + "amount_ore") == 80000); + yyjson_doc_free(d); + + /* the declaration path: the SRU result must not be zeroed either */ + d = call(reqf("{\"v\":1,\"id\":\"ic8\",\"cmd\":\"org.update\"," + "\"session\":\"%s\",\"org\":%d,\"args\":" + "{\"org_nr\":\"559331-2126\",\"postal_code\":\"192 48\"," + "\"city\":\"Sollentuna\"}}", + g_session, (int)org)); + CHECK_OK(d); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"ic9\",\"cmd\":\"sru.export\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{}}", + g_session, (int)org)); + CHECK_OK(d); + const char *sb64 = jstr(d, "result.blanketter.content_base64"); + unsigned char *srub = NULL; + size_t srul = 0; + CHECK(sb64 && util_b64_decode(sb64, strlen(sb64), &srub, &srul) == 0); + char *sru = xmalloc(srul + 1); + memcpy(sru, srub, srul); + sru[srul] = '\0'; + free(srub); + CHECK(strstr(sru, "#UPPGIFT 7450 800") != NULL); + CHECK(strstr(sru, "#UPPGIFT 7650 800") != NULL); + free(sru); + yyjson_doc_free(d); +} + static void test_general_ledger(struct tctx *t) { yyjson_doc *d; @@ -5494,6 +5602,7 @@ static const struct ttest TESTS[] = { { "vouchers", test_vouchers, "org_members" }, { "voucher_errors", test_voucher_errors, "org_members" }, { "reports", test_reports, "vouchers" }, + { "imported_closings", test_imported_closings, "org_members" }, { "general_ledger", test_general_ledger, "vouchers" }, { "voucher_list", test_voucher_list, "vouchers" }, { "vat_eskd", test_vat_eskd, "vouchers" }, -- cgit v1.3