diff options
| -rw-r--r-- | include/administration.hpp | 5 | ||||
| -rw-r--r-- | include/ui.hpp | 1 | ||||
| -rw-r--r-- | src/administration.cpp | 26 | ||||
| -rw-r--r-- | src/ui/helpers.cpp | 45 | ||||
| -rw-r--r-- | src/ui/ui_contacts.cpp | 103 | ||||
| -rw-r--r-- | src/ui/ui_invoices.cpp | 27 | ||||
| -rw-r--r-- | src/ui/ui_settings.cpp | 12 |
7 files changed, 166 insertions, 53 deletions
diff --git a/include/administration.hpp b/include/administration.hpp index dffce89..68deb78 100644 --- a/include/administration.hpp +++ b/include/administration.hpp @@ -111,6 +111,10 @@ typedef struct time_t payment_on_account_date; char tax_representative[64]; char corrected_sequential_number[16]; + + // Not stored. + contact supplier; + contact customer; } invoice; typedef struct @@ -142,6 +146,7 @@ bool administration_update_contact(contact data); u32 administration_get_contact_count(); u32 administration_get_contacts(u32 page_index, u32 page_size, contact* buffer); contact administration_create_empty_contact(); +bool administration_is_contact_valid(contact data); void administration_cancel_project(project data); bool administration_remove_project(project data); diff --git a/include/ui.hpp b/include/ui.hpp index 00a3465..7a02329 100644 --- a/include/ui.hpp +++ b/include/ui.hpp @@ -11,6 +11,7 @@ typedef enum void ui_helper_draw_required_tag(); void ui_helper_show_toast(const char* msg); void ui_helper_draw_toasts(); +void ui_helper_TextInputWithAutocomplete(const char* label, const char* hint, char* buffer, size_t buf_size, char** suggestions, int suggestion_count); void ui_draw_main(); void ui_draw_contacts(); diff --git a/src/administration.cpp b/src/administration.cpp index edbc933..869855e 100644 --- a/src/administration.cpp +++ b/src/administration.cpp @@ -204,6 +204,11 @@ void administration_create() g_administration.next_id = 1; g_administration.next_sequence_number = 1; + strops_copy(g_administration.company_info.name, "Aldrik Ramaekers", sizeof(g_administration.company_info.name)); + strops_copy(g_administration.company_info.address.address1, "Keerderstraat 81", sizeof(g_administration.company_info.address.address1)); + strops_copy(g_administration.company_info.address.address2, "6226XW Maastricht", sizeof(g_administration.company_info.address.address2)); + strops_copy(g_administration.company_info.address.country_code, "NL", sizeof(g_administration.company_info.address.country_code)); + list_init(&g_administration.contacts); list_init(&g_administration.projects); list_init(&g_administration.tax_brackets); @@ -547,6 +552,21 @@ bool administration_update_cost_center(cost_center data) return false; } +bool administration_is_contact_valid(contact data) +{ + if (data.type == contact_type::CONTACT_CONSUMER) + { + return strlen(data.name) > 0 && strlen(data.address.address1) > 0 && strlen(data.address.address2) > 0 && strlen(data.address.country_code) > 0; + } + else if (data.type == contact_type::CONTACT_BUSINESS) + { + return strlen(data.name) > 0 && strlen(data.address.address1) > 0 && strlen(data.address.address2) > 0 && strlen(data.address.country_code) > 0 + && strlen(data.taxid) > 0 && strlen(data.businessid); + } + + return false; +} + static s32 administration_create_sequence_number() { return g_administration.next_sequence_number; @@ -565,7 +585,7 @@ contact administration_create_empty_contact() { contact result; memset(&result, 0, sizeof(contact)); - snprintf(result.id, IM_ARRAYSIZE(result.id), "C/%d", administration_create_id()); + snprintf(result.id, sizeof(result.id), "C/%d", administration_create_id()); return result; } @@ -573,6 +593,6 @@ project administration_create_empty_project() { project result; memset(&result, 0, sizeof(project)); - snprintf(result.id, IM_ARRAYSIZE(result.id), "P/%d", administration_create_id()); - return project; + snprintf(result.id, sizeof(result.id), "P/%d", administration_create_id()); + return result; }
\ No newline at end of file diff --git a/src/ui/helpers.cpp b/src/ui/helpers.cpp index e4b25c8..a239f4c 100644 --- a/src/ui/helpers.cpp +++ b/src/ui/helpers.cpp @@ -1,6 +1,7 @@ #include "ui.hpp" #include "imgui.h" #include "locales.hpp" +#include "strops.hpp" static float toast_timer = 0.0f; static const char* toast_msg = nullptr; @@ -62,4 +63,46 @@ void ui_helper_draw_required_tag() ImGui::PushStyleColor(ImGuiCol_Text, text_color); ImGui::TextUnformatted(text); ImGui::PopStyleColor(); -}
\ No newline at end of file +} + +void ui_helper_TextInputWithAutocomplete(const char* label, const char* hint, char* buffer, size_t buf_size, + char* suggestions[], int suggestion_count) +{ + static bool is_open = false; + ImGui::InputTextWithHint(label, hint, buffer, buf_size); + + bool is_active = ImGui::IsItemActive(); + if (is_active && buffer[0] != '\0') + { + is_open = true; + } + + if (is_open) { + ImGui::BeginChild("autocomplete_popup", ImVec2(0, 100), true); + { + ImVec2 win_pos = ImGui::GetWindowPos(); + ImVec2 win_size = ImGui::GetWindowSize(); + ImVec2 mouse_pos = ImGui::GetMousePos(); + + bool mouse_clicked_outside = !is_active && ImGui::IsMouseClicked(0) && + (mouse_pos.x < win_pos.x || mouse_pos.x > win_pos.x + win_size.x || + mouse_pos.y < win_pos.y || mouse_pos.y > win_pos.y + win_size.y); + + if (mouse_clicked_outside) is_open = false; + + for (int i = 0; i < suggestion_count; ++i) + { + if (ImGui::Selectable(suggestions[i])) + { + // Copy selected suggestion to buffer + strops_copy(buffer, suggestions[i], buf_size); + buffer[buf_size - 1] = '\0'; + + is_open = false; + } + } + + ImGui::EndChild(); + } + } +} diff --git a/src/ui/ui_contacts.cpp b/src/ui/ui_contacts.cpp index e19f571..c381db5 100644 --- a/src/ui/ui_contacts.cpp +++ b/src/ui/ui_contacts.cpp @@ -18,30 +18,33 @@ void ui_setup_contacts() memset(&selected_for_removal, 0, sizeof(contact)); } -bool draw_contact_form(contact* buffer, bool back_button_enabled = true, bool viewing_only = false) +void draw_contact_form(contact* buffer, bool viewing_only = false) { + bool with_autocomplete = false; const char* selected_country = NULL; - if (back_button_enabled) - { - if (ImGui::Button(localize("form.back"))) { - current_view_state = view_state::LIST; - selected_country = 0; - return false; - } - } ImGui::Spacing(); float widthAvailable = ImGui::GetContentRegionAvail().x; + ImGui::BeginDisabled(); + // 1. Identifier - //ImGui::BeginDisabled(); //ImGui::SetNextItemWidth(widthAvailable*0.2f); //ImGui::InputText(localize("contact.form.identifier"), buffer->id, IM_ARRAYSIZE(buffer->id)); - //if (!viewing_only) ImGui::EndDisabled(); + + if (!viewing_only) ImGui::EndDisabled(); // 2. Full name ImGui::SetNextItemWidth(widthAvailable*0.5f); - ImGui::InputTextWithHint(localize("contact.form.fullname"), localize("contact.form.fullname"), buffer->name, IM_ARRAYSIZE(buffer->name)); + if (with_autocomplete) { + contact autocomplete_list[5]; + int autocomplete_count = 5; + char* autocomplete_strings[5] = { "1", "2", "3", "4", "5" }; + + ui_helper_TextInputWithAutocomplete(localize("contact.form.fullname"), localize("contact.form.fullname"), + buffer->name, IM_ARRAYSIZE(buffer->name), (char**)autocomplete_strings, autocomplete_count); + } + else ImGui::InputTextWithHint(localize("contact.form.fullname"), localize("contact.form.fullname"), buffer->name, IM_ARRAYSIZE(buffer->name)); ImGui::SameLine();ui_helper_draw_required_tag(); // 3. Address line 1 @@ -126,23 +129,6 @@ bool draw_contact_form(contact* buffer, bool back_button_enabled = true, bool vi ImGui::InputTextWithHint(localize("contact.form.bankaccount"), localize("contact.form.bankaccount"), buffer->bank_account, IM_ARRAYSIZE(buffer->bank_account)); if (viewing_only) ImGui::EndDisabled(); - - if (!viewing_only) { - bool can_save = strlen(buffer->name) > 0 && strlen(buffer->address.address1) > 0 && - strlen(buffer->address.address2) > 0 && strlen(buffer->address.country_code) > 0; - - if (!can_save) ImGui::BeginDisabled(); - // Save button - ImGui::Spacing(); - if (ImGui::Button(localize("form.save"))) { - return true; - } - if (!can_save) ImGui::EndDisabled(); - } - else { - // TODO list invoices connected to contact. - } - return false; } static void draw_contact_list() @@ -248,25 +234,58 @@ static void draw_contact_list() } } +static void ui_draw_contacts_create() +{ + if (ImGui::Button(localize("form.back"))) { + current_view_state = view_state::LIST; + } + + draw_contact_form(&active_contact); + + bool can_save = administration_is_contact_valid(active_contact); + if (!can_save) ImGui::BeginDisabled(); + // Save button + ImGui::Spacing(); + if (ImGui::Button(localize("form.save"))) { + administration_create_contact(active_contact); + current_view_state = view_state::LIST; + } + if (!can_save) ImGui::EndDisabled(); +} + +static void ui_draw_contacts_update() +{ + if (ImGui::Button(localize("form.back"))) { + current_view_state = view_state::LIST; + } + + draw_contact_form(&active_contact); + + bool can_save = administration_is_contact_valid(active_contact); + if (!can_save) ImGui::BeginDisabled(); + // Save button + ImGui::Spacing(); + if (ImGui::Button(localize("form.save"))) { + administration_update_contact(active_contact); + current_view_state = view_state::LIST; + } + if (!can_save) ImGui::EndDisabled(); +} + void ui_draw_contacts() { switch(current_view_state) { case view_state::LIST: draw_contact_list(); break; - case view_state::CREATE: - if (draw_contact_form(&active_contact)) - { - administration_create_contact(active_contact); + case view_state::CREATE: ui_draw_contacts_create(); break; + case view_state::EDIT: ui_draw_contacts_update(); break; + + case view_state::VIEW: + if (ImGui::Button(localize("form.back"))) { current_view_state = view_state::LIST; - } - break; - case view_state::EDIT: - if (draw_contact_form(&active_contact)) - { - administration_update_contact(active_contact); - current_view_state = view_state::LIST; - } + } + + draw_contact_form(&active_contact, true); break; - case view_state::VIEW: draw_contact_form(&active_contact, true, true); break; } }
\ No newline at end of file diff --git a/src/ui/ui_invoices.cpp b/src/ui/ui_invoices.cpp index 26f60c4..fe4f5a8 100644 --- a/src/ui/ui_invoices.cpp +++ b/src/ui/ui_invoices.cpp @@ -9,6 +9,8 @@ static view_state current_view_state = view_state::LIST; static invoice active_invoice; +extern void draw_contact_form(contact* buffer, bool viewing_only = false); + void ui_setup_invoices() { current_view_state = view_state::LIST; @@ -33,10 +35,25 @@ bool draw_invoice_form(invoice* buffer, bool back_button_enabled = true, bool vi //ImGui::InputText(localize("contact.form.identifier"), buffer->id, IM_ARRAYSIZE(buffer->id)); // 2. Sequential number - ImGui::SetNextItemWidth(widthAvailable*0.5f); - ImGui::InputTextWithHint("Invoice number", "Invoice number", buffer->sequential_number, IM_ARRAYSIZE(buffer->sequential_number)); - ImGui::SameLine();ui_helper_draw_required_tag(); - if (!viewing_only) ImGui::EndDisabled(); + ImGui::Text("Invoice number: %s", buffer->sequential_number); + + // 3. Supplier (you) + ImGui::Text("Supplier: %s", buffer->supplier.name); + + ImGui::Separator(); + + ImGui::Text("Customer information"); + draw_contact_form(&buffer->customer); + strops_copy(buffer->customer_id, buffer->customer.id, sizeof(buffer->customer_id)); + + ImGui::Separator(); + + //ImGui::SetNextItemWidth(widthAvailable*0.5f); + //ImGui::InputTextWithHint("Invoice number", "Invoice number", buffer->sequential_number, IM_ARRAYSIZE(buffer->sequential_number)); + //ImGui::SameLine();ui_helper_draw_required_tag(); + + + //if (!viewing_only) ImGui::EndDisabled(); return false; } @@ -48,6 +65,8 @@ void draw_invoices_list() { current_view_state = view_state::CREATE; active_invoice = administration_create_empty_invoice(); + active_invoice.supplier = administration_get_company_info(); + strops_copy(active_invoice.supplier_id, active_invoice.supplier.id, sizeof(active_invoice.supplier_id)); } } diff --git a/src/ui/ui_settings.cpp b/src/ui/ui_settings.cpp index c2c34b9..c222dbb 100644 --- a/src/ui/ui_settings.cpp +++ b/src/ui/ui_settings.cpp @@ -7,7 +7,7 @@ #include "administration.hpp" #include "locales.hpp" -extern bool draw_contact_form(contact* buffer, bool back_button_enabled = true, bool viewing_only = false); +extern void draw_contact_form(contact* buffer, bool viewing_only = false); static contact company_info; @@ -312,11 +312,17 @@ void ui_draw_settings() { if (ImGui::BeginTabItem(localize("settings.table.company"))) { - bool save = draw_contact_form(&company_info, false); + draw_contact_form(&company_info); - if (save) { + // Save button. + bool can_save = administration_is_contact_valid(company_info); + if (!can_save) ImGui::BeginDisabled(); + ImGui::Spacing(); + if (ImGui::Button(localize("form.save"))) { administration_set_company_info(company_info); } + if (!can_save) ImGui::EndDisabled(); + ImGui::EndTabItem(); } if (ImGui::BeginTabItem(localize("settings.table.vatrates"))) |
