summaryrefslogtreecommitdiff
path: root/tests/test_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_core.c')
-rw-r--r--tests/test_core.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/tests/test_core.c b/tests/test_core.c
index 50dde15..018b0aa 100644
--- a/tests/test_core.c
+++ b/tests/test_core.c
@@ -1561,6 +1561,116 @@ 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);
+
+ /* The source system closes the P&L accounts straight to 2099; the income
+ statement must still show the year's real figures. The file is PC8
+ (CP437) like real exports: \x84 = ä, \x94 = ö. */
+ static const char sie[] =
+ "#FLAGGA 0\n"
+ "#FORMAT PC8\n"
+ "#SIETYP 4\n"
+ "#FNAMN \"Import AB\"\n"
+ "#RAR 0 20260101 20261231\n"
+ "#VER \"V\" \"1\" 20260201 \"F\x94rs\x84" "ljning\"\n"
+ "{\n#TRANS 1930 {} 1250.00\n#TRANS 3001 {} -1000.00\n"
+ "#TRANS 2611 {} -250.00\n}\n"
+ "#VER \"V\" \"2\" 20260202 \"Ink\x94" "p\"\n"
+ "{\n#TRANS 5410 {} 200.00\n#TRANS 2640 {} 50.00\n"
+ "#TRANS 1930 {} -250.00\n}\n"
+ "#VER \"V\" \"3\" 20260430 \"St\x84" "ng intäktskonton\"\n"
+ "{\n#TRANS 3001 {} 1000.00\n#TRANS 2099 {} -1000.00\n}\n"
+ "#VER \"V\" \"4\" 20260430 \"St\x84" "ng kostnadskonton\"\n"
+ "{\n#TRANS 2099 {} 200.00\n#TRANS 5410 {} -200.00\n}\n";
+ char *sie_b64 = util_b64((const unsigned char *)sie, strlen(sie));
+ d = call_sie_import(g_session, org, sie_b64, 0);
+ free(sie_b64);
+ CHECK_OK(d);
+ CHECK(jint(d, "result.vouchers") == 4);
+ 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);
+
+ /* a voucher entered in bokf is never skipped, whatever its text */
+ d = call(reqf("{\"v\":1,\"id\":\"ic10\",\"cmd\":\"voucher.post\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"date\":"
+ "\"2026-05-02\",\"description\":\"Stängsel\",\"rows\":["
+ "{\"account\":\"1930\",\"debit_ore\":100},"
+ "{\"account\":\"3001\",\"credit_ore\":100}]}}",
+ g_session, (int)org));
+ CHECK_OK(d);
+ yyjson_doc_free(d);
+ d = call(reqf("{\"v\":1,\"id\":\"ic11\",\"cmd\":\"report.income_statement\","
+ "\"session\":\"%s\",\"org\":%d}",
+ g_session, (int)org));
+ CHECK_OK(d);
+ CHECK(jint(d, "result.result_ore") == 80100);
+ yyjson_doc_free(d);
+}
+
static void test_general_ledger(struct tctx *t)
{
yyjson_doc *d;
@@ -5614,6 +5724,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" },