Complete CA-3 configuration interface with all sections and headers

Configuration Interface Improvements:
- Added all missing CA-3 lines from planning document
- Implemented proper section headers (A, B, C, D)
- Added section descriptions for better understanding
- Organized lines by section for logical grouping

CA-3 Lines Added:
- A1, A2: Taxable operations base amounts
- B1-B4: VAT rate breakdowns (20%, 10%, 5.5%, 2.1%)
- 05, 06: Intra-EU operations (B2B)
- 17: VAT due on intra-EU acquisitions
- 20, 21: Deductible VAT (fixed assets, other)
- 22, 28, 29: Result calculations

Section Headers:
- A. Opérations imposables (Taxable Operations)
- B. TVA due (VAT Due)
- C. TVA déductible (Deductible VAT)
- D. Résultat (Result)

Enhanced Features:
- Section-based organization in configuration
- Type indicators (Base/VAT) for each line
- Improved visual layout with section headers
- Better grouping in current configuration display

Language Support:
- Added English translations for all new labels
- Added French translations for all new labels
- Consistent terminology across both languages

The configuration page now shows the complete CA-3 structure as defined in the planning document!
This commit is contained in:
Frank Cools 2025-10-02 16:36:12 +02:00
parent e91f0dc3b0
commit d7bb9d23e8
4 changed files with 202 additions and 67 deletions

View File

