#include #include #include #include #include "strops.hpp" #include "administration.hpp" 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) { contact* new_contact = (contact*)malloc(sizeof(contact)); memcpy((void*)new_contact, (void*)&data, sizeof(contact)); list_append(&g_administration.contacts, new_contact); g_administration.next_id++; return true; } bool administration_update_contact(contact data) { 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, data.id) == 0) { memcpy(c, &data, sizeof(data)); list_iterator_stop(&g_administration.contacts); return true; } } list_iterator_stop(&g_administration.contacts); return false; } bool administration_remove_contact(contact data) { 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, data.id) == 0) { list_iterator_stop(&g_administration.contacts); list_delete(&g_administration.contacts, c); return true; } } list_iterator_stop(&g_administration.contacts); return false; } s32 administration_create_id() { return g_administration.next_id; } u32 administration_get_contact_count() { return list_size(&g_administration.contacts); } u32 administration_get_contacts(u32 page_index, u32 page_size, contact* buffer) { assert(buffer); u32 write_cursor = 0; u32 read_start = page_index * page_size; list_iterator_start(&g_administration.contacts); while (list_iterator_hasnext(&g_administration.contacts)) { contact c = *(contact *)list_iterator_next(&g_administration.contacts); if (g_administration.contacts.iter_pos <= read_start) continue; buffer[write_cursor++] = c; if (write_cursor >= page_size) break; } list_iterator_stop(&g_administration.contacts); return write_cursor; } char* administration_get_file_path() { return g_administration.path; } u32 administration_get_project_count() { return list_size(&g_administration.projects); } u32 administration_get_projects(u32 page_index, u32 page_size, project* buffer) { assert(buffer); u32 write_cursor = 0; u32 read_start = page_index * page_size; list_iterator_start(&g_administration.projects); while (list_iterator_hasnext(&g_administration.projects)) { project c = *(project *)list_iterator_next(&g_administration.projects); if (g_administration.projects.iter_pos <= read_start) continue; buffer[write_cursor++] = c; if (write_cursor >= page_size) break; } list_iterator_stop(&g_administration.projects); return write_cursor; } void administration_cancel_project(project data) { data.end_date = time(NULL); data.state = project_state::CANCELLED; administration_update_project(data); } char* administration_project_get_status_string(project data) { switch(data.state) { case project_state::RUNNING: return "project.state.running"; case project_state::PAUSED: return "project.state.paused"; case project_state::CANCELLED: return "project.state.cancelled"; default: assert(0); break; } return ""; } bool administration_create_project(project data) { data.state = project_state::RUNNING; data.start_date = time(NULL); data.end_date = 0; project* new_project = (project*)malloc(sizeof(project)); memcpy((void*)new_project, (void*)&data, sizeof(project)); list_append(&g_administration.projects, new_project); g_administration.next_id++; return true; } bool administration_update_project(project data) { list_iterator_start(&g_administration.projects); while (list_iterator_hasnext(&g_administration.projects)) { project* c = (project *)list_iterator_next(&g_administration.projects); if (strcmp(c->id, data.id) == 0) { memcpy(c, &data, sizeof(data)); list_iterator_stop(&g_administration.projects); return true; } } list_iterator_stop(&g_administration.projects); return false; } bool administration_remove_project(project data) { list_iterator_start(&g_administration.projects); while (list_iterator_hasnext(&g_administration.projects)) { project* c = (project *)list_iterator_next(&g_administration.projects); if (strcmp(c->id, data.id) == 0) { list_iterator_stop(&g_administration.projects); list_delete(&g_administration.projects, c); return true; } } 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; }