diff options
Diffstat (limited to 'src/administration.cpp')
| -rw-r--r-- | src/administration.cpp | 92 |
1 files changed, 90 insertions, 2 deletions
diff --git a/src/administration.cpp b/src/administration.cpp index 9790281..9adce55 100644 --- a/src/administration.cpp +++ b/src/administration.cpp @@ -20,6 +20,7 @@ #include "memops.hpp" #include "logger.hpp" #include "strops.hpp" +#include "countries.hpp" #include "administration.hpp" #include "administration_writer.hpp" @@ -45,7 +46,7 @@ static int compare_tax_countries(const void *a, const void *b) return strcmp(objA->country_code, objB->country_code); } -time_t administration::get_default_invoice_expire_duration() +time_t administration::get_default_invoice_expire_duration() // TODO depricated { return (30 * 24 * 60 * 60); // 30 days } @@ -475,6 +476,93 @@ static void administration_debug_print_income_statement(income_statement* statem } #endif +void administration::create_tax_statement(tax_statement* statement) +{ + STOPWATCH_START; + + char* country_code = company_info_get().address.country_code; + + assert(statement); + statement->quarter_count = 0; + + u32 invoice_count = administration::invoice_count(); + if (invoice_count == 0) return; + invoice* invoice_buffer = (invoice*)memops::alloc(sizeof(invoice)*invoice_count); + invoice_count = administration::invoice_get_all(invoice_buffer); + + // Find oldest and youngest invoice. + time_t oldest = INT64_MAX; + time_t youngest = 0; + for (u32 i = 0; i < invoice_count; i++) + { + if (invoice_buffer[i].delivered_at < oldest) oldest = invoice_buffer[i].delivered_at; + if (invoice_buffer[i].delivered_at > youngest) youngest = invoice_buffer[i].delivered_at; + } + + 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); + + // Generate quarters. + for (u32 i = 0; i < num_quarters; i++) + { + tax_report quarter; + quarter.year = oldest_year + (u16)((oldest_quarter+i) / 4); + quarter.quarter = (u8)((oldest_quarter + (i)) % 4); + quarter.line_count = 0; + quarter.is_empty = 1; + strops::format(quarter.quarter_str, MAX_LEN_SHORT_DESC, "%dQ%d", quarter.quarter+1, quarter.year); + + country::fill_tax_report_with_categories(country_code, &quarter); + } + + // Fill quarters. + for (u32 i = 0; i < invoice_count; i++) + { + invoice* inv = &invoice_buffer[i]; + + u16 yy; + u8 qq; + time_t_to_quarter(inv->issued_at, &yy, &qq); + + u32 report_index = (qq + (yy*4)) - (oldest_quarter + (oldest_year*4)); + + tax_report* quarter = &statement->reports[report_index]; + assert(yy == quarter->year && qq == quarter->quarter); + quarter->is_empty = 0; + + billing_item* item_buffer = (billing_item*)memops::alloc(sizeof(billing_item)*billing_item_count(inv)); + u32 invoice_items = administration::billing_item_get_all_for_invoice(inv, item_buffer); + for (u32 x = 0; x < invoice_items; x++) + { + char* tax_category = country::get_tax_category_for_billing_item(country_code, inv, &item_buffer[x]); + for (u32 t = 0; t < quarter->line_count; t++) + { + if (strops::equals(quarter->lines[t].tax_category, tax_category)) + { + quarter->lines[t].total_net += inv->net; + quarter->lines[t].total_tax += inv->tax; + } + } + + memops::unalloc(item_buffer); + } + } + + memops::unalloc(invoice_buffer); + logger::info("Created tax statement in %.3fms.", STOPWATCH_TIME); +} + void administration::create_income_statement(income_statement* statement) { STOPWATCH_START; @@ -573,7 +661,7 @@ void administration::create_income_statement(income_statement* statement) u16 yy; u8 qq; - time_t_to_quarter(inv->delivered_at, &yy, &qq); + time_t_to_quarter(inv->issued_at, &yy, &qq); u32 report_index = (qq + (yy*4)) - (oldest_quarter + (oldest_year*4)); |
