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
$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(
'test01' => $langs->trans('test01'),
'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
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(
'base_amount' => 0,
'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_amount = $line_16_amount - $line_23_amount;
@ -868,6 +875,32 @@ class DeclarationTVA
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
*

View File

@ -717,7 +717,8 @@ class DeclarationTVA_Config
{
$default_config = array(
'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_products' => '758' // AUTRES PRODUITS DE GESTION COURANT
);
@ -729,7 +730,41 @@ class DeclarationTVA_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
*

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 array $ca3_lookup CA-3 data lookup array
@ -2360,52 +2360,82 @@ class DeclarationTVA_PDF
*/
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)
$line_16_amount = $this->getLineAmount($declaration, '16');
$line_23_amount = $this->getLineAmount($declaration, '23');
$td_amount = $line_16_amount - $line_23_amount;
// If TD = 0, use line 27 value and account 4456700
if (abs($td_amount) < 0.01) {
$line27_amount = $this->getLineAmount($declaration, '27');
if (abs($line27_amount) < 0.01) {
return null;
}
$entry = array(
'account_code' => '4456700',
'account_label' => $this->getAccountLabel('4456700'),
// If TD > 0, use VAT due account (445510)
if ($td_amount > 0) {
return array(
'account_code' => $vat_to_pay_account,
'account_label' => $this->getAccountLabel($vat_to_pay_account),
'entry_label' => $declaration->declaration_name,
'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
$line23_amount = $this->getLineAmount($declaration, '23');
if ($line23_amount > 0) {
$entry['debit'] = $this->formatAmount($line23_amount);
// Check if threshold logic is enabled and amount is below threshold
if ($threshold_enabled && $vat_credit < $refund_threshold) {
// Use carry-forward account (445670)
$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)
$entry = array(
'account_code' => '4455100',
'account_label' => $this->getAccountLabel('4455100'),
'entry_label' => $declaration->declaration_name,
'debit' => '',
'credit' => ''
);
if ($td_amount < 0) {
$entry['debit'] = $this->formatAmount(abs($td_amount));
} else {
$entry['credit'] = $this->formatAmount($td_amount);
}
return $entry;
return null;
}
/**
* 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 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)
AmountCalculationConfigurationUpdated = Configuration du calcul des montants mise à jour
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.