Add VAT refund threshold logic with configurable threshold and 445671 account support

This commit is contained in:
Frank Cools 2025-10-08 16:28:18 +02:00
parent ab6dad1561
commit e00c6f89f7
5 changed files with 168 additions and 52 deletions

View File

@ -145,6 +145,20 @@ $formSetup->newItem('DECLARATIONTVA_MYPARAM8')->setAsProduct();
// Add a title for a new section // Add a title for a new section
$formSetup->newItem('NewSection')->setAsTitle(); $formSetup->newItem('NewSection')->setAsTitle();
// VAT Refund Threshold Configuration
$item = $formSetup->newItem('DECLARATIONTVA_VAT_REFUND_THRESHOLD');
$item->nameText = 'VAT Refund Threshold (€)';
$item->defaultFieldValue = 760.00;
$item->fieldAttr['placeholder'] = '760.00';
$item->helpText = 'Threshold amount for immediate VAT refund vs carry forward. Amounts below this threshold will be carried forward to the next declaration.';
$item->cssClass = 'minwidth200';
// VAT Refund Threshold Enabled
$item = $formSetup->newItem('DECLARATIONTVA_VAT_REFUND_THRESHOLD_ENABLED');
$item->nameText = 'Enable VAT Refund Threshold Logic';
$item->setAsYesNo();
$item->helpText = 'Enable or disable the threshold logic for VAT refunds.';
$TField = array( $TField = array(
'test01' => $langs->trans('test01'), 'test01' => $langs->trans('test01'),
'test02' => $langs->trans('test02'), 'test02' => $langs->trans('test02'),

View File

@ -441,9 +441,31 @@ class DeclarationTVA
)); ));
} }
// Line 27: Crédit de TVA à reporter (ligne 25 ligne 26) - same value as line 25, only if > 0 and < 760 // Get VAT refund threshold configuration
require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_config.class.php';
$config = new DeclarationTVA_Config($this->db, $this->entity);
$threshold_config = $config->getVATRefundThresholdConfiguration();
$refund_threshold = $threshold_config['refund_threshold'];
$threshold_enabled = $threshold_config['refund_threshold_enabled'];
// Line 26: Crédit de TVA à rembourser (≥ threshold)
if ($line_25_amount > 0 && (!$threshold_enabled || $line_25_amount >= $refund_threshold)) {
$this->createCA3Line($declaration_id, '26', 'Crédit de TVA à rembourser (ligne 25 ligne 26)', array(
'base_amount' => 0,
'vat_amount' => $line_25_amount,
'total_amount' => $line_25_amount
));
} else {
$this->createCA3Line($declaration_id, '26', 'Crédit de TVA à rembourser (ligne 25 ligne 26)', array(
'base_amount' => 0,
'vat_amount' => 0,
'total_amount' => 0
));
}
// Line 27: Crédit de TVA à reporter (< threshold)
$line_27_amount = $line_25_amount; // Same value as line 25 $line_27_amount = $line_25_amount; // Same value as line 25
if ($line_27_amount > 0 && $line_27_amount < 760) { if ($line_25_amount > 0 && $threshold_enabled && $line_25_amount < $refund_threshold) {
$this->createCA3Line($declaration_id, '27', 'Crédit de TVA à reporter (ligne 25 ligne 26) (Cette somme est à reporter ligne 22 de la prochaine déclaration)', array( $this->createCA3Line($declaration_id, '27', 'Crédit de TVA à reporter (ligne 25 ligne 26) (Cette somme est à reporter ligne 22 de la prochaine déclaration)', array(
'base_amount' => 0, 'base_amount' => 0,
'vat_amount' => $line_27_amount, 'vat_amount' => $line_27_amount,
@ -457,21 +479,6 @@ class DeclarationTVA
)); ));
} }
// Line 26: Remboursement de crédit de TVA demandé sur formulaire n°3519 - same value as line 25, only if >= 760
$line_26_amount = $line_25_amount; // Same value as line 25
if ($line_26_amount >= 760) {
$this->createCA3Line($declaration_id, '26', 'Remboursement de crédit de TVA demandé sur formulaire n°3519', array(
'base_amount' => 0,
'vat_amount' => $line_26_amount,
'total_amount' => $line_26_amount
));
} else {
$this->createCA3Line($declaration_id, '26', 'Remboursement de crédit de TVA demandé sur formulaire n°3519', array(
'base_amount' => 0,
'vat_amount' => 0,
'total_amount' => 0
));
}
// Line TD: TVA due (ligne 16 ligne 23) - only if > 0 // Line TD: TVA due (ligne 16 ligne 23) - only if > 0
$line_td_amount = $line_16_amount - $line_23_amount; $line_td_amount = $line_16_amount - $line_23_amount;
@ -868,6 +875,32 @@ class DeclarationTVA
return $this->calculateCA3Amounts($declaration_id, $period); return $this->calculateCA3Amounts($declaration_id, $period);
} }
/**
* Get VAT credit carry-forward from previous periods
*/
public function getVATCreditCarryForward($declaration_start_date)
{
// Get journal configuration to use the correct account
require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_config.class.php';
$config = new DeclarationTVA_Config($this->db, $this->entity);
$journal_config = $config->getJournalConfiguration();
$vat_to_receive_account = $journal_config['vat_to_receive'];
// Check VAT credit account balance at declaration start date
$sql = "SELECT SUM(debit - credit) as balance
FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping
WHERE account_number = '" . $this->db->escape($vat_to_receive_account) . "'
AND doc_date < '" . $declaration_start_date . "'";
$result = $this->db->query($sql);
if ($result && $this->db->num_rows($result) > 0) {
$obj = $this->db->fetch_object($result);
return max(0, $obj->balance); // Only positive balances (credits)
}
return 0;
}
/** /**
* Get account mappings with labels from chart of accounts * Get account mappings with labels from chart of accounts
* *

View File

@ -717,7 +717,8 @@ class DeclarationTVA_Config
{ {
$default_config = array( $default_config = array(
'vat_to_pay' => '44551', // TVA A DECAISSER 'vat_to_pay' => '44551', // TVA A DECAISSER
'vat_to_receive' => '44567', // TVA A PAYER 'vat_to_receive' => '44567', // TVA A PAYER (carry forward)
'vat_refund' => '445671', // TVA A REMBOURSER (immediate refund)
'other_charges' => '658', // AUTRES CHARGES DE GESTION COURANTE 'other_charges' => '658', // AUTRES CHARGES DE GESTION COURANTE
'other_products' => '758' // AUTRES PRODUITS DE GESTION COURANT 'other_products' => '758' // AUTRES PRODUITS DE GESTION COURANT
); );
@ -729,7 +730,41 @@ class DeclarationTVA_Config
return $config; return $config;
} }
/**
* Get VAT refund threshold configuration
*
* @return array VAT refund threshold configuration
*/
public function getVATRefundThresholdConfiguration()
{
$default_config = array(
'refund_threshold' => 760.00, // Threshold for immediate refund vs carry forward
'refund_threshold_enabled' => 1 // Enable/disable threshold logic
);
$config = array();
foreach ($default_config as $key => $default_value) {
$config[$key] = $this->get('vat_refund_' . $key, $default_value);
}
return $config;
}
/**
* Update VAT refund threshold configuration
*
* @param array $threshold_config VAT refund threshold configuration
* @return bool Success
*/
public function updateVATRefundThresholdConfiguration($threshold_config)
{
foreach ($threshold_config as $key => $value) {
$this->set('vat_refund_' . $key, $value);
}
return true;
}
/** /**
* Update journal configuration * Update journal configuration
* *

View File

@ -2352,7 +2352,7 @@ class DeclarationTVA_PDF
} }
/** /**
* Get VAT result entry on account 4455100 or 4456700 * Get VAT result entry using configured accounts and threshold
* *
* @param DeclarationTVA $declaration Declaration object * @param DeclarationTVA $declaration Declaration object
* @param array $ca3_lookup CA-3 data lookup array * @param array $ca3_lookup CA-3 data lookup array
@ -2360,52 +2360,82 @@ class DeclarationTVA_PDF
*/ */
private function getVATResultEntry($declaration, $ca3_lookup) private function getVATResultEntry($declaration, $ca3_lookup)
{ {
// Get journal configuration
$journal_config = $this->getJournalConfiguration();
$vat_to_pay_account = $journal_config['vat_to_pay'];
$vat_to_receive_account = $journal_config['vat_to_receive'];
$vat_refund_account = $journal_config['vat_refund'];
// Get VAT refund threshold configuration
$threshold_config = $this->getVATRefundThresholdConfiguration();
$refund_threshold = $threshold_config['refund_threshold'];
$threshold_enabled = $threshold_config['refund_threshold_enabled'];
// Get TD line amount (Line 16 - Line 23) // Get TD line amount (Line 16 - Line 23)
$line_16_amount = $this->getLineAmount($declaration, '16'); $line_16_amount = $this->getLineAmount($declaration, '16');
$line_23_amount = $this->getLineAmount($declaration, '23'); $line_23_amount = $this->getLineAmount($declaration, '23');
$td_amount = $line_16_amount - $line_23_amount; $td_amount = $line_16_amount - $line_23_amount;
// If TD = 0, use line 27 value and account 4456700 // If TD > 0, use VAT due account (445510)
if (abs($td_amount) < 0.01) { if ($td_amount > 0) {
$line27_amount = $this->getLineAmount($declaration, '27'); return array(
'account_code' => $vat_to_pay_account,
if (abs($line27_amount) < 0.01) { 'account_label' => $this->getAccountLabel($vat_to_pay_account),
return null;
}
$entry = array(
'account_code' => '4456700',
'account_label' => $this->getAccountLabel('4456700'),
'entry_label' => $declaration->declaration_name, 'entry_label' => $declaration->declaration_name,
'debit' => '', 'debit' => '',
'credit' => '' 'credit' => $this->formatAmount($td_amount)
); );
}
// If TD < 0, determine which credit account to use
if ($td_amount < 0) {
$vat_credit = abs($td_amount);
// Put line 23 amount on debit side // Check if threshold logic is enabled and amount is below threshold
$line23_amount = $this->getLineAmount($declaration, '23'); if ($threshold_enabled && $vat_credit < $refund_threshold) {
if ($line23_amount > 0) { // Use carry-forward account (445670)
$entry['debit'] = $this->formatAmount($line23_amount); $account_code = $vat_to_receive_account;
$account_label = $this->getAccountLabel($vat_to_receive_account);
} else {
// Use immediate refund account (445671)
$account_code = $vat_refund_account;
$account_label = $this->getAccountLabel($vat_refund_account);
} }
return $entry; return array(
'account_code' => $account_code,
'account_label' => $account_label,
'entry_label' => $declaration->declaration_name,
'debit' => '',
'credit' => $this->formatAmount($vat_credit)
);
} }
// If TD > 0, use TD value and account 4455100 (existing logic) return null;
$entry = array( }
'account_code' => '4455100',
'account_label' => $this->getAccountLabel('4455100'), /**
'entry_label' => $declaration->declaration_name, * Get journal configuration
'debit' => '', *
'credit' => '' * @return array Journal configuration
); */
private function getJournalConfiguration()
if ($td_amount < 0) { {
$entry['debit'] = $this->formatAmount(abs($td_amount)); require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_config.class.php';
} else { $config = new DeclarationTVA_Config($this->db, $this->entity);
$entry['credit'] = $this->formatAmount($td_amount); return $config->getJournalConfiguration();
} }
return $entry; /**
* Get VAT refund threshold configuration
*
* @return array VAT refund threshold configuration
*/
private function getVATRefundThresholdConfiguration()
{
require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_config.class.php';
$config = new DeclarationTVA_Config($this->db, $this->entity);
return $config->getVATRefundThresholdConfiguration();
} }
/** /**

View File

@ -527,3 +527,7 @@ RoundAmounts = Arrondir les montants (€123.56 → €124)
TruncateAmounts = Tronquer les montants (€123.56 → €123) TruncateAmounts = Tronquer les montants (€123.56 → €123)
AmountCalculationConfigurationUpdated = Configuration du calcul des montants mise à jour AmountCalculationConfigurationUpdated = Configuration du calcul des montants mise à jour
AmountCalculationConfigurationUpdateFailed = Erreur lors de la mise à jour de la configuration du calcul des montants AmountCalculationConfigurationUpdateFailed = Erreur lors de la mise à jour de la configuration du calcul des montants
VATRefundThreshold = Seuil de remboursement TVA (€)
VATRefundThresholdEnabled = Activer la logique de seuil de remboursement TVA
VATRefundThresholdHelp = Seuil de montant pour le remboursement immédiat de la TVA vs report. Les montants en dessous de ce seuil seront reportés à la prochaine déclaration.
VATRefundThresholdEnabledHelp = Activer ou désactiver la logique de seuil pour les remboursements de TVA.