DeclarationTVA/admin/setup_mvp.php
Frank Cools 2aebb1ca67 Integrate database migration into module activation
Module Activation Integration:
- Added automatic migration to module init() method
- Migration runs when module is activated/reactivated
- Checks if table exists and migration is needed
- Safe migration with proper error handling

Migration Features:
- Drops old unique constraint (entity, ca3_line)
- Adds new constraint (entity, ca3_line, account_code)
- Allows multiple accounts per CA-3 line
- Adds performance index on account_code
- Updates table comments for new CA-3 structure

Debug Improvements:
- Simplified debug output in setup page
- Shows if table structure is correct
- Indicates if migration is needed
- Clear instructions for user

No manual database access needed - migration runs automatically!
2025-10-02 17:32:59 +02:00

226 lines
8.1 KiB
PHP

<?php
/**
* MVP Setup page for DeclarationTVA module
* Advanced multi-select PCG account mapping using Dolibarr native style
*/
// Load Dolibarr environment
if (file_exists('../../main.inc.php')) {
$res = @include '../../main.inc.php';
} elseif (file_exists('../../../main.inc.php')) {
$res = @include '../../../main.inc.php';
} else {
$res = 0;
}
if (!$res) {
die("Include of main fails");
}
// Libraries
require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
require_once DOL_DOCUMENT_ROOT . '/custom/declarationtva/core/class/declarationtva_config.class.php';
// Access control
if (!$user->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');
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);
if ($result) {
$updated_count++;
}
}
// 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 {
setEventMessages($langs->trans("NoChangesDetected"), null, 'warnings');
}
}
// Get current mappings
$mappings_by_line = $config->getAccountMappingsByLine();
$accounts = $config->getAccountingAccounts();
$ca3_definitions = $config->getCA3LineDefinitions();
// Debug: Check if table exists and show structure (simplified)
$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 - please activate the module first", null, 'errors');
}
$section_headers = $config->getCA3SectionHeaders();
// Page title
$title = $langs->trans("DeclarationTVASetup");
llxHeader('', $title);
// Print page header
print load_fiche_titre($title, '', 'title_accountancy');
// Print notice information
print '<div class="info">';
print '<strong>Notice 4722 - Summary Table CA3 (3310-CA3-SD)</strong><br>';
print 'Configuration basée sur la structure officielle la plus récente du formulaire CA-3.';
print '</div><br>';
// Print configuration form
print '<form method="POST" action="' . $_SERVER['PHP_SELF'] . '">';
print '<input type="hidden" name="action" value="update_mappings">';
print '<input type="hidden" name="token" value="' . newToken() . '">';
print '<div class="fiche">';
print '<div class="titre">' . $langs->trans("DeclarationTVAPCGMapping") . '</div>';
// 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 '<div class="titre">' . $section_info['title'] . '</div>';
print '<div class="info">' . $section_info['description'] . '</div>';
if (isset($section_info['notice'])) {
print '<div class="info"><strong>Référence:</strong> ' . $section_info['notice'] . '</div>';
}
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>' . $langs->trans("CA3Line") . '</th>';
print '<th>' . $langs->trans("LineLabel") . '</th>';
print '<th>' . $langs->trans("Description") . '</th>';
print '<th>' . $langs->trans("PCGAccounts") . '</th>';
print '<th>' . $langs->trans("AccountSelection") . '</th>';
print '</tr>';
foreach ($lines as $line => $definition) {
$selected_accounts = isset($mappings_by_line[$line]) ? $mappings_by_line[$line] : array();
print '<tr>';
print '<td><strong>' . $line . '</strong></td>';
print '<td>' . $definition['label'] . '</td>';
print '<td><small>' . $definition['description'] . '</small></td>';
print '<td><small>' . $definition['pcg_accounts'] . '</small></td>';
print '<td>';
// 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'];
}
// Use Dolibarr's native multi-select with search functionality
print $form->multiselectarray('account_codes_' . $line, $account_options, $selected_accounts, 0, 0, '', 0, '200px');
// Add helper text
print '<br><small>' . $langs->trans("MultiSelectHelp") . '</small>';
print '</td>';
print '</tr>';
}
print '</table>';
print '<br>';
}
print '<div class="titre">' . $langs->trans("Actions") . '</div>';
print '<input type="submit" class="button" value="' . $langs->trans("UpdateConfiguration") . '">';
print '</div>';
print '</form>';
// Print current configuration summary
print '<div class="fiche">';
print '<div class="titre">' . $langs->trans("CurrentConfiguration") . '</div>';
if (empty($mappings_by_line)) {
print '<div class="info">' . $langs->trans("NoConfigurationFound") . '</div>';
} else {
// Group by section for display
$mappings_by_section = array();
foreach ($mappings_by_line as $line => $account_codes) {
if (isset($ca3_definitions[$line])) {
$section = $ca3_definitions[$line]['section'];
if (!isset($mappings_by_section[$section])) {
$mappings_by_section[$section] = array();
}
$mappings_by_section[$section][$line] = $account_codes;
}
}
foreach ($mappings_by_section as $section_code => $section_mappings) {
$section_info = $section_headers[$section_code];
print '<div class="titre">' . $section_info['title'] . '</div>';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>' . $langs->trans("CA3Line") . '</th>';
print '<th>' . $langs->trans("SelectedAccounts") . '</th>';
print '<th>' . $langs->trans("AccountCount") . '</th>';
print '</tr>';
foreach ($section_mappings as $line => $account_codes) {
print '<tr>';
print '<td><strong>' . $line . '</strong></td>';
print '<td>' . implode(', ', $account_codes) . '</td>';
print '<td>' . count($account_codes) . '</td>';
print '</tr>';
}
print '</table>';
print '<br>';
}
}
print '</div>';
// Print footer
llxFooter();
?>
?>