summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrikboy@gmail.com>2025-08-23 18:47:13 +0200
committerAldrik Ramaekers <aldrikboy@gmail.com>2025-08-23 18:47:13 +0200
commitdf9353ecbdadc5ff4efe42c242e233cacedea50b (patch)
treec728dbf80b3c7067dbdaec42261673e697cf9ca6 /src
parent359422c97cce93bbb27051f9df3efb45bd0b9052 (diff)
file writing work
Diffstat (limited to 'src')
-rw-r--r--src/administration.cpp17
-rw-r--r--src/administration_writer.cpp205
-rw-r--r--src/ui/helpers.cpp17
-rw-r--r--src/ui/ui_settings.cpp19
4 files changed, 235 insertions, 23 deletions
diff --git a/src/administration.cpp b/src/administration.cpp
index 1d09e69..b3e30fa 100644
--- a/src/administration.cpp
+++ b/src/administration.cpp
@@ -6,6 +6,7 @@
#include "strops.hpp"
#include "administration.hpp"
+#include "administration_writer.hpp"
administration g_administration;
@@ -392,6 +393,8 @@ void administration_create()
administration_create_default_cost_centers();
administration_create_debug_data();
+
+ administration_writer_save_all();
}
static void administration_destroy_list(list_t *list)
@@ -500,6 +503,20 @@ u32 administration_contact_count()
return list_size(&g_administration.contacts);
}
+u32 administration_contact_get_all(contact* buffer)
+{
+ u32 write_cursor = 0;
+
+ list_iterator_start(&g_administration.contacts);
+ while (list_iterator_hasnext(&g_administration.contacts)) {
+ contact c = *(contact *)list_iterator_next(&g_administration.contacts);
+ buffer[write_cursor++] = c;
+ }
+ list_iterator_stop(&g_administration.contacts);
+
+ return write_cursor;
+}
+
u32 administration_contact_get_partial_list(u32 page_index, u32 page_size, contact* buffer)
{
assert(buffer);
diff --git a/src/administration_writer.cpp b/src/administration_writer.cpp
index 5f23d78..86b3ee2 100644
--- a/src/administration_writer.cpp
+++ b/src/administration_writer.cpp
@@ -3,29 +3,102 @@
#include <zip.h>
#include <xml.h>
#include <stdlib.h>
+#include <threads.h>
+#include "ui.hpp"
#include "administration_writer.hpp"
-bool administration_writer_save_cost_centers()
+static bool administration_writer_write_to_zip(char* entry_to_replace, char* orig_content, int final_length)
{
- return false;
+ bool result = true;
+ bool entry_exists = false;
+
+ // Check if entry exists already.
+ struct zip_t *zip_read = zip_open(administration_file_path_get(), 0, 'r');
+ int i, n = (int)zip_entries_total(zip_read);
+ for (i = 0; i < n; ++i) {
+ zip_entry_openbyindex(zip_read, i);
+ const char *entry_name = zip_entry_name(zip_read);
+ if (strcmp(entry_name, entry_to_replace) == 0) {
+ entry_exists = true;
+ break;
+ }
+ zip_entry_close(zip_read);
+ }
+ zip_close(zip_read);
+
+ struct zip_t *zip_write = zip_open(administration_file_path_get(), 0, 'a');
+ if (!zip_write) zip_write = zip_open(administration_file_path_get(), 0, 'w');
+
+ if (entry_exists)
+ {
+ char* indices[1] = {entry_to_replace};
+ zip_entries_delete(zip_write, indices, 1);
+ zip_close(zip_write); // Need to close to flush removed entry.
+
+ zip_write = zip_open(administration_file_path_get(), 0, 'a');
+ }
+
+ zip_entry_open(zip_write, entry_to_replace);
+ if (zip_entry_write(zip_write, orig_content, final_length) < 0) result = false;
+ zip_entry_close(zip_write);
+
+ zip_close(zip_write);
+
+ return result;
}
-bool administration_writer_save_tax_brackets()
+bool administration_writer_save_all_cost_centers()
{
- struct zip_t *zip = zip_open(administration_file_path_get(), 0, 'w');
- if (!zip) {
- zip = zip_open(administration_file_path_get(), 0, 'a');
- if (!zip) {
- return false;
- }
+ //// Get all data.
+ u32 num_costcenters = administration_cost_center_count();
+ u32 buffer_size = sizeof(cost_center) * num_costcenters;
+ cost_center* costcenter_buffer = (cost_center*)malloc(buffer_size);
+ num_costcenters = administration_cost_center_get_all(costcenter_buffer);
+
+ int buf_length = num_costcenters * 500; // Ballpark file content size.
+ char* settings_content = (char*)malloc(buf_length);
+ memset(settings_content, 0, buf_length);
+
+ char* orig_content = settings_content;
+
+ //// Cost centers.
+ settings_content += sprintf(settings_content, "<cost_centers>\n");
+
+ for (u32 i = 0; i < num_costcenters; i++) {
+ cost_center c = costcenter_buffer[i];
+
+ settings_content += sprintf(settings_content, "\t<cost_center>\n");
+
+ settings_content += sprintf(settings_content, "\t\t<id>%s</id>\n", c.id);
+ settings_content += sprintf(settings_content, "\t\t<code>%s</code>\n", c.code);
+ settings_content += sprintf(settings_content, "\t\t<description>%s</description>\n", c.description);
+
+ settings_content += sprintf(settings_content, "\t</cost_center>\n");
}
- if (zip_entry_open(zip, ADMIN_FILE_SETTINGS) < 0) {
- return false;
+ settings_content += sprintf(settings_content, "</cost_centers>");
+
+ //// Write to Disk.
+ int final_length = (int)strlen(orig_content);
+ bool result = true;
+
+ if (!xml_parse_document((uint8_t*)orig_content, final_length)) {
+ result = false;
+ }
+ else {
+ administration_writer_write_to_zip(ADMIN_FILE_COSTCENTERS, orig_content, final_length);
}
- // Get all data.
+ free(costcenter_buffer);
+ free(orig_content);
+
+ return result;
+}
+
+bool administration_writer_save_all_tax_brackets()
+{
+ //// Get all data.
u32 num_brackets = administration_tax_bracket_count();
u32 buffer_size = sizeof(country_tax_bracket) * num_brackets;
country_tax_bracket* bracket_buffer = (country_tax_bracket*)malloc(buffer_size);
@@ -55,24 +128,122 @@ bool administration_writer_save_tax_brackets()
settings_content += sprintf(settings_content, "</country_tax_brackets>");
+ //// Write to Disk.
int final_length = (int)strlen(orig_content);
-
bool result = true;
+
if (!xml_parse_document((uint8_t*)orig_content, final_length)) {
result = false;
}
+ else {
+ administration_writer_write_to_zip(ADMIN_FILE_BRACKETS, orig_content, final_length);
+ }
+ free(bracket_buffer);
+ free(orig_content);
+
+ return result;
+}
+
+bool administration_writer_save_contact(contact c, char* content_buffer = NULL)
+{
+ bool result = true;
+ bool do_free = false;
+ if (!content_buffer) {
+ int buf_length = 2000; // Ballpark contact content size.
+ content_buffer = (char*)malloc(buf_length);
+ memset(content_buffer, 0, buf_length);
+ do_free = true;
+ }
+
+ char* orig_content = content_buffer;
+
+ content_buffer += sprintf(content_buffer, "<contact>\n");
- if (zip_entry_write(zip, orig_content, final_length) < 0) {
+ content_buffer += sprintf(content_buffer, "\t<id>%s</id>\n", c.id);
+ content_buffer += sprintf(content_buffer, "\t<name>%s</name>\n", c.name);
+ content_buffer += sprintf(content_buffer, "\t<type>%d</type>\n", c.type);
+ content_buffer += sprintf(content_buffer, "\t<taxid>%s</taxid>\n", c.taxid);
+ content_buffer += sprintf(content_buffer, "\t<businessid>%s</businessid>\n", c.businessid);
+ content_buffer += sprintf(content_buffer, "\t<email>%s</email>\n", c.email);
+ content_buffer += sprintf(content_buffer, "\t<phone_number>%s</phone_number>\n", c.phone_number);
+ content_buffer += sprintf(content_buffer, "\t<bank_account>%s</bank_account>\n", c.bank_account);
+
+ content_buffer += sprintf(content_buffer, "\t<address>\n");
+ content_buffer += sprintf(content_buffer, "\t\t<address1>%s</address1>\n", c.address.address1);
+ content_buffer += sprintf(content_buffer, "\t\t<address2>%s</address2>\n", c.address.address2);
+ content_buffer += sprintf(content_buffer, "\t\t<country_code>%s</country_code>\n", c.address.country_code);
+ content_buffer += sprintf(content_buffer, "\t</address>\n");
+
+ content_buffer += sprintf(content_buffer, "</contact>\n");
+
+ char final_path[50];
+ snprintf(final_path, 50, "%s.xml", c.id);
+
+ int final_length = (int)strlen(orig_content);
+ if (!xml_parse_document((uint8_t*)orig_content, final_length)) {
result = false;
}
+ else {
+ administration_writer_write_to_zip(final_path, orig_content, final_length);
+ }
- zip_entry_close(zip);
+ if (do_free) free(content_buffer);
+ return result;
+}
- zip_close(zip);
- free(bracket_buffer);
+bool administration_writer_save_all_contacts()
+{
+ //// Get all data.
+ u32 num_contacts = administration_contact_count();
+ u32 buffer_size = sizeof(contact) * num_contacts;
+ contact* contact_buffer = (contact*)malloc(buffer_size);
+ num_contacts = administration_contact_get_all(contact_buffer);
+
+
+ int buf_length = 2000; // Ballpark contact content size.
+ char* content_buffer = (char*)malloc(buf_length);
+ memset(content_buffer, 0, buf_length);
+ char* orig_content = content_buffer;
+ bool result = true;
+
+ if (!administration_writer_save_contact(administration_company_info_get(), content_buffer)) result = false;
+
+ // Contacts.
+ for (u32 i = 0; i < num_contacts; i++) {
+ contact c = contact_buffer[i];
+
+ if (!administration_writer_save_contact(c, content_buffer)) result = false;
+
+ content_buffer = orig_content;
+ memset(content_buffer, 0, buf_length);
+ }
+
+ free(contact_buffer);
free(orig_content);
return result;
+}
+
+static int administration_writer_write_all_t(void *arg) {
+ int result = 1;
+ if (!administration_writer_save_all_tax_brackets()) result = 0;
+ if (!administration_writer_save_all_cost_centers()) result = 0;
+ if (!administration_writer_save_all_contacts()) result = 0;
+
+ ui_set_status_loading(false);
+ return result; // thread exit code
+}
+
+bool administration_writer_save_all()
+{
+ ui_set_status_loading(true);
+
+ thrd_t thr;
+ if (thrd_create(&thr, administration_writer_write_all_t, 0) != thrd_success) {
+ return false;
+ }
+
+ return true;
} \ No newline at end of file
diff --git a/src/ui/helpers.cpp b/src/ui/helpers.cpp
index c15528e..37c4b36 100644
--- a/src/ui/helpers.cpp
+++ b/src/ui/helpers.cpp
@@ -11,8 +11,14 @@ void ui_draw_status()
{
float region_width = ImGui::GetContentRegionAvail().x;
float text_width = ImGui::CalcTextSize(current_status.text).x;
+
+ if (current_status.loading)
+ {
+ ImGui::SetCursorPosX(ImGui::GetCursorPosX() + region_width - text_width - 20.0f);
+ ImGui::Text("%c", "|/-\\"[(int)(ImGui::GetTime() / 0.1f) & 3]);
+ return;
+ }
- // Move cursor so that the text ends at the right edge
if (current_status.visible)
{
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + region_width - text_width);
@@ -43,6 +49,7 @@ void ui_set_status_ex(const char* txt, int color)
current_status.visible = true;
current_status.time = 0.0f;
current_status.color = color;
+ current_status.loading = false;
strops_copy(current_status.text, txt, STATUS_TEXT_LEN);
}
@@ -56,6 +63,13 @@ void ui_set_status(const char* txt)
ui_set_status_ex(txt, COLOR_DEFAULT);
}
+void ui_set_status_loading(bool loading)
+{
+ current_status.visible = true;
+ current_status.time = 0.0f;
+ current_status.loading = loading;
+}
+
ui_status ui_get_status()
{
return current_status;
@@ -134,4 +148,3 @@ int TextInputWithAutocomplete(const char* label, const char* hint, char* buffer,
}
return result;
}
-
diff --git a/src/ui/ui_settings.cpp b/src/ui/ui_settings.cpp
index 9cc2cd9..75c4918 100644
--- a/src/ui/ui_settings.cpp
+++ b/src/ui/ui_settings.cpp
@@ -125,7 +125,7 @@ static void ui_draw_vat_rates()
is_adding_item = false;
administration_tax_bracket_update(new_tax_bracket);
- if (administration_writer_save_tax_brackets()) {
+ if (administration_writer_save_all_tax_brackets()) {
ui_set_status(localize("status.saved"));
}
else {
@@ -177,7 +177,7 @@ static void ui_draw_vat_rates()
is_adding_item = false;
administration_tax_bracket_add(new_tax_bracket);
- if (administration_writer_save_tax_brackets()) {
+ if (administration_writer_save_all_tax_brackets()) {
ui_set_status(localize("status.saved"));
}
else {
@@ -239,7 +239,13 @@ static void ui_draw_cost_centers()
is_adding_item = false;
administration_cost_center_update(new_cost_center);
- administration_writer_save_cost_centers();
+ if (administration_writer_save_all_cost_centers()) {
+ ui_set_status(localize("status.saved"));
+ }
+ else {
+ ui_set_status_error(localize("status.saveFailed"));
+ }
+
memset(&new_cost_center, 0, sizeof(new_cost_center));
ui_destroy_settings();
@@ -294,7 +300,12 @@ static void ui_draw_cost_centers()
is_adding_item = false;
is_editing_item = false;
administration_cost_center_add(new_cost_center);
- administration_writer_save_cost_centers();
+ if (administration_writer_save_all_cost_centers()) {
+ ui_set_status(localize("status.saved"));
+ }
+ else {
+ ui_set_status_error(localize("status.saveFailed"));
+ }
ui_destroy_settings();
ui_setup_settings();