summaryrefslogtreecommitdiff
path: root/src/administration_reader.cpp
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrikboy@gmail.com>2025-09-13 12:40:22 +0200
committerAldrik Ramaekers <aldrikboy@gmail.com>2025-09-13 12:40:22 +0200
commitd8a9d534a5a39fd3d51a6ffaf92fde39a4b4077c (patch)
treeeb15c2c464147b467417684fbaaebfd37da89bc3 /src/administration_reader.cpp
parentfb1ae39f1abe0dd0335489451e09a24e2336e606 (diff)
save file import: contact, project, tax brackets, cost centers, administration info
Diffstat (limited to 'src/administration_reader.cpp')
-rw-r--r--src/administration_reader.cpp249
1 files changed, 243 insertions, 6 deletions
diff --git a/src/administration_reader.cpp b/src/administration_reader.cpp
index 150c045..b3caeac 100644
--- a/src/administration_reader.cpp
+++ b/src/administration_reader.cpp
@@ -1,11 +1,12 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
#include <zip.h>
#include <xml.h>
-#include <stdlib.h>
-#include <threads.h>
#include "log.hpp"
-#include "ui.hpp"
#include "strops.hpp"
+#include "administration_reader.hpp"
#include "administration_writer.hpp"
#include "tinyfiledialogs.h"
@@ -19,9 +20,245 @@ bool administration_reader_open_new()
administration_create_empty(save_path);
- //administration_writer_save_all_cost_centers_blocking();
- //administration_writer_save_all_tax_brackets_blocking();
- //administration_writer_save_all_administration_info_blocking();
+ return true;
+}
+
+bool administration_reader_open_existing(char* file_path)
+{
+ if (file_path == NULL) {
+ // @localize
+ char const * lFilterPatterns[1] = { "*.openbook" };
+ file_path = tinyfd_openFileDialog("Select save file", NULL, 1, lFilterPatterns, NULL, 0);
+
+ if (!file_path) return false;
+ }
+
+ STOPWATCH_START;
+
+ administration_create_from_file(file_path);
+
+ zip_t* zip = zip_open(file_path, 0, 'r');
+
+ size_t i, n = zip_entries_total(zip);
+ for (i = 0; i < n; ++i) {
+ zip_entry_openbyindex(zip, i);
+ {
+ const char *name = zip_entry_name(zip);
+ int isdir = zip_entry_isdir(zip);
+ if (isdir) continue;
+ unsigned long long size = zip_entry_size(zip);
+
+ char* buffer = (char*)malloc(size+1);
+ memset(buffer, 0, size+1);
+ zip_entry_read(zip, (void**)&buffer, (size_t*)&size);
+
+ if (strlen(name) == 0) continue;
+
+ if (strcmp(name, ADMIN_FILE_INFO) == 0)
+ {
+ administration_reader_import_administration_info(buffer, (size_t)size);
+ }
+ else if (strops_prefix("T/", name))
+ {
+ administration_reader_import_tax_bracket(buffer, (size_t)size);
+ }
+ else if (strops_prefix("E/", name))
+ {
+ administration_reader_import_cost_center(buffer, (size_t)size);
+ }
+ else if (strops_prefix("P/", name))
+ {
+ administration_reader_import_project(buffer, (size_t)size);
+ }
+ else if (strops_prefix("C/", name))
+ {
+ administration_reader_import_contact(buffer, (size_t)size);
+ }
+
+ free(buffer);
+ }
+ zip_entry_close(zip);
+ }
+
+ zip_close(zip);
+
+ log_add("Imported '%s' in %.3fms.", file_path, STOPWATCH_TIME);
return true;
}
+
+static s64 _get_xml_s64(xml_node* root, char* child_name)
+{
+ struct xml_node* node = xml_easy_child(root, (uint8_t *)child_name, 0);
+
+ char xml_content[512];
+ memset(xml_content, 0, 512);
+ struct xml_string* str = xml_node_content(node);
+ xml_string_copy(str, (uint8_t *)xml_content, xml_string_length(str));
+
+ char *endptr;
+ long long val = strtoll(xml_content, &endptr, 10);
+
+ s64 num = (int64_t) val;
+ return num;
+}
+
+static s32 _get_xml_s32(xml_node* root, char* child_name)
+{
+ struct xml_node* node = xml_easy_child(root, (uint8_t *)child_name, 0);
+
+ char xml_content[512];
+ memset(xml_content, 0, 512);
+ struct xml_string* str = xml_node_content(node);
+ xml_string_copy(str, (uint8_t *)xml_content, xml_string_length(str));
+
+ char *endptr;
+ long val = strtol(xml_content, &endptr, 10);
+
+ s32 num = (int32_t) val;
+ return num;
+}
+
+static float _get_xml_float(xml_node* root, char* child_name)
+{
+ struct xml_node* node = xml_easy_child(root, (uint8_t *)child_name, 0);
+
+ char xml_content[512];
+ memset(xml_content, 0, 512);
+ struct xml_string* str = xml_node_content(node);
+ xml_string_copy(str, (uint8_t *)xml_content, xml_string_length(str));
+
+ char *endptr;
+ float val = strtof(xml_content, &endptr);
+ return val;
+}
+
+static char* _get_xml_str(xml_node* root, char* buffer, size_t bufsize, char* child_name)
+{
+ struct xml_node* node = xml_easy_child(root, (uint8_t *)child_name, 0);
+
+ memset(buffer, 0, bufsize);
+ struct xml_string* str = xml_node_content(node);
+ xml_string_copy(str, (uint8_t *)buffer, xml_string_length(str));
+
+ return buffer;
+}
+
+bool administration_reader_import_contact(char* buffer, size_t buffer_size)
+{
+ STOPWATCH_START;
+
+ xml_document* document = xml_parse_document((uint8_t *)buffer, buffer_size);
+ if (!document) return false;
+
+ struct xml_node* root = xml_document_root(document);
+
+ contact data;
+ _get_xml_str(root, data.id, MAX_LEN_ID, "Id");
+ _get_xml_str(root, data.name, MAX_LEN_LONG_DESC, "Name");
+ data.type = (contact_type)_get_xml_s32(root, "Type");
+ _get_xml_str(root, data.taxid, MAX_LEN_TAXID, "TaxId");
+ _get_xml_str(root, data.businessid, MAX_LEN_BUSINESSID, "BusinessId");
+ _get_xml_str(root, data.email, MAX_LEN_EMAIL, "Email");
+ _get_xml_str(root, data.phone_number, MAX_LEN_PHONE, "PhoneNumber");
+ _get_xml_str(root, data.bank_account, MAX_LEN_BANK, "BankAccount");
+
+ struct xml_node* node_address = xml_easy_child(root, (uint8_t *)"Address", 0);
+ _get_xml_str(node_address, data.address.address1, MAX_LEN_ADDRESS, "AddressLine1");
+ _get_xml_str(node_address, data.address.address2, MAX_LEN_ADDRESS, "AddressLine2");
+ _get_xml_str(node_address, data.address.country_code, MAX_LEN_COUNTRY_CODE, "CountryCode");
+ _get_xml_str(node_address, data.address.city, MAX_LEN_ADDRESS, "City");
+ _get_xml_str(node_address, data.address.postal, MAX_LEN_ADDRESS, "Postal");
+ _get_xml_str(node_address, data.address.region, MAX_LEN_ADDRESS, "Region");
+
+ bool result = administration_contact_import(data);
+ log_add("Loaded contact '%s' in %.3fms.", data.name, STOPWATCH_TIME);
+
+ return result;
+}
+
+bool administration_reader_import_project(char* buffer, size_t buffer_size)
+{
+ STOPWATCH_START;
+
+ xml_document* document = xml_parse_document((uint8_t *)buffer, buffer_size);
+ if (!document) return false;
+
+ struct xml_node* root = xml_document_root(document);
+
+ project data;
+ _get_xml_str(root, data.id, MAX_LEN_ID, "Id");
+ _get_xml_str(root, data.description, MAX_LEN_LONG_DESC, "Description");
+ data.state = (project_state)_get_xml_s32(root, "State");
+ data.start_date = _get_xml_s64(root, "StartDate");
+ data.end_date = _get_xml_s64(root, "EndDate");
+
+ bool result = administration_project_import(data);
+ log_add("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);
+
+ return result;
+}
+
+bool administration_reader_import_cost_center(char* buffer, size_t buffer_size)
+{
+ STOPWATCH_START;
+
+ xml_document* document = xml_parse_document((uint8_t *)buffer, buffer_size);
+ if (!document) return false;
+
+ struct xml_node* root = xml_document_root(document);
+
+ cost_center data;
+ _get_xml_str(root, data.id, MAX_LEN_ID, "Id");
+ _get_xml_str(root, data.code, MAX_LEN_CODE, "Code");
+ _get_xml_str(root, data.description, MAX_LEN_LONG_DESC, "Description");
+
+ bool result = administration_cost_center_import(data);
+ log_add("Loaded cost center in %.3fms. id=%s code=%s description=%s",
+ STOPWATCH_TIME, data.id, data.code, data.description);
+
+ return result;
+}
+
+bool administration_reader_import_tax_bracket(char* buffer, size_t buffer_size)
+{
+ STOPWATCH_START;
+
+ xml_document* document = xml_parse_document((uint8_t *)buffer, buffer_size);
+ if (!document) return false;
+
+ struct xml_node* root = xml_document_root(document);
+
+ country_tax_bracket data;
+ _get_xml_str(root, data.id, MAX_LEN_ID, "Id");
+ _get_xml_str(root, data.country_code, MAX_LEN_COUNTRY_CODE, "CountryCode");
+ _get_xml_str(root, data.category_code, MAX_LEN_CODE, "Category");
+ data.rate = _get_xml_float(root, "Rate");
+
+ bool result = administration_tax_bracket_import(data);
+ log_add("Loaded tax bracket 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);
+
+ return result;
+}
+
+bool administration_reader_import_administration_info(char* buffer, size_t buffer_size)
+{
+ STOPWATCH_START;
+
+ xml_document* document = xml_parse_document((uint8_t *)buffer, buffer_size);
+ if (!document) return false;
+
+ struct xml_node* root = xml_document_root(document);
+
+ administration* ad = administration_get();
+ ad->next_id = _get_xml_s32(root, "NextId");
+ ad->next_sequence_number = _get_xml_s32(root, "NextSequenceNumber");
+ _get_xml_str(root, ad->company_info.id, MAX_LEN_ID, "CompanyInfoId");
+
+ log_add("Loaded administration info in %.3fms. next_id=%d next_sequence_number=%d company_id=%s",
+ STOPWATCH_TIME, ad->next_id, ad->next_sequence_number, ad->company_info.id);
+
+ return true;
+} \ No newline at end of file