summaryrefslogtreecommitdiff
path: root/src/administration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/administration.cpp')
-rw-r--r--src/administration.cpp468
1 files changed, 272 insertions, 196 deletions
diff --git a/src/administration.cpp b/src/administration.cpp
index 4d8233e..ace1383 100644
--- a/src/administration.cpp
+++ b/src/administration.cpp
@@ -264,14 +264,29 @@ static void administration_create_debug_data()
ADD_PROJECT("Kayak rental");
// Company info.
+
+ snprintf(g_administration.company_info.id, sizeof(g_administration.company_info.id), "C/%d", administration_create_id());
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));
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));
+ g_administration.next_id++;
+}
+
+static s32 administration_create_sequence_number()
+{
+ return g_administration.next_sequence_number;
}
+static time_t administration_get_default_invoice_expire_duration()
+{
+ return (30 * 24 * 60 * 60); // 30 days
+}
+
+// Setup functions.
+// =======================
void administration_create()
{
g_administration.next_id = 1;
@@ -284,23 +299,50 @@ void administration_create()
list_init(&g_administration.cost_centers);
strops_copy(g_administration.path, "", sizeof(g_administration.path));
- snprintf(g_administration.company_info.id, sizeof(g_administration.company_info.id), "C/%d", administration_create_id());
- g_administration.next_id++;
-
administration_create_default_tax_brackets();
administration_create_default_cost_centers();
administration_create_debug_data();
}
+static void administration_destroy_list(list_t *list)
+{
+ list_iterator_start(list);
+ while (list_iterator_hasnext(list)) {
+ void* c = (void *)list_iterator_next(list);
+ free(c);
+ }
+ list_iterator_stop(list);
+ list_destroy(list);
+}
+
void administration_destroy()
{
- list_destroy(&g_administration.invoices);
- list_destroy(&g_administration.contacts);
- list_destroy(&g_administration.projects);
- list_destroy(&g_administration.tax_brackets);
- list_destroy(&g_administration.cost_centers);
+ administration_destroy_list(&g_administration.invoices);
+ administration_destroy_list(&g_administration.contacts);
+ administration_destroy_list(&g_administration.projects);
+ administration_destroy_list(&g_administration.tax_brackets);
+ administration_destroy_list(&g_administration.cost_centers);
}
+// General functions.
+// =======================
+char* administration_file_path_get()
+{
+ return g_administration.path;
+}
+
+contact administration_company_info_get()
+{
+ return g_administration.company_info;
+}
+
+void administration_company_info_set(contact data)
+{
+ g_administration.company_info = data;
+}
+
+// Contact functions.
+// =======================
bool administration_contact_add(contact data)
{
if (!administration_contact_is_valid(data)) return false;
@@ -349,6 +391,7 @@ bool administration_contact_remove(contact data)
if (strcmp(c->id, data.id) == 0) {
list_iterator_stop(&g_administration.contacts);
list_delete(&g_administration.contacts, c);
+ free(c);
return true;
}
}
@@ -384,6 +427,24 @@ u32 administration_contact_get_partial_list(u32 page_index, u32 page_size, conta
return write_cursor;
}
+bool administration_contact_get_by_id(contact* buffer, char* id)
+{
+ bool result = false;
+ list_iterator_start(&g_administration.contacts);
+ while (list_iterator_hasnext(&g_administration.contacts)) {
+ contact c = *(contact *)list_iterator_next(&g_administration.contacts);
+
+ if (strcmp(c.id, id) == 0) {
+ list_iterator_stop(&g_administration.projects);
+ *buffer = c;
+ result = true;
+ }
+ }
+ list_iterator_stop(&g_administration.contacts);
+
+ return result;
+}
+
int administration_contact_get_autocompletions(contact* buffer, int buf_size, char* name)
{
int write_cursor = 0;
@@ -403,33 +464,39 @@ int administration_contact_get_autocompletions(contact* buffer, int buf_size, ch
return write_cursor;
}
-char* administration_file_path_get()
+bool administration_contact_is_valid(contact data)
{
- return g_administration.path;
+ 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;
}
-u32 administration_project_count()
+contact administration_contact_create_empty()
{
- return list_size(&g_administration.projects);
+ contact result;
+ memset(&result, 0, sizeof(contact));
+ snprintf(result.id, sizeof(result.id), "C/%d", administration_create_id());
+ return result;
}
-u32 administration_billing_items_count(invoice* invoice)
+bool administration_contact_equals(contact c1, contact c2)
{
- return list_size(&invoice->billing_items);
+ return memcmp(&c1, &c2, sizeof(contact)) == 0;
}
-u32 administration_billing_item_get_all_for_invoice(invoice* invoice, billing_item* buffer)
+// Project functions.
+// =======================
+u32 administration_project_count()
{
- u32 write_cursor = 0;
-
- list_iterator_start(&invoice->billing_items);
- while (list_iterator_hasnext(&invoice->billing_items)) {
- billing_item c = *(billing_item *)list_iterator_next(&invoice->billing_items);
- buffer[write_cursor++] = c;
- }
- list_iterator_stop(&invoice->billing_items);
-
- return write_cursor;
+ return list_size(&g_administration.projects);
}
u32 administration_project_get_all(project* buffer)
@@ -480,23 +547,6 @@ bool administration_project_is_valid(project data)
return strlen(data.description) > 0;
}
-char* administration_invoice_get_status_string(invoice* invoice)
-{
- switch(invoice->status)
- {
- case invoice_status::INVOICE_CONCEPT: return "invoice.state.concept";
- case invoice_status::INVOICE_SENT: return "invoice.state.sent";
- case invoice_status::INVOICE_REMINDED: return "invoice.state.reminded";
- case invoice_status::INVOICE_PAID: return "invoice.state.paid";
- case invoice_status::INVOICE_EXPIRED: return "invoice.state.expired";
- case invoice_status::INVOICE_CANCELLED: return "invoice.state.cancelled";
- case invoice_status::INVOICE_REFUNDED: return "invoice.state.refunded";
- case invoice_status::INVOICE_CORRECTED: return "invoice.state.corrected";
- default: assert(0); break;
- }
- return "";
-}
-
char* administration_project_get_status_string(project data)
{
switch(data.state)
@@ -553,6 +603,7 @@ bool administration_project_remove(project data)
if (strcmp(c->id, data.id) == 0) {
list_iterator_stop(&g_administration.projects);
list_delete(&g_administration.projects, c);
+ free(c);
return true;
}
}
@@ -561,14 +612,33 @@ bool administration_project_remove(project data)
return false;
}
-contact administration_company_info_get()
+project administration_project_create_empty()
{
- return g_administration.company_info;
+ project result;
+ memset(&result, 0, sizeof(project));
+ snprintf(result.id, sizeof(result.id), "P/%d", administration_create_id());
+ return result;
}
-void administration_company_info_set(contact data)
+// Tax bracket functions.
+// =======================
+static bool administration_get_tax_bracket_by_id(country_tax_bracket* buffer, char* id)
{
- g_administration.company_info = data;
+ assert(buffer);
+
+ list_iterator_start(&g_administration.tax_brackets);
+ while (list_iterator_hasnext(&g_administration.tax_brackets)) {
+ country_tax_bracket c = *(country_tax_bracket *)list_iterator_next(&g_administration.tax_brackets);
+ if (strcmp(c.id, id) == 0)
+ {
+ *buffer = c;
+ list_iterator_stop(&g_administration.tax_brackets);
+ return true;
+ }
+ }
+ list_iterator_stop(&g_administration.tax_brackets);
+
+ return false;
}
u32 administration_tax_bracket_count()
@@ -634,6 +704,8 @@ bool administration_tax_bracket_update(country_tax_bracket data)
return false;
}
+// Cost center functions.
+// =======================
u32 administration_cost_center_count()
{
return list_size(&g_administration.cost_centers);
@@ -720,52 +792,8 @@ bool administration_cost_center_update(cost_center data)
return false;
}
-bool administration_contact_is_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;
-}
-
-static time_t administration_get_default_invoice_expire_duration()
-{
- return (30 * 24 * 60 * 60); // 30 days
-}
-
-billing_item administration_billing_item_create_empty()
-{
- billing_item item;
- memset(&item, 0, sizeof(billing_item));
- item.amount = 1;
- return item;
-}
-
-bool administration_billing_item_add_to_invoice(invoice* invoice, billing_item item)
-{
- billing_item* tb = (billing_item*)malloc(sizeof(billing_item));
- memcpy(tb, &item, sizeof(billing_item));
- snprintf(tb->id, sizeof(tb->id), "B/%d", administration_create_id());
- strops_copy(tb->invoice_id, invoice->id, sizeof(tb->invoice_id));
- list_append(&invoice->billing_items, tb);
- strops_copy(tb->currency, invoice->currency, MAX_LEN_CURRENCY); // Set billing item currency to invoice currency.
-
- g_administration.next_id++;
-
- return true;
-}
+// Invoice functions.
+// =======================
static char* administration_get_default_currency_for_country(char* country_code)
{
@@ -821,41 +849,6 @@ invoice administration_invoice_create_empty()
return result;
}
-contact administration_contact_create_empty()
-{
- contact result;
- memset(&result, 0, sizeof(contact));
- snprintf(result.id, sizeof(result.id), "C/%d", administration_create_id());
- return result;
-}
-
-project administration_project_create_empty()
-{
- project result;
- memset(&result, 0, sizeof(project));
- snprintf(result.id, sizeof(result.id), "P/%d", administration_create_id());
- return result;
-}
-
-static bool administration_get_tax_bracket_by_id(country_tax_bracket* buffer, char* id)
-{
- assert(buffer);
-
- list_iterator_start(&g_administration.tax_brackets);
- while (list_iterator_hasnext(&g_administration.tax_brackets)) {
- country_tax_bracket c = *(country_tax_bracket *)list_iterator_next(&g_administration.tax_brackets);
- if (strcmp(c.id, id) == 0)
- {
- *buffer = c;
- list_iterator_stop(&g_administration.tax_brackets);
- return true;
- }
- }
- list_iterator_stop(&g_administration.tax_brackets);
-
- return false;
-}
-
static void administration_recalculate_invoice_totals(invoice* invoice)
{
invoice->tax = 0.0f;
@@ -873,75 +866,6 @@ static void administration_recalculate_invoice_totals(invoice* invoice)
list_iterator_stop(&invoice->billing_items);
}
-static void administration_recalculate_billing_item_totals(billing_item* item)
-{
- if (item->amount_is_percentage)
- {
- item->net = item->net_per_item * (item->amount / 100.0f);
- }
- else
- {
- item->net = item->net_per_item * item->amount;
- }
-
- if (item->discount != 0)
- {
- if (item->discount_is_percentage)
- {
- item->net -= item->net * (item->discount / 100.0f);
- }
- else
- {
- item->net -= item->discount;
- }
- }
-
- country_tax_bracket bracket;
- if (administration_get_tax_bracket_by_id(&bracket, item->tax_bracket_id))
- {
- item->tax = item->net * (bracket.rate/100.0f);
- }
-
- item->total = item->net + item->tax;
-}
-
-bool administration_billing_item_remove_from_invoice(invoice* invoice, billing_item item)
-{
- list_iterator_start(&invoice->billing_items);
- while (list_iterator_hasnext(&invoice->billing_items)) {
- billing_item* c = (billing_item *)list_iterator_next(&invoice->billing_items);
-
- if (strcmp(c->id, item.id) == 0) {
- list_iterator_stop(&invoice->billing_items);
- list_delete(&invoice->billing_items, c);
- return true;
- }
- }
- list_iterator_stop(&invoice->billing_items);
-
- return false;
-}
-
-bool administration_billing_item_update_in_invoice(invoice* invoice, billing_item item)
-{
- list_iterator_start(&invoice->billing_items);
- while (list_iterator_hasnext(&invoice->billing_items)) {
- billing_item* c = (billing_item *)list_iterator_next(&invoice->billing_items);
-
- if (strcmp(c->id, item.id) == 0) {
- memcpy(c, &item, sizeof(billing_item));
- list_iterator_stop(&invoice->billing_items);
-
- administration_recalculate_billing_item_totals(c);
- administration_recalculate_invoice_totals(invoice);
- return true;
- }
- }
- list_iterator_stop(&invoice->billing_items);
-
- return false;
-}
-
void administration_invoice_set_currency(invoice* invoice, char* currency)
{
strops_copy(invoice->currency, currency, MAX_LEN_CURRENCY);
@@ -965,6 +889,25 @@ bool administration_invoice_is_valid(invoice* invoice)
return true;
}
+bool administration_invoice_remove(invoice* inv)
+{
+ list_iterator_start(&g_administration.invoices);
+ while (list_iterator_hasnext(&g_administration.invoices)) {
+ invoice* c = (invoice *)list_iterator_next(&g_administration.invoices);
+
+ if (strcmp(c->id, inv->id) == 0)
+ {
+ list_iterator_stop(&g_administration.invoices);
+ administration_destroy_list(&c->billing_items);
+ list_delete(&g_administration.invoices, c);
+ free(c);
+ return true;
+ }
+ }
+ list_iterator_stop(&g_administration.invoices);
+ return false;
+}
+
bool administration_invoice_update(invoice* inv)
{
if (!administration_invoice_is_valid(inv)) return false;
@@ -1084,4 +1027,137 @@ u32 administration_invoice_get_partial_list(u32 page_index, u32 page_size, invoi
list_iterator_stop(&g_administration.invoices);
return write_cursor;
+}
+
+char* administration_invoice_get_status_string(invoice* invoice)
+{
+ switch(invoice->status)
+ {
+ case invoice_status::INVOICE_CONCEPT: return "invoice.state.concept";
+ case invoice_status::INVOICE_SENT: return "invoice.state.sent";
+ case invoice_status::INVOICE_REMINDED: return "invoice.state.reminded";
+ case invoice_status::INVOICE_PAID: return "invoice.state.paid";
+ case invoice_status::INVOICE_EXPIRED: return "invoice.state.expired";
+ case invoice_status::INVOICE_CANCELLED: return "invoice.state.cancelled";
+ case invoice_status::INVOICE_REFUNDED: return "invoice.state.refunded";
+ case invoice_status::INVOICE_CORRECTED: return "invoice.state.corrected";
+ default: assert(0); break;
+ }
+ return "";
+}
+
+// Billing item functions.
+// =======================
+
+static void administration_recalculate_billing_item_totals(billing_item* item)
+{
+ if (item->amount_is_percentage)
+ {
+ item->net = item->net_per_item * (item->amount / 100.0f);
+ }
+ else
+ {
+ item->net = item->net_per_item * item->amount;
+ }
+
+ if (item->discount != 0)
+ {
+ if (item->discount_is_percentage)
+ {
+ item->net -= item->net * (item->discount / 100.0f);
+ }
+ else
+ {
+ item->net -= item->discount;
+ }
+ }
+
+ country_tax_bracket bracket;
+ if (administration_get_tax_bracket_by_id(&bracket, item->tax_bracket_id))
+ {
+ item->tax = item->net * (bracket.rate/100.0f);
+ }
+
+ item->total = item->net + item->tax;
+}
+
+u32 administration_billing_item_count(invoice* invoice)
+{
+ return list_size(&invoice->billing_items);
+}
+
+u32 administration_billing_item_get_all_for_invoice(invoice* invoice, billing_item* buffer)
+{
+ u32 write_cursor = 0;
+
+ list_iterator_start(&invoice->billing_items);
+ while (list_iterator_hasnext(&invoice->billing_items)) {
+ billing_item c = *(billing_item *)list_iterator_next(&invoice->billing_items);
+ buffer[write_cursor++] = c;
+ }
+ list_iterator_stop(&invoice->billing_items);
+
+ return write_cursor;
+}
+
+bool administration_billing_item_remove_from_invoice(invoice* invoice, billing_item item)
+{
+ list_iterator_start(&invoice->billing_items);
+ while (list_iterator_hasnext(&invoice->billing_items)) {
+ billing_item* c = (billing_item *)list_iterator_next(&invoice->billing_items);
+
+ if (strcmp(c->id, item.id) == 0) {
+ list_iterator_stop(&invoice->billing_items);
+ list_delete(&invoice->billing_items, c);
+ free(c);
+ return true;
+ }
+ }
+ list_iterator_stop(&invoice->billing_items);
+
+ return false;
+}
+
+bool administration_billing_item_update_in_invoice(invoice* invoice, billing_item item)
+{
+ list_iterator_start(&invoice->billing_items);
+ while (list_iterator_hasnext(&invoice->billing_items)) {
+ billing_item* c = (billing_item *)list_iterator_next(&invoice->billing_items);
+
+ if (strcmp(c->id, item.id) == 0) {
+ memcpy(c, &item, sizeof(billing_item));
+ list_iterator_stop(&invoice->billing_items);
+
+ administration_recalculate_billing_item_totals(c);
+ administration_recalculate_invoice_totals(invoice);
+ return true;
+ }
+ }
+ list_iterator_stop(&invoice->billing_items);
+
+ return false;
+}
+
+bool administration_billing_item_add_to_invoice(invoice* invoice, billing_item item)
+{
+ if (administration_billing_item_count(invoice) >= MAX_BILLING_ITEMS) return false;
+
+ billing_item* tb = (billing_item*)malloc(sizeof(billing_item));
+ memcpy(tb, &item, sizeof(billing_item));
+ snprintf(tb->id, sizeof(tb->id), "B/%d", administration_create_id());
+ strops_copy(tb->invoice_id, invoice->id, sizeof(tb->invoice_id));
+ list_append(&invoice->billing_items, tb);
+ strops_copy(tb->currency, invoice->currency, MAX_LEN_CURRENCY); // Set billing item currency to invoice currency.
+
+ g_administration.next_id++;
+
+ return true;
+}
+
+billing_item administration_billing_item_create_empty()
+{
+ billing_item item;
+ memset(&item, 0, sizeof(billing_item));
+ item.amount = 1;
+ return item;
} \ No newline at end of file