diff options
| -rw-r--r-- | docs/CHANGES.rst | 1 | ||||
| -rw-r--r-- | include/administration.hpp | 7 | ||||
| -rw-r--r-- | include/ui.hpp | 4 | ||||
| -rw-r--r-- | src/administration.cpp | 92 | ||||
| -rw-r--r-- | src/locales/en.cpp | 9 | ||||
| -rw-r--r-- | src/main.cpp | 1 | ||||
| -rw-r--r-- | src/ui/helpers.cpp | 2 | ||||
| -rw-r--r-- | src/ui/ui_earnings.cpp | 220 | ||||
| -rw-r--r-- | src/ui/ui_settings.cpp | 2 |
9 files changed, 243 insertions, 95 deletions
diff --git a/docs/CHANGES.rst b/docs/CHANGES.rst index 41a2f11..80d676e 100644 --- a/docs/CHANGES.rst +++ b/docs/CHANGES.rst @@ -18,6 +18,7 @@ TODO: - View local business number / vat number naming on contact form. e.g. when country is austria: "Österreichische Umsatzsteuer-Identifikationsnummer" - add allowances to invoice items - add accounting cost to invoice +- if an invoice currency != default currency, final amount should be manually set as the total is always represented in the default currency. v0.1 (master) diff --git a/include/administration.hpp b/include/administration.hpp index 45effee..67efb9c 100644 --- a/include/administration.hpp +++ b/include/administration.hpp @@ -271,6 +271,7 @@ typedef struct char cost_center_id[MAX_LEN_ID]; char description[MAX_LEN_LONG_DESC]; float total; + bool expense_used_in_project; } project_expense; typedef struct @@ -290,6 +291,8 @@ typedef struct float uncategorized_revenue; float uncategorized_taxes; + float profit; + u32 report_count; project_report reports[MAX_LEN_QUARTERLY_REPORT_PROJECTS]; u16 year; // 00-99 @@ -310,6 +313,8 @@ typedef struct s32 next_sequence_number; // Sequence number for generating invoice numbers. char path[MAX_LEN_PATH]; // Full path to save file of current administration file. char program_version[10]; // Program version of exe that stored the save file. + + char default_currency[MAX_LEN_CURRENCY]; // Currency where invoice totals and reports are represented in, based on company location. list_t contacts; list_t projects; @@ -333,6 +338,8 @@ char* administration_file_path_get(); contact administration_company_info_get(); void administration_company_info_set(contact data); void administration_create_income_statement(income_statement* statement); +char* administration_get_currency_symbol_from_currency(char* code); +char* administration_get_default_currency(); // Contact functions. // ======================= diff --git a/include/ui.hpp b/include/ui.hpp index 044eff5..ddfb824 100644 --- a/include/ui.hpp +++ b/include/ui.hpp @@ -1,5 +1,7 @@ #pragma once +#include "imgui.h" + #define STATUS_TEXT_LEN 64 #define STATUS_DURATION 4.0f #define STATUS_FLASH_INTERVAL 0.1f @@ -26,6 +28,8 @@ typedef struct bool loading; } ui_status; +extern ImFont* fontBold; + void ui_helper_draw_required_tag(); void ui_set_status_loading(bool loading); diff --git a/src/administration.cpp b/src/administration.cpp index 0cca2b7..f8cbdb3 100644 --- a/src/administration.cpp +++ b/src/administration.cpp @@ -77,6 +77,7 @@ static time_t administration_get_default_invoice_expire_duration() } static void administration_recalculate_billing_item_totals(billing_item* item); +static char* administration_get_default_currency_for_country(char* country_code); static void administration_get_random_billing_items(invoice* inv) { @@ -357,9 +358,10 @@ static void administration_create_debug_data() strops_copy(g_administration.company_info.address.address2, "", sizeof(g_administration.company_info.address.address2)); strops_copy(g_administration.company_info.address.city, "Maastricht", sizeof(g_administration.company_info.address.city)); strops_copy(g_administration.company_info.address.postal, "6226XW", sizeof(g_administration.company_info.address.postal)); - strops_copy(g_administration.company_info.address.country_code, "NL", sizeof(g_administration.company_info.address.country_code)); + strops_copy(g_administration.company_info.address.country_code, "NL", sizeof(g_administration.company_info.address.country_code)); strops_copy(g_administration.company_info.taxid, "123", sizeof(g_administration.company_info.taxid)); strops_copy(g_administration.company_info.businessid, "123", sizeof(g_administration.company_info.businessid)); + administration_company_info_set(g_administration.company_info); g_administration.next_id++; // Invoices @@ -380,8 +382,8 @@ static void administration_create_debug_data() } // Create about 2 years of random data. - for (int i = 0; i < 200; i++) { ADD_INVOICE(1); } - for (int i = 0; i < 200; i++) { ADD_INVOICE(0); } + for (int i = 0; i < 600; i++) { ADD_INVOICE(1); } + for (int i = 0; i < 600; i++) { ADD_INVOICE(0); } } static s32 administration_create_sequence_number() @@ -436,6 +438,40 @@ void administration_destroy() // Other functions. // ======================= +char* administration_get_default_currency() +{ + return g_administration.default_currency; +} + +char* administration_get_currency_symbol_from_currency(char* code) +{ + // Major European currencies + if (strcmp(code, "EUR") == 0) return "€"; // Euro + if (strcmp(code, "GBP") == 0) return "£"; // British Pound + if (strcmp(code, "CHF") == 0) return "CHF"; // Swiss Franc (no special sign, usually "CHF") + if (strcmp(code, "NOK") == 0) return "kr"; // Norwegian Krone + if (strcmp(code, "SEK") == 0) return "kr"; // Swedish Krona + if (strcmp(code, "DKK") == 0) return "kr"; // Danish Krone + if (strcmp(code, "ISK") == 0) return "kr"; // Icelandic Króna + if (strcmp(code, "CZK") == 0) return "Kč"; // Czech Koruna + if (strcmp(code, "PLN") == 0) return "zł"; // Polish Złoty + if (strcmp(code, "HUF") == 0) return "Ft"; // Hungarian Forint + if (strcmp(code, "RON") == 0) return "lei"; // Romanian Leu + if (strcmp(code, "BGN") == 0) return "лв"; // Bulgarian Lev + if (strcmp(code, "HRK") == 0) return "kn"; // Croatian Kuna (before Euro, now EUR since 2023) + if (strcmp(code, "RSD") == 0) return "дин"; // Serbian Dinar + if (strcmp(code, "MKD") == 0) return "ден"; // Macedonian Denar + if (strcmp(code, "ALL") == 0) return "L"; // Albanian Lek + if (strcmp(code, "MDL") == 0) return "L"; // Moldovan Leu + if (strcmp(code, "BYN") == 0) return "Br"; // Belarusian Ruble + if (strcmp(code, "UAH") == 0) return "₴"; // Ukrainian Hryvnia + if (strcmp(code, "RUB") == 0) return "₽"; // Russian Ruble + if (strcmp(code, "TRY") == 0) return "₺"; // Turkish Lira + + // Unknown currency + return "?"; +} + static void time_t_to_quarter(time_t time, u16* year, u8* quarter) { struct tm *lt = localtime(&time); @@ -444,6 +480,7 @@ static void time_t_to_quarter(time_t time, u16* year, u8* quarter) *quarter = (u8)(lt->tm_mon / 3); } +#if 0 static void administration_debug_print_income_statement(income_statement* statement) { for (u32 i = 0; i < statement->quarter_count; i++) @@ -479,6 +516,7 @@ static void administration_debug_print_income_statement(income_statement* statem printf("\n"); } } +#endif void administration_create_income_statement(income_statement* statement) { @@ -501,13 +539,19 @@ void administration_create_income_statement(income_statement* statement) u16 oldest_year; u8 oldest_quarter; time_t_to_quarter(oldest, &oldest_year, &oldest_quarter); + oldest_quarter = 0; u16 youngest_year; u8 youngest_quarter; time_t_to_quarter(youngest, &youngest_year, &youngest_quarter); + youngest_quarter = 3; u32 num_quarters = (youngest_quarter+1 + (youngest_year*4)) - (oldest_quarter + (oldest_year*4)); assert(num_quarters <= MAX_LEN_INCOME_STATEMENT_REPORT_QUARTERS); + assert(num_quarters % 4 == 0); + + u32 costcenter_count = 0; + u32 project_count = 0; // Generate quarters. for (u32 i = 0; i < num_quarters; i++) @@ -521,12 +565,12 @@ void administration_create_income_statement(income_statement* statement) quarter.report_count = 0; snprintf(quarter.quarter_str, MAX_LEN_SHORT_DESC, "%dQ%d", quarter.quarter+1, quarter.year); - u32 project_count = administration_project_count(); + project_count = administration_project_count(); project* project_buffer = (project*)malloc(sizeof(project)*project_count); project_count = administration_project_get_all(project_buffer); assert(project_count <= MAX_LEN_QUARTERLY_REPORT_PROJECTS); - u32 costcenter_count = administration_cost_center_count(); + costcenter_count = administration_cost_center_count(); cost_center* costcenter_buffer = (cost_center*)malloc(sizeof(cost_center)*costcenter_count); costcenter_count = administration_cost_center_get_all(costcenter_buffer); assert(costcenter_count <= MAX_LEN_PROJECT_REPORT_COSTCENTERS); @@ -547,6 +591,7 @@ void administration_create_income_statement(income_statement* statement) strops_copy(expense.cost_center_id, costcenter_buffer[y].id, MAX_LEN_ID); strops_copy(expense.description, costcenter_buffer[y].description, MAX_LEN_LONG_DESC); expense.total = 0.0f; + expense.expense_used_in_project = true; report.expenses[report.expense_count++] = expense; } @@ -554,6 +599,9 @@ void administration_create_income_statement(income_statement* statement) } statement->quarters[statement->quarter_count++] = quarter; + + free(costcenter_buffer); + free(project_buffer); } // Fill quarters. @@ -574,9 +622,13 @@ void administration_create_income_statement(income_statement* statement) if (inv->is_outgoing) { quarter->uncategorized_revenue += inv->total; quarter->uncategorized_taxes += inv->tax; + + quarter->profit += inv->net; } else { quarter->uncategorized_expenses += inv->total; + + quarter->profit -= inv->total; } } else { @@ -595,9 +647,12 @@ void administration_create_income_statement(income_statement* statement) if (inv->is_outgoing) { report->revenue += inv->total; report->taxes += inv->tax; + + quarter->profit += inv->net; } else { report->expenses_total += inv->total; + quarter->profit -= inv->total; if (strcmp(inv->cost_center_id, "") != 0) { int expense_report_index = -1; @@ -617,6 +672,31 @@ void administration_create_income_statement(income_statement* statement) } } + // Remove unused cost centers from projects. + int years = num_quarters / 4; + for (int i = 0; i < years; i++) + { + for (u32 y = 0; y < costcenter_count; y++) + { + for (u32 x = 0; x < project_count; x++) + { + bool used = false; + + for (u32 q = 0; q < 4; q++) + { + quarterly_report* quarter = &statement->quarters[i*4+q]; + if (quarter->reports[x].expenses[y].total != 0.0f) used = true; + } + + for (u32 q = 0; q < 4; q++) + { + quarterly_report* quarter = &statement->quarters[i*4+q]; + quarter->reports[x].expenses[y].expense_used_in_project = used; + } + } + } + } + //administration_debug_print_income_statement(statement); free(invoice_buffer); @@ -635,6 +715,7 @@ contact administration_company_info_get() void administration_company_info_set(contact data) { g_administration.company_info = data; + strops_copy(g_administration.default_currency, administration_get_default_currency_for_country(g_administration.company_info.address.country_code), MAX_LEN_CURRENCY); } administration* administration_get() @@ -1164,7 +1245,6 @@ bool administration_cost_center_update(cost_center data) // Invoice functions. // ======================= - static char* administration_get_default_currency_for_country(char* country_code) { if (country_code == NULL || strlen(country_code) != 2) diff --git a/src/locales/en.cpp b/src/locales/en.cpp index 6013f84..0fe0a00 100644 --- a/src/locales/en.cpp +++ b/src/locales/en.cpp @@ -43,7 +43,7 @@ locale_entry en_locales[] = { {"taxcategory.Z", "Zero rated goods"}, {"taxcategory.G", "Free export item, VAT not charged"}, {"taxcategory.O", "Services outside scope of tax"}, - {"taxcategory.K", "Intra-community supply of goods and services"}, + {"taxcategory.K", "Intra-community supply of goods"}, // Countries { "country.AT", "Austria" }, @@ -161,6 +161,13 @@ locale_entry en_locales[] = { {"invoice.status.refunded", "Refunded"}, {"invoice.status.corrected", "Corrected"}, {"invoice.status.received", "Received"}, + + // Income statement strings. + {"statement.uncategorized", "Uncategorized"}, + {"statement.revenue", "Revenue"}, + {"statement.tax", "Tax"}, + {"statement.expenses", "Expenses"}, + {"statement.profit", "Profit"}, }; const int en_locale_count = sizeof(en_locales) / sizeof(en_locales[0]);
\ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index fc50c25..289ca57 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -80,6 +80,7 @@ int main() style.FontSizeBase = 18.0f; //io.Fonts->AddFontDefault(); io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf"); + fontBold = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeuib.ttf"); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf"); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf"); //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf"); diff --git a/src/ui/helpers.cpp b/src/ui/helpers.cpp index 37c4b36..0a93cf7 100644 --- a/src/ui/helpers.cpp +++ b/src/ui/helpers.cpp @@ -5,6 +5,8 @@ #include "locales.hpp" #include "strops.hpp" +ImFont* fontBold; + static ui_status current_status; void ui_draw_status() diff --git a/src/ui/ui_earnings.cpp b/src/ui/ui_earnings.cpp index 81e31b5..4f545d2 100644 --- a/src/ui/ui_earnings.cpp +++ b/src/ui/ui_earnings.cpp @@ -21,131 +21,177 @@ void ui_destroy_earnings() void ui_draw_earnings() { - if (ImGui::BeginTable("QuarterlyResultsTable", 5, - ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit)) + static s32 current_page = 0; + s32 max_page = ((statement->quarter_count) / 4); + + if (current_page >= max_page-1) current_page = max_page-1; + if (current_page < 0) current_page = 0; + + bool enable_prev = current_page > 0; + if (!enable_prev) ImGui::BeginDisabled(); + if (ImGui::Button("<< Prev") && current_page > 0) current_page--; + if (!enable_prev) ImGui::EndDisabled(); + + ImGui::SameLine(); + ImGui::Text("(%d/%d)", current_page+1, max_page); + + ImGui::SameLine(); + bool enable_next = current_page < max_page-1; + if (!enable_next) ImGui::BeginDisabled(); + if (ImGui::Button("Next >>") && current_page < max_page-1) current_page++; + if (!enable_next) ImGui::EndDisabled(); + + ImGui::Spacing(); + + char* currency_symbol = administration_get_currency_symbol_from_currency(administration_get_default_currency()); + + if (ImGui::BeginTable("QuarterlyResultsTable", 5, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Hideable)) { - ImGui::TableSetupColumn("##names"); + ImGui::TableSetupColumn("##names", ImGuiTableColumnFlags_WidthFixed, 300); - int quarter_start = 0; int quarter_count = 4; + int quarter_start = current_page*quarter_count; - // Table header + ImGui::PushFont(fontBold); for (int q = 0; q < quarter_count; q++) { - ImGui::TableSetupColumn(statement->quarters[q].quarter_str, ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn(statement->quarters[quarter_start+q].quarter_str, ImGuiTableColumnFlags_WidthStretch); } ImGui::TableHeadersRow(); + ImGui::PopFont(); - // Uncategorized income and expenses - ImGui::TableNextRow(); - ImGui::TableSetColumnIndex(0); ImGui::Text("(Uncategorized)"); - ImGui::TableSetColumnIndex(1); ImGui::Text(""); - ImGui::TableSetColumnIndex(2); ImGui::Text(""); - ImGui::TableSetColumnIndex(3); ImGui::Text(""); - ImGui::TableSetColumnIndex(4); ImGui::Text(""); + bool has_uncategorized_revenue = (statement->quarters[quarter_start + 0].uncategorized_revenue + + statement->quarters[quarter_start + 1].uncategorized_revenue + + statement->quarters[quarter_start + 2].uncategorized_revenue + + statement->quarters[quarter_start + 3].uncategorized_revenue) != 0.0f; - ImGui::TableNextRow(); - ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted(" Revenue"); - ImGui::TableSetColumnIndex(1); ImGui::Text("%.2f", statement->quarters[quarter_start + 0].uncategorized_revenue); - ImGui::TableSetColumnIndex(2); ImGui::Text("%.2f", statement->quarters[quarter_start + 1].uncategorized_revenue); - ImGui::TableSetColumnIndex(3); ImGui::Text("%.2f", statement->quarters[quarter_start + 2].uncategorized_revenue); - ImGui::TableSetColumnIndex(4); ImGui::Text("%.2f", statement->quarters[quarter_start + 3].uncategorized_revenue); + bool has_uncategorized_taxes = (statement->quarters[quarter_start + 0].uncategorized_taxes + + statement->quarters[quarter_start + 1].uncategorized_taxes + + statement->quarters[quarter_start + 2].uncategorized_taxes + + statement->quarters[quarter_start + 3].uncategorized_taxes) != 0.0f; - ImGui::TableNextRow(); - ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted(" Tax"); - ImGui::TableSetColumnIndex(1); ImGui::Text("%.2f", statement->quarters[quarter_start + 0].uncategorized_taxes); - ImGui::TableSetColumnIndex(2); ImGui::Text("%.2f", statement->quarters[quarter_start + 1].uncategorized_taxes); - ImGui::TableSetColumnIndex(3); ImGui::Text("%.2f", statement->quarters[quarter_start + 2].uncategorized_taxes); - ImGui::TableSetColumnIndex(4); ImGui::Text("%.2f", statement->quarters[quarter_start + 3].uncategorized_taxes); + bool has_uncategorized_expenses = (statement->quarters[quarter_start + 0].uncategorized_expenses + + statement->quarters[quarter_start + 1].uncategorized_expenses + + statement->quarters[quarter_start + 2].uncategorized_expenses + + statement->quarters[quarter_start + 3].uncategorized_expenses) != 0.0f; - ImGui::TableNextRow(); - ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted(" Expenses"); - ImGui::TableSetColumnIndex(1); ImGui::Text("%.2f", statement->quarters[quarter_start + 0].uncategorized_expenses); - ImGui::TableSetColumnIndex(2); ImGui::Text("%.2f", statement->quarters[quarter_start + 1].uncategorized_expenses); - ImGui::TableSetColumnIndex(3); ImGui::Text("%.2f", statement->quarters[quarter_start + 2].uncategorized_expenses); - ImGui::TableSetColumnIndex(4); ImGui::Text("%.2f", statement->quarters[quarter_start + 3].uncategorized_expenses); + // Uncategorized income and expenses + if (has_uncategorized_revenue || has_uncategorized_taxes || has_uncategorized_expenses) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); ImGui::Text("(%s)", localize("statement.uncategorized")); + ImGui::TableSetColumnIndex(1); ImGui::Text(""); + ImGui::TableSetColumnIndex(2); ImGui::Text(""); + ImGui::TableSetColumnIndex(3); ImGui::Text(""); + ImGui::TableSetColumnIndex(4); ImGui::Text(""); + } + + if (has_uncategorized_revenue) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); ImGui::Text(" %s", localize("statement.revenue")); + ImGui::TableSetColumnIndex(1); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 0].uncategorized_revenue, currency_symbol); + ImGui::TableSetColumnIndex(2); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 1].uncategorized_revenue, currency_symbol); + ImGui::TableSetColumnIndex(3); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 2].uncategorized_revenue, currency_symbol); + ImGui::TableSetColumnIndex(4); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 3].uncategorized_revenue, currency_symbol); + } + + if (has_uncategorized_taxes) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); ImGui::Text(" %s", localize("statement.tax")); + ImGui::TableSetColumnIndex(1); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 0].uncategorized_taxes, currency_symbol); + ImGui::TableSetColumnIndex(2); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 1].uncategorized_taxes, currency_symbol); + ImGui::TableSetColumnIndex(3); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 2].uncategorized_taxes, currency_symbol); + ImGui::TableSetColumnIndex(4); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 3].uncategorized_taxes, currency_symbol); + } + + if (has_uncategorized_expenses) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); ImGui::Text(" %s", localize("statement.expenses")); + ImGui::TableSetColumnIndex(1); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 0].uncategorized_expenses, currency_symbol); + ImGui::TableSetColumnIndex(2); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 1].uncategorized_expenses, currency_symbol); + ImGui::TableSetColumnIndex(3); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 2].uncategorized_expenses, currency_symbol); + ImGui::TableSetColumnIndex(4); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 3].uncategorized_expenses, currency_symbol); + } quarterly_report default_quater = statement->quarters[0]; for (u32 p = 0; p < default_quater.report_count; p++) { - ImGui::TableNextRow(); project_report* report = &default_quater.reports[p]; - ImGui::TableSetColumnIndex(0); ImGui::Text("(%s)", report->description); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + bool toggled = ImGui::TreeNodeEx(report->description, + ImGuiTreeNodeFlags_SpanFullWidth | + ImGuiTreeNodeFlags_DefaultOpen); + ImGui::TableSetColumnIndex(1); ImGui::Text(""); ImGui::TableSetColumnIndex(2); ImGui::Text(""); ImGui::TableSetColumnIndex(3); ImGui::Text(""); ImGui::TableSetColumnIndex(4); ImGui::Text(""); + if (!toggled) continue; + + ImGui::PushFont(fontBold); ImGui::TableNextRow(); - ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted(" Revenue"); - ImGui::TableSetColumnIndex(1); ImGui::Text("%.2f", statement->quarters[quarter_start + 0].reports[p].revenue); - ImGui::TableSetColumnIndex(2); ImGui::Text("%.2f", statement->quarters[quarter_start + 1].reports[p].revenue); - ImGui::TableSetColumnIndex(3); ImGui::Text("%.2f", statement->quarters[quarter_start + 2].reports[p].revenue); - ImGui::TableSetColumnIndex(4); ImGui::Text("%.2f", statement->quarters[quarter_start + 3].reports[p].revenue); + ImGui::TableSetColumnIndex(0); ImGui::Text(" %s", localize("statement.revenue")); + ImGui::TableSetColumnIndex(1); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 0].reports[p].revenue, currency_symbol); + ImGui::TableSetColumnIndex(2); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 1].reports[p].revenue, currency_symbol); + ImGui::TableSetColumnIndex(3); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 2].reports[p].revenue, currency_symbol); + ImGui::TableSetColumnIndex(4); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 3].reports[p].revenue, currency_symbol); + ImGui::PopFont(); ImGui::TableNextRow(); - ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted(" Tax"); - ImGui::TableSetColumnIndex(1); ImGui::Text("%.2f", statement->quarters[quarter_start + 0].reports[p].taxes); - ImGui::TableSetColumnIndex(2); ImGui::Text("%.2f", statement->quarters[quarter_start + 1].reports[p].taxes); - ImGui::TableSetColumnIndex(3); ImGui::Text("%.2f", statement->quarters[quarter_start + 2].reports[p].taxes); - ImGui::TableSetColumnIndex(4); ImGui::Text("%.2f", statement->quarters[quarter_start + 3].reports[p].taxes); + ImGui::TableSetColumnIndex(0); ImGui::Text(" %s", localize("statement.tax")); + ImGui::TableSetColumnIndex(1); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 0].reports[p].taxes, currency_symbol); + ImGui::TableSetColumnIndex(2); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 1].reports[p].taxes, currency_symbol); + ImGui::TableSetColumnIndex(3); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 2].reports[p].taxes, currency_symbol); + ImGui::TableSetColumnIndex(4); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 3].reports[p].taxes, currency_symbol); + ImGui::PushFont(fontBold); ImGui::TableNextRow(); - ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted(" Expenses"); - ImGui::TableSetColumnIndex(1); ImGui::Text("%.2f", statement->quarters[quarter_start + 0].reports[p].expenses_total); - ImGui::TableSetColumnIndex(2); ImGui::Text("%.2f", statement->quarters[quarter_start + 1].reports[p].expenses_total); - ImGui::TableSetColumnIndex(3); ImGui::Text("%.2f", statement->quarters[quarter_start + 2].reports[p].expenses_total); - ImGui::TableSetColumnIndex(4); ImGui::Text("%.2f", statement->quarters[quarter_start + 3].reports[p].expenses_total); + ImGui::TableSetColumnIndex(0); ImGui::Text(" %s", localize("statement.expenses")); + ImGui::TableSetColumnIndex(1); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 0].reports[p].expenses_total, currency_symbol); + ImGui::TableSetColumnIndex(2); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 1].reports[p].expenses_total, currency_symbol); + ImGui::TableSetColumnIndex(3); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 2].reports[p].expenses_total, currency_symbol); + ImGui::TableSetColumnIndex(4); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 3].reports[p].expenses_total, currency_symbol); + ImGui::PopFont(); for (u32 e = 0; e < report->expense_count; e++) { - ImGui::TableNextRow(); project_expense* expense = &report->expenses[e]; + if (!expense->expense_used_in_project) continue; + ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Text(" %s", localize(expense->description)); - ImGui::TableSetColumnIndex(1); ImGui::Text("%.2f", statement->quarters[quarter_start + 0].reports[p].expenses[e].total); - ImGui::TableSetColumnIndex(2); ImGui::Text("%.2f", statement->quarters[quarter_start + 1].reports[p].expenses[e].total); - ImGui::TableSetColumnIndex(3); ImGui::Text("%.2f", statement->quarters[quarter_start + 2].reports[p].expenses[e].total); - ImGui::TableSetColumnIndex(4); ImGui::Text("%.2f", statement->quarters[quarter_start + 3].reports[p].expenses[e].total); - - + ImGui::TableSetColumnIndex(1); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 0].reports[p].expenses[e].total, currency_symbol); + ImGui::TableSetColumnIndex(2); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 1].reports[p].expenses[e].total, currency_symbol); + ImGui::TableSetColumnIndex(3); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 2].reports[p].expenses[e].total, currency_symbol); + ImGui::TableSetColumnIndex(4); ImGui::Text("%.0f %s", statement->quarters[quarter_start + 3].reports[p].expenses[e].total, currency_symbol); } + + ImGui::TreePop(); } - /* - for (int i = 0; i < 1; i++) - { - quarterly_report quarter = statement->quarters[quarter_start + quarter_index]; + ImGui::PushFont(fontBold); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); ImGui::TextUnformatted(localize("statement.profit")); + + #define PUSH_PROFIT_COLUMN(_profit)\ + ImGui::TableNextColumn(); \ + if (_profit < 0.0f) {\ + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(235, 64, 52, 255));\ + ImGui::Text("(%.0f %s)", _profit, currency_symbol);\ + ImGui::PopStyleColor();\ + }\ + else {\ + ImGui::Text("%.0f %s", _profit, currency_symbol);\ + } - for (u32 p = 0; p < quarter.report_count; p++) - { - ImGui::TableNextRow(); - project_report* report = &quarter.reports[p]; - ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted(report->description); - ImGui::TableSetColumnIndex(1); ImGui::Text(""); - ImGui::TableSetColumnIndex(2); ImGui::Text(""); - ImGui::TableSetColumnIndex(3); ImGui::Text(""); - ImGui::TableSetColumnIndex(4); ImGui::Text(""); - - - // for (u32 e = 0; e < report->expense_count; e++) - // { - // project_expense* expense = &report->expenses[e]; - // ImGui::TableNextColumn(); ImGui::TextUnformatted(expense->description); - // } - } - }*/ - - // // Rows - // for (int i = 0; i < results_count; i++) - // { - // ImGui::TableNextRow(); - // ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted(results[i].quarter); - // ImGui::TableSetColumnIndex(1); ImGui::TextUnformatted(results[i].revenue); - // ImGui::TableSetColumnIndex(2); ImGui::TextUnformatted(results[i].profit); - // ImGui::TableSetColumnIndex(3); ImGui::TextUnformatted(results[i].expenses); - // } + PUSH_PROFIT_COLUMN(statement->quarters[quarter_start + 0].profit); + PUSH_PROFIT_COLUMN(statement->quarters[quarter_start + 1].profit); + PUSH_PROFIT_COLUMN(statement->quarters[quarter_start + 2].profit); + PUSH_PROFIT_COLUMN(statement->quarters[quarter_start + 3].profit); + ImGui::PopFont(); ImGui::EndTable(); } }
\ No newline at end of file diff --git a/src/ui/ui_settings.cpp b/src/ui/ui_settings.cpp index dea58ec..1746111 100644 --- a/src/ui/ui_settings.cpp +++ b/src/ui/ui_settings.cpp @@ -47,7 +47,7 @@ static void ui_draw_vat_rates() if (ImGui::BeginTable("TableVatRates", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) { - ImGui::TableSetupColumn(localize("settings.vat.table.country"), ImGuiTableColumnFlags_WidthFixed, 140); + ImGui::TableSetupColumn(localize("settings.vat.table.country"), ImGuiTableColumnFlags_WidthFixed, 220); ImGui::TableSetupColumn(localize("settings.vat.table.rates")); // Used to generate headers for each individual country. |
