Refactor authorization and token refresh logic; update tax handling and invoice generation

- Changed variable name from `$stmt_service` to `$stmt_refreshkey` for clarity in `authorization.php` and `token_refresh.php`.
- Added null coalescing operator to ensure criteria are set to an empty string if not provided in `products_software_versions.php`.
- Modified SQL script to add `eu` column to `taxes` table and update tax rates based on EU membership.
- Enhanced invoice generation logic in `functions.php` to include VAT notes based on customer country and VAT number.
- Updated email and PDF templates to display VAT notes and percentages correctly.
- Adjusted JavaScript tax calculation logic to handle VAT based on country and VAT number.
- Fixed API URL in `index.php` for token refresh endpoint.
- Updated countries data structure in `countries.php` to include EU membership status.
This commit is contained in:
“VeLiTi”
2026-02-05 15:26:41 +01:00
parent c4cb99b945
commit d7b9b91bb6
10 changed files with 271 additions and 168 deletions

View File

@@ -1485,12 +1485,35 @@ function showPaymentModal(option) {
// Function to calculate and update tax
function updateTaxDisplay() {
const selectedCountry = document.getElementById("paymentCountry").value;
const vatNumber = document.getElementById("paymentVatNumber").value.trim();
let taxRate = 0;
let vatNote = '';
if (selectedCountry && typeof COUNTRIES !== 'undefined' && COUNTRIES) {
const countryData = Object.values(COUNTRIES).find(c => c.country === selectedCountry);
if (countryData) {
taxRate = parseFloat(countryData.taxes) || 0;
const isEU = countryData.eu === 1;
const isNetherlands = selectedCountry === 'Netherlands';
const countryTaxRate = parseFloat(countryData.taxes) || 0;
if (isNetherlands) {
// Netherlands: always take the tax percentage
taxRate = countryTaxRate;
} else if (isEU) {
if (vatNumber) {
// EU with VAT number: 0% VAT, reverse charge
taxRate = 0;
vatNote = 'Reverse charge VAT';
} else {
// EU without VAT number: use country VAT
taxRate = countryTaxRate;
vatNote = 'Local VAT';
}
} else {
// Non-EU: use country tax percentage (usually 0)
taxRate = countryTaxRate;
vatNote = 'Out of scope of EU VAT. Buyer is responsible for local taxes and duties';
}
}
}
@@ -1503,13 +1526,13 @@ function showPaymentModal(option) {
if (taxRate > 0) {
taxDisplay.innerHTML = `
<span>VAT (${taxRate}%):</span>
<span>VAT (${taxRate}%)${vatNote ? ' <small style="font-size: 9px; color: #888;">(' + vatNote + ')</small>' : ''}:</span>
<span style="font-weight: 600;">${currency} ${taxAmount.toFixed(2)}</span>
`;
} else {
taxDisplay.innerHTML = `
<span>VAT:</span>
<span style="font-weight: 600;">-</span>
<span>VAT${vatNote ? ' <small style="font-size: 9px; color: #888;">(' + vatNote + ')</small>' : ''}:</span>
<span style="font-weight: 600;">${vatNote ? '0%' : '-'}</span>
`;
}
@@ -1541,8 +1564,9 @@ function showPaymentModal(option) {
}
}
// Add event listener to country select to update tax
// Add event listeners to country select and VAT number to update tax
document.getElementById("paymentCountry").addEventListener('change', updateTaxDisplay);
document.getElementById("paymentVatNumber").addEventListener('input', updateTaxDisplay);
// Close modal on cancel
document.getElementById("cancelPayment").onclick = () => {