#include #include #include #include #include "memops.hpp" #include "strops.hpp" #include "countries.hpp" #include "administration.hpp" #include "administration_reader.hpp" #include "administration_writer.hpp" char* test_file_path = "build\\test.openbook"; char* validation_file = "libs\\PEPPOL-EN16931-UBL.sch"; char* result_file = "build\\invoice_report.xml"; char* extract_dir = "build\\extracted"; static contact _create_nl_business() { contact pw = administration::contact_create_empty(); strops::copy(pw.name, "Dutch Company BV", sizeof(pw.name)); strops::copy(pw.address.address1, "Address 1", sizeof(pw.address.address1)); strops::copy(pw.address.country_code, "NL", sizeof(pw.address.country_code)); strops::copy(pw.address.city, "Amsterdam", sizeof(pw.address.city)); strops::copy(pw.address.region, "Noord-Holland", sizeof(pw.address.region)); strops::copy(pw.address.postal, "1234AA", sizeof(pw.address.postal)); strops::copy(pw.taxid, "T123", sizeof(pw.taxid)); strops::copy(pw.businessid, "B321", sizeof(pw.businessid)); strops::copy(pw.email, "test@test.com", sizeof(pw.email)); strops::copy(pw.phone_number, "+311234567", sizeof(pw.phone_number)); strops::copy(pw.bank_account, "IBAN123456789", sizeof(pw.bank_account)); pw.type = contact_type::CONTACT_BUSINESS; return pw; } static contact _create_nl_consumer() { contact pw = administration::contact_create_empty(); strops::copy(pw.name, "Piet Pinda", sizeof(pw.name)); strops::copy(pw.address.address1, "Address 2", sizeof(pw.address.address1)); strops::copy(pw.address.country_code, "NL", sizeof(pw.address.country_code)); strops::copy(pw.address.city, "Maastricht", sizeof(pw.address.city)); strops::copy(pw.address.region, "Limburg", sizeof(pw.address.region)); strops::copy(pw.address.postal, "4321AA", sizeof(pw.address.postal)); strops::copy(pw.email, "test@test.com", sizeof(pw.email)); strops::copy(pw.phone_number, "+317654321", sizeof(pw.phone_number)); pw.type = contact_type::CONTACT_CONSUMER; return pw; } static billing_item _create_bi1() { billing_item item = administration::billing_item_create_empty(); item.amount = 1; item.amount_is_percentage = 0; strops::copy(item.description, "Shampoo", MAX_LEN_LONG_DESC); item.net_per_item = 10.00f; item.discount = 2.0f; item.discount_is_percentage = 0; tax_rate rate; administration::tax_rate_get_by_internal_code(&rate, "NL/21"); strops::copy(item.tax_internal_code, rate.internal_code, MAX_LEN_SHORT_DESC); return item; } static billing_item _create_bi2() { billing_item item = administration::billing_item_create_empty(); item.amount = 2; item.amount_is_percentage = 0; strops::copy(item.description, "Soap", MAX_LEN_LONG_DESC); item.net_per_item = 5.00f; item.discount = 5.0f; item.discount_is_percentage = 1; tax_rate rate; administration::tax_rate_get_by_internal_code(&rate, "NL/21"); strops::copy(item.tax_internal_code, rate.internal_code, MAX_LEN_SHORT_DESC); return item; } static billing_item _create_bi3() { billing_item item = administration::billing_item_create_empty(); item.amount = 1; item.amount_is_percentage = 0; strops::copy(item.description, "Guacamole", MAX_LEN_LONG_DESC); item.net_per_item = 10.00f; item.discount = 2.0f; item.discount_is_percentage = 0; tax_rate rate; administration::tax_rate_get_by_internal_code(&rate, "NL/21"); strops::copy(item.tax_internal_code, rate.internal_code, MAX_LEN_SHORT_DESC); return item; } static billing_item _create_bi4() { billing_item item = administration::billing_item_create_empty(); item.amount = 3; item.amount_is_percentage = 0; strops::copy(item.description, "Bananas", MAX_LEN_LONG_DESC); item.net_per_item = 4.00f; item.discount = 0.0f; item.discount_is_percentage = 0; tax_rate rate; administration::tax_rate_get_by_internal_code(&rate, "NL/21"); strops::copy(item.tax_internal_code, rate.internal_code, MAX_LEN_SHORT_DESC); return item; } static billing_item _create_bi5() { billing_item item = administration::billing_item_create_empty(); item.amount = 5; item.amount_is_percentage = 0; strops::copy(item.description, "Apple", MAX_LEN_LONG_DESC); item.net_per_item = 1.00f; item.discount = 5.0f; item.discount_is_percentage = 1; tax_rate rate; administration::tax_rate_get_by_internal_code(&rate, "NL/21"); strops::copy(item.tax_internal_code, rate.internal_code, MAX_LEN_SHORT_DESC); return item; } static billing_item _create_bi6() { billing_item item = administration::billing_item_create_empty(); item.amount = 10; item.amount_is_percentage = 1; strops::copy(item.description, "Tip", MAX_LEN_LONG_DESC); item.net_per_item = 50.00f; item.discount = 0.0f; item.discount_is_percentage = 0; tax_rate rate; administration::tax_rate_get_by_internal_code(&rate, "NL/21"); strops::copy(item.tax_internal_code, rate.internal_code, MAX_LEN_SHORT_DESC); 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_internal_code(&rate, taxrate); strops::copy(item.tax_internal_code, rate.internal_code, MAX_LEN_SHORT_DESC); 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 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; zip_extract(test_file_path, extract_dir, 0, 0); char command[200]; strops::format(command, 200, "java -jar libs\\schxslt-cli.jar -d %s\\%s.xml -s %s -o %s > NUL 2>&1", extract_dir, id, validation_file, result_file); system(command); FILE* file = fopen(result_file, "r"); struct xml_document* document = xml_open_document(file); struct xml_node* root = xml_document_root(document); size_t num_children = xml_node_children(root); for (int i = 0; i < num_children; i++) { struct xml_node* node = xml_node_child(root, i); char* name = (char*)xml_easy_name(node); if (strops::equals(name, "svrl:failed-assert")) { struct xml_node* text_node = xml_easy_child(node, (uint8_t *)"svrl:text", 0); char* content = (char*)xml_easy_content(text_node); size_t num_attributes = xml_node_attributes(node); for (int x = 0; x < num_attributes; x++) { struct xml_string* attr_name = xml_node_attribute_name(node, x); size_t b_length = xml_string_length(attr_name); uint8_t* b_buffer = (uint8_t*)memops::stack_alloc((b_length + 1) * sizeof(uint8_t)); xml_string_copy(attr_name, b_buffer, b_length); b_buffer[b_length] = 0; if (strops::equals((char*)b_buffer, "location")) { struct xml_string* attr_content = xml_node_attribute_content(node, x); size_t a_length = xml_string_length(attr_content); uint8_t* a_buffer = (uint8_t*)memops::stack_alloc((a_length + 1) * sizeof(uint8_t)); xml_string_copy(attr_content, a_buffer, a_length); a_buffer[a_length] = 0; printf("FAILURE: %s @ %s\n", content, (char*)a_buffer); } } result = 0; } } return result; } static void add_default_nl_tax_rates() { tax_rate* tr_buffer = (tax_rate*)memops::alloc(sizeof(tax_rate) * 500); u32 tr_count = country::get_available_tax_rates("NL", tr_buffer, 500); for (u32 i = 0; i < 10; i++) { administration::tax_rate_add(tr_buffer[i]); } for (u32 i = 0; i < 10; i++) { administration::tax_rate_add(tr_buffer[tr_count - i - 1]); } memops::unalloc(tr_buffer); }