summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrikboy@gmail.com>2025-10-20 08:29:53 +0200
committerAldrik Ramaekers <aldrikboy@gmail.com>2025-10-20 08:29:53 +0200
commitfdc74456a98fe9076ff5d029b37cdf5fdd18b1d1 (patch)
tree70e5520d8a2a0ae618d5a8df82f01bde66381d98
parent82f783595f654b62ce57a7cfb537d23efce7affc (diff)
nl tax tests
-rw-r--r--TODO3
-rw-r--r--src/administration.cpp1
-rw-r--r--src/ui/ui_invoices.cpp4
-rw-r--r--tests/nl_tax_tests.cpp170
-rw-r--r--tests/test_helper.cpp13
5 files changed, 186 insertions, 5 deletions
diff --git a/TODO b/TODO
index 57a1d99..8b25d1d 100644
--- a/TODO
+++ b/TODO
@@ -1,14 +1,11 @@
TODO:
Refactor:
-- There is alot of memory leakage
Testing:
-- write tests for all NL tax categories
- write test to make sure all tax rates are unique per country.
- write tests for strops.hpp
- write tests that check error handling for corrupt files. (e.g. references to tax rates, project and cost center that failed to load)
-- it is possible a referenced tax rate is loaded after an invoice is loaded. This means all invoices need to be recalculated after file load. (try to write a test for this).
- peppol testing: add a billing item for each tax category.
Improvements:
diff --git a/src/administration.cpp b/src/administration.cpp
index b3d5ad4..b1e3198 100644
--- a/src/administration.cpp
+++ b/src/administration.cpp
@@ -1068,6 +1068,7 @@ a_err administration::tax_rate_remove(tax_rate data)
char filename[MAX_LEN_PATH];
strops::format(filename, sizeof(filename), "T/%s", c->internal_code);
if (data_deleted_event_callback) data_deleted_event_callback(filename);
+ memops::unalloc(c);
return A_ERR_SUCCESS;
}
}
diff --git a/src/ui/ui_invoices.cpp b/src/ui/ui_invoices.cpp
index 18acc59..d932bfd 100644
--- a/src/ui/ui_invoices.cpp
+++ b/src/ui/ui_invoices.cpp
@@ -97,11 +97,11 @@ void draw_invoice_items_form(invoice* invoice, bool outgoing)
ImGui::TableSetColumnIndex(3);
ImGui::PushItemWidth(-1);
- ImGui::InputFloat("##price", &item.net_per_item, 0.0f, 0.0f, "%.3f");
+ ImGui::InputFloat("##price", &item.net_per_item, 0.0f, 0.0f, "%.2f");
ImGui::PopItemWidth();
ImGui::TableSetColumnIndex(4);
- ImGui::InputFloat("##discount", &item.discount, 0.0f, 0.0f, "%.3f");
+ ImGui::InputFloat("##discount", &item.discount, 0.0f, 0.0f, "%.2f");
ImGui::SameLine();
ImGui::FormToggleCombo(&item.discount_is_percentage, item.currency, "%");
diff --git a/tests/nl_tax_tests.cpp b/tests/nl_tax_tests.cpp
index 0fce093..d5b0f9b 100644
--- a/tests/nl_tax_tests.cpp
+++ b/tests/nl_tax_tests.cpp
@@ -113,9 +113,179 @@ TEST _nl_tax_2currency(void)
PASS();
}
+TEST _nl_tax_2a(void)
+{
+ administration::create_default(test_file_path);
+ administration::company_info_set(_create_nl_business());
+ add_default_nl_tax_rates();
+
+ invoice inv = _create_nl_b2b_inv_incomming();
+
+ administration::billing_item_add_to_invoice(&inv, _create_bi(1, 30.0f, "NL_IN/BV/21"));
+ administration::billing_item_add_to_invoice(&inv, _create_bi(1, 50.0f, "NL_IN/BV/9"));
+ ASSERT_EQ(administration::invoice_add(&inv), A_ERR_SUCCESS);
+
+ tax_statement statement;
+ administration::create_tax_statement(&statement);
+ ASSERT_EQ(statement.report_count, 1);
+
+ tax_line* tl = administration::get_tax_line_from_report(&statement.reports[0], "NL/2a");
+ GREATEST_ASSERT_FEQ(tl->total_net, inv.net);
+ GREATEST_ASSERT_FEQ(tl->total_tax, inv.tax);
+
+ tax_line* tl2 = administration::get_tax_line_from_report(&statement.reports[0], "NL/5a");
+ GREATEST_ASSERT_FEQ(tl2->total_tax, inv.tax);
+
+ tax_line* tl3 = administration::get_tax_line_from_report(&statement.reports[0], "NL/5b");
+ GREATEST_ASSERT_FEQ(tl3->total_tax, inv.tax);
+
+ PASS();
+}
+
+TEST _nl_tax_4a(void)
+{
+ administration::create_default(test_file_path);
+ administration::company_info_set(_create_nl_business());
+ add_default_nl_tax_rates();
+
+ invoice inv = _create_nl_b2b_inv_incomming();
+
+ administration::billing_item_add_to_invoice(&inv, _create_bi(1, 30.0f, "NL_IN/BEUV/21"));
+ administration::billing_item_add_to_invoice(&inv, _create_bi(1, 50.0f, "NL_IN/BEUV/9"));
+ ASSERT_EQ(administration::invoice_add(&inv), A_ERR_SUCCESS);
+
+ tax_statement statement;
+ administration::create_tax_statement(&statement);
+ ASSERT_EQ(statement.report_count, 1);
+
+ tax_line* tl = administration::get_tax_line_from_report(&statement.reports[0], "NL/4a");
+ GREATEST_ASSERT_FEQ(tl->total_net, inv.net);
+ GREATEST_ASSERT_FEQ(tl->total_tax, inv.tax);
+
+ tax_line* tl2 = administration::get_tax_line_from_report(&statement.reports[0], "NL/5a");
+ GREATEST_ASSERT_FEQ(tl2->total_tax, inv.tax);
+
+ tax_line* tl3 = administration::get_tax_line_from_report(&statement.reports[0], "NL/5b");
+ GREATEST_ASSERT_FEQ(tl3->total_tax, inv.tax);
+
+ PASS();
+}
+
+TEST _nl_tax_4b(void)
+{
+ administration::create_default(test_file_path);
+ administration::company_info_set(_create_nl_business());
+ add_default_nl_tax_rates();
+
+ invoice inv = _create_nl_b2b_inv_incomming();
+
+ administration::billing_item_add_to_invoice(&inv, _create_bi(1, 30.0f, "NL_IN/IEUV/21"));
+ administration::billing_item_add_to_invoice(&inv, _create_bi(1, 50.0f, "NL_IN/IEUV/9"));
+ ASSERT_EQ(administration::invoice_add(&inv), A_ERR_SUCCESS);
+
+ tax_statement statement;
+ administration::create_tax_statement(&statement);
+ ASSERT_EQ(statement.report_count, 1);
+
+ tax_line* tl = administration::get_tax_line_from_report(&statement.reports[0], "NL/4b");
+ GREATEST_ASSERT_FEQ(tl->total_net, inv.net);
+ GREATEST_ASSERT_FEQ(tl->total_tax, inv.tax);
+
+ tax_line* tl2 = administration::get_tax_line_from_report(&statement.reports[0], "NL/5a");
+ GREATEST_ASSERT_FEQ(tl2->total_tax, inv.tax);
+
+ tax_line* tl3 = administration::get_tax_line_from_report(&statement.reports[0], "NL/5b");
+ GREATEST_ASSERT_FEQ(tl3->total_tax, inv.tax);
+
+ PASS();
+}
+
+TEST _nl_tax_5a(void)
+{
+ administration::create_default(test_file_path);
+ administration::company_info_set(_create_nl_business());
+ add_default_nl_tax_rates();
+
+ invoice inv = _create_nl_b2b_inv_outgoing();
+
+ administration::billing_item_add_to_invoice(&inv, _create_bi(1, 20.0f, "NL/21"));
+ administration::billing_item_add_to_invoice(&inv, _create_bi(1, 30.0f, "NL/9"));
+ ASSERT_EQ(administration::invoice_add(&inv), A_ERR_SUCCESS);
+
+ tax_statement statement;
+ administration::create_tax_statement(&statement);
+ ASSERT_EQ(statement.report_count, 1);
+
+ tax_line* tl2 = administration::get_tax_line_from_report(&statement.reports[0], "NL/5a");
+ ASSERT_EQ(tl2->total_tax, inv.tax);
+
+ PASS();
+}
+
+TEST _nl_tax_5b(void)
+{
+ administration::create_default(test_file_path);
+ administration::company_info_set(_create_nl_business());
+ add_default_nl_tax_rates();
+
+ invoice inv = _create_nl_b2b_inv_incomming();
+
+ administration::billing_item_add_to_invoice(&inv, _create_bi(1, 30.0f, "NL_IN/21/5B"));
+ administration::billing_item_add_to_invoice(&inv, _create_bi(1, 50.0f, "NL_IN/9/5B"));
+ ASSERT_EQ(administration::invoice_add(&inv), A_ERR_SUCCESS);
+
+ tax_statement statement;
+ administration::create_tax_statement(&statement);
+ ASSERT_EQ(statement.report_count, 1);
+
+ tax_line* tl3 = administration::get_tax_line_from_report(&statement.reports[0], "NL/5b");
+ GREATEST_ASSERT_FEQ(tl3->total_tax, inv.tax);
+
+ PASS();
+}
+
+TEST _nl_tax_5c(void)
+{
+ administration::create_default(test_file_path);
+ administration::company_info_set(_create_nl_business());
+ add_default_nl_tax_rates();
+
+ invoice inv = _create_nl_b2b_inv_outgoing();
+ administration::billing_item_add_to_invoice(&inv, _create_bi(1, 20.0f, "NL/21"));
+ administration::billing_item_add_to_invoice(&inv, _create_bi(1, 30.0f, "NL/9"));
+ ASSERT_EQ(administration::invoice_add(&inv), A_ERR_SUCCESS);
+
+ invoice inv2 = _create_nl_b2b_inv_incomming();
+ administration::billing_item_add_to_invoice(&inv2, _create_bi(1, 30.0f, "NL_IN/21/5B"));
+ administration::billing_item_add_to_invoice(&inv2, _create_bi(1, 50.0f, "NL_IN/9/5B"));
+ ASSERT_EQ(administration::invoice_add(&inv2), A_ERR_SUCCESS);
+
+ tax_statement statement;
+ administration::create_tax_statement(&statement);
+ ASSERT_EQ(statement.report_count, 1);
+
+ float total = inv.tax - inv2.tax;
+ if (total < 0.0f) total = (float)ceil(total);
+ else total = (float)floor(total);
+
+ tax_line* tl3 = administration::get_tax_line_from_report(&statement.reports[0], "NL/5c");
+ GREATEST_ASSERT_FEQ(tl3->total_tax, total);
+
+ PASS();
+}
+
SUITE(nl_tax_statement) {
RUN_TEST(_nl_tax_1a);
RUN_TEST(_nl_tax_1b);
RUN_TEST(_nl_tax_1e);
RUN_TEST(_nl_tax_2currency);
+
+ RUN_TEST(_nl_tax_2a);
+
+ RUN_TEST(_nl_tax_4a);
+ RUN_TEST(_nl_tax_4b);
+
+ RUN_TEST(_nl_tax_5a);
+ RUN_TEST(_nl_tax_5b);
+ RUN_TEST(_nl_tax_5c);
} \ No newline at end of file
diff --git a/tests/test_helper.cpp b/tests/test_helper.cpp
index 63f64ed..ebc61a3 100644
--- a/tests/test_helper.cpp
+++ b/tests/test_helper.cpp
@@ -179,6 +179,19 @@ static invoice _create_nl_b2b_inv_outgoing()
return inv;
}
+static invoice _create_nl_b2b_inv_incomming()
+{
+ invoice inv = administration::invoice_create_empty();
+ inv.supplier = _create_nl_business();
+ inv.customer = administration::company_info_get();
+ inv.is_outgoing = 0;
+ inv.status = invoice_status::INVOICE_CONCEPT;
+ inv.issued_at = time(NULL);
+ inv.delivered_at = inv.issued_at;
+ inv.expires_at = inv.issued_at + 1000;
+ return inv;
+}
+
static bool _test_peppol_file(char* id)
{
bool result = 1;