From 59ef95d3c1f590a05c3bea79834d424200d28250 Mon Sep 17 00:00:00 2001 From: Anders Betts Date: Sun, 20 Sep 2026 09:56:56 +0200 Subject: report: per-org moms rule editor commands --- tests/test_core.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) (limited to 'tests') diff --git a/tests/test_core.c b/tests/test_core.c index ee0d3b9..56c70dd 100644 --- a/tests/test_core.c +++ b/tests/test_core.c @@ -960,6 +960,16 @@ int main(void) CHECK(arg_field_is(find_arg(d, "number"), "type", "string")); yyjson_doc_free(d); + d = call(reqf("{\"v\":1,\"id\":\"30f\",\"cmd\":\"describe\"," + "\"session\":\"%s\",\"args\":{\"cmd\":\"report.rule_create\"}}", + g_session)); + CHECK_OK(d); + CHECK_STR(d, "result.command.name", "report.rule_create"); + CHECK(arg_required(find_arg(d, "report"))); + CHECK(arg_field_is(find_arg(d, "match_type"), "type", "enum")); + CHECK(!arg_required(find_arg(d, "sign"))); + yyjson_doc_free(d); + d = call(reqf("{\"v\":1,\"id\":\"30c\",\"cmd\":\"voucher.post\"," "\"session\":\"%s\",\"org\":%d,\"args\":" "{\"description\":\"Saknar datum\",\"rows\":[" @@ -1996,6 +2006,198 @@ int main(void) CHECK(n05 == 1); yyjson_doc_free(d); + /* ---------------- moms rules: per-org editor -------------------- */ + d = call(reqf("{\"v\":1,\"id\":\"116a\",\"cmd\":\"report.rule_list\"," + "\"session\":\"%s\",\"org\":%d}", + g_session, (int)vat_org)); + CHECK_OK(d); + int nrules = (int)yyjson_arr_size(jget(d, "result.items")); + CHECK(nrules >= 15); + { + yyjson_val *items = jget(d, "result.items"); + for (size_t i = 0; i < yyjson_arr_size(items); i++) { + yyjson_val *rv = yyjson_obj_get(yyjson_arr_get(items, i), "report"); + CHECK(rv && yyjson_is_str(rv) && + strcmp(yyjson_get_str(rv), "vat") == 0); + } + } + CHECK_STR(d, "result.items.0.box", "05"); + CHECK(jint(d, "result.items.0.sort_order") == 10); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116b\",\"cmd\":\"report.rule_list\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"report\":\"vat\"}}", + g_session, (int)vat_org)); + CHECK_OK(d); + CHECK(yyjson_arr_size(jget(d, "result.items")) == (size_t)nrules); + yyjson_doc_free(d); + + /* dry run validates but must not create a rule */ + d = call(reqf("{\"v\":1,\"id\":\"116c\",\"cmd\":\"report.rule_create\"," + "\"session\":\"%s\",\"org\":%d,\"dry_run\":true,\"args\":" + "{\"report\":\"vat\",\"box\":\"05\",\"match_type\":\"type\"," + "\"pattern\":\"revenue\",\"sign\":-1,\"sort_order\":1}}", + g_session, (int)vat_org)); + CHECK_OK(d); + CHECK(jbool(d, "result.dry_run")); + CHECK(jint(d, "result.id") == 0); + CHECK_STR(d, "result.match_type", "type"); + CHECK_STR(d, "result.pattern", "revenue"); + CHECK(jint(d, "result.sign") == -1); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116d\",\"cmd\":\"report.rule_list\"," + "\"session\":\"%s\",\"org\":%d}", + g_session, (int)vat_org)); + CHECK_OK(d); + CHECK(yyjson_arr_size(jget(d, "result.items")) == (size_t)nrules); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116e\",\"cmd\":\"report.rule_create\"," + "\"session\":\"%s\",\"org\":%d,\"args\":" + "{\"report\":\"vat\",\"box\":\"05\",\"match_type\":\"type\"," + "\"pattern\":\"revenue\",\"sign\":-1,\"sort_order\":1}}", + g_session, (int)vat_org)); + CHECK_OK(d); + int64_t rule_id = jint(d, "result.id"); + CHECK(rule_id > 0); + CHECK_STR(d, "result.report", "vat"); + CHECK_STR(d, "result.box", "05"); + CHECK(jint(d, "result.sign") == -1); + CHECK(jint(d, "result.sort_order") == 1); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116f\",\"cmd\":\"report.rule_list\"," + "\"session\":\"%s\",\"org\":%d}", + g_session, (int)vat_org)); + CHECK_OK(d); + CHECK(yyjson_arr_size(jget(d, "result.items")) == (size_t)nrules + 1); + { + int found = 0; + yyjson_val *items = jget(d, "result.items"); + for (size_t i = 0; i < yyjson_arr_size(items); i++) { + yyjson_val *iv = yyjson_obj_get(yyjson_arr_get(items, i), "id"); + if (iv && yyjson_is_int(iv) && yyjson_get_int(iv) == rule_id) + found = 1; + } + CHECK(found); + } + yyjson_doc_free(d); + + /* the rule adds the revenue type on top of the seeded ranges */ + d = call(reqf("{\"v\":1,\"id\":\"116g\",\"cmd\":\"report.vat\"," + "\"session\":\"%s\",\"org\":%d,\"args\":" + "{\"from\":\"2026-02-01\",\"to\":\"2026-02-28\"}}", + g_session, (int)vat_org)); + CHECK_OK(d); + CHECK(vat_box(d, "05") == 300000); + CHECK(vat_box(d, "49") == 35500); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116h\",\"cmd\":\"report.rule_update\"," + "\"session\":\"%s\",\"org\":%d,\"args\":" + "{\"id\":%lld,\"sign\":1,\"sort_order\":2}}", + g_session, (int)vat_org, (long long)rule_id)); + CHECK_OK(d); + CHECK_STR(d, "result.match_type", "type"); + CHECK_STR(d, "result.pattern", "revenue"); + CHECK(jint(d, "result.sign") == 1); + CHECK(jint(d, "result.sort_order") == 2); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116i\",\"cmd\":\"report.vat\"," + "\"session\":\"%s\",\"org\":%d,\"args\":" + "{\"from\":\"2026-02-01\",\"to\":\"2026-02-28\"}}", + g_session, (int)vat_org)); + CHECK_OK(d); + CHECK(vat_box(d, "05") == 0); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116j\",\"cmd\":\"report.rule_update\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%lld," + "\"match_type\":\"range\",\"pattern\":\"3100-3000\"}}", + g_session, (int)vat_org, (long long)rule_id)); + CHECK_STR(d, "error.code", "INVALID_ARGS"); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116k\",\"cmd\":\"report.rule_update\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%d}}", + g_session, (int)vat_org, 999999)); + CHECK_STR(d, "error.code", "NOT_FOUND"); + yyjson_doc_free(d); + + /* dry-run delete keeps the rule */ + d = call(reqf("{\"v\":1,\"id\":\"116l\",\"cmd\":\"report.rule_delete\"," + "\"session\":\"%s\",\"org\":%d,\"dry_run\":true," + "\"args\":{\"id\":%lld}}", + g_session, (int)vat_org, (long long)rule_id)); + CHECK_OK(d); + CHECK(jbool(d, "result.deleted")); + CHECK(jbool(d, "result.dry_run")); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116m\",\"cmd\":\"report.rule_delete\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%lld}}", + g_session, (int)vat_org, (long long)rule_id)); + CHECK_OK(d); + CHECK(jint(d, "result.id") == rule_id); + CHECK(jbool(d, "result.deleted")); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116n\",\"cmd\":\"report.rule_list\"," + "\"session\":\"%s\",\"org\":%d}", + g_session, (int)vat_org)); + CHECK_OK(d); + CHECK(yyjson_arr_size(jget(d, "result.items")) == (size_t)nrules); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116o\",\"cmd\":\"report.vat\"," + "\"session\":\"%s\",\"org\":%d,\"args\":" + "{\"from\":\"2026-02-01\",\"to\":\"2026-02-28\"}}", + g_session, (int)vat_org)); + CHECK_OK(d); + CHECK(vat_box(d, "05") == 150000); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116p\",\"cmd\":\"report.rule_delete\"," + "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%lld}}", + g_session, (int)vat_org, (long long)rule_id)); + CHECK_STR(d, "error.code", "NOT_FOUND"); + yyjson_doc_free(d); + + /* invalid rules are rejected before any write */ + d = call(reqf("{\"v\":1,\"id\":\"116q\",\"cmd\":\"report.rule_create\"," + "\"session\":\"%s\",\"org\":%d,\"args\":" + "{\"report\":\"vat\",\"box\":\"05\"," + "\"match_type\":\"bogus\",\"pattern\":\"3001\"}}", + g_session, (int)vat_org)); + CHECK_STR(d, "error.code", "INVALID_ARGS"); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116r\",\"cmd\":\"report.rule_create\"," + "\"session\":\"%s\",\"org\":%d,\"args\":" + "{\"report\":\"vat\",\"box\":\"05\"," + "\"match_type\":\"range\",\"pattern\":\"3100-3000\"}}", + g_session, (int)vat_org)); + CHECK_STR(d, "error.code", "INVALID_ARGS"); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116s\",\"cmd\":\"report.rule_create\"," + "\"session\":\"%s\",\"org\":%d,\"args\":" + "{\"report\":\"vat\",\"box\":\"05\"," + "\"match_type\":\"account\",\"pattern\":\"30a1\"}}", + g_session, (int)vat_org)); + CHECK_STR(d, "error.code", "INVALID_ARGS"); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"116t\",\"cmd\":\"report.rule_create\"," + "\"session\":\"%s\",\"org\":%d,\"args\":" + "{\"report\":\"vat\",\"box\":\"05\"," + "\"match_type\":\"type\",\"pattern\":\"revenue\",\"sign\":0}}", + g_session, (int)vat_org)); + CHECK_STR(d, "error.code", "INVALID_ARGS"); + yyjson_doc_free(d); + /* ---------------- bokslut: dispositions, tax, transfer ---------- */ d = call(reqf("{\"v\":1,\"id\":\"120\",\"cmd\":\"bokslut.post\"," "\"session\":\"%s\",\"org\":%d,\"dry_run\":true,\"args\":" -- cgit v1.3