summaryrefslogtreecommitdiff
path: root/src/administration.cpp
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrikboy@gmail.com>2025-09-07 15:24:11 +0200
committerAldrik Ramaekers <aldrikboy@gmail.com>2025-09-07 15:24:11 +0200
commit12f306e2144081e00c36ed9942068462604bef55 (patch)
treed0279fa5b3fbd976cd18cc05e4e6d245dcd63ea0 /src/administration.cpp
parent026e38982f5388cede0cd7ebad2ea7571d1d57ed (diff)
income statement finalization
Diffstat (limited to 'src/administration.cpp')
-rw-r--r--src/administration.cpp92
1 files changed, 86 insertions, 6 deletions
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)