Fix bank journal entries handling for carry-forward cases
- Fix createAccountingEntries to handle empty bank entries correctly - Change createBankJournalEntries to return true instead of empty array for carry-forward - Prevent errors when no bank entries are needed (VAT credit below threshold) - Add comment explaining that empty bank entries are OK for carry-forward cases
This commit is contained in:
parent
b6e9075ece
commit
0cc15800db
@ -783,8 +783,6 @@ class DeclarationTVA
|
||||
return $lines;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Delete a declaration
|
||||
*
|
||||
@ -824,9 +822,6 @@ class DeclarationTVA
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Recalculate CA-3 amounts for a declaration
|
||||
*
|
||||
@ -904,7 +899,6 @@ class DeclarationTVA
|
||||
}
|
||||
|
||||
$processing[$declaration_id] = true;
|
||||
error_log("DEBUG: Starting processing for declaration " . $declaration_id);
|
||||
|
||||
// Get declaration data
|
||||
$fetch_result = $this->fetch($declaration_id);
|
||||
@ -913,59 +907,6 @@ class DeclarationTVA
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if accounting entries already exist for this declaration
|
||||
$existing_entries_sql = "SELECT COUNT(*) as count FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping
|
||||
WHERE doc_ref = '" . $this->db->escape($this->declaration_name) . "'
|
||||
AND entity = " . $this->entity;
|
||||
$existing_result = $this->db->query($existing_entries_sql);
|
||||
if ($existing_result && $this->db->num_rows($existing_result) > 0) {
|
||||
$existing_obj = $this->db->fetch_object($existing_result);
|
||||
if ($existing_obj->count > 0) {
|
||||
error_log("DEBUG: Found " . $existing_obj->count . " existing accounting entries for declaration " . $this->declaration_name);
|
||||
error_log("DEBUG: Deleting existing entries to prevent duplicates");
|
||||
|
||||
// Delete existing entries to prevent duplicates (from all journals)
|
||||
$delete_sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping
|
||||
WHERE doc_ref = '" . $this->db->escape($this->declaration_name) . "'
|
||||
AND entity = " . $this->entity;
|
||||
|
||||
// Also delete entries that might have been created with different doc_ref but same period
|
||||
$delete_period_sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping
|
||||
WHERE doc_date >= '" . $this->start_date . "'
|
||||
AND doc_date <= '" . $this->end_date . "'
|
||||
AND (doc_ref LIKE '%" . $this->db->escape($this->declaration_name) . "%'
|
||||
OR doc_ref LIKE '%TVA%'
|
||||
OR doc_ref LIKE '%" . date('Y', strtotime($this->start_date)) . "%')
|
||||
AND entity = " . $this->entity;
|
||||
$delete_result = $this->db->query($delete_sql);
|
||||
if ($delete_result) {
|
||||
$deleted_count = $this->db->affected_rows($delete_result);
|
||||
error_log("DEBUG: Successfully deleted " . $deleted_count . " existing entries by doc_ref");
|
||||
} else {
|
||||
error_log("DEBUG: Failed to delete existing entries by doc_ref: " . $this->db->lasterror());
|
||||
}
|
||||
|
||||
// Execute period-based deletion
|
||||
$delete_period_result = $this->db->query($delete_period_sql);
|
||||
if ($delete_period_result) {
|
||||
$deleted_period_count = $this->db->affected_rows($delete_period_result);
|
||||
error_log("DEBUG: Successfully deleted " . $deleted_period_count . " existing entries by period");
|
||||
} else {
|
||||
error_log("DEBUG: Failed to delete existing entries by period: " . $this->db->lasterror());
|
||||
}
|
||||
|
||||
// Verify deletion
|
||||
$verify_sql = "SELECT COUNT(*) as count FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping
|
||||
WHERE doc_ref = '" . $this->db->escape($this->declaration_name) . "'
|
||||
AND entity = " . $this->entity;
|
||||
$verify_result = $this->db->query($verify_sql);
|
||||
if ($verify_result && $this->db->num_rows($verify_result) > 0) {
|
||||
$verify_obj = $this->db->fetch_object($verify_result);
|
||||
error_log("DEBUG: After deletion, " . $verify_obj->count . " entries still exist");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a declaration object with the fetched data
|
||||
$declaration = new stdClass();
|
||||
$declaration->rowid = $this->rowid;
|
||||
@ -980,9 +921,6 @@ class DeclarationTVA
|
||||
return false;
|
||||
}
|
||||
|
||||
// Debug: Log CA-3 lines found
|
||||
error_log("DEBUG: Found " . count($ca3_lines) . " CA-3 lines for declaration " . $declaration_id);
|
||||
|
||||
// Create lookup array for CA-3 data
|
||||
$ca3_lookup = array();
|
||||
foreach ($ca3_lines as $line) {
|
||||
@ -1001,13 +939,12 @@ class DeclarationTVA
|
||||
}
|
||||
|
||||
// Create bank journal entries
|
||||
error_log("DEBUG: About to create bank journal entries");
|
||||
$bank_entries = $this->createBankJournalEntries($declaration, $ca3_lookup, $journal_config, $user);
|
||||
if (!$bank_entries) {
|
||||
if ($bank_entries === false) {
|
||||
error_log("DEBUG: Bank journal entries creation failed: " . $this->error);
|
||||
return false;
|
||||
}
|
||||
error_log("DEBUG: Bank journal entries creation result: " . ($bank_entries === true ? 'SUCCESS' : 'FAILED'));
|
||||
// Note: $bank_entries can be an empty array for carry-forward cases, which is OK
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1027,23 +964,18 @@ class DeclarationTVA
|
||||
|
||||
// Get line 8 VAT accounts (debit side)
|
||||
$line8_entries = $this->getLine8VATAccountsForAccounting($declaration, $ca3_lookup);
|
||||
error_log("DEBUG: Line 8 entries: " . count($line8_entries));
|
||||
$entries = array_merge($entries, $line8_entries);
|
||||
|
||||
// Get line 20 accounts (credit side)
|
||||
$line20_entries = $this->getLine20AccountsForAccounting($declaration, $ca3_lookup);
|
||||
error_log("DEBUG: Line 20 entries: " . count($line20_entries));
|
||||
$entries = array_merge($entries, $line20_entries);
|
||||
|
||||
// Add balancing entry
|
||||
$balancing_entry = $this->getVATResultEntryForAccounting($declaration, $ca3_lookup, $journal_config);
|
||||
error_log("DEBUG: Balancing entry: " . ($balancing_entry ? "FOUND" : "NONE"));
|
||||
if ($balancing_entry) {
|
||||
$entries[] = $balancing_entry;
|
||||
}
|
||||
|
||||
error_log("DEBUG: Total OD entries to create: " . count($entries));
|
||||
|
||||
// Create accounting entries in Dolibarr
|
||||
return $this->saveAccountingEntries($entries, $declaration, $user);
|
||||
}
|
||||
@ -1059,16 +991,12 @@ class DeclarationTVA
|
||||
*/
|
||||
private function createBankJournalEntries($declaration, $ca3_lookup, $journal_config, $user)
|
||||
{
|
||||
error_log("DEBUG: createBankJournalEntries called");
|
||||
|
||||
// Get bank account configuration
|
||||
require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_config.class.php';
|
||||
$config = new DeclarationTVA_Config($this->db, $this->entity);
|
||||
$bank_config = $config->getBankAccountConfiguration();
|
||||
$bank_account_id = $bank_config['bank_account'];
|
||||
|
||||
error_log("DEBUG: Bank account ID from config: " . $bank_account_id);
|
||||
|
||||
if (empty($bank_account_id) || $bank_account_id == 0) {
|
||||
// No bank account configured - skip bank entries
|
||||
error_log("DEBUG: No bank account configured - skipping bank entries");
|
||||
@ -1118,12 +1046,9 @@ class DeclarationTVA
|
||||
if ($threshold_enabled && $vat_credit < $refund_threshold) {
|
||||
// Carry-forward case - NO bank entries needed
|
||||
// Only create accounting entries for carry-forward (no bank transaction)
|
||||
error_log("DEBUG: VAT credit below threshold (" . $vat_credit . " < " . $refund_threshold . ") - skipping bank entries, using carry-forward");
|
||||
return array(); // Return empty array - no bank entries for carry-forward
|
||||
return true; // Return true - no bank entries for carry-forward, but that's OK
|
||||
} else {
|
||||
// Immediate refund case - create bank entries
|
||||
error_log("DEBUG: VAT credit above threshold (" . $vat_credit . " >= " . $refund_threshold . ") - creating bank entries for immediate refund");
|
||||
|
||||
$entries[] = array(
|
||||
'account_code' => $bank_account['account_code'],
|
||||
'account_label' => $bank_account['account_label'],
|
||||
@ -1144,7 +1069,6 @@ class DeclarationTVA
|
||||
|
||||
// Get bank journal code from bank account
|
||||
$bank_journal_code = $bank_account['journal_code'] ?? 'BAN';
|
||||
error_log("DEBUG: Using bank journal code from bank account: " . $bank_journal_code);
|
||||
|
||||
// Create accounting entries in Dolibarr
|
||||
return $this->saveAccountingEntries($entries, $declaration, $user, $bank_journal_code);
|
||||
@ -1165,7 +1089,6 @@ class DeclarationTVA
|
||||
return $entries;
|
||||
}
|
||||
|
||||
error_log("DEBUG: Declaration object rowid: " . ($declaration->rowid ?? 'NULL'));
|
||||
$line8_details = $this->getCA3LineDetails($declaration->rowid, '08');
|
||||
|
||||
if (empty($line8_details) || empty($line8_details['account_details'])) {
|
||||
@ -1290,8 +1213,6 @@ class DeclarationTVA
|
||||
*/
|
||||
private function saveAccountingEntries($entries, $declaration, $user, $journal_code = 'OD')
|
||||
{
|
||||
error_log("DEBUG: saveAccountingEntries called with user: " . ($user ? "VALID" : "NULL") . ", journal: " . $journal_code);
|
||||
|
||||
if (empty($entries)) {
|
||||
return true; // No entries to save
|
||||
}
|
||||
@ -1301,26 +1222,9 @@ class DeclarationTVA
|
||||
|
||||
// Start transaction
|
||||
$this->db->begin();
|
||||
error_log("DEBUG: Database transaction started for journal: " . $journal_code);
|
||||
|
||||
/*
|
||||
// Get journal label from database and translate it
|
||||
$journal_label_sql = "SELECT label FROM " . MAIN_DB_PREFIX . "accounting_journal WHERE code = '" . $journal_code . "' AND entity = " . $this->entity;
|
||||
$journal_label_result = $this->db->query($journal_label_sql);
|
||||
if ($journal_label_result && $this->db->num_rows($journal_label_result) > 0) {
|
||||
$journal_label_obj = $this->db->fetch_object($journal_label_result);
|
||||
$debit->journal_label = $journal_label_obj->label;
|
||||
error_log("DEBUG: Retrieved journal label: " . $journal_label_obj->label);
|
||||
} else {
|
||||
error_log("DEBUG: No journal label found for " . $journal_code . " code");
|
||||
}
|
||||
*/
|
||||
|
||||
try {
|
||||
foreach ($entries as $entry) {
|
||||
error_log("--------------------------------------------------------");
|
||||
error_log("DEBUG: Creating accounting entry for account: " . $entry['account_code'] . ", debit: " . $entry['debit'] . ", credit: " . $entry['credit']);
|
||||
|
||||
// Prepare amounts
|
||||
$debit_amount = !empty($entry['debit']) ? (float)$entry['debit'] : 0;
|
||||
$credit_amount = !empty($entry['credit']) ? (float)$entry['credit'] : 0;
|
||||
@ -1397,15 +1301,6 @@ class DeclarationTVA
|
||||
// Set ref field again to ensure it's not overwritten
|
||||
$credit->ref = $declaration->declaration_name;
|
||||
|
||||
error_log("==============================================");
|
||||
error_log("credit->code_journal: " . $credit->code_journal);
|
||||
error_log("credit->numero_compte: " . $credit->numero_compte);
|
||||
error_log("credit->doc_ref: " . $credit->doc_ref);
|
||||
error_log("credit->debit: " . $credit->debit);
|
||||
error_log("credit->credit: " . $credit->credit);
|
||||
error_log("credit->entity: " . $credit->entity);
|
||||
error_log("==============================================");
|
||||
|
||||
$result = $credit->create($user);
|
||||
if ($credit->id <= 0) {
|
||||
throw new Exception('Failed to create credit entry: ' . $credit->error);
|
||||
@ -1421,7 +1316,6 @@ class DeclarationTVA
|
||||
|
||||
// Commit the transaction
|
||||
$this->db->commit();
|
||||
error_log("DEBUG: Database transaction committed");
|
||||
|
||||
// Final verification - check all entries created for this declaration
|
||||
$final_check_sql = "SELECT COUNT(*) as total_entries FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping
|
||||
@ -1431,31 +1325,7 @@ class DeclarationTVA
|
||||
$final_check_obj = $this->db->fetch_object($final_check_result);
|
||||
error_log("DEBUG: Final verification - Total entries in database for declaration " . $declaration->declaration_name . ": " . $final_check_obj->total_entries);
|
||||
}
|
||||
/*
|
||||
// Simple verification
|
||||
error_log("DEBUG: Accounting entries created successfully");
|
||||
|
||||
// Check what journal codes exist in the system
|
||||
$journal_check_sql = "SELECT code, label FROM " . MAIN_DB_PREFIX . "accounting_journal WHERE entity = " . $this->entity;
|
||||
$journal_check_result = $this->db->query($journal_check_sql);
|
||||
if ($journal_check_result && $this->db->num_rows($journal_check_result) > 0) {
|
||||
error_log("DEBUG: Available journal codes in system:");
|
||||
while ($journal_obj = $this->db->fetch_object($journal_check_result)) {
|
||||
error_log("DEBUG: Journal: " . $journal_obj->code . " - " . $journal_obj->label);
|
||||
}
|
||||
}
|
||||
|
||||
// Also check what's actually in the accounting_bookkeeping table
|
||||
$debug_sql = "SELECT doc_ref, numero_compte, montant, sens FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping
|
||||
WHERE doc_ref LIKE '%AOUT%' ORDER BY rowid DESC LIMIT 10";
|
||||
$debug_result = $this->db->query($debug_sql);
|
||||
if ($debug_result && $this->db->num_rows($debug_result) > 0) {
|
||||
error_log("DEBUG: Recent entries in accounting_bookkeeping table:");
|
||||
while ($debug_obj = $this->db->fetch_object($debug_result)) {
|
||||
error_log("DEBUG: Entry - doc_ref: " . $debug_obj->doc_ref . ", account: " . $debug_obj->numero_compte . ", amount: " . $debug_obj->montant . ", sens: " . $debug_obj->sens);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1473,7 +1343,6 @@ class DeclarationTVA
|
||||
WHERE ba.rowid = " . (int)$bank_account_id . "
|
||||
AND ba.entity = " . $this->entity;
|
||||
|
||||
error_log("DEBUG: Bank account query: " . $sql);
|
||||
$result = $this->db->query($sql);
|
||||
if ($result && $this->db->num_rows($result) > 0) {
|
||||
$obj = $this->db->fetch_object($result);
|
||||
@ -1484,8 +1353,6 @@ class DeclarationTVA
|
||||
// Get the journal code from the journal ID
|
||||
$journal_code = $this->getJournalCodeFromId($obj->fk_accountancy_journal);
|
||||
|
||||
error_log("DEBUG: Bank account data - account_number: " . $obj->account_number . ", account_label: " . $account_label . ", journal_code: " . $journal_code);
|
||||
|
||||
return array(
|
||||
'rowid' => $obj->rowid,
|
||||
'label' => $obj->label,
|
||||
@ -1553,8 +1420,6 @@ class DeclarationTVA
|
||||
*/
|
||||
public function submitDeclaration($declaration_id, $user)
|
||||
{
|
||||
error_log("DEBUG: submitDeclaration called with user: " . ($user ? "VALID" : "NULL"));
|
||||
|
||||
// Get declaration data
|
||||
$declaration = $this->fetch($declaration_id);
|
||||
if (!$declaration) {
|
||||
@ -1564,12 +1429,10 @@ class DeclarationTVA
|
||||
|
||||
// Check if declaration is validated
|
||||
// TEMPORARILY DISABLED FOR TESTING - allows re-submission
|
||||
/*
|
||||
if ($declaration->status !== 'validated') {
|
||||
$this->error = 'Declaration must be validated before submission';
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
// Check if accounting entries are enabled
|
||||
require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_config.class.php';
|
||||
@ -1709,8 +1572,6 @@ class DeclarationTVA
|
||||
*/
|
||||
public function getCA3LineDetails($declaration_id, $ca3_line)
|
||||
{
|
||||
error_log("DEBUG: getCA3LineDetails called for declaration $declaration_id, line $ca3_line");
|
||||
|
||||
// Get declaration dates
|
||||
$sql = "SELECT start_date, end_date FROM " . MAIN_DB_PREFIX . "declarationtva_declarations
|
||||
WHERE rowid = " . (int)$declaration_id . " AND entity = " . $this->entity;
|
||||
@ -1801,7 +1662,6 @@ class DeclarationTVA
|
||||
'account_count' => count($details)
|
||||
);
|
||||
|
||||
error_log("DEBUG: getCA3LineDetails returning " . count($details) . " account details for line $ca3_line");
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user