diff options
Diffstat (limited to 'tests/test_core.c')
| -rw-r--r-- | tests/test_core.c | 195 |
1 files changed, 159 insertions, 36 deletions
diff --git a/tests/test_core.c b/tests/test_core.c index 1d86b2b..018b0aa 100644 --- a/tests/test_core.c +++ b/tests/test_core.c @@ -1575,44 +1575,30 @@ static void test_imported_closings(struct tctx *t) 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)); + 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\"," @@ -1667,6 +1653,22 @@ static void test_imported_closings(struct tctx *t) 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) @@ -2175,6 +2177,126 @@ static void test_ib(struct tctx *t) yyjson_doc_free(d); } +/* Opening balances carry earlier years' IB vouchers; P&L accounts restart + at every year start (reports and SIE export). */ +static void test_ib_carry(struct tctx *t) +{ + (void)t; + yyjson_doc *d; + + d = call(reqf("{\"v\":1,\"id\":\"ibc1\",\"cmd\":\"org.create\"," + "\"session\":\"%s\",\"args\":{\"name\":\"Överföring AB\"}}", + g_session)); + CHECK_OK(d); + int org = (int)jint(d, "result.id"); + yyjson_doc_free(d); + d = call(reqf("{\"v\":1,\"id\":\"ibc2\",\"cmd\":\"fiscal_year.list\"," + "\"session\":\"%s\",\"org\":%d}", + g_session, org)); + CHECK_OK(d); + char start[11] = "", end[11] = ""; + snprintf(start, sizeof start, "%s", jstr(d, "result.items.0.start_date")); + snprintf(end, sizeof end, "%s", jstr(d, "result.items.0.end_date")); + yyjson_doc_free(d); + int y = atoi(end) + 1; + + const char *posts[][4] = { + { start, "IB", "1940", "2010" }, + { start, "V", "1930", "3001" }, + { end, "V", "8999", "2099" }, + }; + const int64_t amounts[] = { 2500000, 100000, 100000 }; + for (size_t i = 0; i < 3; i++) { + d = call(reqf("{\"v\":1,\"id\":\"ibc3\",\"cmd\":\"voucher.post\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"date\":" + "\"%s\",\"description\":\"År 1\",\"series\":\"%s\"," + "\"rows\":[{\"account\":\"%s\",\"debit_ore\":%lld}," + "{\"account\":\"%s\",\"credit_ore\":%lld}]}}", + g_session, org, posts[i][0], posts[i][1], posts[i][2], + (long long)amounts[i], posts[i][3], + (long long)amounts[i])); + CHECK_OK(d); + yyjson_doc_free(d); + } + + d = call(reqf("{\"v\":1,\"id\":\"ibc4\",\"cmd\":\"fiscal_year.open\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"label\":\"%d\"," + "\"start_date\":\"%d-01-01\",\"end_date\":\"%d-12-31\"}}", + g_session, org, y, y, y)); + CHECK_OK(d); + int64_t fy2 = jint(d, "result.id"); + yyjson_doc_free(d); + d = call(reqf("{\"v\":1,\"id\":\"ibc5\",\"cmd\":\"voucher.post\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"date\":" + "\"%d-02-01\",\"description\":\"År 2\",\"rows\":" + "[{\"account\":\"1930\",\"debit_ore\":5000}," + "{\"account\":\"3001\",\"credit_ore\":5000}]}}", + g_session, org, y)); + CHECK_OK(d); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"ibc6\",\"cmd\":\"report.trial_balance\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"fiscal_year\":" + "%lld}}", + g_session, org, (long long)fy2)); + CHECK_OK(d); + CHECK(find_amount(d, "result.accounts", "account", "1940", "ib_ore") == + 2500000); + CHECK(find_amount(d, "result.accounts", "account", "2010", "ib_ore") == + -2500000); + CHECK(find_amount(d, "result.accounts", "account", "2099", "ib_ore") == + -100000); + CHECK(find_amount(d, "result.accounts", "account", "3001", "ib_ore") == 0); + CHECK(find_amount(d, "result.accounts", "account", "8999", "ib_ore") == -1); + CHECK(jint(d, "result.totals.ib_ore") == 0); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"ibc7\",\"cmd\":\"report.trial_balance\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"fiscal_year\":" + "%lld,\"from\":\"%d-03-01\"}}", + g_session, org, (long long)fy2, y)); + CHECK_OK(d); + CHECK(find_amount(d, "result.accounts", "account", "3001", "ib_ore") == + -5000); + CHECK(find_amount(d, "result.accounts", "account", "1930", "ib_ore") == + 105000); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"ibc8\",\"cmd\":\"report.balance_sheet\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"fiscal_year\":" + "%lld}}", + g_session, org, (long long)fy2)); + CHECK_OK(d); + CHECK(find_amount(d, "result.equity.accounts", "account", "2010", + "amount_ore") == 2500000); + CHECK(jint(d, "result.assets.total_ore") == 2605000); + CHECK(jint(d, "result.assets.total_ore") == + jint(d, "result.liabilities.total_ore") + + jint(d, "result.equity.total_ore")); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"ibc9\",\"cmd\":\"sie.export\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"fiscal_year\":" + "%lld}}", + g_session, org, (long long)fy2)); + CHECK_OK(d); + FILE *sf = fopen(jstr(d, "result.path"), "rb"); + yyjson_doc_free(d); + CHECK(sf != NULL); + if (sf) { + char sbuf[65536]; + size_t sn = fread(sbuf, 1, sizeof sbuf - 1, sf); + sbuf[sn] = '\0'; + fclose(sf); + CHECK(strstr(sbuf, "#IB 0 2010 -25000.00") != NULL); + CHECK(strstr(sbuf, "#UB 0 1930 1050.00") != NULL); + CHECK(strstr(sbuf, "#RES 0 3001 -50.00") != NULL); + CHECK(strstr(sbuf, "#IB 0 3001") == NULL); + CHECK(strstr(sbuf, "#UB 0 3001") == NULL); + CHECK(strstr(sbuf, "#RES 0 1930") == NULL); + } +} + static void test_period_lock(struct tctx *t) { yyjson_doc *d; @@ -5611,6 +5733,7 @@ static const struct ttest TESTS[] = { { "attachments", test_attachments, "vouchers idempotency" }, { "templates", test_templates, "org_members" }, { "ib", test_ib, "org_members" }, + { "ib_carry", test_ib_carry, "org_members" }, { "period_lock", test_period_lock, "fiscal_years" }, { "sie_export", test_sie_export, "ib" }, { "sie_import", test_sie_import, "attachments sie_export" }, |
