#pragma once #include "config.hpp" #include "simclist.h" #define MAX_LEN_SEQ_NUM 16 #define MAX_LEN_ID 16 #define MAX_LEN_COUNTRY_CODE 3 #define MAX_LEN_CODE 5 #define MAX_LEN_ADDRESS 128 #define MAX_LEN_FILENAME 255 #define MAX_LEN_PATH 4096 #define MAX_LEN_CURRENCY 8 #define MAX_LEN_SHORT_DESC 32 #define MAX_LEN_LONG_DESC 64 #define MAX_LEN_EMAIL 64 #define MAX_LEN_PHONE 16 #define MAX_LEN_BANK 35 #define MAX_LEN_TAXID 32 #define MAX_LEN_BUSINESSID 32 #define MAX_LEN_TAX_SECTION 16 #define MAX_LEN_INCOME_STATEMENT_REPORT_QUARTERS 400 #define MAX_LEN_QUARTERLY_REPORT_PROJECTS 200 #define MAX_LEN_PROJECT_REPORT_COSTCENTERS 50 #define MAX_BILLING_ITEMS 50 #define MY_COMPANY_ID "C/1" typedef struct { char id[MAX_LEN_ID]; // T/[id] char country_code[MAX_LEN_COUNTRY_CODE]; // 2 letter country code float rate; // 0-100% char category_code[MAX_LEN_CODE]; // Category code. https://docs.peppol.eu/poacc/billing/3.0/codelist/UNCL5305/ } country_tax_bracket; typedef struct { char id[MAX_LEN_ID]; // E/[id] char code[MAX_LEN_CODE]; // Internal 4 letter code char description[MAX_LEN_LONG_DESC]; } cost_center; typedef struct { char address1[MAX_LEN_ADDRESS]; char address2[MAX_LEN_ADDRESS]; char city[MAX_LEN_ADDRESS]; char postal[MAX_LEN_ADDRESS]; char region[MAX_LEN_ADDRESS]; char country_code[MAX_LEN_COUNTRY_CODE]; // 2 letter country code } address; typedef enum { CONTACT_BUSINESS, CONTACT_CONSUMER, } contact_type; typedef struct { char id[MAX_LEN_ID]; // C/[id] char name[MAX_LEN_LONG_DESC]; address address; contact_type type; char taxid[MAX_LEN_TAXID]; // Required for business contact char businessid[MAX_LEN_BUSINESSID]; // Required for business contact char email[MAX_LEN_EMAIL]; char phone_number[MAX_LEN_PHONE]; char bank_account[MAX_LEN_BANK]; } contact; typedef enum { PROJECT_RUNNING, PROJECT_PAUSED, PROJECT_CANCELLED, } project_state; typedef struct { char id[MAX_LEN_ID]; // P/[id] char description[MAX_LEN_LONG_DESC]; project_state state; time_t start_date; time_t end_date; // Set when project is cancelled } project; typedef enum { INVOICE_CONCEPT, INVOICE_SENT, INVOICE_REMINDED, INVOICE_PAID, INVOICE_EXPIRED, INVOICE_CANCELLED, INVOICE_REFUNDED, INVOICE_CORRECTED, INVOICE_RECEIVED, INVOICE_END, } invoice_status; typedef struct { char id[MAX_LEN_ID]; // B/[id] char invoice_id[MAX_LEN_ID]; // I/[id] float amount; bool amount_is_percentage; char description[MAX_LEN_LONG_DESC]; float net_per_item; // Net per item before discount. float discount; bool discount_is_percentage; float allowance; // Total discount. float net; // Total net, with discount. char currency[MAX_LEN_CURRENCY]; // 3 letter code char tax_bracket_id[MAX_LEN_ID]; // T/[id] float tax; float total; } billing_item; /** * UN/CEFACT Payment Means Code (UNCL4461) * Source: https://docs.peppol.eu/poacc/billing/3.0/codelist/UNCL4461/ */ typedef enum { PAYMENT_METHOD_INSTRUMENT_NOT_DEFINED = 1, PAYMENT_METHOD_ACH_CREDIT = 2, PAYMENT_METHOD_ACH_DEBIT = 3, PAYMENT_METHOD_ACH_DEMAND_DEBIT_REVERSAL = 4, PAYMENT_METHOD_ACH_DEMAND_CREDIT_REVERSAL = 5, PAYMENT_METHOD_ACH_DEMAND_CREDIT = 6, PAYMENT_METHOD_ACH_DEMAND_DEBIT = 7, PAYMENT_METHOD_HOLD = 8, PAYMENT_METHOD_NATIONAL_REGIONAL_CLEARING = 9, PAYMENT_METHOD_CASH = 10, PAYMENT_METHOD_ACH_SAVINGS_CREDIT_REVERSAL = 11, PAYMENT_METHOD_ACH_SAVINGS_DEBIT_REVERSAL = 12, PAYMENT_METHOD_ACH_SAVINGS_CREDIT = 13, PAYMENT_METHOD_ACH_SAVINGS_DEBIT = 14, PAYMENT_METHOD_BOOKENTRY_CREDIT = 15, PAYMENT_METHOD_BOOKENTRY_DEBIT = 16, PAYMENT_METHOD_ACH_DEMAND_CCD_CREDIT = 17, PAYMENT_METHOD_ACH_DEMAND_CCD_DEBIT = 18, PAYMENT_METHOD_ACH_DEMAND_CTP_CREDIT = 19, PAYMENT_METHOD_CHEQUE = 20, PAYMENT_METHOD_BANKERS_DRAFT = 21, PAYMENT_METHOD_CERTIFIED_BANKERS_DRAFT = 22, PAYMENT_METHOD_BANK_CHEQUE = 23, PAYMENT_METHOD_BILL_OF_EXCHANGE_AWAITING_ACCEPTANCE = 24, PAYMENT_METHOD_CERTIFIED_CHEQUE = 25, PAYMENT_METHOD_LOCAL_CHEQUE = 26, PAYMENT_METHOD_ACH_DEMAND_CTP_DEBIT = 27, PAYMENT_METHOD_ACH_DEMAND_CTX_CREDIT = 28, PAYMENT_METHOD_ACH_DEMAND_CTX_DEBIT = 29, PAYMENT_METHOD_CREDIT_TRANSFER = 30, PAYMENT_METHOD_DEBIT_TRANSFER = 31, PAYMENT_METHOD_ACH_DEMAND_CCD_PLUS_CREDIT = 32, PAYMENT_METHOD_ACH_DEMAND_CCD_PLUS_DEBIT = 33, PAYMENT_METHOD_ACH_PPD = 34, PAYMENT_METHOD_ACH_SAVINGS_CCD_CREDIT = 35, PAYMENT_METHOD_ACH_SAVINGS_CCD_DEBIT = 36, PAYMENT_METHOD_ACH_SAVINGS_CTP_CREDIT = 37, PAYMENT_METHOD_ACH_SAVINGS_CTP_DEBIT = 38, PAYMENT_METHOD_ACH_SAVINGS_CTX_CREDIT = 39, PAYMENT_METHOD_ACH_SAVINGS_CTX_DEBIT = 40, PAYMENT_METHOD_ACH_SAVINGS_CCD_PLUS_CREDIT = 41, PAYMENT_METHOD_PAYMENT_TO_BANK_ACCOUNT = 42, PAYMENT_METHOD_ACH_SAVINGS_CCD_PLUS_DEBIT = 43, PAYMENT_METHOD_ACCEPTED_BILL_OF_EXCHANGE = 44, PAYMENT_METHOD_REFERENCED_HOME_BANKING_CREDIT_TRANSFER = 45, PAYMENT_METHOD_INTERBANK_DEBIT_TRANSFER = 46, PAYMENT_METHOD_HOME_BANKING_DEBIT_TRANSFER = 47, PAYMENT_METHOD_BANK_CARD = 48, PAYMENT_METHOD_DIRECT_DEBIT = 49, PAYMENT_METHOD_PAYMENT_BY_POSTGIRO = 50, PAYMENT_METHOD_FR_NORME_6_97_CFONB_OPTION_A = 51, PAYMENT_METHOD_URGENT_COMMERCIAL_PAYMENT = 52, PAYMENT_METHOD_URGENT_TREASURY_PAYMENT = 53, PAYMENT_METHOD_CREDIT_CARD = 54, PAYMENT_METHOD_DEBIT_CARD = 55, PAYMENT_METHOD_BANKGIRO = 56, PAYMENT_METHOD_STANDING_AGREEMENT = 57, PAYMENT_METHOD_SEPA_CREDIT_TRANSFER = 58, PAYMENT_METHOD_SEPA_DIRECT_DEBIT = 59, PAYMENT_METHOD_PROMISSORY_NOTE = 60, PAYMENT_METHOD_PROMISSORY_NOTE_SIGNED_BY_DEBTOR = 61, PAYMENT_METHOD_PROMISSORY_NOTE_SIGNED_BY_DEBTOR_AND_ENDORSED_BY_BANK = 62, PAYMENT_METHOD_PROMISSORY_NOTE_SIGNED_BY_DEBTOR_AND_ENDORSED_BY_THIRD_PARTY = 63, PAYMENT_METHOD_PROMISSORY_NOTE_SIGNED_BY_BANK = 64, PAYMENT_METHOD_PROMISSORY_NOTE_SIGNED_BY_BANK_AND_ENDORSED_BY_ANOTHER_BANK = 65, PAYMENT_METHOD_PROMISSORY_NOTE_SIGNED_BY_THIRD_PARTY = 66, PAYMENT_METHOD_PROMISSORY_NOTE_SIGNED_BY_THIRD_PARTY_AND_ENDORSED_BY_BANK = 67, PAYMENT_METHOD_ONLINE_PAYMENT_SERVICE = 68, PAYMENT_METHOD_TRANSFER_ADVICE = 69, PAYMENT_METHOD_BILL_DRAWN_BY_CREDITOR_ON_DEBTOR = 70, PAYMENT_METHOD_BILL_DRAWN_BY_CREDITOR_ON_BANK = 74, PAYMENT_METHOD_BILL_DRAWN_BY_CREDITOR_ENDORSED_BY_ANOTHER_BANK = 75, PAYMENT_METHOD_BILL_DRAWN_BY_CREDITOR_ON_BANK_ENDORSED_BY_THIRD_PARTY = 76, PAYMENT_METHOD_BILL_DRAWN_BY_CREDITOR_ON_THIRD_PARTY = 77, PAYMENT_METHOD_BILL_DRAWN_BY_CREDITOR_ON_THIRD_PARTY_ACCEPTED_AND_ENDORSED_BY_BANK = 78, PAYMENT_METHOD_NOT_TRANSFERABLE_BANKERS_DRAFT = 91, PAYMENT_METHOD_NOT_TRANSFERABLE_LOCAL_CHEQUE = 92, PAYMENT_METHOD_REFERENCE_GIRO = 93, PAYMENT_METHOD_URGENT_GIRO = 94, PAYMENT_METHOD_FREE_FORMAT_GIRO = 95, PAYMENT_METHOD_REQUESTED_METHOD_NOT_USED = 96, PAYMENT_METHOD_CLEARING_BETWEEN_PARTNERS = 97, PAYMENT_METHOD_JP_ELECTRONICALLY_RECORDED_MONETARY_CLAIMS = 98, PAYMENT_METHOD_MUTUALLY_DEFINED = -1 /** ZZZ */ } payment_method; typedef struct { char payee_bank_account[MAX_LEN_BANK]; // Recipient IBAN or BBAN account. char payee_account_name[MAX_LEN_LONG_DESC]; // Name of account where payment is made to. char service_provider_id[MAX_LEN_LONG_DESC]; // BIC or national clearing code. char payer_bank_account[MAX_LEN_BANK]; // Sender IBAN or BBAN account. payment_method payment_method; } payment_information; typedef struct { float total; float tax; float net; float allowance; } tax_subtotal; typedef struct { char id[MAX_LEN_ID]; // I/[id] char sequential_number[MAX_LEN_SEQ_NUM]; // INV0000000000 - INV9999999999 char customer_id[MAX_LEN_ID]; // C/[id] char supplier_id[MAX_LEN_ID]; // C/[id] contact addressee; time_t issued_at; time_t expires_at; time_t delivered_at; char document[MAX_LEN_PATH]; // path to copy of document for incomming invoice. char project_id[MAX_LEN_ID]; // Optional. char cost_center_id[MAX_LEN_ID]; // For incomming invoices. optional. list_t billing_items; // Total, tax and net are calculated from billing items. float total; float tax; float net; float allowance; char currency[MAX_LEN_CURRENCY]; // 3 letter code bool is_triangulation; // True if addressee != customer invoice_status status; bool is_outgoing; // Outgoing or incomming invoice. payment_information payment_means; // Used for forms, not stored on disk. Filled when retrieved. contact supplier; contact customer; } invoice; 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 { char project_id[MAX_LEN_ID]; char description[MAX_LEN_LONG_DESC]; u32 expense_count; project_expense expenses[MAX_LEN_PROJECT_REPORT_COSTCENTERS]; float expenses_total; // Sum of all expenses. (incl uncategorized) float revenue; float taxes; } project_report; typedef struct { float uncategorized_expenses; // Sum of expenses without project. float uncategorized_revenue; float uncategorized_taxes; float profit; u32 report_count; project_report reports[MAX_LEN_QUARTERLY_REPORT_PROJECTS]; u16 year; // 00-99 u8 quarter; // 0-3 bool is_empty; char quarter_str[MAX_LEN_SHORT_DESC]; } quarterly_report; typedef struct { u32 quarter_count; quarterly_report quarters[MAX_LEN_INCOME_STATEMENT_REPORT_QUARTERS]; } income_statement; // Administration callback functions. // These are called when adding/updating/deleting entries. // These are NOT called when using import functions. typedef void (*data_changed_event)(); typedef void (*data_deleted_event)(char id[MAX_LEN_ID]); typedef void (*invoice_changed_event)(invoice* invoice); typedef void (*contact_changed_event)(contact* contact); typedef void (*taxbracket_changed_event)(country_tax_bracket* bracket); typedef void (*costcenter_changed_event)(cost_center* cost_center); typedef void (*project_changed_event)(project* project); typedef struct { contact company_info; // Company info used for invoices. User cannot create invoices when this is empty/invalid. s32 next_id; // Id increment shared across all objects that have an ID. 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; list_t tax_brackets; list_t cost_centers; u32 invoice_count; u32 expense_count; list_t invoices; } administration; // Setup functions. // ======================= void administration_create(); // TODO remove and move into other setup functions void administration_destroy(); // TODO remove and move into other setup functions void administration_create_empty(char* save_file); void administration_create_from_file(char* save_file); // Callback functions. // ======================= void administration_set_data_changed_event_callback(data_changed_event ev); void administration_set_data_deleted_event_callback(data_deleted_event ev); void administration_set_invoice_changed_event_callback(invoice_changed_event ev); void administration_set_contact_changed_event_callback(contact_changed_event ev); void administration_set_taxbracket_changed_event_callback(taxbracket_changed_event ev); void administration_set_costcenter_changed_event_callback(costcenter_changed_event ev); void administration_set_project_changed_event_callback(project_changed_event ev); // Other functions. // ======================= administration* administration_get(); // TODO get rid of this and make indivual getters and setters char* administration_file_path_get(); contact administration_company_info_get(); void administration_company_info_import(contact data); 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(); bool administration_can_create_invoices(); bool administration_has_save_path(); // Contact functions. // ======================= u32 administration_contact_count(); contact administration_contact_create_empty(); bool administration_contact_import(contact data); bool administration_contact_add(contact data); bool administration_contact_update(contact data); bool administration_contact_remove(contact data); bool administration_contact_is_valid(contact data); bool administration_contact_can_be_deleted(contact data); bool administration_contact_equals(contact c1, contact c2); bool administration_contact_get_by_id(contact* buffer, char* id); int administration_contact_get_autocompletions(contact* buffer, int buf_size, char* name); u32 administration_contact_get_partial_list(u32 page_index, u32 page_size, contact* buffer); u32 administration_contact_get_all(contact* buffer); // Project functions. // ======================= u32 administration_project_count(); project administration_project_create_empty(); bool administration_project_import(project data); bool administration_project_add(project data); bool administration_project_update(project data); bool administration_project_remove(project data); void administration_project_cancel(project data); bool administration_project_is_valid(project data); char* administration_project_get_status_string(project data); u32 administration_project_get_all(project* buffer); u32 administration_project_get_partial_list(u32 page_index, u32 page_size, project* buffer); bool administration_project_get_by_id(project* buffer, char* id); // Tax bracket functions. // ======================= u32 administration_tax_bracket_count(); bool administration_tax_bracket_import(country_tax_bracket data); bool administration_tax_bracket_add(country_tax_bracket data); bool administration_tax_bracket_update(country_tax_bracket data); bool administration_tax_bracket_get_by_id(char* id, country_tax_bracket* buffer); u32 administration_tax_bracket_get_all(country_tax_bracket* buffer); u32 administration_tax_bracket_get_by_country(country_tax_bracket* buffer, char* country_code); // Cost center functions. // ======================= u32 administration_cost_center_count(); bool administration_cost_center_import(cost_center data); bool administration_cost_center_add(cost_center data); bool administration_cost_center_update(cost_center data); bool administration_cost_center_verify_code(char* code); bool administration_cost_center_verify_description(char* text); u32 administration_cost_center_get_all(cost_center* buffer); bool administration_cost_center_get_by_id(cost_center* buffer, char* id); // Invoice functions. // ======================= u32 administration_invoice_count(); u32 administration_invoice_get_incomming_count(); u32 administration_invoice_get_outgoing_count(); invoice administration_invoice_create_empty(); bool administration_invoice_add(invoice* invoice); bool administration_invoice_update(invoice* invoice); bool administration_invoice_remove(invoice* invoice); void administration_invoice_set_currency(invoice* invoice, char* currency); invoice administration_invoice_create_copy(invoice* invoice); bool administration_invoice_is_valid(invoice* invoice); char* administration_invoice_get_status_string(invoice* invoice); u32 administration_invoice_get_partial_list_outgoing(u32 page_index, u32 page_size, invoice* buffer); u32 administration_invoice_get_partial_list_incomming(u32 page_index, u32 page_size, invoice* buffer); u32 administration_invoice_get_all(invoice* buffer); u32 administration_invoice_get_tax_brackets(invoice* invoice, country_tax_bracket* buffer); bool administration_invoice_get_subtotal_for_tax_bracket(invoice* invoice, country_tax_bracket bracket, tax_subtotal* buffer); // Billing item functions. // ======================= u32 administration_billing_item_count(invoice* invoice); billing_item administration_billing_item_create_empty(); bool administration_billing_item_add_to_invoice(invoice* invoice, billing_item item); bool administration_billing_item_update_in_invoice(invoice* invoice, billing_item item); bool administration_billing_item_remove_from_invoice(invoice* invoice, billing_item item); u32 administration_billing_item_get_all_for_invoice(invoice* invoice, billing_item* buffer);