diff options
| author | Aldrik Ramaekers <aldrikboy@gmail.com> | 2025-09-13 18:47:01 +0200 |
|---|---|---|
| committer | Aldrik Ramaekers <aldrikboy@gmail.com> | 2025-09-13 18:47:01 +0200 |
| commit | 38019a9693375ac6719ffec43bff63774e142387 (patch) | |
| tree | e9374df460f7949c93a9dc031f450bffb906f6c2 | |
| parent | d8a9d534a5a39fd3d51a6ffaf92fde39a4b4077c (diff) | |
invoice peppol work
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | docs/CHANGES.rst | 9 | ||||
| -rw-r--r-- | include/administration.hpp | 12 | ||||
| -rw-r--r-- | include/file_templates.hpp | 109 | ||||
| -rw-r--r-- | libs/ImGuiDatePicker/ImGuiDatePicker.cpp | 2 | ||||
| -rw-r--r-- | src/administration.cpp | 1 | ||||
| -rw-r--r-- | src/administration_writer.cpp | 65 | ||||
| -rw-r--r-- | src/ui/ui_settings.cpp | 2 |
8 files changed, 165 insertions, 38 deletions
@@ -1,2 +1,3 @@ imgui.ini -build/*
\ No newline at end of file +build/* +example.openbook
\ No newline at end of file diff --git a/docs/CHANGES.rst b/docs/CHANGES.rst index 7c7ef64..e9881ec 100644 --- a/docs/CHANGES.rst +++ b/docs/CHANGES.rst @@ -9,8 +9,7 @@ TODO: - read invoice from Holodeck instance - send invoice via Holodeck instance - View invoice history for contacts -- View invoice history for projects -- Create monthly and quarterly results (per project). +- View invoice history for projects - Create quarterly tax reports for NL. - Make sure invoices/expenses cannot be added when company info is empty/invalid. - net negative billing items should not also have discounts. @@ -19,7 +18,9 @@ TODO: - View local business number / vat number naming on contact form. e.g. when country is austria: "Österreichische Umsatzsteuer-Identifikationsnummer" - add allowances to invoice items - add accounting cost to invoice -- if an invoice currency != default currency, final amount should be manually set as the total is always represented in the default currency. +- outgoing invoices should always have default currency +- if an incomming invoice currency != default currency, final amount should be manually set as the total is always represented in the default currency. +- ICP reports v0.1 (master) @@ -31,5 +32,5 @@ v0.1 (master) - Generate default VAT rates - Generate default cost centers - Reading & writing administration files -- Archive invoices in Peppol BIS 3.0 format. +- Archive invoices in Peppol BIS 3.0 format - Quarterly income statement reports
\ No newline at end of file diff --git a/include/administration.hpp b/include/administration.hpp index fe3d7b2..95d4622 100644 --- a/include/administration.hpp +++ b/include/administration.hpp @@ -109,18 +109,15 @@ typedef struct float amount; bool amount_is_percentage; char description[MAX_LEN_LONG_DESC]; - float net_per_item; + float net_per_item; // Net per item before discount. float discount; bool discount_is_percentage; float allowance; // Total discount. - float net; + 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; - - // TODO uninplemented - char tax_section[MAX_LEN_TAX_SECTION]; } billing_item; /** @@ -257,11 +254,6 @@ typedef struct invoice_status status; bool is_outgoing; // Outgoing or incomming invoice. payment_information payment_means; - - bool is_intra_community; // TODO uninplemented - time_t payment_on_account_date; // TODO uninplemented - char tax_representative[MAX_LEN_LONG_DESC]; // TODO uninplemented - char corrected_sequential_number[MAX_LEN_ID]; // TODO uninplemented // Used for forms, not stored on disk. Filled when retrieved. contact supplier; diff --git a/include/file_templates.hpp b/include/file_templates.hpp index cb89050..af2f373 100644 --- a/include/file_templates.hpp +++ b/include/file_templates.hpp @@ -64,23 +64,37 @@ const char* peppol_invoice_tax_subtotal_template = " </cac:TaxSubtotal>\n"; const char* peppol_invoice_line_template = -" <cac:InvoiceLine>\n" -" <cbc:ID>{{LINE_ID}}</cbc:ID>\n" -" <cbc:InvoicedQuantity unitCode=\"{{UNIT_CODE}}\">{{QUANTITY}}</cbc:InvoicedQuantity>\n" -" <cbc:LineExtensionAmount currencyID=\"{{CURRENCY}}\">{{LINE_AMOUNT}}</cbc:LineExtensionAmount>\n" -" <cac:Item>\n" -" <cbc:Name>{{ITEM_NAME}}</cbc:Name>\n" -" <cac:ClassifiedTaxCategory>\n" -" <cbc:ID>{{LINE_TAX_CATEGORY}}</cbc:ID>\n" -" <cbc:Percent>{{LINE_TAX_PERCENT}}</cbc:Percent>\n" -" <cac:TaxScheme>\n" -" <cbc:ID>VAT</cbc:ID>\n" -" </cac:TaxScheme>\n" -" </cac:ClassifiedTaxCategory>\n" -" </cac:Item>\n" -" <cac:Price>\n" -" <cbc:PriceAmount currencyID=\"{{CURRENCY}}\">{{UNIT_PRICE}}</cbc:PriceAmount>\n" -" </cac:Price>\n" +" <cac:InvoiceLine>\n" +" <cbc:ID>{{LINE_ID}}</cbc:ID>\n" +" <cbc:InvoicedQuantity unitCode=\"{{UNIT_CODE}}\">{{QUANTITY}}</cbc:InvoicedQuantity>\n" +" <cbc:LineExtensionAmount currencyID=\"{{CURRENCY}}\">{{LINE_AMOUNT}}</cbc:LineExtensionAmount>\n" + +" <cac:OrderLineReference>\n" +" <cbc:LineID>{{TAX_BRACKET_ID}}</cbc:LineID>\n" +" </cac:OrderLineReference>\n" + +" <cac:AllowanceCharge>\n" +" <cbc:ChargeIndicator>false</cbc:ChargeIndicator>\n" +" <cbc:AllowanceChargeReason>Discount</cbc:AllowanceChargeReason>\n" +" {{ALLOWANCE_IS_PERCENTAGE}}\n" +" <cbc:Amount currencyID=\"{{CURRENCY}}\">{{DISCOUNT_TOTAL}}</cbc:Amount>\n" +" <cbc:BaseAmount currencyID=\"{{CURRENCY}}\">{{DISCOUNT_BASE_AMOUNT}}</cbc:BaseAmount>\n" +" </cac:AllowanceCharge>\n" + +" <cac:Item>\n" +" <cbc:Name>{{ITEM_NAME}}</cbc:Name>\n" +" <cac:ClassifiedTaxCategory>\n" +" <cbc:ID>{{LINE_TAX_CATEGORY}}</cbc:ID>\n" +" <cbc:Percent>{{LINE_TAX_PERCENT}}</cbc:Percent>\n" +" <cac:TaxScheme>\n" +" <cbc:ID>VAT</cbc:ID>\n" +" </cac:TaxScheme>\n" +" </cac:ClassifiedTaxCategory>\n" +" </cac:Item>\n" + +" <cac:Price>\n" +" <cbc:PriceAmount currencyID=\"{{CURRENCY}}\">{{UNIT_PRICE}}</cbc:PriceAmount>\n" +" </cac:Price>\n" " </cac:InvoiceLine>\n"; const char *peppol_invoice_template = @@ -94,12 +108,25 @@ const char *peppol_invoice_template = "\n" " <cbc:ID>{{INVOICE_ID}}</cbc:ID>\n" " <cbc:IssueDate>{{ISSUE_DATE}}</cbc:IssueDate>\n" +" <cbc:DueDate>{{DUE_DATE}}</cbc:DueDate>\n" " <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>\n" " <cbc:DocumentCurrencyCode>{{CURRENCY}}</cbc:DocumentCurrencyCode>\n" "\n" +" <cac:AdditionalDocumentReference>\n" +" <cbc:ID>{{INVOICE_DOCUMENT}}</cbc:ID>\n" +" </cac:AdditionalDocumentReference>\n" +"\n" +" <cac:ProjectReference>\n" +" <cbc:ID>{{PROJECT_ID}}</cbc:ID>\n" +" </cac:ProjectReference>\n" +" <cbc:AccountingCost>{{COST_CENTER_CODE}}</cbc:AccountingCost>\n" +"\n" " <cac:AccountingSupplierParty>\n" " <cac:Party>\n" " <cbc:EndpointID schemeID=\"{{SUPPLIER_ENDPOINT_SCHEME}}\">{{SUPPLIER_ENDPOINT_ID}}</cbc:EndpointID>\n" +" <cac:PartyIdentification>\n" +" <cbc:ID schemeID=\"ZZZ\">{{SUPPLIER_ID}}</cbc:ID>\n" +" </cac:PartyIdentification>\n" " <cac:PartyName>\n" " <cbc:Name>{{SUPPLIER_NAME}}</cbc:Name>\n" " </cac:PartyName>\n" @@ -119,12 +146,27 @@ const char *peppol_invoice_template = " <cbc:ID>VAT</cbc:ID>\n" " </cac:TaxScheme>\n" " </cac:PartyTaxScheme>\n" +"\n" +" <cac:PartyLegalEntity>\n" +" <cbc:RegistrationName>{{SUPPLIER_LEGAL_NAME}}</cbc:RegistrationName>\n" +" <cbc:CompanyID schemeID=\"ZZZ\">{{SUPPLIER_BUSINESS_ID}}</cbc:CompanyID>\n" +" </cac:PartyLegalEntity>\n" +"\n" +" <cac:Contact>\n" +" <cbc:Name>{{SUPPLIER_NAME}}</cbc:Name>\n" +" <cbc:Telephone>{{SUPPLIER_PHONE_NUMBER}}</cbc:Telephone>\n" +" <cbc:ElectronicMail>{{SUPPLIER_EMAIL}}</cbc:ElectronicMail>\n" +" </cac:Contact>\n" +"\n" " </cac:Party>\n" " </cac:AccountingSupplierParty>\n" "\n" " <cac:AccountingCustomerParty>\n" " <cac:Party>\n" " <cbc:EndpointID schemeID=\"{{CUSTOMER_ENDPOINT_SCHEME}}\">{{CUSTOMER_ENDPOINT_ID}}</cbc:EndpointID>\n" +" <cac:PartyIdentification>\n" +" <cbc:ID schemeID=\"ZZZ\">{{CUSTOMER_ID}}</cbc:ID>\n" +" </cac:PartyIdentification>\n" " <cac:PartyName>\n" " <cbc:Name>{{CUSTOMER_NAME}}</cbc:Name>\n" " </cac:PartyName>\n" @@ -144,9 +186,42 @@ const char *peppol_invoice_template = " <cbc:ID>VAT</cbc:ID>\n" " </cac:TaxScheme>\n" " </cac:PartyTaxScheme>\n" +"\n" +" <cac:PartyLegalEntity>\n" +" <cbc:RegistrationName>{{CUSTOMER_LEGAL_NAME}}</cbc:RegistrationName>\n" +" <cbc:CompanyID schemeID=\"ZZZ\">{{CUSTOMER_BUSINESS_ID}}</cbc:CompanyID>\n" +" </cac:PartyLegalEntity>\n" +"\n" +" <cac:Contact>\n" +" <cbc:Name>{{CUSTOMER_NAME}}</cbc:Name>\n" +" <cbc:Telephone>{{CUSTOMER_PHONE_NUMBER}}</cbc:Telephone>\n" +" <cbc:ElectronicMail>{{CUSTOMER_EMAIL}}</cbc:ElectronicMail>\n" +" </cac:Contact>\n" +"\n" " </cac:Party>\n" " </cac:AccountingCustomerParty>\n" "\n" +"<cac:Delivery>\n" +" <cbc:ActualDeliveryDate>{{DELIVERY_DATE}}</cbc:ActualDeliveryDate>\n" +" <cac:DeliveryLocation>\n" +" <cac:Address>\n" +" <cbc:StreetName>{{DELIVERY_STREET}}</cbc:StreetName>\n" +" <cbc:AdditionalStreetName>{{DELIVERY_STREET2}}</cbc:AdditionalStreetName>\n" +" <cbc:CityName>{{DELIVERY_CITY}}</cbc:CityName>\n" +" <cbc:PostalZone>{{DELIVERY_POSTAL}}</cbc:PostalZone>\n" +" <cbc:CountrySubentity>{{DELIVERY_REGION}}</cbc:CountrySubentity>\n" +" <cac:Country>\n" +" <cbc:IdentificationCode>{{DELIVERY_COUNTRY}}</cbc:IdentificationCode>\n" +" </cac:Country>\n" +" </cac:Address>\n" +" </cac:DeliveryLocation>\n" +" <cac:DeliveryParty>\n" +" <cac:PartyName>\n" +" <cbc:Name>{{DELIVERY_NAME}}</cbc:Name>\n" +" </cac:PartyName>\n" +" </cac:DeliveryParty>\n" +"</cac:Delivery>\n" +"\n" " <cac:PaymentMeans>\n" " <cbc:PaymentMeansCode>{{PAYMENT_TYPE}}</cbc:PaymentMeansCode>\n" " <cbc:PaymentID>{{INVOICE_ID}}</cbc:PaymentID>\n" diff --git a/libs/ImGuiDatePicker/ImGuiDatePicker.cpp b/libs/ImGuiDatePicker/ImGuiDatePicker.cpp index 8c81b2b..207a902 100644 --- a/libs/ImGuiDatePicker/ImGuiDatePicker.cpp +++ b/libs/ImGuiDatePicker/ImGuiDatePicker.cpp @@ -361,7 +361,7 @@ namespace ImGui if (Button(std::to_string(day).c_str(), ImVec2(GetContentRegionAvail().x, GetTextLineHeightWithSpacing() + 5.0f))) { - v = EncodeTimePoint(day, month, year); + v = EncodeTimePoint(day+1, month, year); res = true; CloseCurrentPopup(); } diff --git a/src/administration.cpp b/src/administration.cpp index 49b2559..2a18747 100644 --- a/src/administration.cpp +++ b/src/administration.cpp @@ -799,6 +799,7 @@ void administration_company_info_import(contact data) void administration_company_info_set(contact data) { + strops_copy(data.id, MY_COMPANY_ID, sizeof(data.id)); 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); diff --git a/src/administration_writer.cpp b/src/administration_writer.cpp index f8b4302..779a5f1 100644 --- a/src/administration_writer.cpp +++ b/src/administration_writer.cpp @@ -229,7 +229,7 @@ bool administration_writer_save_invoice_blocking(invoice inv) STOPWATCH_START; bool result = 1; - int buf_length = 150000; // Ballpark file content size. + int buf_length = 150000; // Ballpark file content size. char* file_content = (char*)malloc(buf_length); memset(file_content, 0, buf_length); memcpy(file_content, peppol_invoice_template, strlen(peppol_invoice_template)); @@ -237,12 +237,31 @@ bool administration_writer_save_invoice_blocking(invoice inv) struct tm *tm_info = 0; char date_buffer[11]; // "YYYY-MM-DD" + null terminator + // properties not stored from invoice: + // - id (can be retrieved from filename) + // - invoice allowance (can be recalculated from billing items) + + // properties not stored from supplier/customer/addressee: + // - type + // - bank account + // These can all be retrieved from existing contacts. + + // properties not stored from billing item: + // - invoice_id (not necessary) + // - discount (can be recalculated from line_amount - (quantity * unit_price) ) + // - tax (can be recalculated) + // - total (can be recalculated) + strops_replace(file_content, buf_length, "{{INVOICE_ID}}", inv.sequential_number); strops_replace(file_content, buf_length, "{{CURRENCY}}", inv.currency); + strops_replace(file_content, buf_length, "{{PROJECT_ID}}", inv.project_id); + strops_replace(file_content, buf_length, "{{COST_CENTER_CODE}}", inv.cost_center_id); + strops_replace(file_content, buf_length, "{{INVOICE_DOCUMENT}}", inv.document); // Supplier data strops_replace(file_content, buf_length, "{{SUPPLIER_ENDPOINT_SCHEME}}", administration_writer_get_eas_scheme_for_address(inv.supplier.address)); strops_replace(file_content, buf_length, "{{SUPPLIER_ENDPOINT_ID}}", administration_writer_get_eas_id_for_contact(inv.supplier)); + strops_replace(file_content, buf_length, "{{SUPPLIER_ID}}", inv.supplier.id); strops_replace(file_content, buf_length, "{{SUPPLIER_NAME}}", inv.supplier.name); strops_replace(file_content, buf_length, "{{SUPPLIER_STREET}}", inv.supplier.address.address1); strops_replace(file_content, buf_length, "{{SUPPLIER_STREET2}}", inv.supplier.address.address2); @@ -251,10 +270,15 @@ bool administration_writer_save_invoice_blocking(invoice inv) strops_replace(file_content, buf_length, "{{SUPPLIER_REGION}}", inv.supplier.address.region); strops_replace(file_content, buf_length, "{{SUPPLIER_COUNTRY}}", inv.supplier.address.country_code); strops_replace(file_content, buf_length, "{{SUPPLIER_VAT_ID}}", inv.supplier.taxid); + strops_replace(file_content, buf_length, "{{SUPPLIER_LEGAL_NAME}}", inv.supplier.name); + strops_replace(file_content, buf_length, "{{SUPPLIER_BUSINESS_ID}}", inv.supplier.businessid); + strops_replace(file_content, buf_length, "{{SUPPLIER_PHONE_NUMBER}}", inv.supplier.phone_number); + strops_replace(file_content, buf_length, "{{SUPPLIER_EMAIL}}", inv.supplier.email); // Customer data strops_replace(file_content, buf_length, "{{CUSTOMER_ENDPOINT_SCHEME}}", administration_writer_get_eas_scheme_for_address(inv.customer.address)); strops_replace(file_content, buf_length, "{{CUSTOMER_ENDPOINT_ID}}", administration_writer_get_eas_id_for_contact(inv.customer)); + strops_replace(file_content, buf_length, "{{CUSTOMER_ID}}", inv.customer.id); strops_replace(file_content, buf_length, "{{CUSTOMER_NAME}}", inv.customer.name); strops_replace(file_content, buf_length, "{{CUSTOMER_STREET}}", inv.customer.address.address1); strops_replace(file_content, buf_length, "{{CUSTOMER_STREET2}}", inv.customer.address.address2); @@ -263,6 +287,22 @@ bool administration_writer_save_invoice_blocking(invoice inv) strops_replace(file_content, buf_length, "{{CUSTOMER_REGION}}", inv.customer.address.region); strops_replace(file_content, buf_length, "{{CUSTOMER_COUNTRY}}", inv.customer.address.country_code); strops_replace(file_content, buf_length, "{{CUSTOMER_VAT_ID}}", inv.customer.taxid); + strops_replace(file_content, buf_length, "{{CUSTOMER_LEGAL_NAME}}", inv.customer.name); + strops_replace(file_content, buf_length, "{{CUSTOMER_BUSINESS_ID}}", inv.customer.businessid); + strops_replace(file_content, buf_length, "{{CUSTOMER_PHONE_NUMBER}}", inv.customer.phone_number); + strops_replace(file_content, buf_length, "{{CUSTOMER_EMAIL}}", inv.customer.email); + + // Delivery data + tm_info = localtime(&inv.delivered_at); + strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", tm_info); + strops_replace(file_content, buf_length, "{{DELIVERY_DATE}}", date_buffer); + strops_replace(file_content, buf_length, "{{DELIVERY_NAME}}", inv.addressee.name); + strops_replace(file_content, buf_length, "{{DELIVERY_STREET}}", inv.addressee.address.address1); + strops_replace(file_content, buf_length, "{{DELIVERY_STREET2}}", inv.addressee.address.address2); + strops_replace(file_content, buf_length, "{{DELIVERY_CITY}}", inv.addressee.address.city); + strops_replace(file_content, buf_length, "{{DELIVERY_POSTAL}}", inv.addressee.address.postal); + strops_replace(file_content, buf_length, "{{DELIVERY_REGION}}", inv.addressee.address.region); + strops_replace(file_content, buf_length, "{{DELIVERY_COUNTRY}}", inv.addressee.address.country_code); // Payment means strops_replace_int32(file_content, buf_length, "{{PAYMENT_TYPE}}", inv.payment_means.payment_method); @@ -270,7 +310,7 @@ bool administration_writer_save_invoice_blocking(invoice inv) strops_replace(file_content, buf_length, "{{SUPPLIER_BIC}}", inv.payment_means.service_provider_id); // Tax breakdown - strops_replace_float(file_content, buf_length, "{{TOTAL_TAX_AMOUNT}}", inv.total, 2); + strops_replace_float(file_content, buf_length, "{{TOTAL_TAX_AMOUNT}}", inv.tax, 2); { // Create tax subtotal list. country_tax_bracket* tax_bracket_buffer = (country_tax_bracket*)malloc(sizeof(country_tax_bracket)*administration_billing_item_count(&inv)); u32 tax_bracket_count = administration_invoice_get_tax_brackets(&inv, tax_bracket_buffer); @@ -337,10 +377,23 @@ bool administration_writer_save_invoice_blocking(invoice inv) strops_replace(billing_item_file_content, billing_item_buf_length, "{{ITEM_NAME}}", bi.description); strops_replace(billing_item_file_content, billing_item_buf_length, "{{LINE_TAX_CATEGORY}}", bracket.category_code); strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{LINE_TAX_PERCENT}}", bracket.rate, 2); - strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{LINE_AMOUNT}}", bi.net, 2); + strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{LINE_AMOUNT}}", bi.net, 2); // line amount = net_per_item * items_count - discount strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{QUANTITY}}", bi.amount, 2); - strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{UNIT_PRICE}}", bi.net_per_item, 2); + strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{UNIT_PRICE}}", bi.net_per_item, 2); // unit price before discount strops_replace(billing_item_file_content, billing_item_buf_length, "{{UNIT_CODE}}", bi.amount_is_percentage ? "%" : "X"); + strops_replace(billing_item_file_content, billing_item_buf_length, "{{TAX_BRACKET_ID}}", bi.tax_bracket_id); + + if (bi.discount_is_percentage) { + strops_replace(billing_item_file_content, billing_item_buf_length, "{{ALLOWANCE_IS_PERCENTAGE}}", + "<cbc:MultiplierFactorNumeric>{{DISCOUNT_TOTAL_PERCENTAGE}}</cbc:MultiplierFactorNumeric>"); + strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_TOTAL_PERCENTAGE}}", bi.allowance / (bi.net + bi.allowance), 2); + } + else { + strops_replace(billing_item_file_content, billing_item_buf_length, "{{ALLOWANCE_IS_PERCENTAGE}}", ""); + } + + strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_TOTAL}}", bi.allowance, 2); + strops_replace_float(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_BASE_AMOUNT}}", bi.net + bi.allowance, 2); // Total net before discount. u32 content_len = (u32)strlen(billing_item_file_content); memcpy(billing_item_list_buffer+billing_item_list_buffer_cursor, billing_item_file_content, content_len); @@ -360,6 +413,10 @@ bool administration_writer_save_invoice_blocking(invoice inv) strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", tm_info); strops_replace(file_content, buf_length, "{{ISSUE_DATE}}", date_buffer); + tm_info = localtime(&inv.expires_at); + strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", tm_info); + strops_replace(file_content, buf_length, "{{DUE_DATE}}", date_buffer); + //// Write to Disk. char final_path[50]; snprintf(final_path, 50, "%s.xml", inv.id); diff --git a/src/ui/ui_settings.cpp b/src/ui/ui_settings.cpp index ae05b1a..dfe6b96 100644 --- a/src/ui/ui_settings.cpp +++ b/src/ui/ui_settings.cpp @@ -61,7 +61,7 @@ static void ui_draw_vat_rates() country_tax_bracket c = tax_brackets[i]; // Set to false for shared rates. - bool can_be_modified = true; + bool can_be_modified = false; // Check for fixed rates shared accross countries. if (strcmp(c.country_code, "00") == 0) |
