diff options
| author | Aldrik Ramaekers <aldrikboy@gmail.com> | 2025-08-09 11:18:02 +0200 |
|---|---|---|
| committer | Aldrik Ramaekers <aldrikboy@gmail.com> | 2025-08-09 11:18:02 +0200 |
| commit | 2cf031b91d5248561fbeff78ceccb0b2d6c73809 (patch) | |
| tree | 0fdd8d1a3aaf3f937b01d708fb334116833fdecb | |
| parent | 432f24319319fe040e142059eb83279c53f90ab8 (diff) | |
refactors, working on settings view
| -rw-r--r-- | NOTES.md | 27 | ||||
| -rw-r--r-- | include/administration.hpp | 77 | ||||
| -rw-r--r-- | include/locales.hpp | 3 | ||||
| -rw-r--r-- | include/ui.hpp | 12 | ||||
| -rw-r--r-- | run.bat | 22 | ||||
| -rw-r--r-- | src/administration.cpp | 162 | ||||
| -rw-r--r-- | src/locales.cpp | 3 | ||||
| -rw-r--r-- | src/ui/helpers.cpp | 39 | ||||
| -rw-r--r-- | src/ui/ui_contacts.cpp | 92 | ||||
| -rw-r--r-- | src/ui/ui_invoices.cpp | 15 | ||||
| -rw-r--r-- | src/ui/ui_main.cpp | 34 | ||||
| -rw-r--r-- | src/ui/ui_projects.cpp | 10 | ||||
| -rw-r--r-- | src/ui/ui_settings.cpp | 35 |
13 files changed, 464 insertions, 67 deletions
@@ -46,6 +46,7 @@ administration.money/ | contacts `list` | List of contacts | | projects `list` | List of projects | | invoices `list` | List of invoices | +| tax brackets `list` | List of available tax brackets | | AI service | Which AI service to use | | AI key | API key for selected AI service | | email service | Which email service to use | @@ -58,6 +59,7 @@ administration.money/ | address line 1 `required` | Address | | address line 2 `required` | Zip, place | | country `required` | Country | +| type `required` | Contact type, `business` or `consumer` | | tax number | Tax identification number | | business number | Business number | | email | Email address | @@ -68,7 +70,6 @@ administration.money/ |-|-| | id `auto` | reference id `I/[id]` | | sequential number `auto` | Generated sequential invoice number | -| is outgoing `required` | incoming or outgoing invoice | | customer `required` | Customer contact information, stored as reference `C/[id]` | | supplier `required` | Supplier contact information, stored as reference `C/[id]` | | issue at `required` | Date when invoice was issued | @@ -77,13 +78,15 @@ administration.money/ | document `required` | Document associated with invoice, stored as filename | | billing items `required` `list` | List of billed items | | project `required` | Project, stored as reference `P/[id]` | -| category `required` | Expense category (incomming invoices only) | +| cost center id `required` | Cost center, stored as reference `E/[id]` (incomming invoices only) | +| cost unit id `required` | Cost unit, stored as reference `U/[id]` (incomming invoices only) | | total `required` | Total amount billed | | tax `required` | Total tax billed | | net `required` | Total amount excl. tax | -| status `required` | Payment status `paid` `expired` `cancelled` `refunded` | +| status `required` | Payment status `paid` `expired` `cancelled` `refunded`, `corrected` | | shipping address line 1 `required` | Address | -| shipping address line 2 `required` | Zip, place, country | +| shipping address line 2 `required` | Zip, place | +| country `required` | Country | | currency `required` | Currency used for billing | | keep untill `required` | Date untill invoice needs to be stored legally | | payment on account date | If advance payment received and differs from invoice date (Ireland only) | @@ -95,7 +98,7 @@ administration.money/ | id `auto` | reference id `B/[id]` | | invoice `auto` | reference to invoice `I/[id]` | | description `required` | Description of billed item | -| tax percentage `required` | Tax percentage (e.g. 0%, 21%, exempt, reversed) | +| tax bracket `required` | Tax bracket (e.g. 0%, 21%, exempt, reversed) | | tax section `required` | Tax section (e.g. 1a upto 4b in The Netherlands) | | amount `required` | Amount of items | | net per item `required` | Price per item excl. tax | @@ -113,4 +116,16 @@ administration.money/ | description `required` | Description of project | | start date `required` | Project started at date | | status `required` | Status of project `running` `paused` `cancelled` | -| end date | Project cancelled at date |
\ No newline at end of file +| end date | Project cancelled at date | + +| Cost center|| +|-|-| +| id `auto` | reference id `E/[id]` | +| code `required` | Code of cost center | +| description `required` | Description of cost center | + +| Cost unit|| +|-|-| +| id `auto` | reference id `U/[id]` | +| code `required` | Code of cost center | +| description `required` | Description of cost center |
\ No newline at end of file diff --git a/include/administration.hpp b/include/administration.hpp index 9506246..79ca6ab 100644 --- a/include/administration.hpp +++ b/include/administration.hpp @@ -5,11 +5,23 @@ typedef struct { - char id[16]; - char name[64]; + char country_code[3]; + float rate; + char description[16]; +} country_tax_bracket; + +typedef struct +{ char address1[128]; char address2[128]; char country[128]; +} address; + +typedef struct +{ + char id[16]; + char name[64]; + address address; char taxid[32]; char businessid[32]; char email[64]; @@ -33,16 +45,70 @@ typedef struct time_t end_date; } project; +typedef enum +{ + INVOICE_PAID, + INVOICE_EXPIRED, + INVOICE_CANCELLED, + INVOICE_REFUNDED, + INVOICE_CORRECTED, +} invoice_status; + +typedef struct +{ + char id[16]; + char invoice_id[16]; + char description[128]; + country_tax_bracket tax_bracket; + char tax_section[16]; + s32 amount; + s32 net_per_item; + s32 net; + s32 discount; + s32 tax; + bool is_intra_community; + bool is_triangulation; + char currency[16]; + char internal_code[64]; +} billing_item; + +typedef struct +{ + char id[16]; + char sequential_number[16]; + char customer_id[16]; + char supplier_id[16]; + time_t issued_at; + time_t delivered_at; + time_t expires_at; + char document[255]; + list_t billing_items; + char project_id[16]; + char cost_center_id[16]; + char cost_unit_id[16]; + s32 total; + s32 tax; + s32 net; + invoice_status status; + address shipping_address; + char currency[16]; + time_t keep_untill; + time_t payment_on_account_date; + char tax_representative[64]; + char corrected_sequential_number[16]; +} invoice; + typedef struct { contact company_info; s32 next_id; char path[4096]; char program_version[10]; - char country_code[2]; + char country_code[3]; list_t contacts; list_t projects; - // invoices + list_t invoices; + list_t tax_brackets; char ai_service[16]; char ai_key[32]; char email_service[16]; @@ -55,6 +121,9 @@ void administration_destroy(); char* administration_get_file_path(); s32 administration_create_id(); +contact administration_get_company_info(); +void administration_set_company_info(contact data); + bool administration_remove_contact(contact data); bool administration_create_contact(contact data); bool administration_update_contact(contact data); diff --git a/include/locales.hpp b/include/locales.hpp index 78bb682..ff116d5 100644 --- a/include/locales.hpp +++ b/include/locales.hpp @@ -1,8 +1,5 @@ #pragma once -#include <stdio.h> -#include <string.h> - typedef struct { const char* key; const char* value; diff --git a/include/ui.hpp b/include/ui.hpp index 827980c..85a5c2f 100644 --- a/include/ui.hpp +++ b/include/ui.hpp @@ -8,8 +8,16 @@ typedef enum VIEW, } view_state; -void view_draw_required_tag(); +void ui_helper_draw_required_tag(); +void ui_helper_show_toast(const char* msg); +void ui_helper_draw_toasts(); void ui_draw_main(); void ui_draw_contacts(); -void ui_draw_projects();
\ No newline at end of file +void ui_draw_projects(); +void ui_draw_invoices(); +void ui_draw_settings(); + +void ui_setup_contacts(); +void ui_setup_projects(); +void ui_setup_settings();
\ No newline at end of file @@ -1,10 +1,28 @@ -call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 +@echo off +REM Find the latest Visual Studio installation path +for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -property installationPath`) do ( + set VSPath=%%i +) + +REM Check if found +if not defined VSPath ( + echo Visual Studio not found. + exit /b 1 +) + +set VCVARSALL=%VSPath%\VC\Auxiliary\Build\vcvarsall.bat +if not exist "%VCVARSALL%" ( + echo vcvarsall.bat not found at "%VCVARSALL%" + exit /b 1 +) + +call "%VCVARSALL%" x64 @set OUT_DIR=build\\ @set OUT_EXE=accounting @set LIB_SOURCES=libs\imgui-1.92.1\backends\imgui_impl_dx11.cpp libs\imgui-1.92.1\backends\imgui_impl_win32.cpp libs\imgui-1.92.1\imgui*.cpp libs\simclist-1.5\simclist.c @set SOURCES= src\*.cpp src\ui\*.cpp src\locales\*.cpp @set LIBS=opengl32.lib Advapi32.lib Shell32.lib Ole32.lib User32.lib Pathcch.lib D3D11.lib -@set FLAGS= /std:c11 /nologo /Ob0 /MT /Oy- /Zi /FS /W4 /EHsc /utf-8 +@set FLAGS=/nologo /Ob0 /MT /Oy- /Zi /FS /W4 /EHsc /utf-8 @set INCLUDE_DIRS=/I"libs/imgui-1.92.1" /I"libs/imgui-1.92.1/backends" /I"/" /I"libs/simclist-1.5" /Iinclude cl %FLAGS% %INCLUDE_DIRS% %SOURCES% %LIB_SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fd%OUT_DIR%/vc140.pdb /Fo%OUT_DIR%/ /link %LIBS% diff --git a/src/administration.cpp b/src/administration.cpp index fb8bd21..5e323d0 100644 --- a/src/administration.cpp +++ b/src/administration.cpp @@ -8,17 +8,169 @@ administration g_administration; +static void administration_create_default_tax_brackets() +{ + #define ADD_BRACKET(_country, _rate, _description)\ + {\ + country_tax_bracket* tb = (country_tax_bracket*)malloc(sizeof(country_tax_bracket));\ + memcpy(tb->country_code, _country, sizeof(tb->country_code));\ + tb->rate = _rate;\ + memcpy(tb->description, _country, sizeof(tb->description));\ + list_append(&g_administration.tax_brackets, tb);\ + } + + // General brackets shared between countries. + ADD_BRACKET("00", 0.0f, "tax.reverse_charge"); + ADD_BRACKET("00", 0.0f, "tax.exempt"); + + // Austria + ADD_BRACKET("AT", 20.0f, "Standard"); + ADD_BRACKET("AT", 10.0f, "Reduced"); + ADD_BRACKET("AT", 13.0f, "Reduced"); + + // Belgium + ADD_BRACKET("BE", 21.0f, "Standard"); + ADD_BRACKET("BE", 6.0f, "Reduced"); + ADD_BRACKET("BE", 12.0f, "Reduced"); + + // Bulgaria + ADD_BRACKET("BG", 20.0f, "Standard"); + ADD_BRACKET("BG", 9.0f, "Reduced"); + + // Cyprus + ADD_BRACKET("CY", 19.0f, "Standard"); + ADD_BRACKET("CY", 5.0f, "Reduced"); + ADD_BRACKET("CY", 9.0f, "Reduced"); + + // Czechia + ADD_BRACKET("CZ", 21.0f, "Standard"); + ADD_BRACKET("CZ", 12.0f, "Reduced"); + + // Croatia + ADD_BRACKET("HR", 25.0f, "Standard"); + ADD_BRACKET("HR", 5.0f, "Reduced"); + ADD_BRACKET("HR", 13.0f, "Reduced"); + + // Denmark + ADD_BRACKET("DK", 25.0f, "Standard"); + + // Estonia + ADD_BRACKET("EE", 22.0f, "Standard"); + ADD_BRACKET("EE", 9.0f, "Reduced"); + + // Finland + ADD_BRACKET("FI", 25.5f, "Standard"); + ADD_BRACKET("FI", 10.0f, "Reduced"); + ADD_BRACKET("FI", 14.0f, "Reduced"); + + // France + ADD_BRACKET("FR", 20.0f, "Standard"); + ADD_BRACKET("FR", 5.5f, "Reduced"); + ADD_BRACKET("FR", 10.0f, "Reduced"); + ADD_BRACKET("FR", 2.1f, "SuperReduced"); + + // Germany + ADD_BRACKET("DE", 19.0f, "Standard"); + ADD_BRACKET("DE", 7.0f, "Reduced"); + + // Greece + ADD_BRACKET("GR", 24.0f, "Standard"); + ADD_BRACKET("GR", 6.0f, "Reduced"); + ADD_BRACKET("GR", 13.0f, "Reduced"); + + // Hungary + ADD_BRACKET("HU", 27.0f, "Standard"); + ADD_BRACKET("HU", 5.0f, "Reduced"); + ADD_BRACKET("HU", 18.0f, "Reduced"); + + // Ireland + ADD_BRACKET("IE", 23.0f, "Standard"); + ADD_BRACKET("IE", 9.0f, "Reduced"); + ADD_BRACKET("IE", 13.5f, "Reduced"); + ADD_BRACKET("IE", 4.8f, "SuperReduced"); + + // Italy + ADD_BRACKET("IT", 22.0f, "Standard"); + ADD_BRACKET("IT", 5.0f, "Reduced"); + ADD_BRACKET("IT", 10.0f, "Reduced"); + ADD_BRACKET("IT", 4.0f, "SuperReduced"); + + // Latvia + ADD_BRACKET("LV", 21.0f, "Standard"); + ADD_BRACKET("LV", 5.0f, "Reduced"); + ADD_BRACKET("LV", 12.0f, "Reduced"); + + // Lithuania + ADD_BRACKET("LT", 21.0f, "Standard"); + ADD_BRACKET("LT", 5.0f, "Reduced"); + ADD_BRACKET("LT", 9.0f, "Reduced"); + + // Luxembourg + ADD_BRACKET("LU", 17.0f, "Standard"); + ADD_BRACKET("LU", 8.0f, "Reduced"); + ADD_BRACKET("LU", 14.0f, "Reduced"); + ADD_BRACKET("LU", 3.0f, "SuperReduced"); + + // Malta + ADD_BRACKET("MT", 18.0f, "Standard"); + ADD_BRACKET("MT", 5.0f, "Reduced"); + ADD_BRACKET("MT", 7.0f, "Reduced"); + + // Netherlands + ADD_BRACKET("NL", 21.0f, "Standard"); + ADD_BRACKET("NL", 9.0f, "Reduced"); + + // Poland + ADD_BRACKET("PL", 23.0f, "Standard"); + ADD_BRACKET("PL", 5.0f, "Reduced"); + ADD_BRACKET("PL", 8.0f, "Reduced"); + + // Portugal + ADD_BRACKET("PT", 23.0f, "Standard"); + ADD_BRACKET("PT", 6.0f, "Reduced"); + ADD_BRACKET("PT", 13.0f, "Reduced"); + + // Romania + ADD_BRACKET("RO", 19.0f, "Standard"); + ADD_BRACKET("RO", 5.0f, "Reduced"); + ADD_BRACKET("RO", 9.0f, "Reduced"); + + // Slovakia + ADD_BRACKET("SK", 23.0f, "Standard"); + ADD_BRACKET("SK", 5.0f, "Reduced"); + ADD_BRACKET("SK", 19.0f, "Reduced"); + + // Slovenia + ADD_BRACKET("SI", 22.0f, "Standard"); + ADD_BRACKET("SI", 5.0f, "Reduced"); + ADD_BRACKET("SI", 9.5f, "Reduced"); + + // Spain + ADD_BRACKET("ES", 21.0f, "Standard"); + ADD_BRACKET("ES", 10.0f, "Reduced"); + ADD_BRACKET("ES", 4.0f, "SuperReduced"); + + // Sweden + ADD_BRACKET("SE", 25.0f, "Standard"); + ADD_BRACKET("SE", 6.0f, "Reduced"); + ADD_BRACKET("SE", 12.0f, "Reduced"); +} + void administration_create() { list_init(&g_administration.contacts); list_init(&g_administration.projects); + list_init(&g_administration.tax_brackets); strops_copy(g_administration.path, "[unsaved project]", sizeof(g_administration.path)); // @localize + + administration_create_default_tax_brackets(); } void administration_destroy() { list_destroy(&g_administration.contacts); list_destroy(&g_administration.projects); + list_destroy(&g_administration.tax_brackets); } bool administration_create_contact(contact data) @@ -195,4 +347,14 @@ bool administration_remove_project(project data) list_iterator_stop(&g_administration.projects); return false; +} + +contact administration_get_company_info() +{ + return g_administration.company_info; +} + +void administration_set_company_info(contact data) +{ + g_administration.company_info = data; }
\ No newline at end of file diff --git a/src/locales.cpp b/src/locales.cpp index 6ec1233..363d3c9 100644 --- a/src/locales.cpp +++ b/src/locales.cpp @@ -1,3 +1,6 @@ +#include <stdio.h> +#include <string.h> + #include "locales.hpp" locale_map locales[] = { diff --git a/src/ui/helpers.cpp b/src/ui/helpers.cpp index 74876c0..e4b25c8 100644 --- a/src/ui/helpers.cpp +++ b/src/ui/helpers.cpp @@ -2,7 +2,44 @@ #include "imgui.h" #include "locales.hpp" -void view_draw_required_tag() +static float toast_timer = 0.0f; +static const char* toast_msg = nullptr; +void ui_helper_show_toast(const char* msg) +{ + toast_msg = msg; + toast_timer = 3.0f; +} + +void ui_helper_draw_toasts() +{ + if (toast_timer > 0.0f && toast_msg) + { + toast_timer -= ImGui::GetIO().DeltaTime; + + const float pad = 10.0f; + const ImVec2 window_pos = ImVec2( + ImGui::GetIO().DisplaySize.x - pad, + ImGui::GetIO().DisplaySize.y - pad + ); + const ImVec2 window_pos_pivot = ImVec2(1.0f, 1.0f); + + ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); + ImGui::SetNextWindowBgAlpha(0.85f); // semi-transparent + + ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | + ImGuiWindowFlags_AlwaysAutoResize | + ImGuiWindowFlags_NoFocusOnAppearing | + ImGuiWindowFlags_NoNav; + + if (ImGui::Begin("##Toast", nullptr, flags)) + { + ImGui::TextUnformatted(toast_msg); + } + ImGui::End(); + } +} + +void ui_helper_draw_required_tag() { ImDrawList* draw_list = ImGui::GetWindowDrawList(); diff --git a/src/ui/ui_contacts.cpp b/src/ui/ui_contacts.cpp index 3115a77..fd9907f 100644 --- a/src/ui/ui_contacts.cpp +++ b/src/ui/ui_contacts.cpp @@ -6,44 +6,51 @@ #include "administration.hpp" #include "locales.hpp" -static view_state current_view_state = LIST; +static view_state current_view_state = view_state::LIST; static contact selected_for_removal; static contact active_contact; -static void draw_contact_form() +void ui_setup_contacts() { - static const char* selected_country = NULL; + current_view_state = view_state::LIST; + memset(&active_contact, 0, sizeof(contact)); + memset(&selected_for_removal, 0, sizeof(contact)); +} - if (ImGui::Button(localize("form.back"))) { - current_view_state = view_state::LIST; - memset(&active_contact, 0, sizeof(contact)); - selected_country = 0; - return; +bool draw_contact_form(contact* buffer, bool back_button_enabled = true, bool viewing_only = 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(); - bool viewing_only = (current_view_state == view_state::VIEW); - ImGui::BeginDisabled(); float widthAvailable = ImGui::GetContentRegionAvail().x; ImGui::SetNextItemWidth(widthAvailable*0.2f); - ImGui::InputText(localize("contact.form.identifier"), active_contact.id, IM_ARRAYSIZE(active_contact.id)); + ImGui::InputText(localize("contact.form.identifier"), buffer->id, IM_ARRAYSIZE(buffer->id)); if (!viewing_only) ImGui::EndDisabled(); ImGui::SetNextItemWidth(widthAvailable*0.5f); - ImGui::InputTextWithHint(localize("contact.form.fullname"), localize("contact.form.fullname"), active_contact.name, IM_ARRAYSIZE(active_contact.name)); - ImGui::SameLine();view_draw_required_tag(); + ImGui::InputTextWithHint(localize("contact.form.fullname"), localize("contact.form.fullname"), buffer->name, IM_ARRAYSIZE(buffer->name)); + ImGui::SameLine();ui_helper_draw_required_tag(); ImGui::SetNextItemWidth(widthAvailable*0.5f); - ImGui::InputTextWithHint(localize("contact.form.address1"), localize("contact.form.address1"), active_contact.address1, IM_ARRAYSIZE(active_contact.address1)); - ImGui::SameLine();view_draw_required_tag(); + ImGui::InputTextWithHint(localize("contact.form.address1"), localize("contact.form.address1"), buffer->address.address1, IM_ARRAYSIZE(buffer->address.address1)); + ImGui::SameLine();ui_helper_draw_required_tag(); ImGui::SetNextItemWidth(widthAvailable*0.5f); - ImGui::InputTextWithHint(localize("contact.form.address2"), localize("contact.form.address2"), active_contact.address2, IM_ARRAYSIZE(active_contact.address2)); - ImGui::SameLine();view_draw_required_tag(); + ImGui::InputTextWithHint(localize("contact.form.address2"), localize("contact.form.address2"), buffer->address.address2, IM_ARRAYSIZE(buffer->address.address2)); + ImGui::SameLine();ui_helper_draw_required_tag(); ImGui::SetNextItemWidth(widthAvailable*0.5f); @@ -52,7 +59,7 @@ static void draw_contact_form() if (selected_country == 0) { for (int i = 0; i < country_count; i++) { - if (strcmp(countries[i], active_contact.country) == 0) + if (strcmp(countries[i], buffer->address.country) == 0) { selected_country = countries[i]; break; @@ -71,50 +78,43 @@ static void draw_contact_form() ImGui::EndCombo(); } if (selected_country) { - strops_copy(active_contact.country, selected_country, IM_ARRAYSIZE(active_contact.country)); + strops_copy(buffer->address.country, selected_country, IM_ARRAYSIZE(buffer->address.country)); } - ImGui::SameLine();view_draw_required_tag(); + ImGui::SameLine();ui_helper_draw_required_tag(); ImGui::SetNextItemWidth(widthAvailable*0.5f); - ImGui::InputTextWithHint(localize("contact.form.taxnumber"), localize("contact.form.taxnumber"), active_contact.taxid, IM_ARRAYSIZE(active_contact.taxid)); + ImGui::InputTextWithHint(localize("contact.form.taxnumber"), localize("contact.form.taxnumber"), buffer->taxid, IM_ARRAYSIZE(buffer->taxid)); ImGui::SetNextItemWidth(widthAvailable*0.5f); - ImGui::InputTextWithHint(localize("contact.form.businessnumber"), localize("contact.form.businessnumber"), active_contact.businessid, IM_ARRAYSIZE(active_contact.businessid)); + ImGui::InputTextWithHint(localize("contact.form.businessnumber"), localize("contact.form.businessnumber"), buffer->businessid, IM_ARRAYSIZE(buffer->businessid)); ImGui::SetNextItemWidth(widthAvailable*0.5f); - ImGui::InputTextWithHint(localize("contact.form.email"), localize("contact.form.email"), active_contact.email, IM_ARRAYSIZE(active_contact.email)); + ImGui::InputTextWithHint(localize("contact.form.email"), localize("contact.form.email"), buffer->email, IM_ARRAYSIZE(buffer->email)); ImGui::SetNextItemWidth(widthAvailable*0.5f); - ImGui::InputTextWithHint(localize("contact.form.phonenumber"), localize("contact.form.phonenumber"), active_contact.phone_number, IM_ARRAYSIZE(active_contact.phone_number)); + ImGui::InputTextWithHint(localize("contact.form.phonenumber"), localize("contact.form.phonenumber"), buffer->phone_number, IM_ARRAYSIZE(buffer->phone_number)); ImGui::SetNextItemWidth(widthAvailable*0.5f); - ImGui::InputTextWithHint(localize("contact.form.bankaccount"), localize("contact.form.bankaccount"), active_contact.bank_account, IM_ARRAYSIZE(active_contact.bank_account)); + 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(active_contact.name) > 0 && strlen(active_contact.address1) > 0 && - strlen(active_contact.address2) > 0 && strlen(active_contact.country) > 0; + bool can_save = strlen(buffer->name) > 0 && strlen(buffer->address.address1) > 0 && + strlen(buffer->address.address2) > 0 && strlen(buffer->address.country) > 0; if (!can_save) ImGui::BeginDisabled(); // Save button ImGui::Spacing(); if (ImGui::Button(localize("form.save"))) { - if (current_view_state == view_state::CREATE) - administration_create_contact(active_contact); - - else if (current_view_state == view_state::EDIT) - administration_update_contact(active_contact); - - memset(&active_contact, 0, sizeof(contact)); - current_view_state = view_state::LIST; - selected_country = 0; + return true; } if (!can_save) ImGui::EndDisabled(); } else { // TODO list invoices connected to contact. } + return false; } static void draw_contact_list() @@ -168,7 +168,7 @@ static void draw_contact_list() ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Text(c.id); ImGui::TableSetColumnIndex(1); ImGui::Text(c.name); - ImGui::TableSetColumnIndex(2); ImGui::Text("%s %s", c.address1, c.address2); + ImGui::TableSetColumnIndex(2); ImGui::Text("%s %s", c.address.address1, c.address.address2); ImGui::TableSetColumnIndex(3); @@ -221,8 +221,20 @@ void ui_draw_contacts() switch(current_view_state) { case view_state::LIST: draw_contact_list(); break; - case view_state::CREATE: draw_contact_form(); break; - case view_state::EDIT: draw_contact_form(); break; - case view_state::VIEW: draw_contact_form(); break; + case view_state::CREATE: + if (draw_contact_form(&active_contact)) + { + administration_create_contact(active_contact); + 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; + } + 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 new file mode 100644 index 0000000..ea45f4e --- /dev/null +++ b/src/ui/ui_invoices.cpp @@ -0,0 +1,15 @@ +#include <stdio.h> + +#include "strops.hpp" +#include "ui.hpp" +#include "imgui.h" +#include "administration.hpp" +#include "locales.hpp" + +static view_state current_view_state = LIST; +static invoice active_invoice; + +void ui_draw_invoices() +{ + +}
\ No newline at end of file diff --git a/src/ui/ui_main.cpp b/src/ui/ui_main.cpp index f6661b8..8af8dbc 100644 --- a/src/ui/ui_main.cpp +++ b/src/ui/ui_main.cpp @@ -11,20 +11,38 @@ typedef enum REPORT_RESULTS = 3, REPORT_TAX = 4, PROJECTS = 5, + SETTINGS = 6, END } dashboard_view_state; static dashboard_view_state dashboard_state = dashboard_view_state::INVOICES; void (*drawcalls[dashboard_view_state::END])(void) = { - 0, + ui_draw_invoices, 0, ui_draw_contacts, 0, 0, ui_draw_projects, + ui_draw_settings, }; +void (*setupcalls[dashboard_view_state::END])(void) = { + 0, + 0, + ui_setup_contacts, + 0, + 0, + ui_setup_projects, + ui_setup_settings, +}; + +static void set_dashboard_state(dashboard_view_state state) +{ + dashboard_state = state; + if (setupcalls[dashboard_state]) setupcalls[dashboard_state](); +} + void ui_draw_main() { // @localize @@ -59,21 +77,22 @@ void ui_draw_main() float buttonWidth = sidePanelWidth; - if (ImGui::Button(localize("nav.invoices"), ImVec2(buttonWidth, 24))) dashboard_state = dashboard_view_state::INVOICES; - if (ImGui::Button(localize("nav.expenses"), ImVec2(buttonWidth, 24))) dashboard_state = dashboard_view_state::EXPENSES; - if (ImGui::Button(localize("nav.contacts"), ImVec2(buttonWidth, 24))) dashboard_state = dashboard_view_state::CONTACTS; + if (ImGui::Button(localize("nav.invoices"), ImVec2(buttonWidth, 24))) set_dashboard_state(dashboard_view_state::INVOICES); + if (ImGui::Button(localize("nav.expenses"), ImVec2(buttonWidth, 24))) set_dashboard_state(dashboard_view_state::EXPENSES); + if (ImGui::Button(localize("nav.contacts"), ImVec2(buttonWidth, 24))) set_dashboard_state(dashboard_view_state::CONTACTS); static bool reports_opened = false; if (ImGui::Button(localize("nav.reports"), ImVec2(buttonWidth, 24))) reports_opened = !reports_opened; if (reports_opened) { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(20.0f, 0.0f)); - if (ImGui::Button(localize("nav.reports.results"), ImVec2(buttonWidth, 24))) dashboard_state = dashboard_view_state::REPORT_RESULTS; - if (ImGui::Button(localize("nav.reports.tax"), ImVec2(buttonWidth, 24))) dashboard_state = dashboard_view_state::REPORT_TAX; + if (ImGui::Button(localize("nav.reports.results"), ImVec2(buttonWidth, 24))) set_dashboard_state(dashboard_view_state::REPORT_RESULTS); + if (ImGui::Button(localize("nav.reports.tax"), ImVec2(buttonWidth, 24))) set_dashboard_state(dashboard_view_state::REPORT_TAX); ImGui::PopStyleVar(); } - if (ImGui::Button(localize("nav.Projects"), ImVec2(buttonWidth, 24))) dashboard_state = dashboard_view_state::PROJECTS; + if (ImGui::Button(localize("nav.Projects"), ImVec2(buttonWidth, 24))) set_dashboard_state(dashboard_view_state::PROJECTS); + if (ImGui::Button("Settings", ImVec2(buttonWidth, 24))) set_dashboard_state(dashboard_view_state::SETTINGS); //@localize ImGui::PopStyleColor(1); ImGui::PopStyleVar(3); @@ -87,6 +106,7 @@ void ui_draw_main() // Main content ImGui::Begin("AccountingMainWindow", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse); if (drawcalls[dashboard_state]) drawcalls[dashboard_state](); + ui_helper_draw_toasts(); ImGui::End(); // Status bar. diff --git a/src/ui/ui_projects.cpp b/src/ui/ui_projects.cpp index 9490254..a349814 100644 --- a/src/ui/ui_projects.cpp +++ b/src/ui/ui_projects.cpp @@ -5,11 +5,17 @@ #include "administration.hpp" #include "locales.hpp" -static view_state current_view_state = LIST; +static view_state current_view_state = view_state::LIST; static project selected_for_cancellation; static project active_project; +void ui_setup_projects() +{ + current_view_state = view_state::LIST; + memset(&active_project, 0, sizeof(contact)); +} + static void draw_project_form() { static const char* selected_country = NULL; @@ -34,7 +40,7 @@ static void draw_project_form() ImGui::SetNextItemWidth(widthAvailable*0.5f); ImGui::InputTextWithHint(localize("project.form.description"), localize("project.form.description"), active_project.description, IM_ARRAYSIZE(active_project.description)); - ImGui::SameLine();view_draw_required_tag(); + ImGui::SameLine();ui_helper_draw_required_tag(); if (viewing_only) ImGui::EndDisabled(); diff --git a/src/ui/ui_settings.cpp b/src/ui/ui_settings.cpp new file mode 100644 index 0000000..81f6d31 --- /dev/null +++ b/src/ui/ui_settings.cpp @@ -0,0 +1,35 @@ +#include "ui.hpp" +#include "imgui.h" +#include "administration.hpp" +#include "locales.hpp" + +extern bool draw_contact_form(contact* buffer, bool back_button_enabled = true, bool viewing_only = false); + +static contact company_info; +void ui_setup_settings() +{ + company_info = administration_get_company_info(); +} + +void ui_draw_settings() +{ + // @localize + if (ImGui::BeginTabBar("SettingsTabBar", 0)) + { + if (ImGui::BeginTabItem("Company")) + { + bool save = draw_contact_form(&company_info, false); + + if (save) { + administration_set_company_info(company_info); + } + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("VAT Rates")) + { + ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah"); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } +}
\ No newline at end of file |
