diff --git a/admin/setup_mvp.php b/admin/setup_mvp.php index 0f77e32..d7c59ae 100644 --- a/admin/setup_mvp.php +++ b/admin/setup_mvp.php @@ -39,11 +39,9 @@ $action = GETPOST('action', 'alpha'); if ($action == 'update_mappings') { $ca3_definitions = $config->getCA3LineDefinitions(); $updated_count = 0; - $debug_info = array(); foreach ($ca3_definitions as $line => $definition) { $account_codes = GETPOST('account_codes_' . $line, 'array'); - $debug_info[] = "Line $line: " . (is_array($account_codes) ? implode(',', $account_codes) : 'empty'); // Process all lines, even empty ones (to clear mappings) $result = $config->updateAccountMapping($line, $account_codes); @@ -52,13 +50,6 @@ if ($action == 'update_mappings') { } } - // Debug output - if (empty($debug_info)) { - setEventMessages("Debug: No form data received", null, 'warnings'); - } else { - setEventMessages("Debug: " . implode(' | ', $debug_info), null, 'warnings'); - } - if ($updated_count > 0) { setEventMessages($langs->trans("ConfigurationUpdated"), null, 'mesgs'); } else { @@ -71,23 +62,12 @@ $mappings_by_line = $config->getAccountMappingsByLine(); $accounts = $config->getAccountingAccounts(); $ca3_definitions = $config->getCA3LineDefinitions(); -// Debug: Check if table exists and create if missing +// Ensure table exists (create if missing) $table_name = MAIN_DB_PREFIX . "declarationtva_account_mappings"; $check_table_sql = "SHOW TABLES LIKE '" . $table_name . "'"; $table_exists = $db->query($check_table_sql); -if ($table_exists && $db->num_rows($table_exists) > 0) { - // Table exists - check if migration is needed - $constraint_check = "SHOW INDEX FROM " . $table_name . " WHERE Key_name = 'uk_mapping_entity_line_account'"; - $constraint_result = $db->query($constraint_check); - if ($constraint_result && $db->num_rows($constraint_result) > 0) { - setEventMessages("Debug: Table structure is correct (supports multiple accounts per line)", null, 'mesgs'); - } else { - setEventMessages("Debug: Table exists but needs migration - please deactivate and reactivate the module", null, 'warnings'); - } -} else { - setEventMessages("Debug: Table $table_name does NOT exist - creating it now", null, 'warnings'); - - // Create the table manually +if (!$table_exists || $db->num_rows($table_exists) == 0) { + // Create the table if it doesn't exist $create_table_sql = "CREATE TABLE IF NOT EXISTS `" . $table_name . "` ( `rowid` int(11) NOT NULL AUTO_INCREMENT, `entity` int(11) NOT NULL DEFAULT 1, @@ -103,12 +83,7 @@ if ($table_exists && $db->num_rows($table_exists) > 0) { KEY `idx_account_code` (`account_code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"; - $create_result = $db->query($create_table_sql); - if ($create_result) { - setEventMessages("Debug: Table created successfully!", null, 'mesgs'); - } else { - setEventMessages("Debug: Failed to create table: " . $db->lasterror(), null, 'errors'); - } + $db->query($create_table_sql); } $section_headers = $config->getCA3SectionHeaders(); diff --git a/core/class/declarationtva_config.class.php b/core/class/declarationtva_config.class.php index 174bd33..e69de29 100644 --- a/core/class/declarationtva_config.class.php +++ b/core/class/declarationtva_config.class.php @@ -1,432 +0,0 @@ -db = $db; - $this->entity = $entity; - } - - /** - * Get configuration value - * - * @param string $key Configuration key - * @param mixed $default Default value - * @return mixed Configuration value - */ - public function get($key, $default = null) - { - $sql = "SELECT config_value FROM " . MAIN_DB_PREFIX . "declarationtva_config - WHERE entity = " . $this->entity . " AND config_key = '" . $this->db->escape($key) . "'"; - - $result = $this->db->query($sql); - if ($result && $this->db->num_rows($result) > 0) { - $obj = $this->db->fetch_object($result); - return $obj->config_value; - } - - return $default; - } - - /** - * Set configuration value - * - * @param string $key Configuration key - * @param mixed $value Configuration value - * @return bool Success - */ - public function set($key, $value) - { - $sql = "INSERT INTO " . MAIN_DB_PREFIX . "declarationtva_config - (entity, config_key, config_value, created_date) - VALUES (" . $this->entity . ", '" . $this->db->escape($key) . "', - '" . $this->db->escape($value) . "', NOW()) - ON DUPLICATE KEY UPDATE config_value = '" . $this->db->escape($value) . "'"; - - $result = $this->db->query($sql); - return $result !== false; - } - - /** - * Get account mapping for a CA-3 line - * - * @param string $ca3_line CA-3 line code - * @return array|false Account mapping or false if not found - */ - public function getAccountMapping($ca3_line) - { - $sql = "SELECT * FROM " . MAIN_DB_PREFIX . "declarationtva_account_mappings - WHERE entity = " . $this->entity . " AND ca3_line = '" . $this->db->escape($ca3_line) . "'"; - - $result = $this->db->query($sql); - if ($result && $this->db->num_rows($result) > 0) { - return $this->db->fetch_array($result); - } - - return false; - } - - /** - * Update account mapping for multiple accounts - * - * @param string $ca3_line CA-3 line code - * @param array $account_codes Array of account codes - * @return bool Success - */ - public function updateAccountMapping($ca3_line, $account_codes) - { - // Debug: Log what we're trying to save - error_log("DeclarationTVA: updateAccountMapping called for line $ca3_line with codes: " . print_r($account_codes, true)); - - // First, deactivate all existing mappings for this CA-3 line - $sql = "UPDATE " . MAIN_DB_PREFIX . "declarationtva_account_mappings - SET is_active = 0 - WHERE entity = " . $this->entity . " AND ca3_line = '" . $this->db->escape($ca3_line) . "'"; - $result1 = $this->db->query($sql); - error_log("DeclarationTVA: Deactivate query result: " . ($result1 ? 'SUCCESS' : 'FAILED - ' . $this->db->lasterror())); - - // Then insert/activate new mappings - if (!empty($account_codes)) { - foreach ($account_codes as $account_code) { - if (!empty($account_code)) { - // Check if mapping already exists - $check_sql = "SELECT id FROM " . MAIN_DB_PREFIX . "declarationtva_account_mappings - WHERE entity = " . $this->entity . " - AND ca3_line = '" . $this->db->escape($ca3_line) . "' - AND account_code = '" . $this->db->escape($account_code) . "'"; - $check_result = $this->db->query($check_sql); - error_log("DeclarationTVA: Check query result: " . ($check_result ? 'SUCCESS' : 'FAILED - ' . $this->db->lasterror())); - - if ($check_result && $this->db->num_rows($check_result) > 0) { - // Update existing mapping - $sql = "UPDATE " . MAIN_DB_PREFIX . "declarationtva_account_mappings - SET is_active = 1 - WHERE entity = " . $this->entity . " - AND ca3_line = '" . $this->db->escape($ca3_line) . "' - AND account_code = '" . $this->db->escape($account_code) . "'"; - $result2 = $this->db->query($sql); - error_log("DeclarationTVA: Update query result: " . ($result2 ? 'SUCCESS' : 'FAILED - ' . $this->db->lasterror())); - } else { - // Insert new mapping - $sql = "INSERT INTO " . MAIN_DB_PREFIX . "declarationtva_account_mappings - (entity, ca3_line, account_code, account_label, vat_rate, is_active, created_date) - VALUES (" . $this->entity . ", '" . $this->db->escape($ca3_line) . "', - '" . $this->db->escape($account_code) . "', '', 0, 1, NOW())"; - $result3 = $this->db->query($sql); - error_log("DeclarationTVA: Insert query result: " . ($result3 ? 'SUCCESS' : 'FAILED - ' . $this->db->lasterror())); - } - } - } - } - - return true; - } - - /** - * Get all account mappings - * - * @return array Account mappings - */ - public function getAllAccountMappings() - { - $sql = "SELECT * 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( - 'rowid' => $obj->rowid, - 'ca3_line' => $obj->ca3_line, - 'account_code' => $obj->account_code, - 'account_label' => $obj->account_label, - 'vat_rate' => $obj->vat_rate, - 'is_active' => $obj->is_active - ); - } - } - - return $mappings; - } - - /** - * Get account mappings grouped by CA-3 line - * - * @return array Account mappings grouped by CA-3 line - */ - public function getAccountMappingsByLine() - { - $sql = "SELECT ca3_line, account_code FROM " . MAIN_DB_PREFIX . "declarationtva_account_mappings - WHERE entity = " . $this->entity . " AND is_active = 1 - ORDER BY ca3_line, account_code"; - - $result = $this->db->query($sql); - $mappings = array(); - - if ($result) { - while ($obj = $this->db->fetch_object($result)) { - if (!isset($mappings[$obj->ca3_line])) { - $mappings[$obj->ca3_line] = array(); - } - $mappings[$obj->ca3_line][] = $obj->account_code; - } - } - - return $mappings; - } - - /** - * Get available accounting accounts from Dolibarr - * - * @return array Accounting accounts - */ - public function getAccountingAccounts() - { - $sql = "SELECT account_number, label FROM " . MAIN_DB_PREFIX . "accounting_account - WHERE active = 1 - ORDER BY account_number"; - - $result = $this->db->query($sql); - $accounts = array(); - - if ($result) { - while ($obj = $this->db->fetch_object($result)) { - $accounts[] = array( - 'account_number' => $obj->account_number, - 'label' => $obj->label - ); - } - } - - return $accounts; - } - - /** - * Get CA-3 line definitions (Notice 4722 - Latest Official Structure) - * - * @return array CA-3 line definitions - */ - public function getCA3LineDefinitions() - { - return array( - // A. Opérations imposables (Taxable Operations) - Notice 4722 - 'A1' => array( - 'label' => 'Montant HT des opérations imposables normales (biens + services imposables en France à 20%, 10%, 5,5%, 2,1%)', - 'type' => 'base', - 'section' => 'A', - 'description' => 'HT amount of all taxable operations that form normal sales (goods + services taxable in France at 20%, 10%, 5,5%, 2,1%)', - 'pcg_accounts' => 'Sales: 7xxxx; VAT: 44571x / 44572x / 44573x / 44574x' - ), - 'A2' => array( - 'label' => 'Montant HT des opérations imposables spéciales ne relevant pas du CA courant (cessions d\'immobilisations, livraisons à soi-même)', - 'type' => 'base', - 'section' => 'A', - 'description' => 'HT amount of special taxable operations not part of ordinary turnover (e.g. cessions d\'immobilisations, livraisons à soi-même)', - 'pcg_accounts' => '775xxx (gains on disposal), 72xxx (production immobilisée), VAT: 44571x' - ), - 'A3' => array( - 'label' => 'Montant HT des services achetés à des prestataires non établis en France mais imposables en France (autoliquidation services étrangers)', - 'type' => 'base', - 'section' => 'A', - 'description' => 'HT amount of services purchased from providers not established in France but taxable in France (reverse charge for foreign services)', - 'pcg_accounts' => '6xxxx (services purchased), 4452xxx (TVA due autoliquidée)' - ), - 'A4' => array( - 'label' => 'Montant HT des importations imposables en France (hors UE), à l\'exclusion des produits pétroliers', - 'type' => 'base', - 'section' => 'A', - 'description' => 'HT amount of imports taxable in France (non-EU), excluding petroleum products', - 'pcg_accounts' => '6xxxx / 2xxxx purchases or assets; VAT: 4452xxx (import VAT)' - ), - 'A5' => array( - 'label' => 'Montant HT des opérations imposables à la sortie d\'un régime fiscal suspensif (régimes douaniers, zones franches, etc.)', - 'type' => 'base', - 'section' => 'A', - 'description' => 'HT amount of taxable operations at exit from a suspensive fiscal regime (customs regimes, free zones, etc.)', - 'pcg_accounts' => 'Specific 6xxxx/2xxxx depending on goods; VAT: 4452xxx' - ), - - // B. Décompte de la TVA due (VAT Due Calculation) - Notice 4722 - '08' => array( - 'label' => 'TVA due au taux de 20%', - 'type' => 'vat', - 'section' => 'B', - 'description' => 'VAT amounts due, calculated on A1/A2 bases at 20% rate', - 'pcg_accounts' => '44571x (TVA collectée à 20%)' - ), - '09' => array( - 'label' => 'TVA due au taux de 10%', - 'type' => 'vat', - 'section' => 'B', - 'description' => 'VAT amounts due, calculated on A1/A2 bases at 10% rate', - 'pcg_accounts' => '44572x (TVA collectée à 10%)' - ), - '9B' => array( - 'label' => 'TVA due aux taux réduits (5,5% et 2,1%)', - 'type' => 'vat', - 'section' => 'B', - 'description' => 'VAT amounts due, calculated on A1/A2 bases at reduced rates (5,5% and 2,1%)', - 'pcg_accounts' => '44573x (5,5%) / 44574x (2,1%) (TVA collectée aux taux réduits)' - ), - '17' => array( - 'label' => 'TVA due au titre des acquisitions intracommunautaires (autoliquidation)', - 'type' => 'vat', - 'section' => 'B', - 'description' => 'VAT due on intra-EU acquisitions (autoliquidation)', - 'pcg_accounts' => '4452xxx (TVA due intracommunautaire)' - ), - - // C. Décompte de la TVA déductible (Deductible VAT Calculation) - Notice 4722 - '20' => array( - 'label' => 'TVA déductible sur immobilisations', - 'type' => 'vat', - 'section' => 'C', - 'description' => 'Deductible VAT on capital goods (fixed assets)', - 'pcg_accounts' => '44562x (TVA déductible sur immobilisations)' - ), - '21' => array( - 'label' => 'TVA déductible sur autres biens et services', - 'type' => 'vat', - 'section' => 'C', - 'description' => 'Deductible VAT on other goods and services (operating expenses)', - 'pcg_accounts' => '44566x (TVA déductible sur autres biens et services)' - ), - '22' => array( - 'label' => 'TVA déductible sur importations', - 'type' => 'vat', - 'section' => 'C', - 'description' => 'Deductible VAT on imports', - 'pcg_accounts' => '44566x / 44562x (TVA déductible sur importations)' - ), - - // D. Résultat (Result) - Notice 4722 - '25' => array( - 'label' => 'TVA brute due (Total TVA due)', - 'type' => 'vat', - 'section' => 'D', - 'description' => 'Total VAT due (sum of all VAT due amounts)', - 'pcg_accounts' => 'Sum of 08 + 09 + 9B + 17' - ), - '26' => array( - 'label' => 'TVA déductible totale (Total deductible VAT)', - 'type' => 'vat', - 'section' => 'D', - 'description' => 'Total deductible VAT (sum of all deductible VAT amounts)', - 'pcg_accounts' => 'Sum of 20 + 21 + 22' - ), - '28' => array( - 'label' => 'TVA nette à payer', - 'type' => 'vat', - 'section' => 'D', - 'description' => 'Net VAT to pay (if total due > total deductible)', - 'pcg_accounts' => '445510 (État - TVA à décaisser)' - ), - '29' => array( - 'label' => 'Crédit de TVA à reporter ou remboursement', - 'type' => 'vat', - 'section' => 'D', - 'description' => 'VAT credit to carry forward or refund (if total deductible > total due)', - 'pcg_accounts' => '445670 (État - Crédit de TVA à reporter ou rembourser)' - ) - ); - } - - /** - * Get CA-3 section headers (Notice 4722) - * - * @return array Section headers - */ - public function getCA3SectionHeaders() - { - return array( - 'A' => array( - 'title' => 'A. Opérations imposables (Taxable Operations)', - 'description' => 'HT amounts of all taxable operations according to Notice 4722 (3310-CA3-SD)', - 'notice' => 'Notice 4722 - Summary Table CA3 (3310-CA3-SD)' - ), - 'B' => array( - 'title' => 'B. Décompte de la TVA due (VAT Due Calculation)', - 'description' => 'VAT amounts due, calculated on A1/A2 bases per applicable rate', - 'notice' => 'Notice 4722 - VAT Due Calculation' - ), - 'C' => array( - 'title' => 'C. Décompte de la TVA déductible (Deductible VAT Calculation)', - 'description' => 'VAT amounts that can be deducted from purchases and expenses', - 'notice' => 'Notice 4722 - Deductible VAT Calculation' - ), - 'D' => array( - 'title' => 'D. Résultat (Result)', - 'description' => 'Final calculation: net VAT to pay or credit to carry forward', - 'notice' => 'Notice 4722 - Final Result' - ) - ); - } - - /** - * Get supported VAT rates - * - * @return array VAT rates - */ - public function getVATRates() - { - return array( - '20.00' => '20%', - '10.00' => '10%', - '5.50' => '5.5%', - '2.10' => '2.1%', - '0.00' => '0%' - ); - } - - /** - * Validate account mapping - * - * @param string $ca3_line CA-3 line code - * @param string $account_code Account code - * @return bool Valid - */ - public function validateAccountMapping($ca3_line, $account_code) - { - // Check if account exists in Dolibarr - $sql = "SELECT COUNT(*) as count FROM " . MAIN_DB_PREFIX . "accounting_account - WHERE account_number = '" . $this->db->escape($account_code) . "' AND active = 1"; - - $result = $this->db->query($sql); - if ($result && $this->db->num_rows($result) > 0) { - $obj = $this->db->fetch_object($result); - return $obj->count > 0; - } - - return false; - } -}