hasRight("declarationtva", "declarationtva", "admin")) { accessforbidden(); } // Load language files $langs->load("declarationtva@declarationtva"); // Initialize objects $config = new DeclarationTVA_Config($db, $conf->entity); $form = new Form($db); // Handle form submission $action = GETPOST('action', 'alpha'); // Handle template actions (must be processed before tab logic) if ($action == 'upload_template' || $action == 'reset_template' || $action == 'update_template') { // Load PDF class require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_pdf.class.php'; $pdf_generator = new DeclarationTVA_PDF($db); if ($action == 'upload_template') { $uploaded_file = $_FILES['template_file']; if ($pdf_generator->uploadCustomTemplate($uploaded_file)) { setEventMessages($langs->trans("TemplateUploaded"), null, 'mesgs'); } else { setEventMessages($pdf_generator->error, null, 'errors'); } } if ($action == 'reset_template') { if ($pdf_generator->resetToDefaultTemplate()) { setEventMessages($langs->trans("TemplateReset"), null, 'mesgs'); } else { setEventMessages($langs->trans("TemplateResetFailed"), null, 'errors'); } } if ($action == 'update_template') { if ($pdf_generator->autoUpdateTemplate()) { setEventMessages($langs->trans("TemplateUpdated"), null, 'mesgs'); } else { setEventMessages($pdf_generator->error ?: $langs->trans("TemplateUpdateFailed"), null, 'errors'); } } } // Handle journal configuration updates if ($action == 'update_journal_config') { $journal_accounts = array( 'vat_to_pay' => GETPOST('journal_vat_to_pay', 'alpha'), 'vat_to_receive' => GETPOST('journal_vat_to_receive', 'alpha'), 'vat_refund' => GETPOST('journal_vat_refund', 'alpha'), 'other_charges' => GETPOST('journal_other_charges', 'alpha'), 'other_products' => GETPOST('journal_other_products', 'alpha') ); $updated = $config->updateJournalConfiguration($journal_accounts); if ($updated) { setEventMessages($langs->trans("JournalConfigurationUpdated"), null, 'mesgs'); } else { setEventMessages($langs->trans("JournalConfigurationUpdateFailed"), null, 'errors'); } } // Handle VAT refund threshold configuration updates if ($action == 'update_vat_refund_threshold') { $threshold_config = array( 'refund_threshold' => GETPOST('vat_refund_threshold', 'float'), 'refund_threshold_enabled' => GETPOST('vat_refund_threshold_enabled', 'int') ); // Debug: Log the received values error_log("VAT Refund Threshold Debug - Received values:"); error_log("refund_threshold: " . $threshold_config['refund_threshold']); error_log("refund_threshold_enabled: " . $threshold_config['refund_threshold_enabled']); $updated = $config->updateVATRefundThresholdConfiguration($threshold_config); if ($updated) { setEventMessages($langs->trans("VATRefundThresholdConfigurationUpdated"), null, 'mesgs'); } else { setEventMessages($langs->trans("VATRefundThresholdConfigurationUpdateFailed"), null, 'errors'); } } // Handle bank account configuration updates if ($action == 'update_bank_config') { $bank_account = GETPOST('journal_bank_account', 'int'); $updated = $config->updateBankAccountConfiguration($bank_account); if ($updated) { setEventMessages($langs->trans("BankAccountConfigurationUpdated"), null, 'mesgs'); } else { setEventMessages($langs->trans("BankAccountConfigurationUpdateFailed"), null, 'errors'); } } // Handle auto-create accounting entries configuration if ($action == 'update_auto_create_config') { $auto_create_accounting = GETPOST('auto_create_accounting', 'int'); $updated = $config->updateAutoCreateAccountingConfiguration($auto_create_accounting); if ($updated) { setEventMessages($langs->trans("AutoCreateAccountingConfigurationUpdated"), null, 'mesgs'); } else { setEventMessages($langs->trans("AutoCreateAccountingConfigurationUpdateFailed"), null, 'errors'); } } // Handle amount calculation configuration if ($action == 'update_amount_calc_config') { $calculation_method = GETPOST('amount_calculation_method', 'alpha'); $updated = $config->updateAmountCalculationConfiguration($calculation_method); if ($updated) { setEventMessages($langs->trans("AmountCalculationConfigurationUpdated"), null, 'mesgs'); } else { setEventMessages($langs->trans("AmountCalculationConfigurationUpdateFailed"), null, 'errors'); } } if ($action == 'update_mappings') { $ca3_definitions = $config->getCA3LineDefinitions(); $updated_count = 0; foreach ($ca3_definitions as $line => $definition) { // Special handling for lines 08, 09, 9B (need both base and VAT accounts) if (in_array($line, array('08', '09', '9B'))) { $base_account_codes = GETPOST('base_account_codes_' . $line, 'array'); $vat_account_codes = GETPOST('vat_account_codes_' . $line, 'array'); // Always process base accounts (even if empty) $result = $config->updateAccountMapping($line . '_BASE', $base_account_codes); if ($result) { $updated_count++; } // Always process VAT accounts (even if empty) $result = $config->updateAccountMapping($line . '_VAT', $vat_account_codes); if ($result) { $updated_count++; } } else { // Normal processing for other lines $account_codes = GETPOST('account_codes_' . $line, 'array'); // Always process account mappings (even if empty) $result = $config->updateAccountMapping($line, $account_codes); if ($result) { $updated_count++; } } } if ($updated_count > 0) { setEventMessages($langs->trans("ConfigurationUpdated"), null, 'mesgs'); } else { setEventMessages($langs->trans("NoChangesDetected"), null, 'warnings'); } } // Get current mappings $mappings_by_line = $config->getAccountMappingsByLine(); $accounts = $config->getAccountingAccounts(); $ca3_definitions = $config->getCA3LineDefinitions(); // 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) { // 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, `ca3_line` varchar(8) NOT NULL COMMENT 'A1, A2, A3, A4, A5, 08, 09, 9B, 17, 20, 21, 22, 25, 26, 28, 29', `account_code` varchar(32) NOT NULL COMMENT 'PCG account code', `account_label` varchar(255) DEFAULT NULL, `vat_rate` decimal(5,2) DEFAULT NULL, `is_active` tinyint(1) DEFAULT 1, `created_date` datetime DEFAULT NULL, PRIMARY KEY (`rowid`), UNIQUE KEY `uk_mapping_entity_line_account` (`entity`, `ca3_line`, `account_code`), KEY `idx_ca3_line` (`ca3_line`), KEY `idx_account_code` (`account_code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"; $db->query($create_table_sql); } $section_headers = $config->getCA3SectionHeaders(); // Page title $title = $langs->trans("DeclarationTVASetup"); llxHeader('', $title); // Print page header print load_fiche_titre($title, '', 'title_accountancy'); // Use Dolibarr's native tab system $head = array(); $head[0][0] = $_SERVER['PHP_SELF'] . '?tab=mapping'; $head[0][1] = $langs->trans("PCGMapping"); $head[0][2] = 'mapping'; $head[1][0] = $_SERVER['PHP_SELF'] . '?tab=templates'; $head[1][1] = $langs->trans("TemplateManagement"); $head[1][2] = 'templates'; $head[2][0] = $_SERVER['PHP_SELF'] . '?tab=journal'; $head[2][1] = $langs->trans("JournalConfiguration"); $head[2][2] = 'journal'; $tab = GETPOST('tab', 'alpha'); if (empty($tab)) { $tab = 'mapping'; } print dol_get_fiche_head($head, $tab, $langs->trans("DeclarationTVASetup"), -1, "declarationtva@declarationtva"); // Tab 1: PCG Mapping if ($tab == 'mapping') { print '
'; print ''; print ''; print '
'; // Group CA-3 lines by section $lines_by_section = array(); foreach ($ca3_definitions as $line => $definition) { $section = $definition['section']; if (!isset($lines_by_section[$section])) { $lines_by_section[$section] = array(); } $lines_by_section[$section][$line] = $definition; } // Print each section foreach ($lines_by_section as $section_code => $lines) { $section_info = $section_headers[$section_code]; // Section header print '
' . $section_info['title'] . '
'; if (!empty($section_info['description'])) { print '
' . $section_info['description'] . '
'; } if (isset($section_info['notice']) && !empty($section_info['notice'])) { print '
Référence: ' . $section_info['notice'] . '
'; } // Skip D-section lines (25, 26, 28, 29) as they are calculated if ($section_code == 'D') { continue; } print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; foreach ($lines as $line => $definition) { print ''; print ''; print ''; print ''; print ''; print ''; print ''; } print '
' . $langs->trans("CA3Line") . '' . $langs->trans("LineLabel") . '' . $langs->trans("Description") . '' . $langs->trans("PCGAccounts") . '' . $langs->trans("AccountSelection") . '
' . $line . '' . $definition['label'] . '' . $definition['description'] . '' . $definition['pcg_accounts'] . ''; // Create account options array for Dolibarr multi-select $account_options = array(); foreach ($accounts as $account) { $account_options[$account['account_number']] = $account['account_number'] . ' - ' . $account['label']; } // Special handling for lines 08, 09, 9B (need both base and VAT accounts) if (in_array($line, array('08', '09', '9B'))) { // Load separate mappings for base and VAT $base_selected_accounts = isset($mappings_by_line[$line . '_BASE']) ? $mappings_by_line[$line . '_BASE'] : array(); $vat_selected_accounts = isset($mappings_by_line[$line . '_VAT']) ? $mappings_by_line[$line . '_VAT'] : array(); print '
'; print 'Comptes de base (ventes):
'; print $form->multiselectarray('base_account_codes_' . $line, $account_options, $base_selected_accounts, 0, 0, '', 0, '200px'); print '
'; print '
'; print 'Comptes de TVA:
'; print $form->multiselectarray('vat_account_codes_' . $line, $account_options, $vat_selected_accounts, 0, 0, '', 0, '200px'); print '
'; } else { // Normal single selection for other lines $selected_accounts = isset($mappings_by_line[$line]) ? $mappings_by_line[$line] : array(); print $form->multiselectarray('account_codes_' . $line, $account_options, $selected_accounts, 0, 0, '', 0, '200px'); } print '
'; print '
'; } print ''; print '
'; print '
'; } elseif ($tab == 'templates') { // Tab 2: Template Management print '
'; print '
'; // Load PDF class require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_pdf.class.php'; $pdf_generator = new DeclarationTVA_PDF($db); // Get template information $template_info = $pdf_generator->getTemplateInfo(); // Get update status $update_status = $pdf_generator->getTemplateUpdateStatus(); print '
'; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; // Update status if ($update_status['update_available']) { print ''; print ''; print ''; print ''; } else { print ''; print ''; print ''; print ''; } if (!empty($update_status['error'])) { print ''; print ''; print ''; print ''; } print ''; print ''; print ''; print ''; print ''; print ''; print ''; if ($template_info['custom_template']) { print ''; print ''; print ''; } print '
Gestion des modèles PDF CA-3
Modèle actuel'; if ($template_info['custom_template']) { print 'Modèle personnalisé'; } else { print 'Modèle officiel'; } print '
Version actuelle' . $template_info['official_number'] . '
Mise à jour disponible'; print 'Version ' . $update_status['latest_version'] . ' disponible'; print ' Mettre à jour'; print '
StatutÀ jour
Erreur' . $update_status['error'] . '
Nouveau modèle'; print ''; print '
Format PDF uniquement, taille max 10MB'; print '
'; print ''; print '
'; print 'Revenir au modèle officiel'; print '
'; print '
'; print '
'; print '
'; print ''; // Close fichehalfleft print ''; // Close fichecenter } elseif ($tab == 'journal') { // Tab 3: Journal Configuration print '
'; // Get current journal configuration $journal_config = $config->getJournalConfiguration(); // Get current auto-create configuration $auto_create_config = $config->getAutoCreateAccountingConfiguration(); // Get current amount calculation configuration $amount_calc_config = $config->getAmountCalculationConfiguration(); // First section: Amount Calculation Method print '
'; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print '
' . $langs->trans("AmountCalculationConfiguration") . '
' . $langs->trans("AmountCalculationMethod") . ''; print '' . $langs->trans("AmountCalculationMethodDescription") . '
'; $calculation_options = array( 'round' => $langs->trans("RoundAmounts"), 'truncate' => $langs->trans("TruncateAmounts") ); print $form->selectarray('amount_calculation_method', $calculation_options, $amount_calc_config['amount_calculation_method'], 0, 0, 0, '', 0, 0, 0, '', 'minwidth200'); print '
'; print ''; print '
'; print '
'; // Second section: Auto-create accounting entries print '
'; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print '
' . $langs->trans("AutoCreateAccountingConfiguration") . '
' . $langs->trans("AutoCreateAccountingEntries") . ''; print '' . $langs->trans("AutoCreateAccountingEntriesDescription") . '
'; print ''; print ' ' . $langs->trans("EnableAutoCreateAccounting"); print '
'; print ''; print '
'; print '
'; // Second section: Journal Account Configuration print '
'; print '
'; print ''; print ''; print ''; print ''; print ''; print ''; // Create account options array exactly like in the mapping section $account_options = array(); foreach ($accounts as $account) { $account_options[$account['account_number']] = $account['account_number'] . ' - ' . $account['label']; } print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print '
' . $langs->trans("JournalAccountConfiguration") . '
' . $langs->trans("VATToPayAccount") . ''; print '' . $langs->trans("VATToPayAccountDescription") . '
'; print $form->selectarray('journal_vat_to_pay', $account_options, $journal_config['vat_to_pay'], 0, 0, 0, '', 0, 0, 0, '', 'minwidth200'); print '
' . $langs->trans("VATToReceiveAccount") . ''; print '' . $langs->trans("VATToReceiveAccountDescription") . '
'; print $form->selectarray('journal_vat_to_receive', $account_options, $journal_config['vat_to_receive'], 0, 0, 0, '', 0, 0, 0, '', 'minwidth200'); print '
' . $langs->trans("VATRefundAccount") . ''; print '' . $langs->trans("VATRefundAccountDescription") . '
'; print $form->selectarray('journal_vat_refund', $account_options, $journal_config['vat_refund'], 0, 0, 0, '', 0, 0, 0, '', 'minwidth200'); print '
' . $langs->trans("OtherChargesAccount") . ''; print '' . $langs->trans("OtherChargesAccountDescription") . '
'; print $form->selectarray('journal_other_charges', $account_options, $journal_config['other_charges'], 0, 0, 0, '', 0, 0, 0, '', 'minwidth200'); print '
' . $langs->trans("OtherProductsAccount") . ''; print '' . $langs->trans("OtherProductsAccountDescription") . '
'; print $form->selectarray('journal_other_products', $account_options, $journal_config['other_products'], 0, 0, 0, '', 0, 0, 0, '', 'minwidth200'); print '
'; print ''; print '
'; print '
'; // Second section: Bank Account Configuration print '
'; print '
'; print ''; print ''; print ''; print ''; print ''; print ''; // Get current bank account configuration $bank_config = $config->getBankAccountConfiguration(); print ''; print ''; print ''; print ''; print ''; print ''; print ''; print '
' . $langs->trans("BankAccountConfiguration") . '
' . $langs->trans("VATPaymentBankAccount") . ''; print '' . $langs->trans("VATPaymentBankAccountDescription") . '
'; // Get bank accounts for selection $bank_accounts = $config->getBankAccounts(); $bank_options = array(); foreach ($bank_accounts as $bank) { $bank_options[$bank['rowid']] = $bank['label'] . ' (' . $bank['number'] . ')'; } if (empty($bank_options)) { print '' . $langs->trans("NoBankAccountsFound") . ''; } else { print $form->selectarray('journal_bank_account', $bank_options, $bank_config['bank_account'], 0, 0, 0, '', 0, 0, 0, '', 'minwidth200'); } print '
'; print ''; print '
'; print '
'; // VAT Refund Threshold Configuration Section print '
'; print '
'; print ''; print ''; print ''; print ''; print ''; print ''; // Get current threshold configuration $threshold_config = $config->getVATRefundThresholdConfiguration(); print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print '
' . $langs->trans("VATRefundThresholdConfiguration") . '
' . $langs->trans("VATRefundThreshold") . ''; print '' . $langs->trans("VATRefundThresholdHelp") . '
'; print ''; print '
' . $langs->trans("VATRefundThresholdEnabled") . ''; print '' . $langs->trans("VATRefundThresholdEnabledHelp") . '
'; print $form->selectyesno('vat_refund_threshold_enabled', $threshold_config['refund_threshold_enabled'], 1); print '
'; print ''; print '
'; print '
'; print '
'; } // Print footer llxFooter(); ?>