v2.5.1: Enhanced PDF layout with light gray section backgrounds

- Added light gray backgrounds to all section titles in detailed pages
- Enhanced visual hierarchy for better readability
- Improved professional appearance of PDF exports
- Updated module version to 2.5.1
This commit is contained in:
Frank Cools 2025-10-08 12:21:26 +02:00
parent f5f1169496
commit 632c77d335
7 changed files with 293 additions and 29 deletions

View File

@ -1,5 +1,12 @@
# CHANGELOG MODULE DECLARATIONTVA FOR [DOLIBARR ERP CRM](https://www.dolibarr.org)
## 2.5.1
### UI/UX Improvements
- **PDF Layout Enhancement**: Added light gray backgrounds to section titles in detailed pages
- **Visual Hierarchy**: Improved readability with distinct section headers
- **Professional Appearance**: Enhanced PDF presentation with consistent styling
## 2.5.0
### New Features

View File

@ -382,7 +382,9 @@ class DeclarationTVA_Config
$config = array();
foreach ($default_config as $key => $default_value) {
$config[$key] = $this->get('bank_' . $key, $default_value);
$value = $this->get('bank_' . $key, $default_value);
$config[$key] = $value;
error_log("DeclarationTVA: Retrieved bank config " . $key . ": " . $value);
}
return $config;
@ -396,7 +398,10 @@ class DeclarationTVA_Config
*/
public function updateBankAccountConfiguration($bank_account_id)
{
return $this->set('bank_bank_account', (int)$bank_account_id);
error_log("DeclarationTVA: Updating bank account to: " . $bank_account_id);
$result = $this->set('bank_bank_account', (int)$bank_account_id);
error_log("DeclarationTVA: Bank account update result: " . ($result ? 'success' : 'failed'));
return $result;
}
/**

View File

@ -89,6 +89,7 @@ class DeclarationTVA_PDF
*/
public function __construct($db)
{
global $conf;
$this->db = $db;
$this->entity = (int) $conf->entity;
// Use absolute path to templates directory
@ -169,6 +170,7 @@ class DeclarationTVA_PDF
$this->error = 'Declaration not found';
return false;
}
// Get CA-3 line data
$ca3_data = $declaration->getCA3Lines($declaration_id);
@ -991,10 +993,11 @@ class DeclarationTVA_PDF
$pdf->Ln(10);
}
// Set section title with separator
// Set section title with light gray background
$pdf->SetFont('helvetica', 'B', 16);
$pdf->SetTextColor(0, 0, 0);
$pdf->Cell(0, 8, 'Détail de la ligne ' . $line_code, 0, 1, 'C');
$pdf->SetFillColor(240, 240, 240); // Light gray background
$pdf->Cell(0, 10, 'Détail de la ligne ' . $line_code, 1, 1, 'C', true);
// Add separator line
$pdf->SetDrawColor(0, 0, 0);
@ -1030,9 +1033,10 @@ class DeclarationTVA_PDF
return;
}
// Add line summary
// Add line summary with light gray background
$pdf->SetFont('helvetica', 'B', 12);
$pdf->Cell(0, 8, 'Résumé de la ligne ' . $line_code, 0, 1);
$pdf->SetFillColor(245, 245, 245); // Slightly lighter gray for subsection
$pdf->Cell(0, 8, 'Résumé de la ligne ' . $line_code, 1, 1, 'L', true);
$pdf->SetFont('helvetica', '', 10);
$pdf->Cell(0, 6, 'Période: ' . dol_print_date($line_details['start_date'], 'day') . ' - ' . dol_print_date($line_details['end_date'], 'day'), 0, 1);
@ -1082,11 +1086,12 @@ class DeclarationTVA_PDF
// Set X position to center the table
$pdf->SetX($start_x);
// Table header - same as view page: Code compte, Libellé compte, Montant
// Table header with light gray background
$pdf->SetFont('helvetica', 'B', 10);
$pdf->Cell(35, 8, 'Code compte', 1, 0, 'C');
$pdf->Cell(80, 8, 'Libellé compte', 1, 0, 'C');
$pdf->Cell(35, 8, 'Montant', 1, 1, 'C');
$pdf->SetFillColor(240, 240, 240); // Light gray background
$pdf->Cell(35, 8, 'Code compte', 1, 0, 'C', true);
$pdf->Cell(80, 8, 'Libellé compte', 1, 0, 'C', true);
$pdf->Cell(35, 8, 'Montant', 1, 1, 'C', true);
$total_base_base = 0;
$total_vat_base = 0;
@ -1098,7 +1103,8 @@ class DeclarationTVA_PDF
// Display BASE accounts first (if any)
if (!empty($base_accounts)) {
$pdf->SetFont('helvetica', 'B', 9);
$pdf->Cell(0, 6, 'Comptes de base (ventes)', 0, 1, 'L');
$pdf->SetFillColor(245, 245, 245); // Light gray background
$pdf->Cell(0, 6, 'Comptes de base (ventes)', 1, 1, 'L', true);
$pdf->SetFont('helvetica', '', 9);
foreach ($base_accounts as $account) {
@ -1122,7 +1128,8 @@ class DeclarationTVA_PDF
// Display VAT accounts second (if any)
if (!empty($vat_accounts)) {
$pdf->SetFont('helvetica', 'B', 9);
$pdf->Cell(0, 6, 'Comptes de TVA', 0, 1, 'L');
$pdf->SetFillColor(245, 245, 245); // Light gray background
$pdf->Cell(0, 6, 'Comptes de TVA', 1, 1, 'L', true);
$pdf->SetFont('helvetica', '', 9);
foreach ($vat_accounts as $account) {
@ -1393,7 +1400,8 @@ class DeclarationTVA_PDF
// Add title page
$pdf->AddPage();
$pdf->SetFont('helvetica', 'B', 16);
$pdf->Cell(0, 10, 'Détails de la Déclaration TVA CA-3', 0, 1, 'C');
$pdf->SetFillColor(240, 240, 240); // Light gray background
$pdf->Cell(0, 10, 'Détails de la Déclaration TVA CA-3', 1, 1, 'C', true);
$pdf->Ln(10);
$pdf->SetFont('helvetica', '', 12);
@ -1405,6 +1413,9 @@ class DeclarationTVA_PDF
// Add journal entry table on page 1
$this->addJournalEntryTable($pdf, $declaration, $ca3_data);
// Add bank journal entry table on page 1
$this->addBankJournalEntryTable($pdf, $declaration, $ca3_data);
// Add detailed breakdown pages starting on page 2
$this->addDetailPages($pdf, $declaration, $ca3_data);
@ -1810,9 +1821,10 @@ class DeclarationTVA_PDF
// Add some space before the journal table
$pdf->Ln(10);
// Title
// Title with light gray background
$pdf->SetFont('helvetica', 'B', 16);
$pdf->Cell(0, 10, 'Écritures du Journal OD', 0, 1, 'C');
$pdf->SetFillColor(240, 240, 240); // Light gray background
$pdf->Cell(0, 10, 'Écritures du Journal OD', 1, 1, 'C', true);
$pdf->Ln(10);
// Create lookup array for CA-3 data
@ -1869,6 +1881,243 @@ class DeclarationTVA_PDF
}
}
/**
* Add bank journal entry table to PDF
*
* @param TCPDF $pdf PDF object
* @param DeclarationTVA $declaration Declaration object
* @param array $ca3_data CA-3 line data
*/
private function addBankJournalEntryTable($pdf, $declaration, $ca3_data)
{
// Add some space before the bank journal table
$pdf->Ln(15);
// Title with light gray background
$pdf->SetFont('helvetica', 'B', 16);
$pdf->SetFillColor(240, 240, 240); // Light gray background
$pdf->Cell(0, 10, 'Écritures du Journal de Banque', 1, 1, 'C', true);
$pdf->Ln(10);
// Get bank journal entries
$bank_entries = $this->generateBankJournalEntries($declaration, $ca3_data);
if (empty($bank_entries)) {
$pdf->SetFont('helvetica', '', 12);
$pdf->Cell(0, 8, 'Aucune écriture bancaire à générer.', 0, 1);
return;
}
// Table header
$pdf->SetFont('helvetica', 'B', 8);
$pdf->SetFillColor(240, 240, 240);
// Column widths - reduced and centered
$col_widths = array(20, 60, 40, 20, 20);
$col_headers = array('Code compte', 'Libellé compte', 'Libellé écriture', 'Débit', 'Crédit');
// Calculate table width and center position
$table_width = array_sum($col_widths);
$page_width = $pdf->getPageWidth() - $pdf->getMargins()['left'] - $pdf->getMargins()['right'];
$start_x = ($page_width - $table_width) / 2 + $pdf->getMargins()['left'];
// Set X position to center the table
$pdf->SetX($start_x);
// Draw header
for ($i = 0; $i < count($col_headers); $i++) {
$pdf->Cell($col_widths[$i], 8, $col_headers[$i], 1, 0, 'C', true);
}
$pdf->Ln();
// Draw entries
$pdf->SetFont('helvetica', '', 7);
$pdf->SetFillColor(255, 255, 255);
foreach ($bank_entries as $entry) {
// Set X position to center the table for each row
$pdf->SetX($start_x);
$pdf->Cell($col_widths[0], 6, $entry['account_code'], 1, 0, 'C');
$pdf->Cell($col_widths[1], 6, $entry['account_label'], 1, 0, 'L');
$pdf->Cell($col_widths[2], 6, $entry['entry_label'], 1, 0, 'L');
$pdf->Cell($col_widths[3], 6, $entry['debit'], 1, 0, 'R');
$pdf->Cell($col_widths[4], 6, $entry['credit'], 1, 0, 'R');
$pdf->Ln();
}
}
/**
* Generate bank journal entries based on CA-3 data
*
* @param DeclarationTVA $declaration Declaration object
* @param array $ca3_data CA-3 line data
* @return array Bank journal entries
*/
private function generateBankJournalEntries($declaration, $ca3_data)
{
$entries = array();
// Get bank account configuration
$bank_config = $this->getBankAccountConfiguration();
$bank_account_id = $bank_config['bank_account'];
// Debug: Log bank configuration
error_log("DeclarationTVA: Bank config: " . print_r($bank_config, true));
error_log("DeclarationTVA: Bank account ID: " . $bank_account_id);
if (empty($bank_account_id) || $bank_account_id == 0) {
// No bank account configured
error_log("DeclarationTVA: No bank account configured");
return $entries;
}
// Get bank account details
$bank_account = $this->getBankAccountDetails($bank_account_id);
if (!$bank_account) {
error_log("DeclarationTVA: Bank account details not found for ID: " . $bank_account_id);
return $entries;
}
error_log("DeclarationTVA: Bank account found: " . print_r($bank_account, true));
// Calculate VAT amounts the same way as in getBalancingEntries
$line_16_amount = $this->getLineAmount($declaration, '16');
$line_23_amount = $this->getLineAmount($declaration, '23');
$td_amount = $line_16_amount - $line_23_amount;
// Determine net VAT due or VAT credit
$net_vat_due = 0;
$vat_credit = 0;
if ($td_amount > 0) {
$net_vat_due = $td_amount;
} elseif ($td_amount < 0) {
$vat_credit = abs($td_amount);
}
// Debug: Log calculated VAT amounts
error_log("DeclarationTVA: Line 16 amount: " . $line_16_amount);
error_log("DeclarationTVA: Line 23 amount: " . $line_23_amount);
error_log("DeclarationTVA: TD amount: " . $td_amount);
error_log("DeclarationTVA: Net VAT due: " . $net_vat_due);
error_log("DeclarationTVA: VAT credit: " . $vat_credit);
// Get journal configuration for VAT accounts
$journal_config = $this->getJournalConfiguration();
error_log("DeclarationTVA: Journal config: " . print_r($journal_config, true));
error_log("DeclarationTVA: About to check VAT amounts - net_vat_due: " . $net_vat_due . ", vat_credit: " . $vat_credit);
if ($net_vat_due > 0) {
// VAT payment case - money going out
// 1. Bank account (credit - money leaving)
$entries[] = array(
'account_code' => $bank_account['account_code'],
'account_label' => $bank_account['account_label'],
'entry_label' => 'Paiement TVA - ' . $declaration->declaration_name,
'debit' => '',
'credit' => $this->formatAmountReal($net_vat_due)
);
// 2. VAT account (debit - VAT being paid)
$entries[] = array(
'account_code' => $journal_config['vat_to_pay'],
'account_label' => $this->getAccountLabel($journal_config['vat_to_pay']),
'entry_label' => 'Paiement TVA - ' . $declaration->declaration_name,
'debit' => $this->formatAmountReal($net_vat_due),
'credit' => ''
);
} elseif ($vat_credit > 0) {
// VAT refund case - money coming in
// 1. Bank account (debit - money coming in)
$entries[] = array(
'account_code' => $bank_account['account_code'],
'account_label' => $bank_account['account_label'],
'entry_label' => 'Remboursement TVA - ' . $declaration->declaration_name,
'debit' => $this->formatAmountReal($vat_credit),
'credit' => ''
);
// 2. VAT account (credit - VAT being received)
$entries[] = array(
'account_code' => $journal_config['vat_to_receive'],
'account_label' => $this->getAccountLabel($journal_config['vat_to_receive']),
'entry_label' => 'Remboursement TVA - ' . $declaration->declaration_name,
'debit' => '',
'credit' => $this->formatAmountReal($vat_credit)
);
}
return $entries;
}
/**
* Get bank account configuration
*
* @return array Bank account configuration
*/
private function getBankAccountConfiguration()
{
require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_config.class.php';
$config = new DeclarationTVA_Config($this->db, $this->entity);
// Debug: Log entity being used
error_log("DeclarationTVA: PDF using entity: " . $this->entity);
$bank_config = $config->getBankAccountConfiguration();
error_log("DeclarationTVA: PDF bank config: " . print_r($bank_config, true));
return $bank_config;
}
/**
* Get journal configuration
*
* @return array Journal configuration
*/
private function getJournalConfiguration()
{
require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_config.class.php';
$config = new DeclarationTVA_Config($this->db, $this->entity);
return $config->getJournalConfiguration();
}
/**
* Get bank account details
*
* @param int $bank_account_id Bank account ID
* @return array|false Bank account details or false if not found
*/
private function getBankAccountDetails($bank_account_id)
{
// Get bank account info and its linked accounting account
$sql = "SELECT ba.rowid, ba.label, ba.number, ba.bank, ba.account_number
FROM " . MAIN_DB_PREFIX . "bank_account ba
WHERE ba.rowid = " . (int)$bank_account_id . "
AND ba.entity = " . $this->entity;
$result = $this->db->query($sql);
if ($result && $this->db->num_rows($result) > 0) {
$obj = $this->db->fetch_object($result);
// Get the accounting account label for the account code
$account_label = $this->getAccountLabel($obj->account_number);
return array(
'rowid' => $obj->rowid,
'label' => $obj->label,
'number' => $obj->number,
'bank' => $obj->bank,
'account_code' => $obj->account_number, // Use the linked accounting account code
'account_label' => $account_label
);
}
return false;
}
/**
* Generate journal entries based on CA-3 data
*
@ -2276,18 +2525,6 @@ class DeclarationTVA_PDF
$amount_string = str_replace(',', '.', $amount_string);
return (float)$amount_string;
}
/**
* Get journal configuration
*
* @return array Journal configuration
*/
private function getJournalConfiguration()
{
require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_config.class.php';
$config = new DeclarationTVA_Config($this->db, $this->entity);
return $config->getJournalConfiguration();
}
/**
* Get account label from chart of accounts

View File

@ -76,7 +76,7 @@ class modDeclarationTVA extends DolibarrModules
$this->editor_squarred_logo = ''; // Must be image filename into the module/img directory followed with @modulename. Example: 'myimage.png@declarationtva'
// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated', 'experimental_deprecated' or a version string like 'x.y.z'
$this->version = '2.5.0';
$this->version = '2.5.1';
// Url to the file with your last numberversion of this module
//$this->url_last_version = 'http://www.example.com/versionmodule.txt';

View File

@ -141,7 +141,18 @@ if (empty($declarations)) {
}
print '<td class="center">' . $langs->trans("Status" . ucfirst($d['status'])) . $status_icon . '</td>';
print '<td class="center">' . price($d['net_vat_due']) . '</td>';
// Show VAT amount with proper label
// Check if there's a VAT credit (refund) or net VAT due
if ($d['vat_credit'] > 0) {
// VAT refund case
print '<td class="center"><strong style="color: #28a745;">' . price($d['vat_credit']) . '</strong><br><small>' . $langs->trans("VATToReceive") . '</small></td>';
} elseif ($d['net_vat_due'] > 0) {
// VAT due case
print '<td class="center"><strong style="color: #dc3545;">' . price($d['net_vat_due']) . '</strong><br><small>' . $langs->trans("NetVATDue") . '</small></td>';
} else {
// Balanced case
print '<td class="center"><strong>' . price(0) . '</strong><br><small>' . $langs->trans("VATBalanced") . '</small></td>';
}
// Document column
print '<td class="center">';

View File

@ -540,6 +540,8 @@ VATPaymentBankAccountDescription = Bank account used for VAT payments and refund
BankAccountConfigurationUpdated = Bank account configuration updated
BankAccountConfigurationUpdateFailed = Error updating bank account configuration
NoBankAccountsFound = No bank accounts found
VATToReceive = VAT to receive
VATBalanced = VAT balanced
AutoCreateAccountingConfiguration = Auto-Create Accounting Configuration
AutoCreateAccountingEntries = Auto-Create Accounting Entries
AutoCreateAccountingEntriesDescription = Enables automatic creation of accounting entries when a declaration is submitted

View File

@ -512,6 +512,8 @@ VATPaymentBankAccountDescription = Compte bancaire utilisé pour les paiements e
BankAccountConfigurationUpdated = Configuration du compte bancaire mise à jour
BankAccountConfigurationUpdateFailed = Erreur lors de la mise à jour de la configuration du compte bancaire
NoBankAccountsFound = Aucun compte bancaire trouvé
VATToReceive = TVA à recevoir
VATBalanced = TVA équilibrée
AutoCreateAccountingConfiguration = Configuration de création automatique des écritures
AutoCreateAccountingEntries = Création automatique des écritures comptables
AutoCreateAccountingEntriesDescription = Active la création automatique des écritures comptables lors de la soumission d'une déclaration