@ -1,7 +1,7 @@
<?php
/**
* MVP Setup page for DeclarationTVA module
* Simplified configuration for Phase 1
* Complete CA-3 configuration with all sections and headers
*/
// Load Dolibarr environment
@ -34,9 +34,9 @@ $config = new DeclarationTVA_Config($db, $conf->entity);
// Handle form submission
$action = GETPOST('action', 'alpha');
if ($action == 'update_mappings') {
$ca3_lines = array('A1', 'A2', 'B1', 'B2', 'B3', 'B4', '17', '20', '21', '22', '28', '29');
$ca3_definitions = $config->getCA3LineDefinitions();
foreach ($ca3_lines as $line) {
foreach ($ca3_definitions as $line => $definition) {
$account_code = GETPOST('account_code_' . $line, 'alpha');
$account_label = GETPOST('account_label_' . $line, 'alpha');
$vat_rate = GETPOST('vat_rate_' . $line, 'alpha');
@ -60,6 +60,7 @@ foreach ($mappings as $mapping) {
$accounts = $config->getAccountingAccounts();
$vat_rates = $config->getVATRates();
$ca3_definitions = $config->getCA3LineDefinitions();
$section_headers = $config->getCA3SectionHeaders();
// Page title
$title = $langs->trans("DeclarationTVASetup");
@ -75,43 +76,65 @@ print '<input type="hidden" name="action" value="update_mappings">';
print '<div class="fiche">';
print '<div class="titre">' . $langs->trans("DeclarationTVAPCGMapping") . '</div>';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>' . $langs->trans("CA3Line") . '</th>';
print '<th>' . $langs->trans("LineLabel") . '</th>';
print '<th>' . $langs->trans("AccountCode") . '</th>';
print '<th>' . $langs->trans("AccountLabel") . '</th>';
print '<th>' . $langs->trans("VATRate") . '</th>';
print '</tr>';
// Group CA-3 lines by section
$lines_by_section = array();
foreach ($ca3_definitions as $line => $definition) {
$mapping = isset($account_mappings[$line]) ? $account_mappings[$line] : array();
print '<tr>';
print '<td><strong>' . $line . '</strong></td>';
print '<td>' . $definition['label'] . '</td>';
print '<td>';
print '<select name="account_code_' . $line . '" class="flat">';
print '<option value="">' . $langs->trans("SelectAccount") . '</option>';
foreach ($accounts as $account) {
$selected = (isset($mapping['account_code']) && $mapping['account_code'] == $account['account_number']) ? 'selected' : '';
print '<option value="' . $account['account_number'] . '" ' . $selected . '>' . $account['account_number'] . ' - ' . $account['label'] . '</option>';
$section = $definition['section'];
if (!isset($lines_by_section[$section])) {
$lines_by_section[$section] = array();
}
print '</select>';
print '</td>';
print '<td><input type="text" name="account_label_' . $line . '" value="' . (isset($mapping['account_label']) ? $mapping['account_label'] : '') . '" class="flat" size="30"></td>';
print '<td>';
print '<select name="vat_rate_' . $line . '" class="flat">';
foreach ($vat_rates as $rate => $label) {
$selected = (isset($mapping['vat_rate']) && $mapping['vat_rate'] == $rate) ? 'selected' : '';
print '<option value="' . $rate . '" ' . $selected . '>' . $label . '</option>';
}
print '</select>';
print '</td>';
print '</tr>';
$lines_by_section[$section][$line] = $definition;
}
print '</table>';
// Print each section
foreach ($lines_by_section as $section_code => $lines) {
$section_info = $section_headers[$section_code];
// Section header
print '<div class="titre">' . $section_info['title'] . '</div>';
print '<div class="info">' . $section_info['description'] . '</div>';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>' . $langs->trans("CA3Line") . '</th>';
print '<th>' . $langs->trans("LineLabel") . '</th>';
print '<th>' . $langs->trans("AccountCode") . '</th>';
print '<th>' . $langs->trans("AccountLabel") . '</th>';
print '<th>' . $langs->trans("VATRate") . '</th>';
print '<th>' . $langs->trans("Type") . '</th>';
print '</tr>';
foreach ($lines as $line => $definition) {
$mapping = isset($account_mappings[$line]) ? $account_mappings[$line] : array();
print '<tr>';
print '<td><strong>' . $line . '</strong></td>';
print '<td>' . $definition['label'] . '</td>';
print '<td>';
print '<select name="account_code_' . $line . '" class="flat">';
print '<option value="">' . $langs->trans("SelectAccount") . '</option>';
foreach ($accounts as $account) {
$selected = (isset($mapping['account_code']) && $mapping['account_code'] == $account['account_number']) ? 'selected' : '';
print '<option value="' . $account['account_number'] . '" ' . $selected . '>' . $account['account_number'] . ' - ' . $account['label'] . '</option>';
}
print '</select>';
print '</td>';
print '<td><input type="text" name="account_label_' . $line . '" value="' . (isset($mapping['account_label']) ? $mapping['account_label'] : '') . '" class="flat" size="30"></td>';
print '<td>';
print '<select name="vat_rate_' . $line . '" class="flat">';
foreach ($vat_rates as $rate => $label) {
$selected = (isset($mapping['vat_rate']) && $mapping['vat_rate'] == $rate) ? 'selected' : '';
print '<option value="' . $rate . '" ' . $selected . '>' . $label . '</option>';
}
print '</select>';
print '</td>';
print '<td><span class="badge badge-' . ($definition['type'] == 'base' ? 'info' : 'success') . '">' . ucfirst($definition['type']) . '</span></td>';
print '</tr>';
}
print '</table>';
print '<br>';
}
print '<div class="titre">' . $langs->trans("Actions") . '</div>';
print '<input type="submit" class="button" value="' . $langs->trans("UpdateConfiguration") . '">';
@ -119,32 +142,52 @@ print '</div>';
print '</form>';
// Print current configuration
// Print current configuration summary
print '<div class="fiche">';
print '<div class="titre">' . $langs->trans("CurrentConfiguration") . '</div>';
if (empty($mappings)) {
print '<div class="info">' . $langs->trans("NoConfigurationFound") . '</div>';
} else {
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>' . $langs->trans("CA3Line") . '</th>';
print '<th>' . $langs->trans("AccountCode") . '</th>';
print '<th>' . $langs->trans("AccountLabel") . '</th>';
print '<th>' . $langs->trans("VATRate") . '</th>';
print '<th>' . $langs->trans("Status") . '</th>';
print '</tr>';
// Group by section for display
$mappings_by_section = array();
foreach ($mappings as $mapping) {
print '<tr>';
print '<td><strong>' . $mapping['ca3_line'] . '</strong></td>';
print '<td>' . $mapping['account_code'] . '</td>';
print '<td>' . $mapping['account_label'] . '</td>';
print '<td>' . $mapping['vat_rate'] . '%</td>';
print '<td>' . ($mapping['is_active'] ? $langs->trans("Active") : $langs->trans("Inactive")) . '</td>';
print '</tr>';
$line = $mapping['ca3_line'];
if (isset($ca3_definitions[$line])) {
$section = $ca3_definitions[$line]['section'];
if (!isset($mappings_by_section[$section])) {
$mappings_by_section[$section] = array();
}
$mappings_by_section[$section][] = $mapping;
}
}
foreach ($mappings_by_section as $section_code => $section_mappings) {
$section_info = $section_headers[$section_code];
print '<div class="titre">' . $section_info['title'] . '</div>';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>' . $langs->trans("CA3Line") . '</th>';
print '<th>' . $langs->trans("AccountCode") . '</th>';
print '<th>' . $langs->trans("AccountLabel") . '</th>';
print '<th>' . $langs->trans("VATRate") . '</th>';
print '<th>' . $langs->trans("Status") . '</th>';
print '</tr>';
foreach ($section_mappings as $mapping) {
print '<tr>';
print '<td><strong>' . $mapping['ca3_line'] . '</strong></td>';
print '<td>' . $mapping['account_code'] . '</td>';
print '<td>' . $mapping['account_label'] . '</td>';
print '<td>' . $mapping['vat_rate'] . '%</td>';
print '<td>' . ($mapping['is_active'] ? $langs->trans("Active") : $langs->trans("Inactive")) . '</td>';
print '</tr>';
}
print '</table>';
print '<br>';
}
print '</table>';
}
print '</div>';

View File

@ -182,18 +182,56 @@ class DeclarationTVA_Config
public function getCA3LineDefinitions()
{
return array(
'A1' => array('label' => 'Montant hors TVA des opérations imposables', 'type' => 'base'),
'A2' => array('label' => 'Opérations imposables mais ne relevant pas du CA courant', 'type' => 'base'),
'B1' => array('label' => 'Répartition 20% (base + taxe)', 'type' => 'vat'),
'B2' => array('label' => 'Répartition 10% (base + taxe)', 'type' => 'vat'),
'B3' => array('label' => 'Répartition 5,5% (base + taxe)', 'type' => 'vat'),
'B4' => array('label' => 'Répartition 2,1% (base + taxe)', 'type' => 'vat'),
'17' => array('label' => 'TVA due au titre des acquisitions intracommunautaires', 'type' => 'vat'),
'20' => array('label' => 'TVA déductible sur immobilisations', 'type' => 'vat'),
'21' => array('label' => 'TVA déductible sur autres biens et services', 'type' => 'vat'),
'22' => array('label' => 'Crédit de TVA reportable', 'type' => 'vat'),
'28' => array('label' => 'TVA nette à payer', 'type' => 'vat'),
'29' => array('label' => 'Crédit de TVA à reporter ou remboursement', 'type' => 'vat')
// A. Opérations imposables (Taxable Operations)
'A1' => array('label' => 'Montant hors TVA des opérations imposables', 'type' => 'base', 'section' => 'A'),
'A2' => array('label' => 'Opérations imposables mais ne relevant pas du CA courant', 'type' => 'base', 'section' => 'A'),
'B1' => array('label' => 'Répartition 20% (base + taxe)', 'type' => 'vat', 'section' => 'A'),
'B2' => array('label' => 'Répartition 10% (base + taxe)', 'type' => 'vat', 'section' => 'A'),
'B3' => array('label' => 'Répartition 5,5% (base + taxe)', 'type' => 'vat', 'section' => 'A'),
'B4' => array('label' => 'Répartition 2,1% (base + taxe)', 'type' => 'vat', 'section' => 'A'),
// A. Opérations intracommunautaires (Intra-EU Operations)
'05' => array('label' => 'Livraisons intracommunautaires (B2B)', 'type' => 'base', 'section' => 'A'),
'06' => array('label' => 'Prestations intracommunautaires (B2B)', 'type' => 'base', 'section' => 'A'),
// B. TVA due (VAT Due)
'17' => array('label' => 'TVA due au titre des acquisitions intracommunautaires', 'type' => 'vat', 'section' => 'B'),
// C. TVA déductible (Deductible VAT)
'20' => array('label' => 'TVA déductible sur immobilisations', 'type' => 'vat', 'section' => 'C'),
'21' => array('label' => 'TVA déductible sur autres biens et services', 'type' => 'vat', 'section' => 'C'),
// D. Résultat (Result)
'22' => array('label' => 'Crédit de TVA reportable', 'type' => 'vat', 'section' => 'D'),
'28' => array('label' => 'TVA nette à payer', 'type' => 'vat', 'section' => 'D'),
'29' => array('label' => 'Crédit de TVA à reporter ou remboursement', 'type' => 'vat', 'section' => 'D')
);
}
/**
* Get CA-3 section headers
*
* @return array Section headers
*/
public function getCA3SectionHeaders()
{
return array(
'A' => array(
'title' => 'A. Opérations imposables (Taxable Operations)',
'description' => 'Base amounts and VAT for domestic taxable operations'
),
'B' => array(
'title' => 'B. TVA due (VAT Due)',
'description' => 'VAT amounts due from intra-EU acquisitions and other sources'
),
'C' => array(
'title' => 'C. TVA déductible (Deductible VAT)',
'description' => 'VAT amounts that can be deducted from purchases and expenses'
),
'D' => array(
'title' => 'D. Résultat (Result)',
'description' => 'Final calculation: net VAT to pay or credit to carry forward'
)
);
}

View File

@ -330,3 +330,30 @@ DeclarationTVASupplierAnalysis = Supplier Analysis
DeclarationTVAGeographicAnalysis = Geographic Analysis
DeclarationTVAProductAnalysis = Product Analysis
DeclarationTVASeasonalAnalysis = Seasonal Analysis
# CA-3 Section Headers
CA3SectionA = Taxable Operations
CA3SectionB = VAT Due
CA3SectionC = Deductible VAT
CA3SectionD = Result
# CA-3 Line Labels
CA3LineA1 = Base amount of taxable operations
CA3LineA2 = Taxable operations not part of current revenue
CA3LineB1 = 20% VAT operations
CA3LineB2 = 10% VAT operations
CA3LineB3 = 5.5% VAT operations
CA3LineB4 = 2.1% VAT operations
CA3Line05 = Intra-EU goods deliveries (B2B)
CA3Line06 = Intra-EU services (B2B)
CA3Line17 = VAT due on intra-EU acquisitions
CA3Line20 = Deductible VAT on fixed assets
CA3Line21 = Deductible VAT on other goods and services
CA3Line22 = VAT credit to carry forward
CA3Line28 = Net VAT to pay
CA3Line29 = VAT credit to carry forward or refund
# Form Labels
Type = Type
Base = Base
VAT = VAT

View File

@ -319,3 +319,30 @@ DeclarationTVASupplierAnalysis = Analyse fournisseurs
DeclarationTVAGeographicAnalysis = Analyse géographique
DeclarationTVAProductAnalysis = Analyse produits
DeclarationTVASeasonalAnalysis = Analyse saisonnière
# En-têtes des sections CA-3
CA3SectionA = Opérations imposables
CA3SectionB = TVA due
CA3SectionC = TVA déductible
CA3SectionD = Résultat
# Labels des lignes CA-3
CA3LineA1 = Montant hors TVA des opérations imposables
CA3LineA2 = Opérations imposables mais ne relevant pas du CA courant
CA3LineB1 = Opérations à 20%
CA3LineB2 = Opérations à 10%
CA3LineB3 = Opérations à 5,5%
CA3LineB4 = Opérations à 2,1%
CA3Line05 = Livraisons intracommunautaires (B2B)
CA3Line06 = Prestations intracommunautaires (B2B)
CA3Line17 = TVA due au titre des acquisitions intracommunautaires
CA3Line20 = TVA déductible sur immobilisations
CA3Line21 = TVA déductible sur autres biens et services
CA3Line22 = Crédit de TVA reportable
CA3Line28 = TVA nette à payer
CA3Line29 = Crédit de TVA à reporter ou remboursement
# Labels de formulaire
Type = Type
Base = Base
VAT = TVA