diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/administration_reader.cpp | 3 | ||||
| -rw-r--r-- | src/administration_writer.cpp | 57 | ||||
| -rw-r--r-- | src/ui/imgui_extensions.cpp | 42 | ||||
| -rw-r--r-- | src/ui/ui_expenses.cpp | 6 | ||||
| -rw-r--r-- | src/ui/ui_invoices.cpp | 6 |
5 files changed, 102 insertions, 12 deletions
diff --git a/src/administration_reader.cpp b/src/administration_reader.cpp index bf8f8db..9c20a27 100644 --- a/src/administration_reader.cpp +++ b/src/administration_reader.cpp @@ -144,7 +144,8 @@ bool administration_reader_import_invoice(char* buffer, size_t buffer_size) data.delivered_at = xml_get_date_x(root, "cac:Delivery", "cbc:ActualDeliveryDate", 0); // References - xml_get_str_x(root, data.document, MAX_LEN_PATH, "cac:AdditionalDocumentReference", "cbc:ID", 0); + xml_get_str_x(root, data.document.copy_path, MAX_LEN_PATH, "cac:AdditionalDocumentReference", "cbc:ID", 0); + xml_get_str_x(root, data.document.original_path, MAX_LEN_PATH, "cac:AdditionalDocumentReference", "cbc:DocumentDescription", 0); xml_get_str_x(root, data.project_id, MAX_LEN_ID, "cac:ProjectReference", "cbc:ID", 0); xml_get_str(root, data.cost_center_id, MAX_LEN_ID, "cac:AccountingCost"); diff --git a/src/administration_writer.cpp b/src/administration_writer.cpp index b08723b..0cc4cd8 100644 --- a/src/administration_writer.cpp +++ b/src/administration_writer.cpp @@ -286,6 +286,49 @@ void _remove_empty_xml_tags(char* file_content, int depth) } } +static const char* _get_file_extension(const char *path) { + const char *dot = strrchr(path, '.'); + if (!dot || dot == path) return ""; + return dot; +} + +static void _add_document_to_zip(invoice* inv) +{ + document* doc = &inv->document; + + if (strlen(doc->copy_path) == 0 && strlen(doc->original_path) != 0) + { + char copy_path[MAX_LEN_PATH]; + snprintf(copy_path, MAX_LEN_PATH, "documents/%s%s", inv->sequential_number, _get_file_extension(doc->original_path)); + + FILE* orig_file = fopen(doc->original_path, "rb"); + if (orig_file == NULL) { + log_error("ERROR: original document file path does not exist."); + return; + } + + fseek(orig_file, 0L, SEEK_END); + long sz = ftell(orig_file); + fseek(orig_file, 0, SEEK_SET); + + char* file_copy = (char*)malloc(sz); + fread(file_copy, sz, 1, orig_file); + file_copy[sz-1] = 0; + + 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); + } + else { + log_error("ERROR: failed to make copy of original document '%s'.", doc->original_path); + } + + free(file_copy); + } +} + bool administration_writer_save_invoice_blocking(invoice inv) { STOPWATCH_START; @@ -299,21 +342,15 @@ bool administration_writer_save_invoice_blocking(invoice inv) struct tm *tm_info = 0; char date_buffer[11]; // "YYYY-MM-DD" + null terminator - // properties not stored from supplier/customer/addressee: - // - type - // These can all be retrieved from existing contacts. - - // properties not stored from billing item: - // - discount (can be recalculated from line_amount - (quantity * unit_price) ) - // - tax (can be recalculated) - // - total (can be recalculated) + _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}}", inv.document); + 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 @@ -524,9 +561,7 @@ 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); diff --git a/src/ui/imgui_extensions.cpp b/src/ui/imgui_extensions.cpp index 8485dbf..483f5f6 100644 --- a/src/ui/imgui_extensions.cpp +++ b/src/ui/imgui_extensions.cpp @@ -6,6 +6,7 @@ #include "config.hpp" #include "locales.hpp" #include "administration.hpp" +#include "tinyfiledialogs.h" namespace ImGui { @@ -42,6 +43,47 @@ namespace ImGui } } + bool FormFileSelector(char* buffer) + { + bool result = false; + float widthAvailable = ImGui::GetContentRegionAvail().x; + ImGui::SetNextItemWidth(widthAvailable*0.5f); + + if (ImGui::Button("Select file...")) + { + // You can adjust filters, title, default path + const char *filterPatterns[] = { "*.png", "*.jpg", "*.pdf", "*" }; + const char *file = tinyfd_openFileDialog( + "Choose a file", // dialog title + NULL, // default path + 4, // number of filter patterns + filterPatterns, // filter patterns array + NULL, // single filter description (can be NULL) + 0); // allowMultiple (0 = single) + if (file) + { + strops_copy(buffer, file, MAX_LEN_PATH); + buffer[MAX_LEN_PATH-1] = '\0'; + result = true; + } + } + + if (buffer[0] != '\0') + { + ImGui::SameLine(); + if (ImGui::Button("Clear")) + { + buffer[0] = '\0'; + result = true; + } + ImGui::SameLine(); + ImGui::TextWrapped("Selected: %s", buffer); + + } + + return result; + } + void FormCountryCombo(char* buffer, size_t buf_size) { const char* selected_country = 0; diff --git a/src/ui/ui_expenses.cpp b/src/ui/ui_expenses.cpp index 9094d30..92f9c7c 100644 --- a/src/ui/ui_expenses.cpp +++ b/src/ui/ui_expenses.cpp @@ -85,6 +85,12 @@ static void draw_expense_form(invoice* buffer, bool viewing_only = false) ImGui::Separator(); + if (ImGui::FormFileSelector(buffer->document.original_path)) { + buffer->document.copy_path[0] = 0; + } + + ImGui::Separator(); + ImGui::Text(localize("invoice.form.supplier")); draw_contact_form_ex(&buffer->supplier, false, true); diff --git a/src/ui/ui_invoices.cpp b/src/ui/ui_invoices.cpp index 0ef3fb2..fdeafc6 100644 --- a/src/ui/ui_invoices.cpp +++ b/src/ui/ui_invoices.cpp @@ -206,6 +206,12 @@ static void draw_invoice_form(invoice* buffer, bool viewing_only = false) ImGui::Separator(); + if (ImGui::FormFileSelector(buffer->document.original_path)) { + buffer->document.copy_path[0] = 0; + } + + ImGui::Separator(); + ImGui::Text(localize("invoice.form.billinginformation")); draw_contact_form_ex(&buffer->customer, false, true); |
