Enhanced: - Line 16 (Sous-total TVA due): Light red background (#ffe6e6) - Line 23 (Sous-total TVA déductible): Light red background (#ffe6e6) - All D-section lines (25, 26, TD, 28, 29): Light red background (#ffe6e6) This makes calculated/result lines stand out visually from mapped lines, improving user experience and making it clear which lines are automatically calculated vs manually configured.
469 lines
16 KiB
PHP
469 lines
16 KiB
PHP
<?php
|
|
/**
|
|
* DeclarationTVA View Declaration
|
|
* French CA-3 VAT Declaration Module for Dolibarr
|
|
* MVP Version - Phase 1
|
|
*/
|
|
|
|
// Load Dolibarr environment
|
|
if (file_exists('../main.inc.php')) {
|
|
$res = @include '../main.inc.php';
|
|
} elseif (file_exists('../../main.inc.php')) {
|
|
$res = @include '../../main.inc.php';
|
|
} else {
|
|
$res = 0;
|
|
}
|
|
|
|
if (!$res) {
|
|
die("Include of main fails");
|
|
}
|
|
|
|
// Load module classes
|
|
require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva.class.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_config.class.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_period.class.php';
|
|
|
|
// Access control
|
|
if (!$user->hasRight("declarationtva", "declarationtva", "read")) {
|
|
accessforbidden();
|
|
}
|
|
|
|
// Load language files
|
|
$langs->load("declarationtva@declarationtva");
|
|
|
|
// Get declaration ID
|
|
$id = GETPOST('id', 'int');
|
|
if (empty($id)) {
|
|
accessforbidden();
|
|
}
|
|
|
|
// Initialize objects
|
|
$declarationtva = new DeclarationTVA($db, $conf->entity);
|
|
$config = new DeclarationTVA_Config($db, $conf->entity);
|
|
$period = new DeclarationTVA_Period($db, $conf->entity);
|
|
|
|
// Handle actions
|
|
$action = GETPOST('action', 'alpha');
|
|
$token = GETPOST('token', 'alpha');
|
|
|
|
if ($action == 'recalculate' && $token) {
|
|
if ($declarationtva->recalculateCA3Amounts($id)) {
|
|
setEventMessages($langs->trans("DeclarationRecalculated"), null, 'mesgs');
|
|
} else {
|
|
setEventMessages($langs->trans("ErrorRecalculatingDeclaration"), null, 'errors');
|
|
}
|
|
}
|
|
|
|
// Fetch declaration
|
|
if ($declarationtva->fetch($id) < 0) {
|
|
setEventMessages($langs->trans("DeclarationNotFound"), null, 'errors');
|
|
header("Location: declarationtvaindex.php");
|
|
exit;
|
|
}
|
|
|
|
// Use declaration's own dates
|
|
$start_date = $declarationtva->start_date;
|
|
$end_date = $declarationtva->end_date;
|
|
|
|
// Page title
|
|
$title = $langs->trans("ViewDeclaration") . ' - ' . $declarationtva->declaration_number;
|
|
llxHeader('', $title);
|
|
|
|
// Print page header
|
|
print load_fiche_titre($title, '', 'title_accountancy');
|
|
|
|
// Print declaration details
|
|
print '<div class="fiche">';
|
|
print '<div class="titre">' . $langs->trans("DeclarationDetails") . '</div>';
|
|
|
|
print '<table class="noborder centpercent">';
|
|
|
|
print '<tr>';
|
|
print '<td class="fieldrequired">' . $langs->trans("DeclarationNumber") . '</td>';
|
|
print '<td>' . $declarationtva->declaration_number . '</td>';
|
|
print '</tr>';
|
|
|
|
print '<tr>';
|
|
print '<td>' . $langs->trans("DeclarationName") . '</td>';
|
|
print '<td>' . $declarationtva->declaration_name . '</td>';
|
|
print '</tr>';
|
|
|
|
print '<tr>';
|
|
print '<td>' . $langs->trans("Period") . '</td>';
|
|
print '<td>' . dol_print_date($start_date, 'day') . ' - ' . dol_print_date($end_date, 'day') . '</td>';
|
|
print '</tr>';
|
|
|
|
print '<tr>';
|
|
print '<td>' . $langs->trans("Status") . '</td>';
|
|
print '<td>' . $langs->trans("Status" . ucfirst($declarationtva->status)) . '</td>';
|
|
print '</tr>';
|
|
|
|
print '<tr>';
|
|
print '<td>' . $langs->trans("CreatedDate") . '</td>';
|
|
print '<td>' . dol_print_date($declarationtva->created_date, 'dayhour') . '</td>';
|
|
print '</tr>';
|
|
|
|
|
|
print '</table>';
|
|
print '</div>';
|
|
|
|
// Print CA-3 amounts (placeholder for now)
|
|
print '<div class="fiche">';
|
|
print '<div class="titre">' . $langs->trans("CA3Amounts") . '</div>';
|
|
|
|
print '<table class="noborder centpercent">';
|
|
|
|
// Get actual CA-3 lines from database
|
|
$ca3_lines = $declarationtva->getCA3Lines($id);
|
|
|
|
// Get CA-3 line definitions for proper descriptions
|
|
$ca3_definitions = $config->getCA3LineDefinitions();
|
|
|
|
// Helper function to format amounts with original values in brackets
|
|
function formatAmountWithOriginal($amount, $line_label, $amount_type = 'vat') {
|
|
// If amount is zero, show empty field
|
|
if ($amount == 0) {
|
|
return '';
|
|
}
|
|
|
|
// Parse original amounts from line_label if they exist
|
|
if (strpos($line_label, '|ORIGINAL_') !== false) {
|
|
$parts = explode('|', $line_label);
|
|
$original_info = $parts[1] ?? '';
|
|
|
|
$pattern = $amount_type == 'base' ? '/ORIGINAL_BASE:([0-9.]+)/' : '/ORIGINAL_VAT:([0-9.]+)/';
|
|
if (preg_match($pattern, $original_info, $matches)) {
|
|
$original_amount = floatval($matches[1]);
|
|
if ($original_amount != $amount) {
|
|
return number_format($amount, 0) . ' (' . number_format($original_amount, 2) . ')';
|
|
}
|
|
}
|
|
}
|
|
return number_format($amount, 0);
|
|
}
|
|
|
|
// Helper function to format simple amounts (no original values)
|
|
function formatAmount($amount) {
|
|
// If amount is zero, show empty field
|
|
if ($amount == 0) {
|
|
return '';
|
|
}
|
|
return number_format($amount, 0);
|
|
}
|
|
|
|
// Create a lookup array for quick access
|
|
$ca3_data = array();
|
|
foreach ($ca3_lines as $line) {
|
|
$ca3_data[$line['ca3_line']] = $line;
|
|
}
|
|
|
|
// Section A: Opérations imposables
|
|
print '<tr class="liste_titre">';
|
|
print '<td colspan="4"><strong>A. ' . $langs->trans("CA3SectionA") . '</strong></td>';
|
|
print '</tr>';
|
|
|
|
print '<tr class="liste_titre">';
|
|
print '<th>' . $langs->trans("CA3Line") . '</th>';
|
|
print '<th colspan="2">' . $langs->trans("Description") . '</th>';
|
|
print '<th class="right">' . $langs->trans("Amount") . '</th>';
|
|
print '</tr>';
|
|
|
|
$section_a_lines = array('A1', 'A2', 'A3', 'A4', 'A5');
|
|
foreach ($section_a_lines as $line) {
|
|
$data = isset($ca3_data[$line]) ? $ca3_data[$line] : array('line_label' => '', 'vat_amount' => 0);
|
|
$description = isset($ca3_definitions[$line]) ? $ca3_definitions[$line]['label'] : $data['line_label'];
|
|
print '<tr>';
|
|
print '<td><a href="#" onclick="toggleDetails(\'' . $line . '\'); return false;" class="butAction">' . $line . '</a></td>';
|
|
print '<td colspan="2">' . $description . '</td>';
|
|
print '<td class="right">' . formatAmountWithOriginal($data['vat_amount'], $data['line_label']) . '</td>';
|
|
print '</tr>';
|
|
|
|
// Add dropdown row for account details
|
|
print '<tr id="details_' . $line . '" style="display: none;">';
|
|
print '<td colspan="4">';
|
|
print '<div class="account-details">';
|
|
print '<div class="account-details-header">' . $langs->trans("AccountBreakdown") . ' - ' . $line . '</div>';
|
|
print '<div class="account-details-content" id="content_' . $line . '">';
|
|
print '<div class="loading">' . $langs->trans("Loading") . '...</div>';
|
|
print '</div>';
|
|
print '</div>';
|
|
print '</td>';
|
|
print '</tr>';
|
|
}
|
|
|
|
// Section B: TVA due
|
|
print '<tr class="liste_titre">';
|
|
print '<td colspan="4"><strong>B. ' . $langs->trans("CA3SectionB") . '</strong></td>';
|
|
print '</tr>';
|
|
|
|
// Special header for lines 08, 09, 9B with base and VAT columns
|
|
print '<tr class="liste_titre">';
|
|
print '<td colspan="4"><strong>' . $langs->trans("BaseHTAndVATByRate") . '</strong></td>';
|
|
print '</tr>';
|
|
|
|
print '<tr class="liste_titre">';
|
|
print '<th>' . $langs->trans("CA3Line") . '</th>';
|
|
print '<th>' . $langs->trans("Description") . '</th>';
|
|
print '<th class="right">' . $langs->trans("BaseAmount") . '</th>';
|
|
print '<th class="right">' . $langs->trans("VATAmount") . '</th>';
|
|
print '</tr>';
|
|
|
|
$base_vat_lines = array('08', '09', '9B');
|
|
foreach ($base_vat_lines as $line) {
|
|
$data = isset($ca3_data[$line]) ? $ca3_data[$line] : array('line_label' => '', 'base_amount' => 0, 'vat_amount' => 0);
|
|
$description = isset($ca3_definitions[$line]) ? $ca3_definitions[$line]['label'] : $data['line_label'];
|
|
print '<tr>';
|
|
print '<td><a href="#" onclick="toggleDetails(\'' . $line . '\'); return false;" class="butAction">' . $line . '</a></td>';
|
|
print '<td>' . $description . '</td>';
|
|
print '<td class="right">' . formatAmountWithOriginal($data['base_amount'], $data['line_label'], 'base') . '</td>';
|
|
print '<td class="right">' . formatAmountWithOriginal($data['vat_amount'], $data['line_label']) . '</td>';
|
|
print '</tr>';
|
|
|
|
// Add dropdown row for account details
|
|
print '<tr id="details_' . $line . '" style="display: none;">';
|
|
print '<td colspan="4">';
|
|
print '<div class="account-details">';
|
|
print '<div class="account-details-header">' . $langs->trans("AccountBreakdown") . ' - ' . $line . '</div>';
|
|
print '<div class="account-details-content" id="content_' . $line . '">';
|
|
print '<div class="loading">' . $langs->trans("Loading") . '...</div>';
|
|
print '</div>';
|
|
print '</div>';
|
|
print '</td>';
|
|
print '</tr>';
|
|
}
|
|
|
|
// Line 16: Subtotal (calculated automatically)
|
|
$data = isset($ca3_data['16']) ? $ca3_data['16'] : array('line_label' => '', 'vat_amount' => 0);
|
|
print '<tr class="pair" style="background-color: #ffe6e6;">';
|
|
print '<td><strong>16</strong></td>';
|
|
print '<td colspan="2"><strong>Sous-total TVA due (08 + 09 + 9B)</strong></td>';
|
|
print '<td class="right"><strong>' . formatAmount($data['vat_amount']) . '</strong></td>';
|
|
print '</tr>';
|
|
|
|
// Reset to normal layout for line 17
|
|
print '<tr class="liste_titre">';
|
|
print '<th>' . $langs->trans("CA3Line") . '</th>';
|
|
print '<th colspan="2">' . $langs->trans("Description") . '</th>';
|
|
print '<th class="right">' . $langs->trans("Amount") . '</th>';
|
|
print '</tr>';
|
|
|
|
$data = isset($ca3_data['17']) ? $ca3_data['17'] : array('line_label' => '', 'vat_amount' => 0);
|
|
$description = isset($ca3_definitions['17']) ? $ca3_definitions['17']['label'] : $data['line_label'];
|
|
print '<tr>';
|
|
print '<td><a href="#" onclick="toggleDetails(\'17\'); return false;" class="butAction">17</a></td>';
|
|
print '<td colspan="2">' . $description . '</td>';
|
|
print '<td class="right">' . formatAmountWithOriginal($data['vat_amount'], $data['line_label']) . '</td>';
|
|
print '</tr>';
|
|
|
|
// Add dropdown row for account details
|
|
print '<tr id="details_17" style="display: none;">';
|
|
print '<td colspan="4">';
|
|
print '<div class="account-details">';
|
|
print '<div class="account-details-header">' . $langs->trans("AccountBreakdown") . ' - 17</div>';
|
|
print '<div class="account-details-content" id="content_17">';
|
|
print '<div class="loading">' . $langs->trans("Loading") . '...</div>';
|
|
print '</div>';
|
|
print '</div>';
|
|
print '</td>';
|
|
print '</tr>';
|
|
|
|
// Section C: TVA déductible
|
|
print '<tr class="liste_titre">';
|
|
print '<td colspan="4"><strong>C. ' . $langs->trans("CA3SectionC") . '</strong></td>';
|
|
print '</tr>';
|
|
|
|
print '<tr class="liste_titre">';
|
|
print '<th>' . $langs->trans("CA3Line") . '</th>';
|
|
print '<th colspan="2">' . $langs->trans("Description") . '</th>';
|
|
print '<th class="right">' . $langs->trans("Amount") . '</th>';
|
|
print '</tr>';
|
|
|
|
$section_c_lines = array('20', '21', '22');
|
|
foreach ($section_c_lines as $line) {
|
|
$data = isset($ca3_data[$line]) ? $ca3_data[$line] : array('line_label' => '', 'vat_amount' => 0);
|
|
$description = isset($ca3_definitions[$line]) ? $ca3_definitions[$line]['label'] : $data['line_label'];
|
|
print '<tr>';
|
|
print '<td><a href="#" onclick="toggleDetails(\'' . $line . '\'); return false;" class="butAction">' . $line . '</a></td>';
|
|
print '<td colspan="2">' . $description . '</td>';
|
|
print '<td class="right">' . formatAmountWithOriginal($data['vat_amount'], $data['line_label']) . '</td>';
|
|
print '</tr>';
|
|
|
|
// Add dropdown row for account details
|
|
print '<tr id="details_' . $line . '" style="display: none;">';
|
|
print '<td colspan="4">';
|
|
print '<div class="account-details">';
|
|
print '<div class="account-details-header">' . $langs->trans("AccountBreakdown") . ' - ' . $line . '</div>';
|
|
print '<div class="account-details-content" id="content_' . $line . '">';
|
|
print '<div class="loading">' . $langs->trans("Loading") . '...</div>';
|
|
print '</div>';
|
|
print '</div>';
|
|
print '</td>';
|
|
print '</tr>';
|
|
}
|
|
|
|
// Line 23: Subtotal (calculated automatically)
|
|
$data = isset($ca3_data['23']) ? $ca3_data['23'] : array('line_label' => '', 'vat_amount' => 0);
|
|
print '<tr class="pair" style="background-color: #ffe6e6;">';
|
|
print '<td><strong>23</strong></td>';
|
|
print '<td colspan="2"><strong>Sous-total TVA déductible (20 + 21 + 22)</strong></td>';
|
|
print '<td class="right"><strong>' . formatAmount($data['vat_amount']) . '</strong></td>';
|
|
print '</tr>';
|
|
|
|
// Section D: Résultat
|
|
print '<tr class="liste_titre">';
|
|
print '<td colspan="4"><strong>D. ' . $langs->trans("CA3SectionD") . '</strong></td>';
|
|
print '</tr>';
|
|
|
|
print '<tr class="liste_titre">';
|
|
print '<th>' . $langs->trans("CA3Line") . '</th>';
|
|
print '<th colspan="2">' . $langs->trans("Description") . '</th>';
|
|
print '<th class="right">' . $langs->trans("Amount") . '</th>';
|
|
print '</tr>';
|
|
|
|
$section_d_lines = array('25', '26', 'TD', '28', '29');
|
|
foreach ($section_d_lines as $line) {
|
|
$data = isset($ca3_data[$line]) ? $ca3_data[$line] : array('line_label' => '', 'vat_amount' => 0);
|
|
|
|
// Special handling for line TD
|
|
if ($line == 'TD') {
|
|
$description = 'TVA due (montant à payer)';
|
|
} else {
|
|
$description = isset($ca3_definitions[$line]) ? $ca3_definitions[$line]['label'] : $data['line_label'];
|
|
}
|
|
|
|
print '<tr style="background-color: #ffe6e6;">';
|
|
print '<td><strong>' . $line . '</strong></td>';
|
|
print '<td colspan="2">' . $description . '</td>';
|
|
print '<td class="right">' . formatAmount($data['vat_amount']) . '</td>';
|
|
print '</tr>';
|
|
}
|
|
|
|
// Show message if no data
|
|
if (empty($ca3_lines)) {
|
|
print '<tr>';
|
|
print '<td colspan="3" class="center">' . $langs->trans("NoCA3Data") . '</td>';
|
|
print '</tr>';
|
|
}
|
|
|
|
print '</table>';
|
|
print '</div>';
|
|
|
|
// Print actions
|
|
print '<div class="fiche">';
|
|
print '<div class="titre">' . $langs->trans("Actions") . '</div>';
|
|
|
|
print '<div class="center">';
|
|
|
|
// Recalculate button (always available)
|
|
print '<a href="' . $_SERVER['PHP_SELF'] . '?id=' . $id . '&action=recalculate&token=' . newToken() . '" class="butAction">' . $langs->trans("Recalculate") . '</a> ';
|
|
|
|
if ($declarationtva->status == 'draft') {
|
|
print '<a href="' . $_SERVER['PHP_SELF'] . '?id=' . $id . '&action=validate" class="butAction">' . $langs->trans("Validate") . '</a> ';
|
|
} elseif ($declarationtva->status == 'validated') {
|
|
print '<a href="' . $_SERVER['PHP_SELF'] . '?id=' . $id . '&action=submit" class="butAction">' . $langs->trans("Submit") . '</a> ';
|
|
}
|
|
|
|
print '<a href="declarationtvaindex.php" class="butAction">' . $langs->trans("BackToList") . '</a>';
|
|
|
|
print '</div>';
|
|
print '</div>';
|
|
|
|
// Add CSS for dropdown styling
|
|
print '<style>
|
|
.account-details {
|
|
background-color: #f8f9fa;
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 4px;
|
|
margin: 10px 0;
|
|
padding: 15px;
|
|
}
|
|
|
|
.account-details-header {
|
|
font-weight: bold;
|
|
color: #495057;
|
|
margin-bottom: 10px;
|
|
padding-bottom: 5px;
|
|
border-bottom: 1px solid #dee2e6;
|
|
}
|
|
|
|
.account-details-content {
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
.account-details table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
.account-details table th,
|
|
.account-details table td {
|
|
padding: 8px;
|
|
text-align: left;
|
|
border: 1px solid #dee2e6;
|
|
}
|
|
|
|
.account-details table th {
|
|
background-color: #e9ecef;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.account-details table tr:nth-child(even) {
|
|
background-color: #f8f9fa;
|
|
}
|
|
|
|
.loading {
|
|
text-align: center;
|
|
color: #6c757d;
|
|
font-style: italic;
|
|
}
|
|
</style>';
|
|
|
|
// Add JavaScript for dropdown functionality
|
|
print '<script>
|
|
var loadedDetails = {};
|
|
|
|
function toggleDetails(line) {
|
|
var detailsRow = document.getElementById("details_" + line);
|
|
var contentDiv = document.getElementById("content_" + line);
|
|
|
|
if (detailsRow.style.display === "none") {
|
|
// Show the dropdown
|
|
detailsRow.style.display = "";
|
|
|
|
// Load content if not already loaded
|
|
if (!loadedDetails[line]) {
|
|
loadLineDetails(line);
|
|
}
|
|
} else {
|
|
// Hide the dropdown
|
|
detailsRow.style.display = "none";
|
|
}
|
|
}
|
|
|
|
function loadLineDetails(line) {
|
|
var contentDiv = document.getElementById("content_" + line);
|
|
var declarationId = ' . $declarationtva->rowid . ';
|
|
|
|
// Show loading
|
|
contentDiv.innerHTML = "<div class=\"loading\">' . $langs->trans("Loading") . '...</div>";
|
|
|
|
// Make AJAX request to get line details
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open("GET", "declarationtva_line_details_ajax.php?declaration_id=" + declarationId + "&ca3_line=" + line, true);
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
|
contentDiv.innerHTML = xhr.responseText;
|
|
loadedDetails[line] = true;
|
|
} else if (xhr.readyState === 4) {
|
|
contentDiv.innerHTML = "<div class=\"error\">' . $langs->trans("ErrorLoadingDetails") . '</div>";
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
</script>';
|
|
|
|
// Print footer
|
|
llxFooter();
|
|
?>
|