From 2600fb6982af7816725b475f977dc4a229da24ba Mon Sep 17 00:00:00 2001 From: Frank Cools Date: Thu, 2 Oct 2025 20:48:12 +0200 Subject: [PATCH] Add debugging to calculation system Debug Features: - Added error_log statements to getAccountAmounts() method - Added debugging to calculateCA3Amounts() method - Logs account queries, mappings found, and calculation results - Helps diagnose why calculations show 0.00 values To debug: 1. Check if PCG accounts are configured 2. Check if accounting data exists in Dolibarr 3. Check error logs for calculation details --- core/class/declarationtva.class.php | 558 ++++++++++++++++++++++++++++ 1 file changed, 558 insertions(+) diff --git a/core/class/declarationtva.class.php b/core/class/declarationtva.class.php index e69de29..86277ad 100644 --- a/core/class/declarationtva.class.php +++ b/core/class/declarationtva.class.php @@ -0,0 +1,558 @@ +db = $db; + $this->entity = $entity; + } + + /** + * Fetch declaration by ID + * + * @param int $id Declaration ID + * @return int 1 if found, 0 if not found, -1 if error + */ + public function fetch($id) + { + $sql = "SELECT * FROM " . MAIN_DB_PREFIX . "declarationtva_declarations + WHERE rowid = " . (int)$id . " AND entity = " . $this->entity; + + $result = $this->db->query($sql); + if ($result) { + $obj = $this->db->fetch_object($result); + if ($obj) { + $this->rowid = $obj->rowid; + $this->period_id = $obj->period_id; + $this->declaration_number = $obj->declaration_number; + $this->declaration_name = $obj->declaration_name; + $this->start_date = $obj->start_date; + $this->end_date = $obj->end_date; + $this->status = $obj->status; + $this->created_date = $obj->created_date; + return 1; + } + } + return 0; + } + + /** + * Create a new declaration for a period + * + * @param int $period_id Period ID + * @return int Declaration ID or -1 if error + */ + public function createDeclaration($period_id) + { + global $user; + + $this->db->begin(); + + // Get period information + $period = $this->getPeriod($period_id); + if (!$period) { + $this->error = "Period not found"; + $this->db->rollback(); + return -1; + } + + // Generate declaration number + $declaration_number = $this->generateDeclarationNumber($period); + + // Create declaration record + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "declarationtva_declarations + (entity, period_id, declaration_number, status, created_date) + VALUES (" . $this->entity . ", " . $period_id . ", '" . $declaration_number . "', 'draft', NOW())"; + + $result = $this->db->query($sql); + if (!$result) { + $this->error = "Error creating declaration: " . $this->db->lasterror(); + $this->db->rollback(); + return -1; + } + + $declaration_id = $this->db->last_insert_id(MAIN_DB_PREFIX . "declarationtva_declarations"); + + // Calculate CA-3 amounts + $this->calculateCA3Amounts($declaration_id, $period); + + $this->db->commit(); + return $declaration_id; + } + + /** + * Create a new declaration with specific dates + * + * @param string $start_date Start date (YYYY-MM-DD) + * @param string $end_date End date (YYYY-MM-DD) + * @param string $declaration_name Declaration name + * @return int Declaration ID or -1 if error + */ + public function createDeclarationWithDates($start_date, $end_date, $declaration_name = '') + { + global $user; + + $this->db->begin(); + + // Generate declaration number + $declaration_number = $this->generateDeclarationNumberFromDates($start_date, $end_date); + + // Create declaration record + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "declarationtva_declarations + (entity, period_id, declaration_number, declaration_name, start_date, end_date, status, created_date) + VALUES (" . $this->entity . ", 0, '" . $declaration_number . "', '" . $this->db->escape($declaration_name) . "', '" . $start_date . "', '" . $end_date . "', 'draft', NOW())"; + + $result = $this->db->query($sql); + if (!$result) { + $this->error = "Error creating declaration: " . $this->db->lasterror(); + $this->db->rollback(); + return -1; + } + + $declaration_id = $this->db->last_insert_id(MAIN_DB_PREFIX . "declarationtva_declarations"); + + // Calculate CA-3 amounts + $period = array('start_date' => $start_date, 'end_date' => $end_date); + $this->calculateCA3Amounts($declaration_id, $period); + + $this->db->commit(); + return $declaration_id; + } + + /** + * Calculate CA-3 amounts for a declaration + * + * @param int $declaration_id Declaration ID + * @param array $period Period information + * @return bool Success + */ + public function calculateCA3Amounts($declaration_id, $period) + { + error_log("DeclarationTVA: Starting calculation for declaration $declaration_id"); + error_log("DeclarationTVA: Period: " . $period['start_date'] . " to " . $period['end_date']); + + // Get account mappings + $mappings = $this->getAccountMappings(); + error_log("DeclarationTVA: Found " . count($mappings) . " account mappings"); + + $total_vat_collected = 0; + $total_vat_deductible = 0; + + // Process each CA-3 line + foreach ($mappings as $mapping) { + error_log("DeclarationTVA: Processing mapping: " . $mapping['ca3_line'] . " -> " . $mapping['account_code']); + $amounts = $this->getAccountAmounts($mapping['account_code'], $period['start_date'], $period['end_date']); + + // Create CA-3 line record + $this->createCA3Line($declaration_id, $mapping['ca3_line'], $mapping['account_label'], $amounts); + + // Update totals + if (in_array($mapping['ca3_line'], ['A1', 'A2', 'B1', 'B2', 'B3', 'B4', '17'])) { + $total_vat_collected += $amounts['vat_amount']; + } elseif (in_array($mapping['ca3_line'], ['20', '21'])) { + $total_vat_deductible += $amounts['vat_amount']; + } + } + + error_log("DeclarationTVA: Totals - Collected: $total_vat_collected, Deductible: $total_vat_deductible"); + + // Calculate net amounts + $net_vat_due = $total_vat_collected - $total_vat_deductible; + $vat_credit = $net_vat_due < 0 ? abs($net_vat_due) : 0; + $net_vat_due = $net_vat_due > 0 ? $net_vat_due : 0; + + // Update declaration totals + $this->updateDeclarationTotals($declaration_id, $total_vat_collected, $total_vat_deductible, $net_vat_due, $vat_credit); + + return true; + } + + /** + * Get account amounts for a period + * + * @param string $account_code Account code + * @param string $start_date Start date + * @param string $end_date End date + * @return array Amounts (base_amount, vat_amount, total_amount) + */ + public function getAccountAmounts($account_code, $start_date, $end_date) + { + // Query Dolibarr accounting entries + $sql = "SELECT SUM(debit) as total_debit, SUM(credit) as total_credit + FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping + WHERE account_number = '" . $this->db->escape($account_code) . "' + AND doc_date >= '" . $this->db->escape($start_date) . "' + AND doc_date <= '" . $this->db->escape($end_date) . "'"; + + // Debug: Log the query + error_log("DeclarationTVA: Querying account $account_code from $start_date to $end_date"); + error_log("DeclarationTVA: SQL: $sql"); + + $result = $this->db->query($sql); + if ($result && $this->db->num_rows($result) > 0) { + $obj = $this->db->fetch_object($result); + $total_amount = $obj->total_debit - $obj->total_credit; + + error_log("DeclarationTVA: Found amounts for $account_code: debit=$obj->total_debit, credit=$obj->total_credit, net=$total_amount"); + + return array( + 'base_amount' => $total_amount, + 'vat_amount' => $total_amount, + 'total_amount' => $total_amount + ); + } + + error_log("DeclarationTVA: No data found for account $account_code"); + return array('base_amount' => 0, 'vat_amount' => 0, 'total_amount' => 0); + } + + /** + * Create CA-3 line record + * + * @param int $declaration_id Declaration ID + * @param string $ca3_line CA-3 line code + * @param string $line_label Line label + * @param array $amounts Amounts array + * @return bool Success + */ + public function createCA3Line($declaration_id, $ca3_line, $line_label, $amounts) + { + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "declarationtva_ca3_lines + (declaration_id, ca3_line, line_label, base_amount, vat_amount, total_amount, created_date) + VALUES (" . $declaration_id . ", '" . $this->db->escape($ca3_line) . "', + '" . $this->db->escape($line_label) . "', " . $amounts['base_amount'] . ", + " . $amounts['vat_amount'] . ", " . $amounts['total_amount'] . ", NOW())"; + + $result = $this->db->query($sql); + return $result !== false; + } + + /** + * Update declaration totals + * + * @param int $declaration_id Declaration ID + * @param float $total_vat_collected Total VAT collected + * @param float $total_vat_deductible Total VAT deductible + * @param float $net_vat_due Net VAT due + * @param float $vat_credit VAT credit + * @return bool Success + */ + public function updateDeclarationTotals($declaration_id, $total_vat_collected, $total_vat_deductible, $net_vat_due, $vat_credit) + { + $sql = "UPDATE " . MAIN_DB_PREFIX . "declarationtva_declarations + SET total_vat_collected = " . $total_vat_collected . ", + total_vat_deductible = " . $total_vat_deductible . ", + net_vat_due = " . $net_vat_due . ", + vat_credit = " . $vat_credit . " + WHERE rowid = " . $declaration_id; + + $result = $this->db->query($sql); + return $result !== false; + } + + /** + * Get account mappings + * + * @return array Account mappings + */ + public function getAccountMappings() + { + $sql = "SELECT ca3_line, account_code, account_label, vat_rate + FROM " . MAIN_DB_PREFIX . "declarationtva_account_mappings + WHERE entity = " . $this->entity . " AND is_active = 1 + ORDER BY ca3_line"; + + $result = $this->db->query($sql); + $mappings = array(); + + if ($result) { + while ($obj = $this->db->fetch_object($result)) { + $mappings[] = array( + 'ca3_line' => $obj->ca3_line, + 'account_code' => $obj->account_code, + 'account_label' => $obj->account_label, + 'vat_rate' => $obj->vat_rate + ); + } + } + + return $mappings; + } + + /** + * Get period information + * + * @param int $period_id Period ID + * @return array|false Period information or false if not found + */ + public function getPeriod($period_id) + { + $sql = "SELECT * FROM " . MAIN_DB_PREFIX . "declarationtva_periods + WHERE rowid = " . $period_id . " AND entity = " . $this->entity; + + $result = $this->db->query($sql); + if ($result && $this->db->num_rows($result) > 0) { + return $this->db->fetch_array($result); + } + + return false; + } + + /** + * Generate declaration number + * + * @param array $period Period information + * @return string Declaration number + */ + public function generateDeclarationNumber($period) + { + $year = date('Y', strtotime($period['start_date'])); + $start_month = date('m', strtotime($period['start_date'])); + $end_month = date('m', strtotime($period['end_date'])); + + if ($start_month == $end_month) { + $month_part = $start_month; + } else { + $month_part = $start_month . '-' . $end_month; + } + + return 'CA3-' . $year . '-' . $month_part . '-' . date('YmdHis'); + } + + /** + * Generate declaration number from dates + * + * @param string $start_date Start date + * @param string $end_date End date + * @return string Declaration number + */ + public function generateDeclarationNumberFromDates($start_date, $end_date) + { + $year = date('Y', strtotime($start_date)); + $start_month = date('m', strtotime($start_date)); + $end_month = date('m', strtotime($end_date)); + + if ($start_month == $end_month) { + $month_part = $start_month; + } else { + $month_part = $start_month . '-' . $end_month; + } + + return 'CA3-' . $year . '-' . $month_part . '-' . date('YmdHis'); + } + + /** + * Get declaration information + * + * @param int $declaration_id Declaration ID + * @return array|false Declaration information or false if not found + */ + public function getDeclaration($declaration_id) + { + $sql = "SELECT d.*, p.period_name, p.start_date, p.end_date + FROM " . MAIN_DB_PREFIX . "declarationtva_declarations d + LEFT JOIN " . MAIN_DB_PREFIX . "declarationtva_periods p ON d.period_id = p.rowid + WHERE d.rowid = " . $declaration_id . " AND d.entity = " . $this->entity; + + $result = $this->db->query($sql); + if ($result && $this->db->num_rows($result) > 0) { + return $this->db->fetch_array($result); + } + + return false; + } + + /** + * Get CA-3 lines for a declaration + * + * @param int $declaration_id Declaration ID + * @return array CA-3 lines + */ + public function getCA3Lines($declaration_id) + { + $sql = "SELECT * FROM " . MAIN_DB_PREFIX . "declarationtva_ca3_lines + WHERE declaration_id = " . $declaration_id . " + ORDER BY ca3_line"; + + $result = $this->db->query($sql); + $lines = array(); + + if ($result) { + while ($obj = $this->db->fetch_object($result)) { + $lines[] = array( + 'ca3_line' => $obj->ca3_line, + 'line_label' => $obj->line_label, + 'base_amount' => $obj->base_amount, + 'vat_amount' => $obj->vat_amount, + 'total_amount' => $obj->total_amount + ); + } + } + + return $lines; + } + + /** + * Validate declaration + * + * @param int $declaration_id Declaration ID + * @return bool Success + */ + public function validateDeclaration($declaration_id) + { + $sql = "UPDATE " . MAIN_DB_PREFIX . "declarationtva_declarations + SET status = 'validated' + WHERE rowid = " . $declaration_id . " AND entity = " . $this->entity; + + $result = $this->db->query($sql); + return $result !== false; + } + + /** + * Submit declaration + * + * @param int $declaration_id Declaration ID + * @return bool Success + */ + public function submitDeclaration($declaration_id) + { + $sql = "UPDATE " . MAIN_DB_PREFIX . "declarationtva_declarations + SET status = 'submitted', submission_date = NOW() + WHERE rowid = " . $declaration_id . " AND entity = " . $this->entity; + + $result = $this->db->query($sql); + return $result !== false; + } + + /** + * Delete a declaration + * + * @param int $declaration_id Declaration ID + * @return bool Success + */ + public function deleteDeclaration($declaration_id) + { + $this->db->begin(); + + // Check if declaration exists and is in draft status + $sql = "SELECT status FROM " . MAIN_DB_PREFIX . "declarationtva_declarations + WHERE rowid = " . (int)$declaration_id . " AND entity = " . $this->entity; + + $result = $this->db->query($sql); + if ($result) { + $obj = $this->db->fetch_object($result); + if ($obj && $obj->status == 'draft') { + // Delete CA-3 lines first + $sql_lines = "DELETE FROM " . MAIN_DB_PREFIX . "declarationtva_ca3_lines + WHERE declaration_id = " . (int)$declaration_id; + $this->db->query($sql_lines); + + // Delete declaration + $sql_declaration = "DELETE FROM " . MAIN_DB_PREFIX . "declarationtva_declarations + WHERE rowid = " . (int)$declaration_id . " AND entity = " . $this->entity; + + $result = $this->db->query($sql_declaration); + if ($result) { + $this->db->commit(); + return true; + } + } + } + + $this->db->rollback(); + return false; + } + + + + + /** + * Recalculate CA-3 amounts for a declaration + * + * @param int $declaration_id Declaration ID + * @return bool Success + */ + public function recalculateCA3Amounts($declaration_id) + { + // Get declaration info + $declaration = $this->getDeclarationInfo($declaration_id); + if (!$declaration) { + return false; + } + + // Clear existing CA-3 lines + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "declarationtva_ca3_lines + WHERE declaration_id = " . $declaration_id; + $this->db->query($sql); + + // Recalculate using declaration dates + $period = array( + 'start_date' => $declaration['start_date'], + 'end_date' => $declaration['end_date'] + ); + + return $this->calculateCA3Amounts($declaration_id, $period); + } +}