diff options
| author | Aldrik Ramaekers <aldrikboy@gmail.com> | 2025-10-10 22:03:05 +0200 |
|---|---|---|
| committer | Aldrik Ramaekers <aldrikboy@gmail.com> | 2025-10-10 22:03:05 +0200 |
| commit | d976c1227f367a4547a004597b8d360a8958eba9 (patch) | |
| tree | 891b89263176375f058598b629b145177531a54a | |
| parent | 1c53bd3ac83cc7a985983ac656bc2599276808a4 (diff) | |
working on NL tax reports
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | include/administration.hpp | 9 | ||||
| -rw-r--r-- | include/countries.hpp | 8 | ||||
| -rw-r--r-- | include/strops.hpp | 1 | ||||
| -rw-r--r-- | src/administration.cpp | 70 | ||||
| -rw-r--r-- | src/administration_writer.cpp | 7 | ||||
| -rw-r--r-- | src/countries.cpp | 22 | ||||
| -rw-r--r-- | src/countries/nl.cpp | 125 | ||||
| -rw-r--r-- | src/locales/en.cpp | 3 | ||||
| -rw-r--r-- | src/strops.cpp | 5 | ||||
| -rw-r--r-- | tests/main.cpp | 3 | ||||
| -rw-r--r-- | tests/nl_tax_tests.cpp | 114 | ||||
| -rw-r--r-- | tests/test_helper.cpp | 28 |
13 files changed, 349 insertions, 49 deletions
@@ -1,4 +1,5 @@ imgui.ini build/* example.openbook -keys
\ No newline at end of file +keys +.vscode/
\ No newline at end of file diff --git a/include/administration.hpp b/include/administration.hpp index 54f8aac..69c0c0a 100644 --- a/include/administration.hpp +++ b/include/administration.hpp @@ -443,10 +443,17 @@ namespace administration { void set_project_changed_event_callback(project_changed_event ev); // Company info functions. + // ======================= contact company_info_get(); void company_info_import(contact data); void company_info_set(contact data); + + // Tax functions. + // ======================= + tax_line* get_tax_line_from_report(tax_report* quarter, char* category); + void create_tax_statement(tax_statement* statement); + // Other functions. // ======================= char* get_file_path(); @@ -463,7 +470,6 @@ namespace administration { void set_ai_service(ai_service provider); void create_income_statement(income_statement* statement); - void create_tax_statement(tax_statement* statement); bool can_create_invoices(); // Contact functions. @@ -541,6 +547,7 @@ namespace administration { invoice invoice_create_copy(invoice* invoice); a_err invoice_is_valid(invoice* invoice); + bool invoice_has_intra_community_services(invoice* invoice); char* invoice_get_status_string(invoice* invoice); u32 invoice_get_partial_list_outgoing(u32 page_index, u32 page_size, invoice* buffer); diff --git a/include/countries.hpp b/include/countries.hpp index 0849ed6..8b4bb88 100644 --- a/include/countries.hpp +++ b/include/countries.hpp @@ -24,7 +24,9 @@ typedef struct bool is_EU; time_t (*get_default_invoice_expire_duration)(); void (*fill_tax_report_with_categories)(tax_report* report); - char* (*get_tax_category_for_billing_item)(invoice* inv, billing_item* item); + bool (*add_billing_item_to_tax_report)(tax_report* report, invoice* inv, billing_item* item); + float (*calculate_tax_report_final)(tax_report* report); + time_t (*get_invoice_date_to_use_for_tax_report)(invoice* inv); } country_impl; namespace country { @@ -37,6 +39,8 @@ namespace country { bool is_EU(char* country_code); bool tax_is_implemented(char* country_code); void fill_tax_report_with_categories(char* country_code, tax_report* report); - char* get_tax_category_for_billing_item(char* country_code, invoice* inv, billing_item* item); + bool add_billing_item_to_tax_report(char* country_code, tax_report* report, invoice* inv, billing_item* item); + float calculate_tax_report_final(char* country_code, tax_report* report); + time_t get_invoice_date_to_use_for_tax_report(char* country_code, invoice* inv); }
\ No newline at end of file diff --git a/include/strops.hpp b/include/strops.hpp index 5dc7368..206aaee 100644 --- a/include/strops.hpp +++ b/include/strops.hpp @@ -23,6 +23,7 @@ namespace strops { size_t copy(char *dst, const char *src, size_t size); char* contains(char* a, char* b); bool equals(const char* a, const char* b); + char* tokenize(char* a, const char* find); s32 format_va(char* s, size_t n, const char* format, va_list args); s32 format(char* s, size_t n, const char* format, ...); diff --git a/src/administration.cpp b/src/administration.cpp index 9adce55..0ad9684 100644 --- a/src/administration.cpp +++ b/src/administration.cpp @@ -78,7 +78,8 @@ static void create_default_tax_rates() ADD_BRACKET("00", 0.0f, "Z"); // Zero rated goods ADD_BRACKET("00", 0.0f, "G"); // Free export item, VAT not charged ADD_BRACKET("00", 0.0f, "O"); // Services outside scope of tax - ADD_BRACKET("00", 0.0f, "K"); // VAT exempt for EEA intra-community supply of goods and services + ADD_BRACKET("00", 0.0f, "K#G"); // VAT exempt for EEA intra-community supply of goods + ADD_BRACKET("00", 0.0f, "K#S"); // VAT exempt for EEA intra-community supply of services // Austria ADD_BRACKET("AT", 20.0f, "S"); @@ -502,16 +503,16 @@ void administration::create_tax_statement(tax_statement* statement) u16 oldest_year; u8 oldest_quarter; time_t_to_quarter(oldest, &oldest_year, &oldest_quarter); - oldest_quarter = 0; + //oldest_quarter = 0; u16 youngest_year; u8 youngest_quarter; time_t_to_quarter(youngest, &youngest_year, &youngest_quarter); - youngest_quarter = 3; + //youngest_quarter = 3; u32 num_quarters = (youngest_quarter+1 + (youngest_year*4)) - (oldest_quarter + (oldest_year*4)); assert(num_quarters <= MAX_LEN_INCOME_STATEMENT_REPORT_QUARTERS); - assert(num_quarters % 4 == 0); + //assert(num_quarters % 4 == 0); // Generate quarters. for (u32 i = 0; i < num_quarters; i++) @@ -524,6 +525,8 @@ void administration::create_tax_statement(tax_statement* statement) strops::format(quarter.quarter_str, MAX_LEN_SHORT_DESC, "%dQ%d", quarter.quarter+1, quarter.year); country::fill_tax_report_with_categories(country_code, &quarter); + + statement->reports[statement->quarter_count++] = quarter; } // Fill quarters. @@ -533,7 +536,7 @@ void administration::create_tax_statement(tax_statement* statement) u16 yy; u8 qq; - time_t_to_quarter(inv->issued_at, &yy, &qq); + time_t_to_quarter(country::get_invoice_date_to_use_for_tax_report(country_code, inv), &yy, &qq); u32 report_index = (qq + (yy*4)) - (oldest_quarter + (oldest_year*4)); @@ -545,24 +548,30 @@ void administration::create_tax_statement(tax_statement* statement) u32 invoice_items = administration::billing_item_get_all_for_invoice(inv, item_buffer); for (u32 x = 0; x < invoice_items; x++) { - char* tax_category = country::get_tax_category_for_billing_item(country_code, inv, &item_buffer[x]); - for (u32 t = 0; t < quarter->line_count; t++) - { - if (strops::equals(quarter->lines[t].tax_category, tax_category)) - { - quarter->lines[t].total_net += inv->net; - quarter->lines[t].total_tax += inv->tax; - } - } + bool success = country::add_billing_item_to_tax_report(country_code, quarter, inv, &item_buffer[x]); + if (!success) logger::error("Failed to add billing item to tax report: %s - %s.", inv->sequential_number, item_buffer[x].description); + } + country::calculate_tax_report_final(country_code, quarter); - memops::unalloc(item_buffer); - } + memops::unalloc(item_buffer); } - + memops::unalloc(invoice_buffer); logger::info("Created tax statement in %.3fms.", STOPWATCH_TIME); } +tax_line* administration::get_tax_line_from_report(tax_report* quarter, char* category) +{ + for (u32 t = 0; t < quarter->line_count; t++) + { + if (strops::equals(quarter->lines[t].tax_category, category)) + { + return &quarter->lines[t]; + } + } + return 0; +} + void administration::create_income_statement(income_statement* statement) { STOPWATCH_START; @@ -1216,6 +1225,13 @@ a_err administration::tax_rate_get_by_shorthandle(tax_rate* buffer, char* handle list_iterator_stop(&g_administration.tax_rates); return A_ERR_SUCCESS; } + strops::format(compare_str, 20, "%s/%s", c.country_code, c.category_code); + if (strcmp(compare_str, handle) == 0) + { + *buffer = c; + list_iterator_stop(&g_administration.tax_rates); + return A_ERR_SUCCESS; + } } list_iterator_stop(&g_administration.tax_rates); @@ -1527,6 +1543,26 @@ static char* get_default_currency_for_country(char* country_code) return "EUR"; } +bool administration::invoice_has_intra_community_services(invoice* invoice) +{ + list_iterator_start(&invoice->billing_items); + while (list_iterator_hasnext(&invoice->billing_items)) { + billing_item* c = (billing_item *)list_iterator_next(&invoice->billing_items); + + tax_rate rate; + a_err found = administration::tax_rate_get_by_id(&rate, c->tax_rate_id); + if (found == A_ERR_SUCCESS) { + if (strops::equals(rate.category_code, "K#S")) { + list_iterator_stop(&invoice->billing_items); + return true; + } + } + } + list_iterator_stop(&invoice->billing_items); + + return false; +} + invoice administration::invoice_create_empty() { invoice result; diff --git a/src/administration_writer.cpp b/src/administration_writer.cpp index f7069a6..81c90fa 100644 --- a/src/administration_writer.cpp +++ b/src/administration_writer.cpp @@ -426,7 +426,12 @@ bool administration_writer::save_invoice_blocking(invoice inv) strops::replace(tax_entry_file_content, tax_entry_buf_length, "{{CURRENCY}}", inv.currency); strops::replace_float(tax_entry_file_content, tax_entry_buf_length, "{{TAXABLE_AMOUNT}}", subtotal.net, 2); strops::replace_float(tax_entry_file_content, tax_entry_buf_length, "{{TAX_AMOUNT}}", subtotal.tax, 2); - strops::replace(tax_entry_file_content, tax_entry_buf_length, "{{TAX_CATEGORY}}", tax_rate_buffer[i].category_code); + + char tax_category[10]; + strops::copy(tax_category, tax_rate_buffer[i].category_code, sizeof(tax_category)); + strops::tokenize(tax_category, "#"); + + strops::replace(tax_entry_file_content, tax_entry_buf_length, "{{TAX_CATEGORY}}", tax_category); strops::replace_float(tax_entry_file_content, tax_entry_buf_length, "{{TAX_PERCENT}}", tax_rate_buffer[i].rate, 2); u32 content_len = (u32)strlen(tax_entry_file_content); diff --git a/src/countries.cpp b/src/countries.cpp index d4bcae1..5712a7f 100644 --- a/src/countries.cpp +++ b/src/countries.cpp @@ -68,7 +68,7 @@ bool country::tax_is_implemented(char* country_code) if (index == -1) return false; return country_map[index].fill_tax_report_with_categories && - country_map[index].get_tax_category_for_billing_item; + country_map[index].add_billing_item_to_tax_report; } void country::fill_tax_report_with_categories(char* country_code, tax_report* report) @@ -79,10 +79,26 @@ void country::fill_tax_report_with_categories(char* country_code, tax_report* re country_map[index].fill_tax_report_with_categories(report); } -char* country::get_tax_category_for_billing_item(char* country_code, invoice* inv, billing_item* item) +bool country::add_billing_item_to_tax_report(char* country_code, tax_report* report, invoice* inv, billing_item* item) { s32 index = get_index_by_country_code(country_code); assert(index != -1); - return country_map[index].get_tax_category_for_billing_item(inv, item); + return country_map[index].add_billing_item_to_tax_report(report, inv, item); +} + +float country::calculate_tax_report_final(char* country_code, tax_report* report) +{ + s32 index = get_index_by_country_code(country_code); + assert(index != -1); + + return country_map[index].calculate_tax_report_final(report); +} + +time_t country::get_invoice_date_to_use_for_tax_report(char* country_code, invoice* inv) +{ + s32 index = get_index_by_country_code(country_code); + assert(index != -1); + + return country_map[index].get_invoice_date_to_use_for_tax_report(inv); }
\ No newline at end of file diff --git a/src/countries/nl.cpp b/src/countries/nl.cpp index 85005d6..9c8a20b 100644 --- a/src/countries/nl.cpp +++ b/src/countries/nl.cpp @@ -14,7 +14,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <math.h> + #include "countries.hpp" +#include "strops.hpp" time_t _nl_get_default_invoice_expire_duration() { @@ -44,7 +47,7 @@ void _nl_fill_tax_report_with_categories(tax_report* report) report->lines[report->line_count++] = tax_line {"Total", 0.0f, 0.0f}; } -char* _nl_get_tax_category_for_billing_item(invoice* inv, billing_item* item) +bool _nl_add_billing_item_to_tax_report(tax_report* report, invoice* inv, billing_item* item) { // https://goedestartbelastingdienst.nl/wiki/view/7494ecb4-f6d2-4f85-a200-5a3ee5d45b75/btw-aangifte-het-invullen-van-de-verschillende-rubrieken @@ -52,43 +55,117 @@ char* _nl_get_tax_category_for_billing_item(invoice* inv, billing_item* item) a_err err = administration::tax_rate_get_by_id(&rate, item->tax_rate_id); if (err != A_ERR_SUCCESS) return 0; - - /* - We moeten 5a ook nog berekenen, dus misschien tax_report meegeven en hier alles doen wat nodig is? - we moeten ook nog het uiteindelijke bedrag uitregenen 5a-5b dus dat moet ook hier gebeuren. - - */ - - // Outgoing = 1 + 3 if (inv->is_outgoing) { + tax_line* a5 = administration::get_tax_line_from_report(report, "5a"); // Total owed. + if (strops::equals(inv->customer.address.country_code, "NL")) { - if (rate.rate == 21.0f) return "1a"; - else if (rate.rate == 9.0f) return "1b"; + if (rate.rate == 21.0f) { + tax_line* tl = administration::get_tax_line_from_report(report, "1a"); + tl->total_net += item->net; + tl->total_tax += item->tax; + + a5->total_tax += item->tax; + } + else if (rate.rate == 9.0f) { + tax_line* tl = administration::get_tax_line_from_report(report, "1b"); + tl->total_net += item->net; + tl->total_tax += item->tax; + + a5->total_tax += item->tax; + } // TODO 1c - else if (rate.rate > 0.0f) return "1d"; - else if (rate.rate == 0.0f) return "1e"; + else if (rate.rate > 0.0f) { + tax_line* tl = administration::get_tax_line_from_report(report, "1d"); + tl->total_net += item->net; + tl->total_tax += item->tax; + + a5->total_tax += item->tax; + } + else if (rate.rate == 0.0f) { + tax_line* tl = administration::get_tax_line_from_report(report, "1e"); + tl->total_net += item->net; + tl->total_tax += item->tax; + + a5->total_tax += item->tax; + } + } + else if (!country::is_EU(inv->customer.address.country_code)) { + tax_line* tl = administration::get_tax_line_from_report(report, "3a"); + tl->total_net += item->net; + // Tax is paid to country of customer. + } + else { + tax_line* tl = administration::get_tax_line_from_report(report, "3b"); + tl->total_net += item->net; + // Tax is paid to country of customer. } - else if (!country::is_EU(inv->customer.address.country_code)) return "3a"; - else return "3b"; // TODO 3c } - - // Incomming = 2 + 4 + 5 else { + tax_line* a5 = administration::get_tax_line_from_report(report, "5a"); // Total owed. + tax_line* b5 = administration::get_tax_line_from_report(report, "5b"); // Input tax. if (strops::equals(inv->customer.address.country_code, "NL")) { - if (strops::equals(rate.category_code, "AE")) return "2a"; // NL reverse charge. - else return "5b"; + + if (strops::equals(rate.category_code, "AE")) { // NL reverse charge. + tax_line* tl = administration::get_tax_line_from_report(report, "2a"); + + tl->total_net += item->net; + tl->total_tax += item->net * 0.21f; // TODO fr? + + a5->total_tax += item->net * 0.21f; + b5->total_tax += item->net * 0.21f; + } + else { + b5->total_tax += item->tax; + } + } + + if (!country::is_EU(inv->customer.address.country_code)) { + tax_line* tl = administration::get_tax_line_from_report(report, "4a"); + + tl->total_net += item->net; + tl->total_tax += item->net * 0.21f; + + a5->total_tax += item->net * 0.21f; + b5->total_tax += item->net * 0.21f; } + else { + tax_line* tl = administration::get_tax_line_from_report(report, "4b"); + + tl->total_net += item->net; + tl->total_tax += item->net * 0.21f; - if (!country::is_EU(inv->customer.address.country_code)) return "4a"; - else return "4b"; + a5->total_tax += item->net * 0.21f; + b5->total_tax += item->net * 0.21f; + } } - return 0; + return 1; +} + +float _nl_calculate_tax_report_final(tax_report* report) +{ + tax_line* a5 = administration::get_tax_line_from_report(report, "5a"); // Total owed. + tax_line* b5 = administration::get_tax_line_from_report(report, "5b"); // Input tax. + tax_line* total = administration::get_tax_line_from_report(report, "Total"); + + total->total_tax = a5->total_tax - b5->total_tax; + return (float)ceil(total->total_tax); +} + +time_t _nl_get_invoice_date_to_use_for_tax_report(invoice* inv) +{ + if (!inv->is_outgoing) { // Intra-Community services need to be reported in the quarter the service was delivered. + if (administration::invoice_has_intra_community_services(inv)) { + return inv->delivered_at; + } + } + + return inv->issued_at; } country_impl _nl_country_impl = { @@ -96,5 +173,7 @@ country_impl _nl_country_impl = { true, _nl_get_default_invoice_expire_duration, _nl_fill_tax_report_with_categories, - _nl_get_tax_category_for_billing_item, + _nl_add_billing_item_to_tax_report, + _nl_calculate_tax_report_final, + _nl_get_invoice_date_to_use_for_tax_report, };
\ No newline at end of file diff --git a/src/locales/en.cpp b/src/locales/en.cpp index aa04853..e7ad41b 100644 --- a/src/locales/en.cpp +++ b/src/locales/en.cpp @@ -63,7 +63,8 @@ locale_entry en_locales[] = { {"taxcategory.Z", "Zero rated goods"}, {"taxcategory.G", "Free export item, VAT not charged"}, {"taxcategory.O", "Services outside scope of tax"}, - {"taxcategory.K", "Intra-community supply of goods"}, + {"taxcategory.K#G", "Intra-community supply of goods"}, + {"taxcategory.K#S", "Intra-community supply of services"}, // Countries { "country.AT", "Austria" }, diff --git a/src/strops.cpp b/src/strops.cpp index 146a909..d47ec2e 100644 --- a/src/strops.cpp +++ b/src/strops.cpp @@ -63,6 +63,11 @@ namespace strops { return 0; } + char* tokenize(char* a, const char* find) + { + return strtok(a, find); + } + s32 format_va(char* s, size_t n, const char* format, va_list args) { s32 result = vsnprintf(s, n, format, args); diff --git a/tests/main.cpp b/tests/main.cpp index 358ca2e..d9bd1c9 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -4,11 +4,14 @@ #include "administration_validation_tests.cpp" #include "peppol_write_tests.cpp" +#include "nl_tax_tests.cpp" + GREATEST_MAIN_DEFS(); int main(int argc, char **argv) { timer_lib_initialize(); GREATEST_MAIN_BEGIN(); + RUN_SUITE(nl_tax_statement); RUN_SUITE(administration_rw); RUN_SUITE(administration_validate); RUN_SUITE(peppol_write); diff --git a/tests/nl_tax_tests.cpp b/tests/nl_tax_tests.cpp new file mode 100644 index 0000000..e6fda94 --- /dev/null +++ b/tests/nl_tax_tests.cpp @@ -0,0 +1,114 @@ + + +TEST _nl_tax_1a(void) +{ + administration::create_default(test_file_path); + administration::company_info_set(_create_nl_business()); + + invoice inv = _create_nl_b2b_inv_outgoing(); + + administration::billing_item_add_to_invoice(&inv, _create_bi(1, 20.0f, "NL/21.00")); + administration::billing_item_add_to_invoice(&inv, _create_bi(1, 30.0f, "NL/21.00")); + ASSERT_EQ(administration::invoice_add(&inv), A_ERR_SUCCESS); + + tax_statement statement; + administration::create_tax_statement(&statement); + ASSERT_EQ(statement.quarter_count, 1); + + tax_line* tl = administration::get_tax_line_from_report(&statement.reports[0], "1a"); + ASSERT_EQ(tl->total_net, 50.0f); + ASSERT_EQ(tl->total_tax, 50.0f * 0.21f); + + tax_line* tl2 = administration::get_tax_line_from_report(&statement.reports[0], "5a"); + ASSERT_EQ(tl2->total_tax, 50.0f * 0.21f); + + PASS(); +} + +TEST _nl_tax_1b(void) +{ + administration::create_default(test_file_path); + administration::company_info_set(_create_nl_business()); + + invoice inv = _create_nl_b2b_inv_outgoing(); + + administration::billing_item_add_to_invoice(&inv, _create_bi(1, 10.0f, "NL/9.00")); + administration::billing_item_add_to_invoice(&inv, _create_bi(1, 15.0f, "NL/9.00")); + ASSERT_EQ(administration::invoice_add(&inv), A_ERR_SUCCESS); + + tax_statement statement; + administration::create_tax_statement(&statement); + ASSERT_EQ(statement.quarter_count, 1); + + tax_line* tl = administration::get_tax_line_from_report(&statement.reports[0], "1b"); + ASSERT_EQ(tl->total_net, 25.0f); + ASSERT_EQ(tl->total_tax, 25.0f * 0.09f); + + tax_line* tl2 = administration::get_tax_line_from_report(&statement.reports[0], "5a"); + ASSERT_EQ(tl2->total_tax, 25.0f * 0.09f); + + PASS(); +} + +TEST _nl_tax_1d(void) +{ + administration::create_default(test_file_path); + administration::company_info_set(_create_nl_business()); + + tax_rate new_tax_rate = administration::tax_rate_create_empty(); + new_tax_rate.rate = 5.0f; + strops::copy(new_tax_rate.category_code, "S", MAX_LEN_CODE); + strops::copy(new_tax_rate.country_code, "NL", MAX_LEN_COUNTRY_CODE); + administration::tax_rate_add(new_tax_rate); + + invoice inv = _create_nl_b2b_inv_outgoing(); + + administration::billing_item_add_to_invoice(&inv, _create_bi(1, 30.0f, "NL/5.00")); + administration::billing_item_add_to_invoice(&inv, _create_bi(1, 15.0f, "NL/5.00")); + ASSERT_EQ(administration::invoice_add(&inv), A_ERR_SUCCESS); + + tax_statement statement; + administration::create_tax_statement(&statement); + ASSERT_EQ(statement.quarter_count, 1); + + tax_line* tl = administration::get_tax_line_from_report(&statement.reports[0], "1d"); + ASSERT_EQ(tl->total_net, 45.0f); + ASSERT_EQ(tl->total_tax, 45.0f * 0.05f); + + tax_line* tl2 = administration::get_tax_line_from_report(&statement.reports[0], "5a"); + ASSERT_EQ(tl2->total_tax, 45.0f * 0.05f); + + PASS(); +} + +TEST _nl_tax_1e(void) +{ + administration::create_default(test_file_path); + administration::company_info_set(_create_nl_business()); + + invoice inv = _create_nl_b2b_inv_outgoing(); + + administration::billing_item_add_to_invoice(&inv, _create_bi(1, 30.0f, "00/E")); + administration::billing_item_add_to_invoice(&inv, _create_bi(1, 50.0f, "00/E")); + ASSERT_EQ(administration::invoice_add(&inv), A_ERR_SUCCESS); + + tax_statement statement; + administration::create_tax_statement(&statement); + ASSERT_EQ(statement.quarter_count, 1); + + tax_line* tl = administration::get_tax_line_from_report(&statement.reports[0], "1e"); + ASSERT_EQ(tl->total_net, 80.0f); + ASSERT_EQ(tl->total_tax, 0.0f); + + tax_line* tl2 = administration::get_tax_line_from_report(&statement.reports[0], "5a"); + ASSERT_EQ(tl2->total_tax, 0.0f); + + PASS(); +} + +SUITE(nl_tax_statement) { + RUN_TEST(_nl_tax_1a); + RUN_TEST(_nl_tax_1b); + RUN_TEST(_nl_tax_1d); + RUN_TEST(_nl_tax_1e); +}
\ No newline at end of file diff --git a/tests/test_helper.cpp b/tests/test_helper.cpp index 1dbb2b2..167cb15 100644 --- a/tests/test_helper.cpp +++ b/tests/test_helper.cpp @@ -162,6 +162,34 @@ static billing_item _create_bi6(invoice *inv) return item; } +static billing_item _create_bi(float amount, float npi, char* taxrate) +{ + billing_item item = administration::billing_item_create_empty(); + item.amount = amount; + item.amount_is_percentage = 0; + strops::copy(item.description, "#", MAX_LEN_LONG_DESC); + item.net_per_item = npi; + item.discount = 0.0f; + item.discount_is_percentage = 0; + tax_rate rate; + administration::tax_rate_get_by_shorthandle(&rate, taxrate); + strops::copy(item.tax_rate_id, rate.id, MAX_LEN_ID); + return item; +} + +static invoice _create_nl_b2b_inv_outgoing() +{ + invoice inv = administration::invoice_create_empty(); + inv.supplier = administration::company_info_get(); + inv.customer = _create_nl_business(); + inv.is_outgoing = 1; + 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; |
