summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/logger.hpp (renamed from include/log.hpp)34
-rw-r--r--include/strops.hpp26
-rw-r--r--src/administration.cpp52
-rw-r--r--src/administration_reader.cpp54
-rw-r--r--src/administration_writer.cpp260
-rw-r--r--src/ai_providers/DeepSeek.cpp18
-rw-r--r--src/ai_providers/openAI.cpp40
-rw-r--r--src/importer.cpp16
-rw-r--r--src/locales.cpp6
-rw-r--r--src/log.cpp110
-rw-r--r--src/logger.cpp114
-rw-r--r--src/strops.cpp302
-rw-r--r--src/ui/helpers.cpp2
-rw-r--r--src/ui/imgui_extensions.cpp14
-rw-r--r--src/ui/ui_log.cpp6
-rw-r--r--src/ui/ui_settings.cpp6
-rw-r--r--tests/administration_rw_tests.cpp26
-rw-r--r--tests/administration_validation_tests.cpp130
-rw-r--r--tests/test_helper.cpp62
19 files changed, 647 insertions, 631 deletions
diff --git a/include/log.hpp b/include/logger.hpp
index bff3d05..b191ecb 100644
--- a/include/log.hpp
+++ b/include/logger.hpp
@@ -21,22 +21,26 @@
#include "config.hpp"
#include "administration.hpp"
-#define MAX_LEN_LOG_HISTORY 256
-#define MAX_LEN_LOG_TXT 128
-
-typedef struct {
- u32 write_cursor;
- u32 history_length;
- char history[MAX_LEN_LOG_HISTORY][MAX_LEN_LOG_TXT];
- ImVec4 colors[MAX_LEN_LOG_HISTORY];
-} program_log;
-
#define STOPWATCH_START tick_t timestamp_start = timer_current();
#define STOPWATCH_TIME (timer_elapsed(timestamp_start)*1000.0f)
-program_log* get_log();
+namespace logger {
+
+ static const u32 MAX_LEN_LOG_HISTORY = 256;
+ static const u32 MAX_LEN_LOG_TXT = 128;
+
+ typedef struct {
+ u32 write_cursor;
+ u32 history_length;
+ char history[MAX_LEN_LOG_HISTORY][MAX_LEN_LOG_TXT];
+ ImVec4 colors[MAX_LEN_LOG_HISTORY];
+ } program_log;
+
+ program_log* get();
+
+ void clear();
+ void aerr(a_err errors);
+ void info(const char* fmt, ...) IM_FMTARGS(2);
+ void error(const char* fmt, ...) IM_FMTARGS(2);
-void log_clear();
-void log_aerr(a_err errors);
-void log_info(const char* fmt, ...) IM_FMTARGS(2);
-void log_error(const char* fmt, ...) IM_FMTARGS(2); \ No newline at end of file
+} \ No newline at end of file
diff --git a/include/strops.hpp b/include/strops.hpp
index d11f0c2..ec3dcdd 100644
--- a/include/strops.hpp
+++ b/include/strops.hpp
@@ -18,14 +18,18 @@
#include <stdint.h>
-size_t strops_copy(char *dst, const char *src, size_t size);
-char* strops_stristr(char* a, char* b);
-void strops_replace(char *buf, size_t buf_size, const char *search, const char *replace);
-void strops_replace_int32(char *buf, size_t buf_size, const char *search, int32_t number);
-void strops_replace_int64(char *buf, size_t buf_size, const char *search, int64_t number);
-void strops_replace_float(char *buf, size_t buf_size, const char *search, float number, int decimals);
-bool strops_prefix(const char *pre, const char *str);
-char* strops_get_json_value(const char *json, const char *key, char *out, size_t out_size, int nth = 0);
-char* strops_get_filename(const char* path);
-char* strops_prep_str_for_json(const char *input, size_t buffer_size);
-char* strops_unprep_str_from_json(char *input); \ No newline at end of file
+namespace strops {
+
+ size_t copy(char *dst, const char *src, size_t size);
+ char* contains(char* a, char* b);
+ void replace(char *buf, size_t buf_size, const char *search, const char *replace);
+ void replace_int32(char *buf, size_t buf_size, const char *search, int32_t number);
+ void replace_int64(char *buf, size_t buf_size, const char *search, int64_t number);
+ void replace_float(char *buf, size_t buf_size, const char *search, float number, int decimals);
+ bool prefix(const char *pre, const char *str);
+ char* get_json_value(const char *json, const char *key, char *out, size_t out_size, int nth = 0);
+ char* get_filename(const char* path);
+ char* prep_str_for_json(const char *input, size_t buffer_size);
+ char* unprep_str_from_json(char *input);
+
+} \ No newline at end of file
diff --git a/src/administration.cpp b/src/administration.cpp
index 4f996bf..f9770bd 100644
--- a/src/administration.cpp
+++ b/src/administration.cpp
@@ -22,7 +22,7 @@
#include <time.h>
#include <stdio.h>
-#include "log.hpp"
+#include "logger.hpp"
#include "strops.hpp"
#include "administration.hpp"
#include "administration_writer.hpp"
@@ -295,7 +295,7 @@ static bool is_initialized = false;
void administration_create()
{
STOPWATCH_START;
- log_clear();
+ logger::clear();
is_initialized = true;
list_init(&g_administration.invoices);
@@ -303,11 +303,11 @@ void administration_create()
list_init(&g_administration.projects);
list_init(&g_administration.tax_rates);
list_init(&g_administration.cost_centers);
- strops_copy(g_administration.path, "", sizeof(g_administration.path));
+ strops::copy(g_administration.path, "", sizeof(g_administration.path));
memset(&g_administration.ai_service, 0, sizeof(ai_service));
- log_info("Setup took %.3fms.", STOPWATCH_TIME);
+ logger::info("Setup took %.3fms.", STOPWATCH_TIME);
}
static void administration_destroy_list(list_t *list)
@@ -336,8 +336,8 @@ void administration_create_from_file(char* save_file)
if (is_initialized) administration_destroy();
administration_create();
- strops_copy(g_administration.path, save_file, sizeof(g_administration.path));
- strops_copy(g_administration.program_version, config::PROGRAM_VERSION, sizeof(g_administration.program_version));
+ strops::copy(g_administration.path, save_file, sizeof(g_administration.path));
+ strops::copy(g_administration.program_version, config::PROGRAM_VERSION, sizeof(g_administration.program_version));
}
void administration_create_empty(char* save_file)
@@ -348,8 +348,8 @@ void administration_create_empty(char* save_file)
g_administration.next_id = 2;
g_administration.next_sequence_number = 1;
- strops_copy(g_administration.path, save_file, sizeof(g_administration.path));
- strops_copy(g_administration.program_version, config::PROGRAM_VERSION, sizeof(g_administration.program_version));
+ strops::copy(g_administration.path, save_file, sizeof(g_administration.path));
+ strops::copy(g_administration.program_version, config::PROGRAM_VERSION, sizeof(g_administration.program_version));
administration_company_info_set(administration_contact_create_empty());
}
@@ -548,14 +548,14 @@ void administration_create_income_statement(income_statement* statement)
report.revenue = 0.0f;
report.taxes = 0.0f;
report.expense_count = 0;
- strops_copy(report.project_id, project_buffer[x].id, MAX_LEN_ID);
- strops_copy(report.description, project_buffer[x].description, MAX_LEN_LONG_DESC);
+ strops::copy(report.project_id, project_buffer[x].id, MAX_LEN_ID);
+ strops::copy(report.description, project_buffer[x].description, MAX_LEN_LONG_DESC);
for (u32 y = 0; y < costcenter_count; y++)
{
project_expense expense;
- strops_copy(expense.cost_center_id, costcenter_buffer[y].id, MAX_LEN_ID);
- strops_copy(expense.description, costcenter_buffer[y].description, MAX_LEN_LONG_DESC);
+ strops::copy(expense.cost_center_id, costcenter_buffer[y].id, MAX_LEN_ID);
+ strops::copy(expense.description, costcenter_buffer[y].description, MAX_LEN_LONG_DESC);
expense.total = 0.0f;
expense.expense_used_in_project = true;
report.expenses[report.expense_count++] = expense;
@@ -668,12 +668,12 @@ void administration_create_income_statement(income_statement* statement)
free(invoice_buffer);
- log_info("Created income statement in %.3fms.", STOPWATCH_TIME);
+ logger::info("Created income statement in %.3fms.", STOPWATCH_TIME);
}
void administration_set_file_path(char* path)
{
- strops_copy(g_administration.path, path, MAX_LEN_PATH);
+ strops::copy(g_administration.path, path, MAX_LEN_PATH);
}
char* administration_get_file_path()
@@ -689,14 +689,14 @@ contact administration_company_info_get()
void administration_company_info_import(contact data)
{
g_administration.company_info = data;
- strops_copy(g_administration.default_currency, administration_get_default_currency_for_country(g_administration.company_info.address.country_code), MAX_LEN_CURRENCY);
+ strops::copy(g_administration.default_currency, administration_get_default_currency_for_country(g_administration.company_info.address.country_code), MAX_LEN_CURRENCY);
}
void administration_company_info_set(contact data)
{
- strops_copy(data.id, MY_COMPANY_ID, sizeof(data.id));
+ strops::copy(data.id, MY_COMPANY_ID, sizeof(data.id));
g_administration.company_info = data;
- strops_copy(g_administration.default_currency, administration_get_default_currency_for_country(g_administration.company_info.address.country_code), MAX_LEN_CURRENCY);
+ strops::copy(g_administration.default_currency, administration_get_default_currency_for_country(g_administration.company_info.address.country_code), MAX_LEN_CURRENCY);
if (contact_changed_event_callback) contact_changed_event_callback(&data);
if (data_changed_event_callback) data_changed_event_callback();
@@ -868,7 +868,7 @@ int administration_contact_get_autocompletions(contact* buffer, int buf_size, ch
while (list_iterator_hasnext(&g_administration.contacts)) {
contact c = *(contact *)list_iterator_next(&g_administration.contacts);
- if (strops_stristr(c.name, name)) {
+ if (strops::contains(c.name, name)) {
buffer[write_cursor++] = c;
if (write_cursor >= buf_size) break;
}
@@ -1455,7 +1455,7 @@ invoice administration_invoice_create_empty()
result.delivered_at = result.issued_at;
result.expires_at = result.issued_at + administration_get_default_invoice_expire_duration();
list_init(&result.billing_items); // @leak
- strops_copy(result.currency, administration_get_default_currency_for_country(g_administration.company_info.address.country_code), MAX_LEN_CURRENCY);
+ strops::copy(result.currency, administration_get_default_currency_for_country(g_administration.company_info.address.country_code), MAX_LEN_CURRENCY);
return result;
}
@@ -1487,13 +1487,13 @@ static void administration_recalculate_invoice_totals(invoice* invoice)
void administration_invoice_set_currency(invoice* invoice, char* currency)
{
- strops_copy(invoice->currency, currency, MAX_LEN_CURRENCY);
+ strops::copy(invoice->currency, currency, MAX_LEN_CURRENCY);
list_iterator_start(&invoice->billing_items);
while (list_iterator_hasnext(&invoice->billing_items)) {
billing_item* c = (billing_item *)list_iterator_next(&invoice->billing_items);
- strops_copy(c->currency, currency, MAX_LEN_CURRENCY);
+ strops::copy(c->currency, currency, MAX_LEN_CURRENCY);
}
list_iterator_stop(&invoice->billing_items);
}
@@ -1617,10 +1617,10 @@ a_err administration_invoice_add(invoice* inv)
inv->is_outgoing = strcmp(inv->supplier.id, MY_COMPANY_ID) == 0;
inv->payment_means.payment_method = PAYMENT_METHOD_STANDING_AGREEMENT;
- strops_copy(inv->payment_means.payee_bank_account, inv->supplier.bank_account, sizeof(inv->payment_means.payee_bank_account));
- strops_copy(inv->payment_means.payee_account_name, inv->supplier.name, sizeof(inv->payment_means.payee_account_name));
- strops_copy(inv->payment_means.service_provider_id, "", sizeof(inv->payment_means.service_provider_id));
- strops_copy(inv->payment_means.payer_bank_account, inv->customer.bank_account, sizeof(inv->payment_means.payer_bank_account));
+ strops::copy(inv->payment_means.payee_bank_account, inv->supplier.bank_account, sizeof(inv->payment_means.payee_bank_account));
+ strops::copy(inv->payment_means.payee_account_name, inv->supplier.name, sizeof(inv->payment_means.payee_account_name));
+ strops::copy(inv->payment_means.service_provider_id, "", sizeof(inv->payment_means.service_provider_id));
+ strops::copy(inv->payment_means.payer_bank_account, inv->customer.bank_account, sizeof(inv->payment_means.payer_bank_account));
invoice copy = administration_invoice_create_copy(inv); // Create copy to make copy of billing item list.
invoice* new_inv = (invoice*)malloc(sizeof(invoice));
@@ -1952,7 +1952,7 @@ a_err administration_billing_item_add_to_invoice(invoice* invoice, billing_item
memcpy(tb, &item, sizeof(billing_item));
snprintf(tb->id, sizeof(tb->id), "B/%d", administration_create_id());
- strops_copy(tb->currency, invoice->currency, MAX_LEN_CURRENCY); // Set billing item currency to invoice currency.
+ strops::copy(tb->currency, invoice->currency, MAX_LEN_CURRENCY); // Set billing item currency to invoice currency.
administration_recalculate_billing_item_totals(tb);
if (!list_append(&invoice->billing_items, tb)) {
diff --git a/src/administration_reader.cpp b/src/administration_reader.cpp
index 801941b..5d94eff 100644
--- a/src/administration_reader.cpp
+++ b/src/administration_reader.cpp
@@ -22,7 +22,7 @@
#include <xml.h>
#include <time.h>
-#include "log.hpp"
+#include "logger.hpp"
#include "strops.hpp"
#include "administration_reader.hpp"
#include "administration_writer.hpp"
@@ -90,23 +90,23 @@ bool administration_reader_open_existing(char* file_path)
{
administration_reader_import_administration_info(buffer, (size_t)size);
}
- else if (strops_prefix("T/", name))
+ else if (strops::prefix("T/", name))
{
administration_reader_import_tax_rate(buffer, (size_t)size);
}
- else if (strops_prefix("E/", name))
+ else if (strops::prefix("E/", name))
{
administration_reader_import_cost_center(buffer, (size_t)size);
}
- else if (strops_prefix("P/", name))
+ else if (strops::prefix("P/", name))
{
administration_reader_import_project(buffer, (size_t)size);
}
- else if (strops_prefix("C/", name))
+ else if (strops::prefix("C/", name))
{
administration_reader_import_contact(buffer, (size_t)size);
}
- else if (strops_prefix("I/", name))
+ else if (strops::prefix("I/", name))
{
administration_reader_import_invoice(buffer, (size_t)size);
}
@@ -118,7 +118,7 @@ bool administration_reader_open_existing(char* file_path)
zip_close(zip);
- log_info("Imported '%s' in %.3fms.", file_path, STOPWATCH_TIME);
+ logger::info("Imported '%s' in %.3fms.", file_path, STOPWATCH_TIME);
return true;
}
@@ -163,7 +163,7 @@ bool administration_reader_read_invoice_from_xml(invoice* result, char* buffer,
// Supplier
xml_get_str_x(root, data.supplier.id, MAX_LEN_ID, "cac:AccountingSupplierParty", "cac:Party", "cac:Contact", "cbc:Name", 0);
- strops_copy(data.supplier.bank_account, data.payment_means.payee_bank_account, MAX_LEN_BANK);
+ strops::copy(data.supplier.bank_account, data.payment_means.payee_bank_account, MAX_LEN_BANK);
xml_get_str_x(root, data.supplier.name, MAX_LEN_LONG_DESC, "cac:AccountingSupplierParty", "cac:Party", "cac:PartyName", "cbc:Name", 0);
xml_get_str_x(root, data.supplier.address.address1, MAX_LEN_ADDRESS, "cac:AccountingSupplierParty", "cac:Party", "cac:PostalAddress", "cbc:StreetName", 0);
xml_get_str_x(root, data.supplier.address.address2, MAX_LEN_ADDRESS, "cac:AccountingSupplierParty", "cac:Party", "cac:PostalAddress", "cbc:AdditionalStreetName", 0);
@@ -178,7 +178,7 @@ bool administration_reader_read_invoice_from_xml(invoice* result, char* buffer,
// Customer
xml_get_str_x(root, data.customer.id, MAX_LEN_ID, "cac:AccountingCustomerParty", "cac:Party", "cac:Contact", "cbc:Name", 0);
- strops_copy(data.customer.bank_account, data.payment_means.payer_bank_account, MAX_LEN_BANK);
+ strops::copy(data.customer.bank_account, data.payment_means.payer_bank_account, MAX_LEN_BANK);
xml_get_str_x(root, data.customer.name, MAX_LEN_LONG_DESC, "cac:AccountingCustomerParty", "cac:Party", "cac:PartyName", "cbc:Name", 0);
xml_get_str_x(root, data.customer.address.address1, MAX_LEN_ADDRESS, "cac:AccountingCustomerParty", "cac:Party", "cac:PostalAddress", "cbc:StreetName", 0);
xml_get_str_x(root, data.customer.address.address2, MAX_LEN_ADDRESS, "cac:AccountingCustomerParty", "cac:Party", "cac:PostalAddress", "cbc:AdditionalStreetName", 0);
@@ -236,10 +236,10 @@ bool administration_reader_read_invoice_from_xml(invoice* result, char* buffer,
tax_rate tax_rate;
if (administration_tax_rate_get_by_id(&tax_rate, bi.tax_rate_id) == A_ERR_NOT_FOUND) {
if (administration_tax_rate_get_by_shorthandle(&tax_rate, bi.tax_rate_id) == A_ERR_SUCCESS) {
- strops_copy(bi.tax_rate_id, tax_rate.id, MAX_LEN_ID);
+ strops::copy(bi.tax_rate_id, tax_rate.id, MAX_LEN_ID);
}
else {
- strops_copy(bi.tax_rate_id, "", MAX_LEN_ID);
+ strops::copy(bi.tax_rate_id, "", MAX_LEN_ID);
}
}
@@ -262,11 +262,11 @@ bool administration_reader_import_invoice(char* buffer, size_t buffer_size)
a_err result = administration_invoice_import(&data);
if (result == A_ERR_SUCCESS) {
- log_info("Loaded invoice '%s' in %.3fms.", data.sequential_number, STOPWATCH_TIME);
+ logger::info("Loaded invoice '%s' in %.3fms.", data.sequential_number, STOPWATCH_TIME);
}
else {
- log_aerr(result);
- log_error("ERROR loading invoice '%s'.", data.sequential_number);
+ logger::aerr(result);
+ logger::error("ERROR loading invoice '%s'.", data.sequential_number);
}
return result == A_ERR_SUCCESS;
@@ -301,11 +301,11 @@ bool administration_reader_import_contact(char* buffer, size_t buffer_size)
a_err result = administration_contact_import(data);
if (result == A_ERR_SUCCESS) {
- log_info("Loaded contact '%s' in %.3fms.", data.name, STOPWATCH_TIME);
+ logger::info("Loaded contact '%s' in %.3fms.", data.name, STOPWATCH_TIME);
}
else {
- log_aerr(result);
- log_error("ERROR loading contact '%s'.", data.name);
+ logger::aerr(result);
+ logger::error("ERROR loading contact '%s'.", data.name);
}
return result;
@@ -329,12 +329,12 @@ bool administration_reader_import_project(char* buffer, size_t buffer_size)
a_err result = administration_project_import(data);
if (result == A_ERR_SUCCESS) {
- log_info("Loaded project in %.3fms. id=%s description=%s state=%d started=%lld end=%lld",
+ logger::info("Loaded project in %.3fms. id=%s description=%s state=%d started=%lld end=%lld",
STOPWATCH_TIME, data.id, data.description, data.state, data.start_date, data.end_date);
}
else {
- log_aerr(result);
- log_error("ERROR loading project '%s'.", data.id);
+ logger::aerr(result);
+ logger::error("ERROR loading project '%s'.", data.id);
}
return result;
@@ -356,12 +356,12 @@ bool administration_reader_import_cost_center(char* buffer, size_t buffer_size)
a_err result = administration_cost_center_import(data);
if (result == A_ERR_SUCCESS) {
- log_info("Loaded cost center in %.3fms. id=%s code=%s description=%s",
+ logger::info("Loaded cost center in %.3fms. id=%s code=%s description=%s",
STOPWATCH_TIME, data.id, data.code, data.description);
}
else {
- log_aerr(result);
- log_error("ERROR loading cost center '%s'.", data.id);
+ logger::aerr(result);
+ logger::error("ERROR loading cost center '%s'.", data.id);
}
return result;
@@ -384,12 +384,12 @@ bool administration_reader_import_tax_rate(char* buffer, size_t buffer_size)
a_err result = administration_tax_rate_import(data);
if (result == A_ERR_SUCCESS) {
- log_info("Loaded tax rate info in %.3fms. id=%s country_code=%s category_code=%s rate=%.2f",
+ logger::info("Loaded tax rate info in %.3fms. id=%s country_code=%s category_code=%s rate=%.2f",
STOPWATCH_TIME, data.id, data.country_code, data.category_code, data.rate);
}
else {
- log_aerr(result);
- log_error("ERROR loading tax rate '%s'.", data.id);
+ logger::aerr(result);
+ logger::error("ERROR loading tax rate '%s'.", data.id);
}
return result;
@@ -412,7 +412,7 @@ bool administration_reader_import_administration_info(char* buffer, size_t buffe
xml_get_str_x(root, ai_service.api_key_public, MAX_LEN_API_KEY, "AIService", "PublicKey", 0);
administration_set_ai_service(ai_service);
- log_info("Loaded administration info in %.3fms. next_id=%d next_sequence_number=%d",
+ logger::info("Loaded administration info in %.3fms. next_id=%d next_sequence_number=%d",
STOPWATCH_TIME, administration_get_next_id(), administration_get_next_sequence_number());
return true;
diff --git a/src/administration_writer.cpp b/src/administration_writer.cpp
index 6f58a21..4f5a7ca 100644
--- a/src/administration_writer.cpp
+++ b/src/administration_writer.cpp
@@ -21,7 +21,7 @@
#include <stdlib.h>
#include <threads.h>
-#include "log.hpp"
+#include "logger.hpp"
#include "ui.hpp"
#include "locales.hpp"
#include "strops.hpp"
@@ -122,8 +122,8 @@ static bool _administration_writer_delete_entry_by_name(char* entry)
if (zip_entries_delete(zip_write, indices, 1) < 0) result = 0;
zip_close(zip_write);
- if (result) log_info("Deleted entry '%s' in %.3fms.", entry, STOPWATCH_TIME);
- else log_error("Failed to delete entry '%s'.", entry);
+ if (result) logger::info("Deleted entry '%s' in %.3fms.", entry, STOPWATCH_TIME);
+ else logger::error("Failed to delete entry '%s'.", entry);
return result;
}
@@ -303,7 +303,7 @@ static void _add_document_to_zip(invoice* inv)
FILE* orig_file = fopen(doc->original_path, "rb");
if (orig_file == NULL) {
- log_error("ERROR: original document file path does not exist.");
+ logger::error("ERROR: original document file path does not exist.");
return;
}
@@ -318,11 +318,11 @@ static void _add_document_to_zip(invoice* inv)
fclose(orig_file);
if (administration_writer_write_to_zip(copy_path, file_copy, sz)) {
- strops_copy(doc->copy_path, copy_path, MAX_LEN_PATH);
- log_info("Made copy of '%s' to '%s'.", doc->original_path, doc->copy_path);
+ strops::copy(doc->copy_path, copy_path, MAX_LEN_PATH);
+ logger::info("Made copy of '%s' to '%s'.", doc->original_path, doc->copy_path);
}
else {
- log_error("ERROR: failed to make copy of original document '%s'.", doc->original_path);
+ logger::error("ERROR: failed to make copy of original document '%s'.", doc->original_path);
}
free(file_copy);
@@ -344,70 +344,70 @@ bool administration_writer_save_invoice_blocking(invoice inv)
_add_document_to_zip(&inv);
- strops_replace(file_content, buf_length, "{{INVOICE_ID}}", inv.id);
- strops_replace(file_content, buf_length, "{{INVOICE_SEQUENCE_ID}}", inv.sequential_number);
- strops_replace(file_content, buf_length, "{{CURRENCY}}", inv.currency);
- strops_replace(file_content, buf_length, "{{PROJECT_ID}}", inv.project_id);
- strops_replace(file_content, buf_length, "{{COST_CENTER_ID}}", inv.cost_center_id);
- strops_replace(file_content, buf_length, "{{INVOICE_DOCUMENT_COPY}}", inv.document.copy_path);
- strops_replace(file_content, buf_length, "{{INVOICE_DOCUMENT_ORIG}}", inv.document.original_path);
- strops_replace_int32(file_content, buf_length, "{{INVOICE_STATUS}}", (s32)inv.status);
+ strops::replace(file_content, buf_length, "{{INVOICE_ID}}", inv.id);
+ strops::replace(file_content, buf_length, "{{INVOICE_SEQUENCE_ID}}", inv.sequential_number);
+ strops::replace(file_content, buf_length, "{{CURRENCY}}", inv.currency);
+ strops::replace(file_content, buf_length, "{{PROJECT_ID}}", inv.project_id);
+ strops::replace(file_content, buf_length, "{{COST_CENTER_ID}}", inv.cost_center_id);
+ strops::replace(file_content, buf_length, "{{INVOICE_DOCUMENT_COPY}}", inv.document.copy_path);
+ strops::replace(file_content, buf_length, "{{INVOICE_DOCUMENT_ORIG}}", inv.document.original_path);
+ strops::replace_int32(file_content, buf_length, "{{INVOICE_STATUS}}", (s32)inv.status);
// Supplier data
- strops_replace(file_content, buf_length, "{{SUPPLIER_ENDPOINT_SCHEME}}", administration_writer_get_eas_scheme_for_contact(inv.supplier));
- 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_ID}}", inv.supplier.id);
- 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);
- strops_replace(file_content, buf_length, "{{SUPPLIER_LEGAL_NAME}}", inv.supplier.name);
- strops_replace(file_content, buf_length, "{{SUPPLIER_BUSINESS_ID}}", inv.supplier.businessid);
- strops_replace(file_content, buf_length, "{{SUPPLIER_PHONE_NUMBER}}", inv.supplier.phone_number);
- strops_replace(file_content, buf_length, "{{SUPPLIER_EMAIL}}", inv.supplier.email);
+ strops::replace(file_content, buf_length, "{{SUPPLIER_ENDPOINT_SCHEME}}", administration_writer_get_eas_scheme_for_contact(inv.supplier));
+ 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_ID}}", inv.supplier.id);
+ 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);
+ strops::replace(file_content, buf_length, "{{SUPPLIER_LEGAL_NAME}}", inv.supplier.name);
+ strops::replace(file_content, buf_length, "{{SUPPLIER_BUSINESS_ID}}", inv.supplier.businessid);
+ strops::replace(file_content, buf_length, "{{SUPPLIER_PHONE_NUMBER}}", inv.supplier.phone_number);
+ strops::replace(file_content, buf_length, "{{SUPPLIER_EMAIL}}", inv.supplier.email);
// Customer data
- strops_replace(file_content, buf_length, "{{CUSTOMER_ENDPOINT_SCHEME}}", administration_writer_get_eas_scheme_for_contact(inv.customer));
- 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_ID}}", inv.customer.id);
- 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);
- strops_replace(file_content, buf_length, "{{CUSTOMER_LEGAL_NAME}}", inv.customer.name);
- strops_replace(file_content, buf_length, "{{CUSTOMER_BUSINESS_ID}}", inv.customer.businessid);
- strops_replace(file_content, buf_length, "{{CUSTOMER_PHONE_NUMBER}}", inv.customer.phone_number);
- strops_replace(file_content, buf_length, "{{CUSTOMER_EMAIL}}", inv.customer.email);
+ strops::replace(file_content, buf_length, "{{CUSTOMER_ENDPOINT_SCHEME}}", administration_writer_get_eas_scheme_for_contact(inv.customer));
+ 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_ID}}", inv.customer.id);
+ 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);
+ strops::replace(file_content, buf_length, "{{CUSTOMER_LEGAL_NAME}}", inv.customer.name);
+ strops::replace(file_content, buf_length, "{{CUSTOMER_BUSINESS_ID}}", inv.customer.businessid);
+ strops::replace(file_content, buf_length, "{{CUSTOMER_PHONE_NUMBER}}", inv.customer.phone_number);
+ strops::replace(file_content, buf_length, "{{CUSTOMER_EMAIL}}", inv.customer.email);
// Delivery data
tm_info = localtime(&inv.delivered_at);
strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", tm_info);
- strops_replace(file_content, buf_length, "{{DELIVERY_DATE}}", date_buffer);
- strops_replace(file_content, buf_length, "{{DELIVERY_NAME}}", inv.addressee.name);
- strops_replace(file_content, buf_length, "{{DELIVERY_STREET}}", inv.addressee.address.address1);
- strops_replace(file_content, buf_length, "{{DELIVERY_STREET2}}", inv.addressee.address.address2);
- strops_replace(file_content, buf_length, "{{DELIVERY_CITY}}", inv.addressee.address.city);
- strops_replace(file_content, buf_length, "{{DELIVERY_POSTAL}}", inv.addressee.address.postal);
- strops_replace(file_content, buf_length, "{{DELIVERY_REGION}}", inv.addressee.address.region);
- strops_replace(file_content, buf_length, "{{DELIVERY_COUNTRY}}", inv.addressee.address.country_code);
+ strops::replace(file_content, buf_length, "{{DELIVERY_DATE}}", date_buffer);
+ strops::replace(file_content, buf_length, "{{DELIVERY_NAME}}", inv.addressee.name);
+ strops::replace(file_content, buf_length, "{{DELIVERY_STREET}}", inv.addressee.address.address1);
+ strops::replace(file_content, buf_length, "{{DELIVERY_STREET2}}", inv.addressee.address.address2);
+ strops::replace(file_content, buf_length, "{{DELIVERY_CITY}}", inv.addressee.address.city);
+ strops::replace(file_content, buf_length, "{{DELIVERY_POSTAL}}", inv.addressee.address.postal);
+ strops::replace(file_content, buf_length, "{{DELIVERY_REGION}}", inv.addressee.address.region);
+ strops::replace(file_content, buf_length, "{{DELIVERY_COUNTRY}}", inv.addressee.address.country_code);
// Payment means
- strops_replace_int32(file_content, buf_length, "{{PAYMENT_TYPE}}", inv.payment_means.payment_method);
- strops_replace(file_content, buf_length, "{{RECIPIENT_IBAN}}", inv.payment_means.payee_bank_account);
- strops_replace(file_content, buf_length, "{{RECIPIENT_NAME}}", inv.payment_means.payee_account_name);
- strops_replace(file_content, buf_length, "{{RECIPIENT_BIC}}", inv.payment_means.service_provider_id);
- strops_replace(file_content, buf_length, "{{SENDER_IBAN}}", inv.payment_means.payer_bank_account);
+ strops::replace_int32(file_content, buf_length, "{{PAYMENT_TYPE}}", inv.payment_means.payment_method);
+ strops::replace(file_content, buf_length, "{{RECIPIENT_IBAN}}", inv.payment_means.payee_bank_account);
+ strops::replace(file_content, buf_length, "{{RECIPIENT_NAME}}", inv.payment_means.payee_account_name);
+ strops::replace(file_content, buf_length, "{{RECIPIENT_BIC}}", inv.payment_means.service_provider_id);
+ strops::replace(file_content, buf_length, "{{SENDER_IBAN}}", inv.payment_means.payer_bank_account);
// Tax breakdown
- strops_replace_float(file_content, buf_length, "{{TOTAL_TAX_AMOUNT}}", inv.tax, 2);
+ strops::replace_float(file_content, buf_length, "{{TOTAL_TAX_AMOUNT}}", inv.tax, 2);
{ // Create tax subtotal list.
tax_rate* tax_rate_buffer = (tax_rate*)malloc(sizeof(tax_rate)*administration_billing_item_count(&inv));
u32 tax_rate_count = administration_invoice_get_tax_rates(&inv, tax_rate_buffer);
@@ -425,11 +425,11 @@ bool administration_writer_save_invoice_blocking(invoice inv)
tax_subtotal subtotal;
administration_invoice_get_subtotal_for_tax_rate(&inv, tax_rate_buffer[i], &subtotal);
- 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);
- strops_replace_float(tax_entry_file_content, tax_entry_buf_length, "{{TAX_PERCENT}}", tax_rate_buffer[i].rate, 2);
+ 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);
+ 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);
memcpy(tax_subtotal_list_buffer+tax_subtotal_list_buffer_cursor, tax_entry_file_content, content_len);
@@ -438,17 +438,17 @@ bool administration_writer_save_invoice_blocking(invoice inv)
}
tax_subtotal_list_buffer[tax_subtotal_list_buffer_cursor] = 0;
- strops_replace(file_content, buf_length, "{{TAX_SUBTOTAL_LIST}}", tax_subtotal_list_buffer);
+ strops::replace(file_content, buf_length, "{{TAX_SUBTOTAL_LIST}}", tax_subtotal_list_buffer);
free(tax_subtotal_list_buffer);
free(tax_rate_buffer);
}
// Totals
- strops_replace_float(file_content, buf_length, "{{LINE_EXTENSION_AMOUNT}}", inv.net - inv.allowance, 2);
- strops_replace_float(file_content, buf_length, "{{TAX_EXCLUSIVE_AMOUNT}}", inv.net, 2);
- strops_replace_float(file_content, buf_length, "{{TAX_INCLUSIVE_AMOUNT}}", inv.total, 2);
- strops_replace_float(file_content, buf_length, "{{PAYABLE_AMOUNT}}", inv.total, 2);
+ strops::replace_float(file_content, buf_length, "{{LINE_EXTENSION_AMOUNT}}", inv.net - inv.allowance, 2);
+ strops::replace_float(file_content, buf_length, "{{TAX_EXCLUSIVE_AMOUNT}}", inv.net, 2);
+ strops::replace_float(file_content, buf_length, "{{TAX_INCLUSIVE_AMOUNT}}", inv.total, 2);
+ strops::replace_float(file_content, buf_length, "{{PAYABLE_AMOUNT}}", inv.total, 2);
// Invoice lines
{
@@ -469,27 +469,27 @@ bool administration_writer_save_invoice_blocking(invoice inv)
tax_rate rate;
administration_tax_rate_get_by_id(&rate, bi.tax_rate_id);
- strops_replace(billing_item_file_content, billing_item_buf_length, "{{CURRENCY}}", bi.currency);
- strops_replace(billing_item_file_content, billing_item_buf_length, "{{LINE_ID}}", bi.id);
- strops_replace(billing_item_file_content, billing_item_buf_length, "{{LINE_TAX_ID}}", bi.tax_rate_id);
- strops_replace(billing_item_file_content, billing_item_buf_length, "{{ITEM_NAME}}", bi.description);
- strops_replace(billing_item_file_content, billing_item_buf_length, "{{LINE_TAX_CATEGORY}}", rate.category_code);
- strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{LINE_TAX_PERCENT}}", rate.rate, 2);
- strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{LINE_AMOUNT}}", bi.net, 2); // line amount = net_per_item * items_count - discount
- strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{QUANTITY}}", bi.amount, 2);
- strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{UNIT_PRICE}}", bi.net_per_item, 2); // unit price before discount
- strops_replace(billing_item_file_content, billing_item_buf_length, "{{UNIT_CODE}}", bi.amount_is_percentage ? "%" : "X");
+ strops::replace(billing_item_file_content, billing_item_buf_length, "{{CURRENCY}}", bi.currency);
+ strops::replace(billing_item_file_content, billing_item_buf_length, "{{LINE_ID}}", bi.id);
+ strops::replace(billing_item_file_content, billing_item_buf_length, "{{LINE_TAX_ID}}", bi.tax_rate_id);
+ strops::replace(billing_item_file_content, billing_item_buf_length, "{{ITEM_NAME}}", bi.description);
+ strops::replace(billing_item_file_content, billing_item_buf_length, "{{LINE_TAX_CATEGORY}}", rate.category_code);
+ strops::replace_float(billing_item_file_content, billing_item_buf_length, "{{LINE_TAX_PERCENT}}", rate.rate, 2);
+ strops::replace_float(billing_item_file_content, billing_item_buf_length, "{{LINE_AMOUNT}}", bi.net, 2); // line amount = net_per_item * items_count - discount
+ strops::replace_float(billing_item_file_content, billing_item_buf_length, "{{QUANTITY}}", bi.amount, 2);
+ strops::replace_float(billing_item_file_content, billing_item_buf_length, "{{UNIT_PRICE}}", bi.net_per_item, 2); // unit price before discount
+ strops::replace(billing_item_file_content, billing_item_buf_length, "{{UNIT_CODE}}", bi.amount_is_percentage ? "%" : "X");
if (bi.discount_is_percentage) {
- strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_TOTAL_PERCENTAGE}}", bi.discount, 2);
- strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_BASE_AMOUNT}}", bi.net + bi.allowance, 2); // Total net before discount.
+ strops::replace_float(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_TOTAL_PERCENTAGE}}", bi.discount, 2);
+ strops::replace_float(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_BASE_AMOUNT}}", bi.net + bi.allowance, 2); // Total net before discount.
}
else {
- strops_replace(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_TOTAL_PERCENTAGE}}", "");
- strops_replace(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_BASE_AMOUNT}}", "");
+ strops::replace(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_TOTAL_PERCENTAGE}}", "");
+ strops::replace(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_BASE_AMOUNT}}", "");
}
- strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_TOTAL}}", bi.allowance, 2);
+ strops::replace_float(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_TOTAL}}", bi.allowance, 2);
u32 content_len = (u32)strlen(billing_item_file_content);
memcpy(billing_item_list_buffer+billing_item_list_buffer_cursor, billing_item_file_content, content_len);
@@ -498,7 +498,7 @@ bool administration_writer_save_invoice_blocking(invoice inv)
}
billing_item_list_buffer[billing_item_list_buffer_cursor] = 0;
- strops_replace(file_content, buf_length, "{{INVOICE_LINE_LIST}}", billing_item_list_buffer);
+ strops::replace(file_content, buf_length, "{{INVOICE_LINE_LIST}}", billing_item_list_buffer);
free(billing_item_list_buffer);
free(billing_item_buffer);
@@ -507,11 +507,11 @@ bool administration_writer_save_invoice_blocking(invoice inv)
// 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);
+ strops::replace(file_content, buf_length, "{{ISSUE_DATE}}", date_buffer);
tm_info = localtime(&inv.expires_at);
strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", tm_info);
- strops_replace(file_content, buf_length, "{{DUE_DATE}}", date_buffer);
+ strops::replace(file_content, buf_length, "{{DUE_DATE}}", date_buffer);
_remove_empty_xml_tags(file_content, 5);
@@ -525,8 +525,8 @@ bool administration_writer_save_invoice_blocking(invoice inv)
free(file_content);
- if (result) log_info("Saved invoice '%s' in %.3fms.", inv.sequential_number, STOPWATCH_TIME);
- else log_error("Failed to save invoice '%s'.", inv.sequential_number);
+ if (result) logger::info("Saved invoice '%s' in %.3fms.", inv.sequential_number, STOPWATCH_TIME);
+ else logger::error("Failed to save invoice '%s'.", inv.sequential_number);
return result;
}
@@ -562,17 +562,17 @@ bool administration_writer_save_project_blocking(project project)
struct tm *tm_info = 0;
char date_buffer[11]; // "YYYY-MM-DD" + null terminator
- strops_replace(file_content, buf_length, "{{PROJECT_ID}}", project.id);
- strops_replace(file_content, buf_length, "{{PROJECT_DESCRIPTION}}", project.description);
- strops_replace_int32(file_content, buf_length, "{{PROJECT_STATE}}", project.state);
+ strops::replace(file_content, buf_length, "{{PROJECT_ID}}", project.id);
+ strops::replace(file_content, buf_length, "{{PROJECT_DESCRIPTION}}", project.description);
+ strops::replace_int32(file_content, buf_length, "{{PROJECT_STATE}}", project.state);
tm_info = gmtime(&project.start_date);
strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", tm_info);
- strops_replace(file_content, buf_length, "{{PROJECT_STARTDATE}}", date_buffer);
+ strops::replace(file_content, buf_length, "{{PROJECT_STARTDATE}}", date_buffer);
tm_info = gmtime(&project.end_date);
strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", tm_info);
- strops_replace(file_content, buf_length, "{{PROJECT_ENDDATE}}", date_buffer);
+ strops::replace(file_content, buf_length, "{{PROJECT_ENDDATE}}", date_buffer);
//// Write to Disk.
char final_path[50];
@@ -584,8 +584,8 @@ bool administration_writer_save_project_blocking(project project)
free(file_content);
- if (result) log_info("Saved project '%s' in %.3fms.", project.description, STOPWATCH_TIME);
- else log_error("Failed to save project '%s'.", project.description);
+ if (result) logger::info("Saved project '%s' in %.3fms.", project.description, STOPWATCH_TIME);
+ else logger::error("Failed to save project '%s'.", project.description);
return result;
}
@@ -618,9 +618,9 @@ bool administration_writer_save_cost_center_blocking(cost_center cost)
int buf_length = 0;
char* file_content = administration_writer_copy_template(file_template::costcenter_save_template, &buf_length);
- strops_replace(file_content, buf_length, "{{COSTCENTER_ID}}", cost.id);
- strops_replace(file_content, buf_length, "{{COSTCENTER_CODE}}", cost.code);
- strops_replace(file_content, buf_length, "{{COSTCENTER_DESCRIPTION}}", cost.description);
+ strops::replace(file_content, buf_length, "{{COSTCENTER_ID}}", cost.id);
+ strops::replace(file_content, buf_length, "{{COSTCENTER_CODE}}", cost.code);
+ strops::replace(file_content, buf_length, "{{COSTCENTER_DESCRIPTION}}", cost.description);
//// Write to Disk.
char final_path[50];
@@ -632,8 +632,8 @@ bool administration_writer_save_cost_center_blocking(cost_center cost)
free(file_content);
- if (result) log_info("Saved cost center '%s' in %.3fms.", cost.code, STOPWATCH_TIME);
- else log_error("Failed to save cost center '%s'.", cost.code);
+ if (result) logger::info("Saved cost center '%s' in %.3fms.", cost.code, STOPWATCH_TIME);
+ else logger::error("Failed to save cost center '%s'.", cost.code);
return result;
}
@@ -666,10 +666,10 @@ bool administration_writer_save_tax_rate_blocking(tax_rate rate)
int buf_length = 0;
char* file_content = administration_writer_copy_template(file_template::taxrate_save_template, &buf_length);
- strops_replace(file_content, buf_length, "{{TAXBRACKET_ID}}", rate.id);
- strops_replace(file_content, buf_length, "{{TAXBRACKET_COUNTRY}}", rate.country_code);
- strops_replace_float(file_content, buf_length, "{{TAXBRACKET_RATE}}", rate.rate, 2);
- strops_replace(file_content, buf_length, "{{TAXBRACKET_CATEGORY}}", rate.category_code);
+ strops::replace(file_content, buf_length, "{{TAXBRACKET_ID}}", rate.id);
+ strops::replace(file_content, buf_length, "{{TAXBRACKET_COUNTRY}}", rate.country_code);
+ strops::replace_float(file_content, buf_length, "{{TAXBRACKET_RATE}}", rate.rate, 2);
+ strops::replace(file_content, buf_length, "{{TAXBRACKET_CATEGORY}}", rate.category_code);
//// Write to Disk.
char final_path[50];
@@ -681,8 +681,8 @@ bool administration_writer_save_tax_rate_blocking(tax_rate rate)
free(file_content);
- if (result) log_info("Saved tax rate '%s/%.1f' in %.3fms.", rate.country_code, rate.rate, STOPWATCH_TIME);
- else log_error("Failed to save tax rate '%s/%.1f'.", rate.country_code, rate.rate);
+ if (result) logger::info("Saved tax rate '%s/%.1f' in %.3fms.", rate.country_code, rate.rate, STOPWATCH_TIME);
+ else logger::error("Failed to save tax rate '%s/%.1f'.", rate.country_code, rate.rate);
return result;
}
@@ -717,20 +717,20 @@ bool administration_writer_save_contact_blocking(contact c)
int buf_length = 0;
char* file_content = administration_writer_copy_template(file_template::contact_save_template, &buf_length);
- strops_replace(file_content, buf_length, "{{CONTACT_ID}}", c.id);
- strops_replace(file_content, buf_length, "{{CONTACT_NAME}}", c.name);
- strops_replace_int32(file_content, buf_length, "{{CONTACT_TYPE}}", c.type);
- strops_replace(file_content, buf_length, "{{CONTACT_TAXID}}", c.taxid);
- strops_replace(file_content, buf_length, "{{CONTACT_BUSINESSID}}", c.businessid);
- strops_replace(file_content, buf_length, "{{CONTACT_EMAIL}}", c.email);
- strops_replace(file_content, buf_length, "{{CONTACT_PHONENUMBER}}", c.phone_number);
- strops_replace(file_content, buf_length, "{{CONTACT_BANKACCOUNT}}", c.bank_account);
- strops_replace(file_content, buf_length, "{{CONTACT_ADDRESS1}}", c.address.address1);
- strops_replace(file_content, buf_length, "{{CONTACT_ADDRESS2}}", c.address.address2);
- strops_replace(file_content, buf_length, "{{CONTACT_COUNTRY}}", c.address.country_code);
- strops_replace(file_content, buf_length, "{{CONTACT_CITY}}", c.address.city);
- strops_replace(file_content, buf_length, "{{CONTACT_POSTAL}}", c.address.postal);
- strops_replace(file_content, buf_length, "{{CONTACT_REGION}}", c.address.region);
+ strops::replace(file_content, buf_length, "{{CONTACT_ID}}", c.id);
+ strops::replace(file_content, buf_length, "{{CONTACT_NAME}}", c.name);
+ strops::replace_int32(file_content, buf_length, "{{CONTACT_TYPE}}", c.type);
+ strops::replace(file_content, buf_length, "{{CONTACT_TAXID}}", c.taxid);
+ strops::replace(file_content, buf_length, "{{CONTACT_BUSINESSID}}", c.businessid);
+ strops::replace(file_content, buf_length, "{{CONTACT_EMAIL}}", c.email);
+ strops::replace(file_content, buf_length, "{{CONTACT_PHONENUMBER}}", c.phone_number);
+ strops::replace(file_content, buf_length, "{{CONTACT_BANKACCOUNT}}", c.bank_account);
+ strops::replace(file_content, buf_length, "{{CONTACT_ADDRESS1}}", c.address.address1);
+ strops::replace(file_content, buf_length, "{{CONTACT_ADDRESS2}}", c.address.address2);
+ strops::replace(file_content, buf_length, "{{CONTACT_COUNTRY}}", c.address.country_code);
+ strops::replace(file_content, buf_length, "{{CONTACT_CITY}}", c.address.city);
+ strops::replace(file_content, buf_length, "{{CONTACT_POSTAL}}", c.address.postal);
+ strops::replace(file_content, buf_length, "{{CONTACT_REGION}}", c.address.region);
char final_path[50];
snprintf(final_path, 50, "%s.xml", c.id);
@@ -741,8 +741,8 @@ bool administration_writer_save_contact_blocking(contact c)
free(file_content);
- if (result) log_info("Saved contact '%s' in %.3fms.", c.name, STOPWATCH_TIME);
- else log_error("Failed to save contact '%s'.", c.name);
+ if (result) logger::info("Saved contact '%s' in %.3fms.", c.name, STOPWATCH_TIME);
+ else logger::error("Failed to save contact '%s'.", c.name);
return result;
}
@@ -781,13 +781,13 @@ bool administration_writer_save_all_administration_info_blocking()
int buf_length = 0;
char* file_content = administration_writer_copy_template(file_template::administration_save_template, &buf_length);
- strops_replace_int32(file_content, buf_length, "{{NEXT_ID}}", administration_get_next_id());
- strops_replace_int32(file_content, buf_length, "{{NEXT_SEQUENCE_NUMBER}}", administration_get_next_sequence_number());
- strops_replace(file_content, buf_length, "{{PROGRAM_VERSION}}", config::PROGRAM_VERSION);
+ strops::replace_int32(file_content, buf_length, "{{NEXT_ID}}", administration_get_next_id());
+ strops::replace_int32(file_content, buf_length, "{{NEXT_SEQUENCE_NUMBER}}", administration_get_next_sequence_number());
+ strops::replace(file_content, buf_length, "{{PROGRAM_VERSION}}", config::PROGRAM_VERSION);
ai_service ai_service = administration_get_ai_service();
- strops_replace_int32(file_content, buf_length, "{{AI_SERVICE_PROVIDER}}", (s32)ai_service.provider);
- strops_replace(file_content, buf_length, "{{AI_SERVICE_PUBLIC_KEY}}", ai_service.api_key_public);
+ strops::replace_int32(file_content, buf_length, "{{AI_SERVICE_PROVIDER}}", (s32)ai_service.provider);
+ strops::replace(file_content, buf_length, "{{AI_SERVICE_PUBLIC_KEY}}", ai_service.api_key_public);
//// Write to Disk.
int final_length = (int)strlen(file_content);
@@ -796,8 +796,8 @@ bool administration_writer_save_all_administration_info_blocking()
free(file_content);
- if (result) log_info("Saved administration info in %.3fms.", STOPWATCH_TIME);
- else log_error("Failed to save administration info.");
+ if (result) logger::info("Saved administration info in %.3fms.", STOPWATCH_TIME);
+ else logger::error("Failed to save administration info.");
return result;
}
diff --git a/src/ai_providers/DeepSeek.cpp b/src/ai_providers/DeepSeek.cpp
index 334f024..1bec8f8 100644
--- a/src/ai_providers/DeepSeek.cpp
+++ b/src/ai_providers/DeepSeek.cpp
@@ -23,7 +23,7 @@
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"
#include "strops.hpp"
-#include "log.hpp"
+#include "logger.hpp"
#include "importer.hpp"
#define QUERY_BUFFER_SIZE 1000000
@@ -40,13 +40,13 @@ static bool _DeepSeek_query_with_file(char* query, size_t query_length, char* fi
httplib::SSLClient cli("api.deepseek.com");
//cli.enable_server_certificate_verification(false);
- //char* query_escaped = strops_prep_str_for_json(query, query_length);
+ //char* query_escaped = strops::prep_str_for_json(query, query_length);
//free(query); // TODO why??
size_t file_size = strlen(query_buffer);
sprintf(query_buffer + file_size, "%s", query);
- char* query_escaped = strops_prep_str_for_json(query_buffer, strlen(query_buffer));
+ char* query_escaped = strops::prep_str_for_json(query_buffer, strlen(query_buffer));
size_t body_size = file_size + QUERY_BUFFER_SIZE;
char* body = (char*)malloc(body_size);
@@ -62,8 +62,8 @@ static bool _DeepSeek_query_with_file(char* query, size_t query_length, char* fi
free(body);
if (!res || res->status != 200) {
- log_error("ERROR Failed to query API.");
- log_error(res->body.c_str());
+ logger::error("ERROR Failed to query API.");
+ logger::error(res->body.c_str());
return 0;
}
@@ -72,8 +72,8 @@ static bool _DeepSeek_query_with_file(char* query, size_t query_length, char* fi
memset(*response, 0, 100000);
strncpy(*response, response_body, 100000);
- strops_get_json_value(*response, "content", *response, 100000);
- *response = strops_unprep_str_from_json(*response);
+ strops::get_json_value(*response, "content", *response, 100000);
+ *response = strops::unprep_str_from_json(*response);
return 1;
}
@@ -82,11 +82,11 @@ static bool _DeepSeek_upload_file(char* file_path, char* file_id, size_t file_id
{
(void)file_id;
(void)file_id_len;
- const char *filename = strops_get_filename(file_path);
+ const char *filename = strops::get_filename(file_path);
FILE* orig_file = fopen(file_path, "r");
if (orig_file == NULL) {
- log_error("ERROR: file to upload could not be opened.");
+ logger::error("ERROR: file to upload could not be opened.");
return 0;
}
diff --git a/src/ai_providers/openAI.cpp b/src/ai_providers/openAI.cpp
index 415d8ce..340359e 100644
--- a/src/ai_providers/openAI.cpp
+++ b/src/ai_providers/openAI.cpp
@@ -23,7 +23,7 @@
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"
#include "strops.hpp"
-#include "log.hpp"
+#include "logger.hpp"
#include "importer.hpp"
static bool _openAI_query_with_file(char* query, size_t query_length, char* file_id, char** response)
@@ -34,7 +34,7 @@ static bool _openAI_query_with_file(char* query, size_t query_length, char* file
httplib::SSLClient cli("api.openai.com", 443);
//cli.enable_server_certificate_verification(false);
- char* query_escaped = strops_prep_str_for_json(query, query_length);
+ char* query_escaped = strops::prep_str_for_json(query, query_length);
free(query);
size_t body_size = query_length + 200;
@@ -50,8 +50,8 @@ static bool _openAI_query_with_file(char* query, size_t query_length, char* file
free(body);
if (!res || res->status != 200) {
- log_error("ERROR Failed to query API.");
- log_error(res->body.c_str());
+ logger::error("ERROR Failed to query API.");
+ logger::error(res->body.c_str());
return 0;
}
@@ -60,12 +60,12 @@ static bool _openAI_query_with_file(char* query, size_t query_length, char* file
memset(*response, 0, 100000);
strncpy(*response, response_body, 100000);
- strops_get_json_value(*response, "text", *response, 100000);
- *response = strops_unprep_str_from_json(*response);
+ strops::get_json_value(*response, "text", *response, 100000);
+ *response = strops::unprep_str_from_json(*response);
#else
*response = (char*)malloc(100000);
memset(*response, 0, 100000);
- strops_copy(*response, "<Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\" xmlns:cac=\"urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2\" xmlns:cbc=\"urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2\"> <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID> <cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID> <cbc:ID>492043632</cbc:ID> <cbc:IssueDate>2024-09-01</cbc:IssueDate> <cbc:DueDate>2024-09-01</cbc:DueDate> <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode> <cbc:DocumentCurrencyCode>USD</cbc:DocumentCurrencyCode> <cac:DespatchDocumentReference> <cbc:ID>Final invoice</cbc:ID> </cac:DespatchDocumentReference> <cac:AdditionalDocumentReference> <cbc:ID></cbc:ID> <cbc:DocumentDescription></cbc:DocumentDescription> </cac:AdditionalDocumentReference> <cac:OrderReference> <cbc:ID></cbc:ID> </cac:OrderReference> <cac:ProjectReference> <cbc:ID>do:team:67840ecb-44e2-472e-bc45-801bd4e1f1fe</cbc:ID> </cac:ProjectReference> <cbc:AccountingCost></cbc:AccountingCost> <cac:AccountingSupplierParty> <cac:Party> <cbc:EndpointID schemeID=""></cbc:EndpointID> <cac:PartyIdentification> <cbc:ID schemeID=\"ZZZ\"></cbc:ID> </cac:PartyIdentification> <cac:PartyName> <cbc:Name>DigitalOcean LLC</cbc:Name> </cac:PartyName> <cac:PostalAddress> <cbc:StreetName>101 Avenue of the Americas</cbc:StreetName> <cbc:AdditionalStreetName>2nd Floor</cbc:AdditionalStreetName> <cbc:CityName>New York</cbc:CityName> <cbc:PostalZone>10013</cbc:PostalZone> <cbc:CountrySubentity>NY</cbc:CountrySubentity> <cac:Country> <cbc:IdentificationCode>US</cbc:IdentificationCode> </cac:Country> </cac:PostalAddress> <cac:PartyTaxScheme> <cbc:CompanyID>EU528002224</cbc:CompanyID> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:PartyTaxScheme> <cac:PartyLegalEntity> <cbc:RegistrationName>DigitalOcean LLC</cbc:RegistrationName> </cac:PartyLegalEntity> <cac:Contact> <cbc:Name></cbc:Name> <cbc:Telephone></cbc:Telephone> <cbc:ElectronicMail></cbc:ElectronicMail> </cac:Contact> </cac:Party> </cac:AccountingSupplierParty> <cac:AccountingCustomerParty> <cac:Party> <cbc:EndpointID schemeID=""></cbc:EndpointID> <cac:PartyIdentification> <cbc:ID schemeID=\"ZZZ\"></cbc:ID> </cac:PartyIdentification> <cac:PartyName> <cbc:Name>My Team</cbc:Name> </cac:PartyName> <cac:PostalAddress> <cbc:StreetName>Keerderstraat 81</cbc:StreetName> <cbc:AdditionalStreetName></cbc:AdditionalStreetName> <cbc:CityName>Maastricht</cbc:CityName> <cbc:PostalZone>6226 XW</cbc:PostalZone> <cbc:CountrySubentity>LI</cbc:CountrySubentity> <cac:Country> <cbc:IdentificationCode>NL</cbc:IdentificationCode> </cac:Country> </cac:PostalAddress> <cac:PartyTaxScheme> <cbc:CompanyID></cbc:CompanyID> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:PartyTaxScheme> <cac:PartyLegalEntity> <cbc:RegistrationName></cbc:RegistrationName> </cac:PartyLegalEntity> <cac:Contact> <cbc:Name></cbc:Name> <cbc:Telephone></cbc:Telephone> <cbc:ElectronicMail>aldrikboy@gmail.com</cbc:ElectronicMail> </cac:Contact> </cac:Party> </cac:AccountingCustomerParty> <cac:Delivery> <cbc:ActualDeliveryDate></cbc:ActualDeliveryDate> <cac:DeliveryLocation> <cac:Address> <cbc:StreetName></cbc:StreetName> <cbc:AdditionalStreetName></cbc:AdditionalStreetName> <cbc:CityName></cbc:CityName> <cbc:PostalZone></cbc:PostalZone> <cbc:CountrySubentity></cbc:CountrySubentity> <cac:Country> <cbc:IdentificationCode></cbc:IdentificationCode> </cac:Country> </cac:Address> </cac:DeliveryLocation> <cac:DeliveryParty> <cac:PartyName> <cbc:Name></cbc:Name> </cac:PartyName> </cac:DeliveryParty> </cac:Delivery> <cac:PaymentMeans> <cbc:PaymentMeansCode></cbc:PaymentMeansCode> <cbc:PaymentID>492043632</cbc:PaymentID> <cac:PayeeFinancialAccount> <cbc:ID></cbc:ID> <cbc:Name></cbc:Name> <cac:FinancialInstitutionBranch> <cac:FinancialInstitution> <cbc:ID></cbc:ID> </cac:FinancialInstitution> </cac:FinancialInstitutionBranch> </cac:PayeeFinancialAccount> <cac:PayerFinancialAccount> <cbc:ID></cbc:ID> </cac:PayerFinancialAccount> </cac:PaymentMeans> <cac:TaxTotal> <cbc:TaxAmount currencyID=\"USD\">3.49</cbc:TaxAmount> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID=\"USD\">15.60</cbc:TaxableAmount> <cbc:TaxAmount currencyID=\"USD\">3.28</cbc:TaxAmount> <cac:TaxCategory> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:TaxCategory> </cac:TaxSubtotal> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID=\"USD\">1.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID=\"USD\">0.21</cbc:TaxAmount> <cac:TaxCategory> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:TaxCategory> </cac:TaxSubtotal> </cac:TaxTotal> <cac:LegalMonetaryTotal> <cbc:LineExtensionAmount currencyID=\"USD\">16.60</cbc:LineExtensionAmount> <cbc:TaxExclusiveAmount currencyID=\"USD\">16.60</cbc:TaxExclusiveAmount> <cbc:TaxInclusiveAmount currencyID=\"USD\">20.09</cbc:TaxInclusiveAmount> <cbc:PayableAmount currencyID=\"USD\">20.09</cbc:PayableAmount> </cac:LegalMonetaryTotal> <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:InvoicedQuantity unitCode=""></cbc:InvoicedQuantity> <cbc:LineExtensionAmount currencyID=\"USD\">16.60</cbc:LineExtensionAmount> <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:AllowanceChargeReason>Discount</cbc:AllowanceChargeReason> <cbc:MultiplierFactorNumeric></cbc:MultiplierFactorNumeric> <cbc:Amount currencyID=\"USD\"></cbc:Amount> <cbc:BaseAmount currencyID=\"USD\"></cbc:BaseAmount> </cac:AllowanceCharge> <cac:Item> <cbc:Name>Product Usage Charges</cbc:Name> <cac:AdditionalItemProperty> <cbc:Name>Internal Tax Rate ID</cbc:Name> <cbc:Value></cbc:Value> </cac:AdditionalItemProperty> <cac:ClassifiedTaxCategory> <cbc:ID></cbc:ID> <cbc:Percent></cbc:Percent> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:ClassifiedTaxCategory> </cac:Item> <cac:Price> <cbc:PriceAmount currencyID=\"USD\"></cbc:PriceAmount> </cac:Price> </cac:InvoiceLine></Invoice>", 100000);
+ strops::copy(*response, "<Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\" xmlns:cac=\"urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2\" xmlns:cbc=\"urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2\"> <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID> <cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID> <cbc:ID>492043632</cbc:ID> <cbc:IssueDate>2024-09-01</cbc:IssueDate> <cbc:DueDate>2024-09-01</cbc:DueDate> <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode> <cbc:DocumentCurrencyCode>USD</cbc:DocumentCurrencyCode> <cac:DespatchDocumentReference> <cbc:ID>Final invoice</cbc:ID> </cac:DespatchDocumentReference> <cac:AdditionalDocumentReference> <cbc:ID></cbc:ID> <cbc:DocumentDescription></cbc:DocumentDescription> </cac:AdditionalDocumentReference> <cac:OrderReference> <cbc:ID></cbc:ID> </cac:OrderReference> <cac:ProjectReference> <cbc:ID>do:team:67840ecb-44e2-472e-bc45-801bd4e1f1fe</cbc:ID> </cac:ProjectReference> <cbc:AccountingCost></cbc:AccountingCost> <cac:AccountingSupplierParty> <cac:Party> <cbc:EndpointID schemeID=""></cbc:EndpointID> <cac:PartyIdentification> <cbc:ID schemeID=\"ZZZ\"></cbc:ID> </cac:PartyIdentification> <cac:PartyName> <cbc:Name>DigitalOcean LLC</cbc:Name> </cac:PartyName> <cac:PostalAddress> <cbc:StreetName>101 Avenue of the Americas</cbc:StreetName> <cbc:AdditionalStreetName>2nd Floor</cbc:AdditionalStreetName> <cbc:CityName>New York</cbc:CityName> <cbc:PostalZone>10013</cbc:PostalZone> <cbc:CountrySubentity>NY</cbc:CountrySubentity> <cac:Country> <cbc:IdentificationCode>US</cbc:IdentificationCode> </cac:Country> </cac:PostalAddress> <cac:PartyTaxScheme> <cbc:CompanyID>EU528002224</cbc:CompanyID> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:PartyTaxScheme> <cac:PartyLegalEntity> <cbc:RegistrationName>DigitalOcean LLC</cbc:RegistrationName> </cac:PartyLegalEntity> <cac:Contact> <cbc:Name></cbc:Name> <cbc:Telephone></cbc:Telephone> <cbc:ElectronicMail></cbc:ElectronicMail> </cac:Contact> </cac:Party> </cac:AccountingSupplierParty> <cac:AccountingCustomerParty> <cac:Party> <cbc:EndpointID schemeID=""></cbc:EndpointID> <cac:PartyIdentification> <cbc:ID schemeID=\"ZZZ\"></cbc:ID> </cac:PartyIdentification> <cac:PartyName> <cbc:Name>My Team</cbc:Name> </cac:PartyName> <cac:PostalAddress> <cbc:StreetName>Keerderstraat 81</cbc:StreetName> <cbc:AdditionalStreetName></cbc:AdditionalStreetName> <cbc:CityName>Maastricht</cbc:CityName> <cbc:PostalZone>6226 XW</cbc:PostalZone> <cbc:CountrySubentity>LI</cbc:CountrySubentity> <cac:Country> <cbc:IdentificationCode>NL</cbc:IdentificationCode> </cac:Country> </cac:PostalAddress> <cac:PartyTaxScheme> <cbc:CompanyID></cbc:CompanyID> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:PartyTaxScheme> <cac:PartyLegalEntity> <cbc:RegistrationName></cbc:RegistrationName> </cac:PartyLegalEntity> <cac:Contact> <cbc:Name></cbc:Name> <cbc:Telephone></cbc:Telephone> <cbc:ElectronicMail>aldrikboy@gmail.com</cbc:ElectronicMail> </cac:Contact> </cac:Party> </cac:AccountingCustomerParty> <cac:Delivery> <cbc:ActualDeliveryDate></cbc:ActualDeliveryDate> <cac:DeliveryLocation> <cac:Address> <cbc:StreetName></cbc:StreetName> <cbc:AdditionalStreetName></cbc:AdditionalStreetName> <cbc:CityName></cbc:CityName> <cbc:PostalZone></cbc:PostalZone> <cbc:CountrySubentity></cbc:CountrySubentity> <cac:Country> <cbc:IdentificationCode></cbc:IdentificationCode> </cac:Country> </cac:Address> </cac:DeliveryLocation> <cac:DeliveryParty> <cac:PartyName> <cbc:Name></cbc:Name> </cac:PartyName> </cac:DeliveryParty> </cac:Delivery> <cac:PaymentMeans> <cbc:PaymentMeansCode></cbc:PaymentMeansCode> <cbc:PaymentID>492043632</cbc:PaymentID> <cac:PayeeFinancialAccount> <cbc:ID></cbc:ID> <cbc:Name></cbc:Name> <cac:FinancialInstitutionBranch> <cac:FinancialInstitution> <cbc:ID></cbc:ID> </cac:FinancialInstitution> </cac:FinancialInstitutionBranch> </cac:PayeeFinancialAccount> <cac:PayerFinancialAccount> <cbc:ID></cbc:ID> </cac:PayerFinancialAccount> </cac:PaymentMeans> <cac:TaxTotal> <cbc:TaxAmount currencyID=\"USD\">3.49</cbc:TaxAmount> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID=\"USD\">15.60</cbc:TaxableAmount> <cbc:TaxAmount currencyID=\"USD\">3.28</cbc:TaxAmount> <cac:TaxCategory> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:TaxCategory> </cac:TaxSubtotal> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID=\"USD\">1.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID=\"USD\">0.21</cbc:TaxAmount> <cac:TaxCategory> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:TaxCategory> </cac:TaxSubtotal> </cac:TaxTotal> <cac:LegalMonetaryTotal> <cbc:LineExtensionAmount currencyID=\"USD\">16.60</cbc:LineExtensionAmount> <cbc:TaxExclusiveAmount currencyID=\"USD\">16.60</cbc:TaxExclusiveAmount> <cbc:TaxInclusiveAmount currencyID=\"USD\">20.09</cbc:TaxInclusiveAmount> <cbc:PayableAmount currencyID=\"USD\">20.09</cbc:PayableAmount> </cac:LegalMonetaryTotal> <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:InvoicedQuantity unitCode=""></cbc:InvoicedQuantity> <cbc:LineExtensionAmount currencyID=\"USD\">16.60</cbc:LineExtensionAmount> <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:AllowanceChargeReason>Discount</cbc:AllowanceChargeReason> <cbc:MultiplierFactorNumeric></cbc:MultiplierFactorNumeric> <cbc:Amount currencyID=\"USD\"></cbc:Amount> <cbc:BaseAmount currencyID=\"USD\"></cbc:BaseAmount> </cac:AllowanceCharge> <cac:Item> <cbc:Name>Product Usage Charges</cbc:Name> <cac:AdditionalItemProperty> <cbc:Name>Internal Tax Rate ID</cbc:Name> <cbc:Value></cbc:Value> </cac:AdditionalItemProperty> <cac:ClassifiedTaxCategory> <cbc:ID></cbc:ID> <cbc:Percent></cbc:Percent> <cac:TaxScheme> <cbc:ID>VAT</cbc:ID> </cac:TaxScheme> </cac:ClassifiedTaxCategory> </cac:Item> <cac:Price> <cbc:PriceAmount currencyID=\"USD\"></cbc:PriceAmount> </cac:Price> </cac:InvoiceLine></Invoice>", 100000);
#endif
return 1;
@@ -74,11 +74,11 @@ static bool _openAI_query_with_file(char* query, size_t query_length, char* file
static bool _openAI_upload_file(char* file_path, char* file_id, size_t file_id_len)
{
const char *api_key = administration_get_ai_service().api_key_public;
- const char *filename = strops_get_filename(file_path);
+ const char *filename = strops::get_filename(file_path);
FILE* orig_file = fopen(file_path, "rb");
if (orig_file == NULL) {
- log_error("ERROR: file to upload could not be opened.");
+ logger::error("ERROR: file to upload could not be opened.");
return 0;
}
@@ -97,16 +97,16 @@ static bool _openAI_upload_file(char* file_path, char* file_id, size_t file_id_l
httplib::Result res = cli.Post("/v1/uploads", headers, body, "application/json");
if (!res || res->status != 200) {
- log_error("ERROR Failed to create upload.");
- log_error(res->body.c_str());
+ logger::error("ERROR Failed to create upload.");
+ logger::error(res->body.c_str());
fclose(orig_file);
return 0;
}
char upload_id[128];
- strops_get_json_value(res->body.c_str(), "id", upload_id, sizeof(upload_id));
+ strops::get_json_value(res->body.c_str(), "id", upload_id, sizeof(upload_id));
size_t part_size = 64000000; // 64mb
- log_info("Created upload %s with part size %zu.", upload_id, part_size);
+ logger::info("Created upload %s with part size %zu.", upload_id, part_size);
char *buffer = (char*)malloc(part_size);
@@ -133,20 +133,20 @@ static bool _openAI_upload_file(char* file_path, char* file_id, size_t file_id_l
httplib::Result part_res = cli.Post(path, part_headers, items);
if (!part_res || part_res->status != 200) {
- log_error("Failed to upload part %d.", part_number);
- log_error(part_res->body.c_str());
+ logger::error("Failed to upload part %d.", part_number);
+ logger::error(part_res->body.c_str());
free(buffer);
fclose(orig_file);
return 0;
}
else {
char part_id[128];
- strops_get_json_value(part_res->body.c_str(), "id", part_id, sizeof(part_id));
+ strops::get_json_value(part_res->body.c_str(), "id", part_id, sizeof(part_id));
if (part_number == 0) snprintf(completion_body+strlen(completion_body), sizeof(completion_body)-strlen(completion_body), "\"%s\"", part_id);
if (part_number != 0) snprintf(completion_body+strlen(completion_body), sizeof(completion_body)-strlen(completion_body), ", \"%s\"", part_id);
}
- log_info("Uploaded part %d\n", part_number);
+ logger::info("Uploaded part %d\n", part_number);
part_number++;
}
@@ -162,13 +162,13 @@ static bool _openAI_upload_file(char* file_path, char* file_id, size_t file_id_l
if (!complete_res || complete_res->status != 200) {
- log_error("ERROR Failed to complete upload.");
- log_error(complete_res->body.c_str());
+ logger::error("ERROR Failed to complete upload.");
+ logger::error(complete_res->body.c_str());
return 0;
}
char* completion_body_response = (char*)complete_res->body.c_str();
- strops_get_json_value(completion_body_response, "id", file_id, file_id_len, 1);
+ strops::get_json_value(completion_body_response, "id", file_id, file_id_len, 1);
return 1;
}
diff --git a/src/importer.cpp b/src/importer.cpp
index 404ee8c..42fdaa4 100644
--- a/src/importer.cpp
+++ b/src/importer.cpp
@@ -23,7 +23,7 @@
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"
-#include "log.hpp"
+#include "logger.hpp"
#include "importer.hpp"
#include "strops.hpp"
#include "administration_reader.hpp"
@@ -65,7 +65,7 @@ static int _ai_document_to_invoice_t(void *arg) {
memset(template_buffer, 0, query_buffer_len);
strncpy(template_buffer, file_template::peppol_invoice_template, query_buffer_len);
- strops_replace(template_buffer, 50000, "{{INVOICE_LINE_LIST}}", file_template::peppol_invoice_line_template);
+ strops::replace(template_buffer, 50000, "{{INVOICE_LINE_LIST}}", file_template::peppol_invoice_line_template);
char* ai_query =
"\n\nI have provided a file containing an invoice. Fill in the above Peppol 3.0 template with the information from the invoice.\n"
@@ -120,15 +120,15 @@ static int _ai_document_to_invoice_t(void *arg) {
// Set customer or supplier depending on incomming or outgoing.
contact my_info = administration_company_info_get();
memcpy(&inv.customer, &my_info, sizeof(contact));
- strops_copy(inv.customer.id, MY_COMPANY_ID, MAX_LEN_ID);
+ strops::copy(inv.customer.id, MY_COMPANY_ID, MAX_LEN_ID);
// Project and cost centers cannot be interpreted from file so are set to 0.
- strops_copy(inv.project_id, "", MAX_LEN_ID);
- strops_copy(inv.cost_center_id, "", MAX_LEN_ID);
+ strops::copy(inv.project_id, "", MAX_LEN_ID);
+ strops::copy(inv.cost_center_id, "", MAX_LEN_ID);
// Set document references and save copy to disk.
- strops_copy(inv.document.original_path, file_path, MAX_LEN_PATH);
- strops_copy(inv.document.copy_path, "", MAX_LEN_PATH);
+ strops::copy(inv.document.original_path, file_path, MAX_LEN_PATH);
+ strops::copy(inv.document.copy_path, "", MAX_LEN_PATH);
// Set dates.
if (inv.expires_at == 0) {
@@ -153,7 +153,7 @@ import_invoice_request* ai_document_to_invoice(char* file_path)
result->started_at = time(NULL);
result->error = I_ERR_SUCCESS;
result->status = import_status::IMPORT_STARTING;
- strops_copy(result->file_path, file_path, MAX_LEN_PATH);
+ strops::copy(result->file_path, file_path, MAX_LEN_PATH);
thrd_t thr;
if (thrd_create(&thr, _ai_document_to_invoice_t, result) != thrd_success) {
diff --git a/src/locales.cpp b/src/locales.cpp
index ef2ff6a..883d511 100644
--- a/src/locales.cpp
+++ b/src/locales.cpp
@@ -28,12 +28,12 @@ namespace locale {
static const int locale_map_count = sizeof(locales) / sizeof(locales[0]);
static locale_map g_locale = locales[0]; // Default to english.
- const char* locale::get_locale()
+ const char* get_locale()
{
return g_locale.lang_code;
}
- void locale::set_locale(const char* key)
+ void set_locale(const char* key)
{
for (int i = 0; i < locale_map_count; ++i) {
if (strcmp(locales[i].lang_code, key) == 0) {
@@ -42,7 +42,7 @@ namespace locale {
}
}
- const char* locale::get(const char* key)
+ const char* get(const char* key)
{
for (int i = 0; i < g_locale.entry_count; ++i) {
if (strcmp(g_locale.entries[i].key, key) == 0) {
diff --git a/src/log.cpp b/src/log.cpp
deleted file mode 100644
index 094bcab..0000000
--- a/src/log.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-* Copyright (c) 2025 Aldrik Ramaekers <aldrik.ramaekers@gmail.com>
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <time.h>
-#include "timer.h"
-#include "log.hpp"
-
-program_log g_log = {0};
-
-program_log* get_log()
-{
- return &g_log;
-}
-
-void log_clear()
-{
- g_log.write_cursor = 0;
- g_log.history_length = 0;
-}
-
-static void log_message(const char* fmt, ImVec4 color, va_list args)
-{
- vsnprintf(g_log.history[g_log.write_cursor], MAX_LEN_LOG_TXT, fmt, args);
- g_log.colors[g_log.write_cursor] = color;
-
- tick_t ms_since_epoch = timer_system();
- char time_buf[50];
- time_t seconds = (time_t)(ms_since_epoch / 1000);
- int milliseconds = (int)(ms_since_epoch % 1000);
-
- // Convert to local time
- struct tm tm_time;
- #if defined(_WIN32)
- localtime_s(&tm_time, &seconds);
- #else
- localtime_r(&seconds, &tm_time);
- #endif
-
- snprintf(time_buf, 50, "%02d:%02d %02d.%03d",
- tm_time.tm_hour,
- tm_time.tm_min,
- tm_time.tm_sec,
- milliseconds);
-
- char tmp[MAX_LEN_LOG_TXT];
- snprintf(tmp, MAX_LEN_LOG_TXT, "[%s] %s", time_buf, g_log.history[g_log.write_cursor]);
- tmp[MAX_LEN_LOG_TXT-1] = 0;
- memcpy(g_log.history[g_log.write_cursor], tmp, MAX_LEN_LOG_TXT);
-
- g_log.write_cursor++;
- if (g_log.write_cursor >= MAX_LEN_LOG_HISTORY) g_log.write_cursor = 0;
-
- g_log.history_length++;
- if (g_log.history_length > MAX_LEN_LOG_HISTORY) g_log.history_length = MAX_LEN_LOG_HISTORY;
-}
-
-void log_aerr(a_err errors)
-{
- if (errors & A_ERR_GENERIC) log_error(" ERROR: Generic error");
- if (errors & A_ERR_NOT_FOUND) log_error(" ERROR: Not found");
- if (errors & A_ERR_MISSING_DESCRIPTION) log_error(" ERROR: Missing description");
- if (errors & A_ERR_CODE_EXISTS) log_error(" ERROR: Code already exists");
- if (errors & A_ERR_MISSING_BILLING_ITEMS) log_error(" ERROR: Missing billing items");
- if (errors & A_ERR_INVALID_ADDRESSEE) log_error(" ERROR: Invalid addressee");
- if (errors & A_ERR_INVALID_CUSTOMER) log_error(" ERROR: Invalid customer");
- if (errors & A_ERR_INVALID_SUPPLIER) log_error(" ERROR: Invalid supplier");
- if (errors & A_ERR_MISSING_NAME) log_error(" ERROR: Missing name");
- if (errors & A_ERR_MISSING_CITY) log_error(" ERROR: Missing city");
- if (errors & A_ERR_MISSING_POSTAL) log_error(" ERROR: Missing postal code");
- if (errors & A_ERR_MISSING_ADDRESS1) log_error(" ERROR: Missing address line 1");
- if (errors & A_ERR_MISSING_COUNTRYCODE) log_error(" ERROR: Missing country code");
- if (errors & A_ERR_MISSING_TAXID) log_error(" ERROR: Missing tax ID");
- if (errors & A_ERR_MISSING_BUSINESSID) log_error(" ERROR: Missing business ID");
- if (errors & A_ERR_MAX_ITEMS_REACHED) log_error(" ERROR: Maximum items reached");
- if (errors & A_ERR_MISSING_CODE) log_error(" ERROR: Missing code");
- if (errors & A_ERR_MISSING_EMAIL) log_error(" ERROR: Missing email");
- if (errors & A_ERR_MISSING_TAX_RATE) log_error(" ERROR: Missing tax rate");
- if (errors & A_ERR_INVALID_BILLING_ITEM) log_error(" ERROR: Invalid billing item");
-}
-
-void log_error(const char* fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- log_message(fmt, ImVec4(1,0,0,1), args);
- va_end(args);
-}
-
-void log_info(const char* fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- log_message(fmt, ImVec4(1,1,1,1), args);
- va_end(args);
-}
diff --git a/src/logger.cpp b/src/logger.cpp
new file mode 100644
index 0000000..38d17b7
--- /dev/null
+++ b/src/logger.cpp
@@ -0,0 +1,114 @@
+/*
+* Copyright (c) 2025 Aldrik Ramaekers <aldrik.ramaekers@gmail.com>
+*
+* Permission to use, copy, modify, and/or distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+#include "timer.h"
+#include "logger.hpp"
+
+namespace logger {
+
+ static logger::program_log g_log = {0};
+
+ static void log_message(const char* fmt, ImVec4 color, va_list args)
+ {
+ vsnprintf(g_log.history[g_log.write_cursor], logger::MAX_LEN_LOG_TXT, fmt, args);
+ g_log.colors[g_log.write_cursor] = color;
+
+ tick_t ms_since_epoch = timer_system();
+ char time_buf[50];
+ time_t seconds = (time_t)(ms_since_epoch / 1000);
+ int milliseconds = (int)(ms_since_epoch % 1000);
+
+ // Convert to local time
+ struct tm tm_time;
+ #if defined(_WIN32)
+ localtime_s(&tm_time, &seconds);
+ #else
+ localtime_r(&seconds, &tm_time);
+ #endif
+
+ snprintf(time_buf, 50, "%02d:%02d %02d.%03d",
+ tm_time.tm_hour,
+ tm_time.tm_min,
+ tm_time.tm_sec,
+ milliseconds);
+
+ char tmp[logger::MAX_LEN_LOG_TXT];
+ snprintf(tmp, logger::MAX_LEN_LOG_TXT, "[%s] %s", time_buf, g_log.history[g_log.write_cursor]);
+ tmp[logger::MAX_LEN_LOG_TXT-1] = 0;
+ memcpy(g_log.history[g_log.write_cursor], tmp, logger::MAX_LEN_LOG_TXT);
+
+ g_log.write_cursor++;
+ if (g_log.write_cursor >= logger::MAX_LEN_LOG_HISTORY) g_log.write_cursor = 0;
+
+ g_log.history_length++;
+ if (g_log.history_length > logger::MAX_LEN_LOG_HISTORY) g_log.history_length = logger::MAX_LEN_LOG_HISTORY;
+ }
+
+ logger::program_log* get()
+ {
+ return &g_log;
+ }
+
+ void clear()
+ {
+ g_log.write_cursor = 0;
+ g_log.history_length = 0;
+ }
+
+ void aerr(a_err errors)
+ {
+ if (errors & A_ERR_GENERIC) logger::error(" ERROR: Generic error");
+ if (errors & A_ERR_NOT_FOUND) logger::error(" ERROR: Not found");
+ if (errors & A_ERR_MISSING_DESCRIPTION) logger::error(" ERROR: Missing description");
+ if (errors & A_ERR_CODE_EXISTS) logger::error(" ERROR: Code already exists");
+ if (errors & A_ERR_MISSING_BILLING_ITEMS) logger::error(" ERROR: Missing billing items");
+ if (errors & A_ERR_INVALID_ADDRESSEE) logger::error(" ERROR: Invalid addressee");
+ if (errors & A_ERR_INVALID_CUSTOMER) logger::error(" ERROR: Invalid customer");
+ if (errors & A_ERR_INVALID_SUPPLIER) logger::error(" ERROR: Invalid supplier");
+ if (errors & A_ERR_MISSING_NAME) logger::error(" ERROR: Missing name");
+ if (errors & A_ERR_MISSING_CITY) logger::error(" ERROR: Missing city");
+ if (errors & A_ERR_MISSING_POSTAL) logger::error(" ERROR: Missing postal code");
+ if (errors & A_ERR_MISSING_ADDRESS1) logger::error(" ERROR: Missing address line 1");
+ if (errors & A_ERR_MISSING_COUNTRYCODE) logger::error(" ERROR: Missing country code");
+ if (errors & A_ERR_MISSING_TAXID) logger::error(" ERROR: Missing tax ID");
+ if (errors & A_ERR_MISSING_BUSINESSID) logger::error(" ERROR: Missing business ID");
+ if (errors & A_ERR_MAX_ITEMS_REACHED) logger::error(" ERROR: Maximum items reached");
+ if (errors & A_ERR_MISSING_CODE) logger::error(" ERROR: Missing code");
+ if (errors & A_ERR_MISSING_EMAIL) logger::error(" ERROR: Missing email");
+ if (errors & A_ERR_MISSING_TAX_RATE) logger::error(" ERROR: Missing tax rate");
+ if (errors & A_ERR_INVALID_BILLING_ITEM) logger::error(" ERROR: Invalid billing item");
+ }
+
+ void error(const char* fmt, ...)
+ {
+ va_list args;
+ va_start(args, fmt);
+ log_message(fmt, ImVec4(1,0,0,1), args);
+ va_end(args);
+ }
+
+ void info(const char* fmt, ...)
+ {
+ va_list args;
+ va_start(args, fmt);
+ log_message(fmt, ImVec4(1,1,1,1), args);
+ va_end(args);
+ }
+
+} \ No newline at end of file
diff --git a/src/strops.cpp b/src/strops.cpp
index 28f9bcc..303b64c 100644
--- a/src/strops.cpp
+++ b/src/strops.cpp
@@ -21,174 +21,178 @@
#include "strops.hpp"
-bool strops_prefix(const char *pre, const char *str)
-{
- return strncmp(pre, str, strlen(pre)) == 0;
-}
-
-size_t strops_copy(char *dst, const char *src, size_t size)
-{
- size_t srclen;
- size --;
- srclen = strlen(src);
-
- if (srclen > size)
- srclen = size;
-
- memcpy(dst, src, srclen);
- dst[srclen] = '\0';
-
- return (srclen);
-}
-
-char* strops_stristr(char* haystack, char* needle)
-{
- do {
- const char* h = haystack;
- const char* n = needle;
- while (tolower((unsigned char) *h) == tolower((unsigned char ) *n) && *n) {
- h++;
- n++;
+namespace strops {
+
+ bool prefix(const char *pre, const char *str)
+ {
+ return strncmp(pre, str, strlen(pre)) == 0;
}
- if (*n == 0) {
- return (char *) haystack;
+
+ size_t copy(char *dst, const char *src, size_t size)
+ {
+ size_t srclen;
+ size --;
+ srclen = strlen(src);
+
+ if (srclen > size)
+ srclen = size;
+
+ memcpy(dst, src, srclen);
+ dst[srclen] = '\0';
+
+ return (srclen);
+ }
+
+ char* contains(char* haystack, char* needle)
+ {
+ do {
+ const char* h = haystack;
+ const char* n = needle;
+ while (tolower((unsigned char) *h) == tolower((unsigned char ) *n) && *n) {
+ h++;
+ n++;
+ }
+ if (*n == 0) {
+ return (char *) haystack;
+ }
+ } while (*haystack++);
+ return 0;
}
- } while (*haystack++);
- return 0;
-}
-
-void strops_replace(char *buf, size_t buf_size, const char *search, const char *replace)
-{
- size_t search_len = strlen(search);
- size_t replace_len = strlen(replace);
-
- char *r = buf; // read pointer
- char *w = buf; // write pointer
-
- while (*r && (w - buf) < (signed int)(buf_size - 1)) {
- if (strncmp(r, search, search_len) == 0) {
- // Ensure space
- size_t remaining = buf_size - (w - buf) - 1;
- size_t copy_len = (replace_len < remaining) ? replace_len : remaining;
- size_t skip_size = search_len;
-
- if (replace_len > search_len)
- {
- memmove(w+replace_len, w+search_len, remaining - replace_len);
- skip_size = replace_len;
- }
- memcpy(w, replace, copy_len);
- w += copy_len;
- r += skip_size;
- } else {
- *w++ = *r++;
+ void replace(char *buf, size_t buf_size, const char *search, const char *replace)
+ {
+ size_t search_len = strlen(search);
+ size_t replace_len = strlen(replace);
+
+ char *r = buf; // read pointer
+ char *w = buf; // write pointer
+
+ while (*r && (w - buf) < (signed int)(buf_size - 1)) {
+ if (strncmp(r, search, search_len) == 0) {
+ // Ensure space
+ size_t remaining = buf_size - (w - buf) - 1;
+ size_t copy_len = (replace_len < remaining) ? replace_len : remaining;
+ size_t skip_size = search_len;
+
+ if (replace_len > search_len)
+ {
+ memmove(w+replace_len, w+search_len, remaining - replace_len);
+ skip_size = replace_len;
+ }
+
+ memcpy(w, replace, copy_len);
+ w += copy_len;
+ r += skip_size;
+ } else {
+ *w++ = *r++;
+ }
}
+
+ *w = '\0'; // terminate
}
- *w = '\0'; // terminate
-}
-
-void strops_replace_int32(char *buf, size_t buf_size, const char *search, int32_t number)
-{
- char num_buf[200];
- snprintf(num_buf, 200, "%d", number);
- strops_replace(buf, buf_size, search, num_buf);
-}
-
-void strops_replace_int64(char *buf, size_t buf_size, const char *search, int64_t number)
-{
- char num_buf[200];
- snprintf(num_buf, 200, "%lld", number);
- strops_replace(buf, buf_size, search, num_buf);
-}
-
-void strops_replace_float(char *buf, size_t buf_size, const char *search, float number, int decimals)
-{
- char num_buf[200];
- snprintf(num_buf, 200, "%.*f", decimals, number);
- strops_replace(buf, buf_size, search, num_buf);
-}
-
-char* strops_get_json_value(const char *json, const char *key, char *out, size_t out_size, int skip)
-{
- char pattern[128];
- snprintf(pattern, sizeof(pattern), "\"%s\"", key);
- const char *pos = strstr(json, pattern);
- while(skip > 0) {
- pos = strstr(pos+1, pattern);
- skip--;
+ void replace_int32(char *buf, size_t buf_size, const char *search, int32_t number)
+ {
+ char num_buf[200];
+ snprintf(num_buf, 200, "%d", number);
+ strops::replace(buf, buf_size, search, num_buf);
}
- if (!pos) return NULL;
- pos = strchr(pos, ':');
- if (!pos) return NULL;
- pos++;
- // Skip whitespace and quotes
- while (*pos == ' ' || *pos == '\"') pos++;
+ void replace_int64(char *buf, size_t buf_size, const char *search, int64_t number)
+ {
+ char num_buf[200];
+ snprintf(num_buf, 200, "%lld", number);
+ strops::replace(buf, buf_size, search, num_buf);
+ }
- size_t i = 0;
- while (*pos && !(*pos == '\"' && *(pos-1) != '\\') && i < out_size - 1) {
- out[i++] = *pos++;
+ void replace_float(char *buf, size_t buf_size, const char *search, float number, int decimals)
+ {
+ char num_buf[200];
+ snprintf(num_buf, 200, "%.*f", decimals, number);
+ strops::replace(buf, buf_size, search, num_buf);
}
- out[i] = '\0';
- return out;
-}
-
-char* strops_get_filename(const char* path)
-{
- char* filename = (char*)strrchr(path, '/'); // for Unix-style paths
- if (filename) return filename + 1; // skip the '/'
- filename = (char*)strrchr(path, '\\'); // for Windows-style paths
- if (filename) return filename + 1;
- return (char*)path; // no slashes found, path itself is filename
-}
-
-char* strops_prep_str_for_json(const char *input, size_t buffer_size)
-{
- if (!input) return NULL;
-
- char *result = (char*)malloc(buffer_size * 2 + 1);
- if (!result) return NULL;
-
- const char *src = input;
- char *dst = result;
-
- while (*src) {
- if (*src == '"') {
- *dst++ = '\\';
- *dst++ = '"';
- }
- else if (*src == '\n') {
- // empty
+
+ char* get_json_value(const char *json, const char *key, char *out, size_t out_size, int skip)
+ {
+ char pattern[128];
+ snprintf(pattern, sizeof(pattern), "\"%s\"", key);
+ const char *pos = strstr(json, pattern);
+ while(skip > 0) {
+ pos = strstr(pos+1, pattern);
+ skip--;
}
- else {
- *dst++ = *src;
+ if (!pos) return NULL;
+ pos = strchr(pos, ':');
+ if (!pos) return NULL;
+ pos++;
+
+ // Skip whitespace and quotes
+ while (*pos == ' ' || *pos == '\"') pos++;
+
+ size_t i = 0;
+ while (*pos && !(*pos == '\"' && *(pos-1) != '\\') && i < out_size - 1) {
+ out[i++] = *pos++;
}
- src++;
+ out[i] = '\0';
+ return out;
+ }
+
+ char* get_filename(const char* path)
+ {
+ char* filename = (char*)strrchr(path, '/'); // for Unix-style paths
+ if (filename) return filename + 1; // skip the '/'
+ filename = (char*)strrchr(path, '\\'); // for Windows-style paths
+ if (filename) return filename + 1;
+ return (char*)path; // no slashes found, path itself is filename
}
- *dst = '\0';
- return result;
-}
+ char* prep_str_for_json(const char *input, size_t buffer_size)
+ {
+ if (!input) return NULL;
-char* strops_unprep_str_from_json(char *input)
-{
- if (!input) return NULL;
+ char *result = (char*)malloc(buffer_size * 2 + 1);
+ if (!result) return NULL;
- char *src = input;
- char *dst = input;
+ const char *src = input;
+ char *dst = result;
- while (*src) {
- if (*src == '\\' && *(src+1) == '"') {
+ while (*src) {
+ if (*src == '"') {
+ *dst++ = '\\';
+ *dst++ = '"';
+ }
+ else if (*src == '\n') {
+ // empty
+ }
+ else {
+ *dst++ = *src;
+ }
src++;
}
- else if (*src == '\\' && *(src+1) == 'n') {
- src++;src++;
- }
- *dst++ = *src++;
+ *dst = '\0';
+
+ return result;
+ }
+
+ char* unprep_str_from_json(char *input)
+ {
+ if (!input) return NULL;
+
+ char *src = input;
+ char *dst = input;
+
+ while (*src) {
+ if (*src == '\\' && *(src+1) == '"') {
+ src++;
+ }
+ else if (*src == '\\' && *(src+1) == 'n') {
+ src++;src++;
+ }
+ *dst++ = *src++;
+ }
+ *dst = '\0';
+
+ return input;
}
- *dst = '\0';
- return input;
} \ No newline at end of file
diff --git a/src/ui/helpers.cpp b/src/ui/helpers.cpp
index 2447270..19eeee3 100644
--- a/src/ui/helpers.cpp
+++ b/src/ui/helpers.cpp
@@ -69,7 +69,7 @@ void ui_set_status_ex(const char* txt, int color)
current_status.time = 0.0f;
current_status.color = color;
current_status.loading = false;
- strops_copy(current_status.text, txt, STATUS_TEXT_LEN);
+ strops::copy(current_status.text, txt, STATUS_TEXT_LEN);
}
void ui_set_status_error(const char* txt)
diff --git a/src/ui/imgui_extensions.cpp b/src/ui/imgui_extensions.cpp
index 8c8f4c4..a283ad4 100644
--- a/src/ui/imgui_extensions.cpp
+++ b/src/ui/imgui_extensions.cpp
@@ -61,7 +61,7 @@ namespace ImGui
0); // allowMultiple (0 = single)
if (file)
{
- strops_copy(buffer, file, MAX_LEN_PATH);
+ strops::copy(buffer, file, MAX_LEN_PATH);
buffer[MAX_LEN_PATH-1] = '\0';
result = true;
}
@@ -136,7 +136,7 @@ namespace ImGui
}
if (selected_country_index != -1) {
- strops_copy(buffer, config::country_codes[selected_country_index], buf_size);
+ strops::copy(buffer, config::country_codes[selected_country_index], buf_size);
}
}
@@ -201,7 +201,7 @@ namespace ImGui
if (ImGui::Selectable(suggestions[i]))
{
// Copy selected suggestion to buffer
- strops_copy(buffer, suggestions[i], buf_size);
+ strops::copy(buffer, suggestions[i], buf_size);
buffer[buf_size - 1] = '\0';
result = i;
is_open = false;
@@ -279,7 +279,7 @@ namespace ImGui
}
if (selected_costcenter_index != -1) {
- strops_copy(costcenter_id, buffer[selected_costcenter_index].id, MAX_LEN_ID);
+ strops::copy(costcenter_id, buffer[selected_costcenter_index].id, MAX_LEN_ID);
}
free(buffer);
@@ -320,7 +320,7 @@ namespace ImGui
}
if (selected_project_index != -1) {
- strops_copy(project_id, buffer[selected_project_index].id, MAX_LEN_ID);
+ strops::copy(project_id, buffer[selected_project_index].id, MAX_LEN_ID);
}
free(buffer);
@@ -392,7 +392,7 @@ namespace ImGui
}
if (selected_tax_rate_index != -1) {
- strops_copy(tax_rate_id, buffer[selected_tax_rate_index].id, MAX_LEN_ID);
+ strops::copy(tax_rate_id, buffer[selected_tax_rate_index].id, MAX_LEN_ID);
}
free(buffer);
@@ -441,7 +441,7 @@ namespace ImGui
if (ImGui::Selectable(currencies[n], isSelected))
{
result = true;
- strops_copy(currency, currencies[n], MAX_LEN_CURRENCY);
+ strops::copy(currency, currencies[n], MAX_LEN_CURRENCY);
}
if (isSelected)
diff --git a/src/ui/ui_log.cpp b/src/ui/ui_log.cpp
index fa56f4a..48eaf1c 100644
--- a/src/ui/ui_log.cpp
+++ b/src/ui/ui_log.cpp
@@ -18,18 +18,18 @@
#include "ui.hpp"
#include "imgui.h"
-#include "log.hpp"
+#include "logger.hpp"
#include "locales.hpp"
void ui_draw_log()
{
- program_log* l = get_log();
+ logger::program_log* l = logger::get();
for (int i = (int)l->history_length-1; i >= 0; i--)
{
s32 cursor = l->write_cursor - l->history_length + i;
if (cursor < 0) {
- cursor = (l->write_cursor + i) % MAX_LEN_LOG_HISTORY;
+ cursor = (l->write_cursor + i) % logger::MAX_LEN_LOG_HISTORY;
}
ImGui::TextColored(l->colors[cursor], l->history[cursor]);
}
diff --git a/src/ui/ui_settings.cpp b/src/ui/ui_settings.cpp
index 79d65da..e497615 100644
--- a/src/ui/ui_settings.cpp
+++ b/src/ui/ui_settings.cpp
@@ -85,13 +85,13 @@ static void ui_draw_vat_rates()
// Check for fixed rates shared accross countries.
if (strcmp(c.country_code, "00") == 0)
{
- strops_copy(prev_country, c.country_code, 3);
+ strops::copy(prev_country, c.country_code, 3);
can_be_modified = false;
}
// Generate headers per country.
else if (strcmp(c.country_code, prev_country) != 0)
{
- strops_copy(prev_country, c.country_code, 3);
+ strops::copy(prev_country, c.country_code, 3);
// Empty row.
ImGui::TableNextRow();
@@ -118,7 +118,7 @@ static void ui_draw_vat_rates()
is_adding_item = true;
is_editing_item = false;
new_tax_rate = administration_tax_rate_create_empty();
- strops_copy(new_tax_rate.country_code, c.country_code, 3);
+ strops::copy(new_tax_rate.country_code, c.country_code, 3);
}
ImGui::PopStyleVar();
}
diff --git a/tests/administration_rw_tests.cpp b/tests/administration_rw_tests.cpp
index 375fe0a..0bea1ce 100644
--- a/tests/administration_rw_tests.cpp
+++ b/tests/administration_rw_tests.cpp
@@ -26,9 +26,9 @@ TEST _administration_rw_taxrate(void)
administration_create_empty(test_file_path);
{
pw = administration_tax_rate_create_empty();
- strops_copy(pw.country_code, "NL", sizeof(pw.country_code));
+ strops::copy(pw.country_code, "NL", sizeof(pw.country_code));
pw.rate = 10.0f;
- strops_copy(pw.category_code, "S", sizeof(pw.category_code));
+ strops::copy(pw.category_code, "S", sizeof(pw.category_code));
count = administration_tax_rate_count();
administration_tax_rate_add(pw);
@@ -57,8 +57,8 @@ TEST _administration_rw_costcenter(void)
administration_create_empty(test_file_path);
{
pw = administration_cost_center_create_empty();
- strops_copy(pw.code, "CODE", sizeof(pw.code));
- strops_copy(pw.description, "Description", sizeof(pw.description));
+ strops::copy(pw.code, "CODE", sizeof(pw.code));
+ strops::copy(pw.description, "Description", sizeof(pw.description));
count = administration_cost_center_count();
administration_cost_center_add(pw);
@@ -87,7 +87,7 @@ TEST _administration_rw_project(void)
administration_create_empty(test_file_path);
{
pw = administration_project_create_empty();
- strops_copy(pw.description, "Test Project", sizeof(pw.description));
+ strops::copy(pw.description, "Test Project", sizeof(pw.description));
count = administration_project_count();
administration_project_add(pw);
@@ -115,12 +115,12 @@ TEST _administration_rw_contact(void)
administration_create_empty(test_file_path);
{
pw = administration_contact_create_empty();
- strops_copy(pw.name, "John Johnsson", sizeof(pw.name));
- strops_copy(pw.address.address1, "Address 1", sizeof(pw.address.address1));
- strops_copy(pw.address.country_code, "FR", sizeof(pw.address.country_code));
- strops_copy(pw.address.city, "Paris", sizeof(pw.address.city));
- strops_copy(pw.address.postal, "12345", sizeof(pw.address.postal));
- strops_copy(pw.email, "test@test.com", sizeof(pw.email));
+ strops::copy(pw.name, "John Johnsson", sizeof(pw.name));
+ strops::copy(pw.address.address1, "Address 1", sizeof(pw.address.address1));
+ strops::copy(pw.address.country_code, "FR", sizeof(pw.address.country_code));
+ strops::copy(pw.address.city, "Paris", sizeof(pw.address.city));
+ strops::copy(pw.address.postal, "12345", sizeof(pw.address.postal));
+ strops::copy(pw.email, "test@test.com", sizeof(pw.email));
pw.type = contact_type::CONTACT_CONSUMER;
count = administration_contact_count();
@@ -152,7 +152,7 @@ TEST _administration_rw_info(void)
ai_service ss = {0};
ss.provider = AI_PROVIDER_OPENAI;
- strops_copy(ss.api_key_public, "123", sizeof(ss.api_key_public));
+ strops::copy(ss.api_key_public, "123", sizeof(ss.api_key_public));
administration_set_ai_service(ss);
ais = administration_get_ai_service();
@@ -327,7 +327,7 @@ TEST _administration_rw_b2b2c_invoice(void)
inv = administration_invoice_create_empty();
inv.supplier = _create_nl_business();
inv.customer = _create_nl_business();
- strops_copy(inv.addressee.name, "Piet Pinda", sizeof(inv.addressee.name));
+ strops::copy(inv.addressee.name, "Piet Pinda", sizeof(inv.addressee.name));
inv.addressee.address = _create_nl_consumer().address;
inv.is_triangulation = 1;
inv.is_outgoing = 1;
diff --git a/tests/administration_validation_tests.cpp b/tests/administration_validation_tests.cpp
index f406efd..3803469 100644
--- a/tests/administration_validation_tests.cpp
+++ b/tests/administration_validation_tests.cpp
@@ -8,7 +8,7 @@ TEST _administration_validate_project_add(void)
ASSERT_EQ(administration_project_add(p1), A_ERR_MISSING_DESCRIPTION);
- strops_copy(p1.description, "test project", sizeof(p1.description));
+ strops::copy(p1.description, "test project", sizeof(p1.description));
ASSERT_EQ(administration_project_add(p1), A_ERR_SUCCESS);
PASS();
@@ -21,7 +21,7 @@ TEST _administration_validate_project_import(void)
ASSERT_EQ(administration_project_import(p1), A_ERR_MISSING_DESCRIPTION);
- strops_copy(p1.description, "test project", sizeof(p1.description));
+ strops::copy(p1.description, "test project", sizeof(p1.description));
ASSERT_EQ(administration_project_import(p1), A_ERR_SUCCESS);
PASS();
@@ -33,15 +33,15 @@ TEST _administration_validate_project_update(void)
administration_create_empty("");
project p1 = administration_project_create_empty();
- strops_copy(p1.description, "test project", sizeof(p1.description));
+ strops::copy(p1.description, "test project", sizeof(p1.description));
ASSERT_EQ(administration_project_add(p1), A_ERR_SUCCESS);
ASSERT_EQ(administration_project_update(p1), A_ERR_SUCCESS);
- strops_copy(p1.description, "", sizeof(p1.description));
+ strops::copy(p1.description, "", sizeof(p1.description));
ASSERT_EQ(administration_project_update(p1), A_ERR_MISSING_DESCRIPTION);
- strops_copy(p1.id, "-1", sizeof(p1.id));
- strops_copy(p1.description, "test project 2", sizeof(p1.description));
+ strops::copy(p1.id, "-1", sizeof(p1.id));
+ strops::copy(p1.description, "test project 2", sizeof(p1.description));
ASSERT_EQ(administration_project_update(p1), A_ERR_NOT_FOUND);
PASS();
@@ -52,13 +52,13 @@ TEST _administration_validate_project_remove(void)
administration_create_empty("");
project p1 = administration_project_create_empty();
- strops_copy(p1.description, "test project", sizeof(p1.description));
+ strops::copy(p1.description, "test project", sizeof(p1.description));
ASSERT_EQ(administration_project_add(p1), A_ERR_SUCCESS);
ASSERT_EQ(administration_project_remove(p1), A_ERR_SUCCESS);
ASSERT_EQ(administration_project_add(p1), A_ERR_SUCCESS);
- strops_copy(p1.id, "-1", sizeof(p1.id));
+ strops::copy(p1.id, "-1", sizeof(p1.id));
ASSERT_EQ(administration_project_remove(p1), A_ERR_NOT_FOUND);
PASS();
@@ -71,7 +71,7 @@ TEST _administration_validate_project_isvalid(void)
ASSERT_EQ(administration_project_is_valid(p1), A_ERR_MISSING_DESCRIPTION);
- strops_copy(p1.description, "test project", sizeof(p1.description));
+ strops::copy(p1.description, "test project", sizeof(p1.description));
ASSERT_EQ(administration_project_is_valid(p1), A_ERR_SUCCESS);
PASS();
@@ -108,7 +108,7 @@ TEST _administration_validate_taxrate_update(void)
ASSERT_EQ(administration_tax_rate_add(p1), A_ERR_SUCCESS);
ASSERT_EQ(administration_tax_rate_update(p1), A_ERR_SUCCESS);
- strops_copy(p1.id, "-1", sizeof(p1.id));
+ strops::copy(p1.id, "-1", sizeof(p1.id));
ASSERT_EQ(administration_tax_rate_update(p1), A_ERR_NOT_FOUND);
PASS();
@@ -120,14 +120,14 @@ TEST _administration_validate_costcenter_add(void)
{
administration_create_empty("");
cost_center p1 = administration_cost_center_create_empty();
- strops_copy(p1.code, "TEST", sizeof(p1.code));
- strops_copy(p1.description, "description", sizeof(p1.description));
+ strops::copy(p1.code, "TEST", sizeof(p1.code));
+ strops::copy(p1.description, "description", sizeof(p1.description));
ASSERT_EQ(administration_cost_center_add(p1), A_ERR_SUCCESS);
ASSERT_EQ(administration_cost_center_add(p1), A_ERR_CODE_EXISTS);
- strops_copy(p1.code, "", sizeof(p1.code));
+ strops::copy(p1.code, "", sizeof(p1.code));
ASSERT_EQ(administration_cost_center_add(p1), A_ERR_MISSING_CODE);
- strops_copy(p1.description, "", sizeof(p1.description));
+ strops::copy(p1.description, "", sizeof(p1.description));
ASSERT_EQ(administration_cost_center_add(p1), A_ERR_MISSING_CODE|A_ERR_MISSING_DESCRIPTION);
PASS();
@@ -137,14 +137,14 @@ TEST _administration_validate_costcenter_import(void)
{
administration_create_empty("");
cost_center p1 = administration_cost_center_create_empty();
- strops_copy(p1.code, "TEST", sizeof(p1.code));
- strops_copy(p1.description, "description", sizeof(p1.description));
+ strops::copy(p1.code, "TEST", sizeof(p1.code));
+ strops::copy(p1.description, "description", sizeof(p1.description));
ASSERT_EQ(administration_cost_center_import(p1), A_ERR_SUCCESS);
ASSERT_EQ(administration_cost_center_import(p1), A_ERR_CODE_EXISTS);
- strops_copy(p1.code, "", sizeof(p1.code));
+ strops::copy(p1.code, "", sizeof(p1.code));
ASSERT_EQ(administration_cost_center_import(p1), A_ERR_MISSING_CODE);
- strops_copy(p1.description, "", sizeof(p1.description));
+ strops::copy(p1.description, "", sizeof(p1.description));
ASSERT_EQ(administration_cost_center_import(p1), A_ERR_MISSING_CODE|A_ERR_MISSING_DESCRIPTION);
PASS();
@@ -155,19 +155,19 @@ TEST _administration_validate_costcenter_update(void)
{
administration_create_empty("");
cost_center p1 = administration_cost_center_create_empty();
- strops_copy(p1.code, "TEST", sizeof(p1.code));
- strops_copy(p1.description, "description", sizeof(p1.description));
+ strops::copy(p1.code, "TEST", sizeof(p1.code));
+ strops::copy(p1.description, "description", sizeof(p1.description));
ASSERT_EQ(administration_cost_center_add(p1), A_ERR_SUCCESS);
ASSERT_EQ(administration_cost_center_update(p1), A_ERR_SUCCESS);
- strops_copy(p1.code, "", sizeof(p1.code));
+ strops::copy(p1.code, "", sizeof(p1.code));
ASSERT_EQ(administration_cost_center_update(p1), A_ERR_MISSING_CODE);
- strops_copy(p1.description, "", sizeof(p1.description));
+ strops::copy(p1.description, "", sizeof(p1.description));
ASSERT_EQ(administration_cost_center_update(p1), A_ERR_MISSING_CODE|A_ERR_MISSING_DESCRIPTION);
- strops_copy(p1.id, "-1", sizeof(p1.id));
- strops_copy(p1.code, "TEST", sizeof(p1.code));
- strops_copy(p1.description, "description", sizeof(p1.description));
+ strops::copy(p1.id, "-1", sizeof(p1.id));
+ strops::copy(p1.code, "TEST", sizeof(p1.code));
+ strops::copy(p1.description, "description", sizeof(p1.description));
ASSERT_EQ(administration_cost_center_update(p1), A_ERR_NOT_FOUND);
PASS();
@@ -177,20 +177,20 @@ TEST _administration_validate_costcenter_isvalid(void)
{
administration_create_empty("");
cost_center p1 = administration_cost_center_create_empty();
- strops_copy(p1.code, "TEST", sizeof(p1.code));
- strops_copy(p1.description, "description", sizeof(p1.description));
+ strops::copy(p1.code, "TEST", sizeof(p1.code));
+ strops::copy(p1.description, "description", sizeof(p1.description));
ASSERT_EQ(administration_cost_center_is_valid(p1), A_ERR_SUCCESS);
- strops_copy(p1.code, "", sizeof(p1.code));
+ strops::copy(p1.code, "", sizeof(p1.code));
ASSERT_EQ(administration_cost_center_is_valid(p1), A_ERR_MISSING_CODE);
- strops_copy(p1.code, "", sizeof(p1.code));
- strops_copy(p1.description, "", sizeof(p1.description));
+ strops::copy(p1.code, "", sizeof(p1.code));
+ strops::copy(p1.description, "", sizeof(p1.description));
ASSERT_EQ(administration_cost_center_is_valid(p1), A_ERR_MISSING_CODE|A_ERR_MISSING_DESCRIPTION);
- strops_copy(p1.code, "TEST", sizeof(p1.code));
- strops_copy(p1.description, "description", sizeof(p1.description));
+ strops::copy(p1.code, "TEST", sizeof(p1.code));
+ strops::copy(p1.description, "description", sizeof(p1.description));
ASSERT_EQ(administration_cost_center_add(p1), A_ERR_SUCCESS);
ASSERT_EQ(administration_cost_center_is_valid(p1), A_ERR_CODE_EXISTS);
@@ -203,12 +203,12 @@ TEST _administration_validate_costcenter_isvalid(void)
contact _create_test_contact()
{
contact p1 = administration_contact_create_empty();
- strops_copy(p1.name, "John Johnsson", sizeof(p1.name));
- strops_copy(p1.address.address1, "Address 1", sizeof(p1.address.address1));
- strops_copy(p1.address.country_code, "FR", sizeof(p1.address.country_code));
- strops_copy(p1.address.city, "Paris", sizeof(p1.address.city));
- strops_copy(p1.address.postal, "12345", sizeof(p1.address.postal));
- strops_copy(p1.email, "test@test.com", sizeof(p1.email));
+ strops::copy(p1.name, "John Johnsson", sizeof(p1.name));
+ strops::copy(p1.address.address1, "Address 1", sizeof(p1.address.address1));
+ strops::copy(p1.address.country_code, "FR", sizeof(p1.address.country_code));
+ strops::copy(p1.address.city, "Paris", sizeof(p1.address.city));
+ strops::copy(p1.address.postal, "12345", sizeof(p1.address.postal));
+ strops::copy(p1.email, "test@test.com", sizeof(p1.email));
p1.type = contact_type::CONTACT_CONSUMER;
return p1;
}
@@ -220,15 +220,15 @@ TEST _administration_validate_contact_add(void)
ASSERT_EQ(administration_contact_add(p1), A_ERR_SUCCESS);
- strops_copy(p1.name, "", sizeof(p1.name));
+ strops::copy(p1.name, "", sizeof(p1.name));
ASSERT_EQ(administration_contact_add(p1), A_ERR_MISSING_NAME);
- strops_copy(p1.address.address1, "", sizeof(p1.address.address1));
+ strops::copy(p1.address.address1, "", sizeof(p1.address.address1));
ASSERT_EQ(administration_contact_add(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1);
- strops_copy(p1.address.city, "", sizeof(p1.address.city));
+ strops::copy(p1.address.city, "", sizeof(p1.address.city));
ASSERT_EQ(administration_contact_add(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY);
- strops_copy(p1.address.postal, "", sizeof(p1.address.postal));
+ strops::copy(p1.address.postal, "", sizeof(p1.address.postal));
ASSERT_EQ(administration_contact_add(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY|A_ERR_MISSING_POSTAL);
- strops_copy(p1.address.country_code, "", sizeof(p1.address.country_code));
+ strops::copy(p1.address.country_code, "", sizeof(p1.address.country_code));
ASSERT_EQ(administration_contact_add(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY|A_ERR_MISSING_POSTAL|A_ERR_MISSING_COUNTRYCODE);
p1.type = contact_type::CONTACT_BUSINESS;
@@ -246,15 +246,15 @@ TEST _administration_validate_contact_import(void)
ASSERT_EQ(administration_contact_import(p1), A_ERR_SUCCESS);
- strops_copy(p1.name, "", sizeof(p1.name));
+ strops::copy(p1.name, "", sizeof(p1.name));
ASSERT_EQ(administration_contact_import(p1), A_ERR_MISSING_NAME);
- strops_copy(p1.address.address1, "", sizeof(p1.address.address1));
+ strops::copy(p1.address.address1, "", sizeof(p1.address.address1));
ASSERT_EQ(administration_contact_import(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1);
- strops_copy(p1.address.city, "", sizeof(p1.address.city));
+ strops::copy(p1.address.city, "", sizeof(p1.address.city));
ASSERT_EQ(administration_contact_import(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY);
- strops_copy(p1.address.postal, "", sizeof(p1.address.postal));
+ strops::copy(p1.address.postal, "", sizeof(p1.address.postal));
ASSERT_EQ(administration_contact_import(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY|A_ERR_MISSING_POSTAL);
- strops_copy(p1.address.country_code, "", sizeof(p1.address.country_code));
+ strops::copy(p1.address.country_code, "", sizeof(p1.address.country_code));
ASSERT_EQ(administration_contact_import(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY|A_ERR_MISSING_POSTAL|A_ERR_MISSING_COUNTRYCODE);
p1.type = contact_type::CONTACT_BUSINESS;
@@ -273,27 +273,27 @@ TEST _administration_validate_contact_update(void)
ASSERT_EQ(administration_contact_add(p1), A_ERR_SUCCESS);
ASSERT_EQ(administration_contact_update(p1), A_ERR_SUCCESS);
- strops_copy(p1.name, "", sizeof(p1.name));
+ strops::copy(p1.name, "", sizeof(p1.name));
ASSERT_EQ(administration_contact_update(p1), A_ERR_MISSING_NAME);
- strops_copy(p1.address.address1, "", sizeof(p1.address.address1));
+ strops::copy(p1.address.address1, "", sizeof(p1.address.address1));
ASSERT_EQ(administration_contact_update(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1);
- strops_copy(p1.address.city, "", sizeof(p1.address.city));
+ strops::copy(p1.address.city, "", sizeof(p1.address.city));
ASSERT_EQ(administration_contact_update(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY);
- strops_copy(p1.address.postal, "", sizeof(p1.address.postal));
+ strops::copy(p1.address.postal, "", sizeof(p1.address.postal));
ASSERT_EQ(administration_contact_update(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY|A_ERR_MISSING_POSTAL);
- strops_copy(p1.address.country_code, "", sizeof(p1.address.country_code));
+ strops::copy(p1.address.country_code, "", sizeof(p1.address.country_code));
ASSERT_EQ(administration_contact_update(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY|A_ERR_MISSING_POSTAL|A_ERR_MISSING_COUNTRYCODE);
p1.type = contact_type::CONTACT_BUSINESS;
ASSERT_EQ(administration_contact_update(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY|
A_ERR_MISSING_POSTAL|A_ERR_MISSING_COUNTRYCODE|A_ERR_MISSING_TAXID|A_ERR_MISSING_BUSINESSID);
- strops_copy(p1.id, "-1", sizeof(p1.id));
- strops_copy(p1.name, "John Johnsson", sizeof(p1.name));
- strops_copy(p1.address.address1, "Address 1", sizeof(p1.address.address1));
- strops_copy(p1.address.country_code, "FR", sizeof(p1.address.country_code));
- strops_copy(p1.address.city, "Paris", sizeof(p1.address.city));
- strops_copy(p1.address.postal, "12345", sizeof(p1.address.postal));
+ strops::copy(p1.id, "-1", sizeof(p1.id));
+ strops::copy(p1.name, "John Johnsson", sizeof(p1.name));
+ strops::copy(p1.address.address1, "Address 1", sizeof(p1.address.address1));
+ strops::copy(p1.address.country_code, "FR", sizeof(p1.address.country_code));
+ strops::copy(p1.address.city, "Paris", sizeof(p1.address.city));
+ strops::copy(p1.address.postal, "12345", sizeof(p1.address.postal));
p1.type = contact_type::CONTACT_CONSUMER;
ASSERT_EQ(administration_contact_update(p1), A_ERR_NOT_FOUND);
@@ -310,7 +310,7 @@ TEST _administration_validate_contact_remove(void)
ASSERT_EQ(administration_contact_remove(p1), A_ERR_SUCCESS);
ASSERT_EQ(administration_contact_add(p1), A_ERR_SUCCESS);
- strops_copy(p1.id, "-1", sizeof(p1.id));
+ strops::copy(p1.id, "-1", sizeof(p1.id));
ASSERT_EQ(administration_contact_remove(p1), A_ERR_NOT_FOUND);
PASS();
@@ -324,15 +324,15 @@ TEST _administration_validate_contact_isvalid(void)
ASSERT_EQ(administration_contact_is_valid(p1), A_ERR_SUCCESS);
ASSERT_EQ(administration_contact_is_valid(p1), A_ERR_SUCCESS);
- strops_copy(p1.name, "", sizeof(p1.name));
+ strops::copy(p1.name, "", sizeof(p1.name));
ASSERT_EQ(administration_contact_is_valid(p1), A_ERR_MISSING_NAME);
- strops_copy(p1.address.address1, "", sizeof(p1.address.address1));
+ strops::copy(p1.address.address1, "", sizeof(p1.address.address1));
ASSERT_EQ(administration_contact_is_valid(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1);
- strops_copy(p1.address.city, "", sizeof(p1.address.city));
+ strops::copy(p1.address.city, "", sizeof(p1.address.city));
ASSERT_EQ(administration_contact_is_valid(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY);
- strops_copy(p1.address.postal, "", sizeof(p1.address.postal));
+ strops::copy(p1.address.postal, "", sizeof(p1.address.postal));
ASSERT_EQ(administration_contact_is_valid(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY|A_ERR_MISSING_POSTAL);
- strops_copy(p1.address.country_code, "", sizeof(p1.address.country_code));
+ strops::copy(p1.address.country_code, "", sizeof(p1.address.country_code));
ASSERT_EQ(administration_contact_is_valid(p1), A_ERR_MISSING_NAME|A_ERR_MISSING_ADDRESS1|A_ERR_MISSING_CITY|A_ERR_MISSING_POSTAL|A_ERR_MISSING_COUNTRYCODE);
p1.type = contact_type::CONTACT_BUSINESS;
diff --git a/tests/test_helper.cpp b/tests/test_helper.cpp
index aedaccc..38aa655 100644
--- a/tests/test_helper.cpp
+++ b/tests/test_helper.cpp
@@ -22,17 +22,17 @@ 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));
+ 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;
}
@@ -40,14 +40,14 @@ static contact _create_nl_business()
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));
+ 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;
}
@@ -58,7 +58,7 @@ static billing_item _create_bi1(invoice *inv)
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);
+ strops::copy(item.description, "Shampoo", MAX_LEN_LONG_DESC);
item.net_per_item = 10.00f;
item.discount = 2.0f;
item.discount_is_percentage = 0;
@@ -67,7 +67,7 @@ static billing_item _create_bi1(invoice *inv)
char* _country_codes[2] = {inv->supplier.address.country_code, inv->customer.address.country_code};
u32 tax_rate_count = administration_tax_rate_get_by_country(buffer, 2, _country_codes);
tax_rate rand_rate = buffer[tax_rate_count-1];
- strops_copy(item.tax_rate_id, rand_rate.id, MAX_LEN_ID);
+ strops::copy(item.tax_rate_id, rand_rate.id, MAX_LEN_ID);
return item;
}
@@ -77,7 +77,7 @@ static billing_item _create_bi2(invoice *inv)
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);
+ strops::copy(item.description, "Soap", MAX_LEN_LONG_DESC);
item.net_per_item = 5.00f;
item.discount = 5.0f;
item.discount_is_percentage = 1;
@@ -86,7 +86,7 @@ static billing_item _create_bi2(invoice *inv)
char* _country_codes[2] = {inv->supplier.address.country_code, inv->customer.address.country_code};
u32 tax_rate_count = administration_tax_rate_get_by_country(buffer, 2, _country_codes);
tax_rate rand_rate = buffer[tax_rate_count-1];
- strops_copy(item.tax_rate_id, rand_rate.id, MAX_LEN_ID);
+ strops::copy(item.tax_rate_id, rand_rate.id, MAX_LEN_ID);
return item;
}
@@ -96,7 +96,7 @@ static billing_item _create_bi3(invoice *inv)
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);
+ strops::copy(item.description, "Guacamole", MAX_LEN_LONG_DESC);
item.net_per_item = 10.00f;
item.discount = 2.0f;
item.discount_is_percentage = 0;
@@ -105,7 +105,7 @@ static billing_item _create_bi3(invoice *inv)
char* _country_codes[2] = {inv->supplier.address.country_code, inv->customer.address.country_code};
u32 tax_rate_count = administration_tax_rate_get_by_country(buffer, 2, _country_codes);
tax_rate rand_rate = buffer[tax_rate_count-1];
- strops_copy(item.tax_rate_id, rand_rate.id, MAX_LEN_ID);
+ strops::copy(item.tax_rate_id, rand_rate.id, MAX_LEN_ID);
return item;
}
@@ -115,7 +115,7 @@ static billing_item _create_bi4(invoice *inv)
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);
+ strops::copy(item.description, "Bananas", MAX_LEN_LONG_DESC);
item.net_per_item = 4.00f;
item.discount = 0.0f;
item.discount_is_percentage = 0;
@@ -124,7 +124,7 @@ static billing_item _create_bi4(invoice *inv)
char* _country_codes[2] = {inv->supplier.address.country_code, inv->customer.address.country_code};
u32 tax_rate_count = administration_tax_rate_get_by_country(buffer, 2, _country_codes);
tax_rate rand_rate = buffer[tax_rate_count-1];
- strops_copy(item.tax_rate_id, rand_rate.id, MAX_LEN_ID);
+ strops::copy(item.tax_rate_id, rand_rate.id, MAX_LEN_ID);
return item;
}
@@ -134,7 +134,7 @@ static billing_item _create_bi5(invoice *inv)
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);
+ strops::copy(item.description, "Apple", MAX_LEN_LONG_DESC);
item.net_per_item = 1.00f;
item.discount = 5.0f;
item.discount_is_percentage = 1;
@@ -143,7 +143,7 @@ static billing_item _create_bi5(invoice *inv)
char* _country_codes[2] = {inv->supplier.address.country_code, inv->customer.address.country_code};
u32 tax_rate_count = administration_tax_rate_get_by_country(buffer, 2, _country_codes);
tax_rate rand_rate = buffer[tax_rate_count-1];
- strops_copy(item.tax_rate_id, rand_rate.id, MAX_LEN_ID);
+ strops::copy(item.tax_rate_id, rand_rate.id, MAX_LEN_ID);
return item;
}
@@ -153,7 +153,7 @@ static billing_item _create_bi6(invoice *inv)
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);
+ strops::copy(item.description, "Tip", MAX_LEN_LONG_DESC);
item.net_per_item = 50.00f;
item.discount = 0.0f;
item.discount_is_percentage = 0;
@@ -162,7 +162,7 @@ static billing_item _create_bi6(invoice *inv)
char* _country_codes[2] = {inv->supplier.address.country_code, inv->customer.address.country_code};
u32 tax_rate_count = administration_tax_rate_get_by_country(buffer, 2, _country_codes);
tax_rate rand_rate = buffer[tax_rate_count-1];
- strops_copy(item.tax_rate_id, rand_rate.id, MAX_LEN_ID);
+ strops::copy(item.tax_rate_id, rand_rate.id, MAX_LEN_ID);
return item;
}