diff options
Diffstat (limited to 'src/administration_writer.cpp')
| -rw-r--r-- | src/administration_writer.cpp | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/src/administration_writer.cpp b/src/administration_writer.cpp index 00543af..40fcd25 100644 --- a/src/administration_writer.cpp +++ b/src/administration_writer.cpp @@ -6,7 +6,9 @@ #include <threads.h> #include "ui.hpp" +#include "strops.hpp" #include "administration_writer.hpp" +#include "file_templates.hpp" mtx_t _save_file_mutex; @@ -80,6 +82,155 @@ static bool administration_writer_write_to_zip(char* entry_to_replace, char* ori } ///////////////////////////// +//// Invoices +///////////////////////////// +static char* administration_writer_get_eas_id_for_contact(contact contact) +{ + // https://docs.peppol.eu/poacc/billing/3.0/codelist/eas/ + char* country_code = contact.address.country_code; + + // Countries using tax identification numbers. + if (strcmp(country_code, "AT") == 0) return contact.taxid; // Austria + if (strcmp(country_code, "BE") == 0) return contact.taxid; // Belgium + if (strcmp(country_code, "BG") == 0) return contact.taxid; // Bulgaria + if (strcmp(country_code, "CY") == 0) return contact.taxid; // Cyprus + if (strcmp(country_code, "CZ") == 0) return contact.taxid; // Czech Republic + if (strcmp(country_code, "DE") == 0) return contact.taxid; // Germany + if (strcmp(country_code, "EE") == 0) return contact.taxid; // Estonia + if (strcmp(country_code, "FR") == 0) return contact.taxid; // France + if (strcmp(country_code, "GR") == 0) return contact.taxid; // Greece + if (strcmp(country_code, "HR") == 0) return contact.taxid; // Croatia + if (strcmp(country_code, "HU") == 0) return contact.taxid; // Hungary + if (strcmp(country_code, "IE") == 0) return contact.taxid; // Ireland + if (strcmp(country_code, "LU") == 0) return contact.taxid; // Luxembourg + if (strcmp(country_code, "LV") == 0) return contact.taxid; // Latvia + if (strcmp(country_code, "MT") == 0) return contact.taxid; // Malta + if (strcmp(country_code, "NL") == 0) return contact.taxid; // Netherlands + if (strcmp(country_code, "PL") == 0) return contact.taxid; // Poland + if (strcmp(country_code, "PT") == 0) return contact.taxid; // Portugal + if (strcmp(country_code, "RO") == 0) return contact.taxid; // Romania + if (strcmp(country_code, "SI") == 0) return contact.taxid; // Slovenia + if (strcmp(country_code, "SK") == 0) return contact.taxid; // Slovakia + if (strcmp(country_code, "ES") == 0) return contact.taxid; // Spain + + // Countries using business identification numbers. + if (strcmp(country_code, "SE") == 0) return contact.businessid; // Sweden + if (strcmp(country_code, "LT") == 0) return contact.businessid; // Lithuania + if (strcmp(country_code, "IT") == 0) return contact.businessid; // Italy + if (strcmp(country_code, "FI") == 0) return contact.businessid; // Finland + if (strcmp(country_code, "DK") == 0) return contact.businessid; // Denmark + return NULL; // Unknown country code +} + +static char* administration_writer_get_eas_scheme_for_address(address addr) +{ + // https://docs.peppol.eu/poacc/billing/3.0/codelist/eas/ + char* country_code = addr.country_code; + if (strcmp(country_code, "AT") == 0) return "9914"; // Austria + if (strcmp(country_code, "BE") == 0) return "9925"; // Belgium + if (strcmp(country_code, "BG") == 0) return "9926"; // Bulgaria + if (strcmp(country_code, "CY") == 0) return "9928"; // Cyprus + if (strcmp(country_code, "CZ") == 0) return "9929"; // Czech Republic + if (strcmp(country_code, "DE") == 0) return "9930"; // Germany + if (strcmp(country_code, "DK") == 0) return "0096"; // Denmark + if (strcmp(country_code, "EE") == 0) return "9931"; // Estonia + if (strcmp(country_code, "FR") == 0) return "9957"; // France + if (strcmp(country_code, "GR") == 0) return "9933"; // Greece + if (strcmp(country_code, "HR") == 0) return "9934"; // Croatia + if (strcmp(country_code, "HU") == 0) return "9910"; // Hungary + if (strcmp(country_code, "IE") == 0) return "9935"; // Ireland + if (strcmp(country_code, "FI") == 0) return "0212"; // Finland + if (strcmp(country_code, "IT") == 0) return "0208"; // Italy + if (strcmp(country_code, "LT") == 0) return "0200"; // Lithuania + if (strcmp(country_code, "LU") == 0) return "9938"; // Luxembourg + if (strcmp(country_code, "LV") == 0) return "9939"; // Latvia + if (strcmp(country_code, "MT") == 0) return "9943"; // Malta + if (strcmp(country_code, "NL") == 0) return "9944"; // Netherlands + if (strcmp(country_code, "PL") == 0) return "9945"; // Poland + if (strcmp(country_code, "PT") == 0) return "9946"; // Portugal + if (strcmp(country_code, "RO") == 0) return "9947"; // Romania + if (strcmp(country_code, "SE") == 0) return "0007"; // Sweden + if (strcmp(country_code, "SI") == 0) return "9949"; // Slovenia + if (strcmp(country_code, "SK") == 0) return "9950"; // Slovakia + if (strcmp(country_code, "ES") == 0) return "9920"; // Spain + return NULL; // Unknown country code +} + +bool administration_writer_save_invoice_blocking(invoice inv) +{ + #define APPEND(_txt, ...) file_content += sprintf(file_content, _txt, __VA_ARGS__); + + bool result = 1; + int buf_length = 15000; // Ballpark file content size. + char* file_content = (char*)malloc(buf_length); + memset(file_content, 0, buf_length); + memcpy(file_content, peppol_invoice_template, strlen(peppol_invoice_template)); + + struct tm *tm_info = 0; + char date_buffer[11]; // "YYYY-MM-DD" + null terminator + + strops_replace(file_content, buf_length, "{{INVOICE_ID}}", inv.sequential_number); + strops_replace(file_content, buf_length, "{{CURRENCY}}", inv.currency); + + // Supplier data + strops_replace(file_content, buf_length, "{{SUPPLIER_ENDPOINT_SCHEME}}", administration_writer_get_eas_scheme_for_address(inv.supplier.address)); + strops_replace(file_content, buf_length, "{{SUPPLIER_ENDPOINT_ID}}", administration_writer_get_eas_id_for_contact(inv.supplier)); + strops_replace(file_content, buf_length, "{{SUPPLIER_NAME}}", inv.supplier.name); + strops_replace(file_content, buf_length, "{{SUPPLIER_STREET}}", inv.supplier.address.address1); + strops_replace(file_content, buf_length, "{{SUPPLIER_STREET2}}", inv.supplier.address.address2); + strops_replace(file_content, buf_length, "{{SUPPLIER_CITY}}", inv.supplier.address.city); + strops_replace(file_content, buf_length, "{{SUPPLIER_POSTAL}}", inv.supplier.address.postal); + strops_replace(file_content, buf_length, "{{SUPPLIER_REGION}}", inv.supplier.address.region); + strops_replace(file_content, buf_length, "{{SUPPLIER_COUNTRY}}", inv.supplier.address.country_code); + strops_replace(file_content, buf_length, "{{SUPPLIER_VAT_ID}}", inv.supplier.taxid); + + // Customer data + strops_replace(file_content, buf_length, "{{CUSTOMER_ENDPOINT_SCHEME}}", administration_writer_get_eas_scheme_for_address(inv.customer.address)); + strops_replace(file_content, buf_length, "{{CUSTOMER_ENDPOINT_ID}}", administration_writer_get_eas_id_for_contact(inv.customer)); + strops_replace(file_content, buf_length, "{{CUSTOMER_NAME}}", inv.customer.name); + strops_replace(file_content, buf_length, "{{CUSTOMER_STREET}}", inv.customer.address.address1); + strops_replace(file_content, buf_length, "{{CUSTOMER_STREET2}}", inv.customer.address.address2); + strops_replace(file_content, buf_length, "{{CUSTOMER_CITY}}", inv.customer.address.city); + strops_replace(file_content, buf_length, "{{CUSTOMER_POSTAL}}", inv.customer.address.postal); + strops_replace(file_content, buf_length, "{{CUSTOMER_REGION}}", inv.customer.address.region); + strops_replace(file_content, buf_length, "{{CUSTOMER_COUNTRY}}", inv.customer.address.country_code); + strops_replace(file_content, buf_length, "{{CUSTOMER_VAT_ID}}", inv.customer.taxid); + + // Dates + tm_info = localtime(&inv.issued_at); + strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", tm_info); + strops_replace(file_content, buf_length, "{{ISSUE_DATE}}", date_buffer); + + //// Write to Disk. + char final_path[50]; + snprintf(final_path, 50, "%s.xml", inv.id); + + int final_length = (int)strlen(file_content); + if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0; + else if (!administration_writer_write_to_zip(final_path, file_content, final_length)) result = 0; + + free(file_content); + return result; +} + +static bool administration_writer_save_all_invoices_blocking() +{ + bool result = 1; + u32 num_invoices = administration_invoice_count(); + u32 buffer_size = sizeof(invoice) * num_invoices; + invoice* invoice_buffer = (invoice*)malloc(buffer_size); + num_invoices = administration_invoice_get_all(invoice_buffer); + + for (u32 i = 0; i < num_invoices; i++) { + invoice c = invoice_buffer[i]; + if (!administration_writer_save_invoice_blocking(c)) result = 0; + } + + free(invoice_buffer); + return result; +} + +///////////////////////////// //// Projects ///////////////////////////// bool administration_writer_save_project_blocking(project project) @@ -326,6 +477,7 @@ static int administration_writer_write_all_t(void *arg) { mtx_lock(&_save_file_mutex); + if (!administration_writer_save_all_invoices_blocking()) result = 0; if (!administration_writer_save_all_projects_blocking()) result = 0; if (!administration_writer_save_all_administration_info_blocking()) result = 0; if (!administration_writer_save_all_tax_brackets_blocking()) result = 0; |
