dolibarr.bankimport/admin/setup.php
data 5264a2e91e Add link to repair page in admin setup
- Admin Tools section in setup page with link to repair.php
- Translations for AdminTools and Open (DE/EN)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-20 12:06:13 +01:00

640 lines
20 KiB
PHP
Executable file

<?php
/* Copyright (C) 2004-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file bankimport/admin/setup.php
* \ingroup bankimport
* \brief BankImport setup page for FinTS configuration.
*/
// Load Dolibarr environment
$res = 0;
if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
$res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
}
$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME'];
$tmp2 = realpath(__FILE__);
$i = strlen($tmp) - 1;
$j = strlen($tmp2) - 1;
while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
$i--;
$j--;
}
if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
$res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
}
if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
$res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
}
if (!$res && file_exists("../../main.inc.php")) {
$res = @include "../../main.inc.php";
}
if (!$res && file_exists("../../../main.inc.php")) {
$res = @include "../../../main.inc.php";
}
if (!$res) {
die("Include of main fails");
}
// Libraries
require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
require_once DOL_DOCUMENT_ROOT."/core/lib/security.lib.php";
require_once '../lib/bankimport.lib.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Translations
$langs->loadLangs(array("admin", "bankimport@bankimport"));
// Initialize hooks
$hookmanager->initHooks(array('bankimportsetup', 'globalsetup'));
// Parameters
$action = GETPOST('action', 'aZ09');
$backtopage = GETPOST('backtopage', 'alpha');
$error = 0;
// Access control
if (!$user->admin) {
accessforbidden();
}
/*
* Actions
*/
// Select IBAN from account list
if ($action == 'selectiban') {
$newIban = GETPOST('iban', 'alpha');
if (!empty($newIban)) {
$res = dolibarr_set_const($db, "BANKIMPORT_FINTS_IBAN", $newIban, 'chaine', 0, '', $conf->entity);
if ($res > 0) {
setEventMessages($langs->trans("IBANUpdated", $newIban), null, 'mesgs');
// Refresh page to show updated value
header("Location: ".$_SERVER["PHP_SELF"]);
exit;
} else {
setEventMessages($langs->trans("Error"), null, 'errors');
}
}
}
if ($action == 'update') {
$db->begin();
// FinTS Server URL
$res = dolibarr_set_const(
$db,
"BANKIMPORT_FINTS_URL",
GETPOST('BANKIMPORT_FINTS_URL', 'alpha'),
'chaine',
0,
'',
$conf->entity
);
if (!($res > 0)) {
$error++;
}
// BLZ (Bankleitzahl)
$res = dolibarr_set_const(
$db,
"BANKIMPORT_FINTS_BLZ",
GETPOST('BANKIMPORT_FINTS_BLZ', 'alpha'),
'chaine',
0,
'',
$conf->entity
);
if (!($res > 0)) {
$error++;
}
// Benutzerkennung
$res = dolibarr_set_const(
$db,
"BANKIMPORT_FINTS_USERNAME",
GETPOST('BANKIMPORT_FINTS_USERNAME', 'alpha'),
'chaine',
0,
'',
$conf->entity
);
if (!($res > 0)) {
$error++;
}
// PIN (verschlüsselt speichern)
$pin = GETPOST('BANKIMPORT_FINTS_PIN', 'none');
if (!empty($pin)) {
$encryptedPin = dolEncrypt($pin);
$res = dolibarr_set_const(
$db,
"BANKIMPORT_FINTS_PIN",
$encryptedPin,
'chaine',
0,
'',
$conf->entity
);
if (!($res > 0)) {
$error++;
}
}
// Kontonummer/IBAN
$res = dolibarr_set_const(
$db,
"BANKIMPORT_FINTS_IBAN",
GETPOST('BANKIMPORT_FINTS_IBAN', 'alpha'),
'chaine',
0,
'',
$conf->entity
);
if (!($res > 0)) {
$error++;
}
// FinTS Registrierungsnummer
$res = dolibarr_set_const(
$db,
"BANKIMPORT_FINTS_PRODUCT_ID",
GETPOST('BANKIMPORT_FINTS_PRODUCT_ID', 'alpha'),
'chaine',
0,
'',
$conf->entity
);
if (!($res > 0)) {
$error++;
}
// PDF Upload mode default
$res = dolibarr_set_const($db, "BANKIMPORT_UPLOAD_MODE", GETPOST('BANKIMPORT_UPLOAD_MODE', 'alpha'), 'chaine', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
// Dolibarr Bank Account mapping
$res = dolibarr_set_const($db, "BANKIMPORT_BANK_ACCOUNT_ID", GETPOSTINT('BANKIMPORT_BANK_ACCOUNT_ID'), 'chaine', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
// Reminder setting
$res = dolibarr_set_const($db, "BANKIMPORT_REMINDER_ENABLED", GETPOSTINT('BANKIMPORT_REMINDER_ENABLED'), 'chaine', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
$res = dolibarr_set_const($db, "BANKIMPORT_REMINDER_MONTHS", GETPOSTINT('BANKIMPORT_REMINDER_MONTHS'), 'chaine', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
// Automatic import settings
$res = dolibarr_set_const($db, "BANKIMPORT_AUTO_ENABLED", GETPOSTINT('BANKIMPORT_AUTO_ENABLED'), 'chaine', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
$res = dolibarr_set_const($db, "BANKIMPORT_AUTO_FREQUENCY", GETPOST('BANKIMPORT_AUTO_FREQUENCY', 'alpha'), 'chaine', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
$res = dolibarr_set_const($db, "BANKIMPORT_AUTO_DAYS", GETPOSTINT('BANKIMPORT_AUTO_DAYS'), 'chaine', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
if (!$error) {
$db->commit();
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else {
$db->rollback();
setEventMessages($langs->trans("Error"), null, 'errors');
}
}
// Test connection action
if ($action == 'testconnection') {
dol_include_once('/bankimport/class/fints.class.php');
if (class_exists('BankImportFinTS')) {
$fints = new BankImportFinTS($db);
$result = $fints->testConnection();
if ($result > 0) {
setEventMessages($langs->trans("ConnectionTestSuccessful"), null, 'mesgs');
} else {
setEventMessages($langs->trans("ConnectionTestFailed").': '.$fints->error, null, 'errors');
}
} else {
setEventMessages($langs->trans("FinTSClassNotFound"), null, 'warnings');
}
}
// Fetch accounts action
$availableAccounts = array();
if ($action == 'fetchaccounts') {
dol_include_once('/bankimport/class/fints.class.php');
if (class_exists('BankImportFinTS')) {
$fints = new BankImportFinTS($db);
// Login
$loginResult = $fints->login();
if ($loginResult < 0) {
setEventMessages($langs->trans("LoginFailed").': '.$fints->error, null, 'errors');
} elseif ($loginResult == 0) {
// TAN required - not supported in setup
setEventMessages($langs->trans("TANRequiredForAccountList"), null, 'warnings');
} else {
// Fetch accounts
$accounts = $fints->getAccounts();
if (is_array($accounts) && !empty($accounts)) {
$availableAccounts = $accounts;
setEventMessages($langs->trans("AccountsFound", count($accounts)), null, 'mesgs');
} elseif ($accounts === 0) {
setEventMessages($langs->trans("TANRequiredForAccountList"), null, 'warnings');
} else {
setEventMessages($langs->trans("NoAccountsFound").': '.$fints->error, null, 'errors');
}
$fints->close();
}
} else {
setEventMessages($langs->trans("FinTSClassNotFound"), null, 'warnings');
}
}
/*
* View
*/
$form = new Form($db);
$help_url = '';
$title = "BankImportSetup";
llxHeader('', $langs->trans($title), $help_url, '', 0, 0, '', '', '', 'mod-bankimport page-admin');
// Subheader
$linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1').'">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans($title), $linkback, 'title_setup');
// Configuration header
$head = bankimportAdminPrepareHead();
print dol_get_fiche_head($head, 'settings', $langs->trans($title), -1, "bankimport@bankimport");
// Setup page description
print '<span class="opacitymedium">'.$langs->trans("BankImportSetupDescription").'</span><br><br>';
// Load current values
$fintsUrl = getDolGlobalString('BANKIMPORT_FINTS_URL');
$fintsBLZ = getDolGlobalString('BANKIMPORT_FINTS_BLZ');
$fintsUsername = getDolGlobalString('BANKIMPORT_FINTS_USERNAME');
$fintsPin = getDolGlobalString('BANKIMPORT_FINTS_PIN');
$fintsIBAN = getDolGlobalString('BANKIMPORT_FINTS_IBAN');
$fintsProductId = getDolGlobalString('BANKIMPORT_FINTS_PRODUCT_ID');
// Check if PIN is set
$pinIsSet = !empty($fintsPin);
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update">';
print '<table class="noborder centpercent">';
// FinTS Section Header
print '<tr class="liste_titre">';
print '<td colspan="2">'.$langs->trans("FinTSConfiguration").'</td>';
print '</tr>';
// FinTS Server URL
print '<tr class="oddeven">';
print '<td class="titlefield fieldrequired">'.$langs->trans("FinTSServerURL").'</td>';
print '<td>';
print '<input type="text" class="flat minwidth500" name="BANKIMPORT_FINTS_URL" value="'.dol_escape_htmltag($fintsUrl).'" placeholder="https://fints1.atruvia.de/cgi-bin/hbciservlet">';
print '<br><span class="opacitymedium small">'.$langs->trans("FinTSServerURLHelp").'</span>';
print '</td>';
print '</tr>';
// BLZ (Bankleitzahl)
print '<tr class="oddeven">';
print '<td class="fieldrequired">'.$langs->trans("BLZ").'</td>';
print '<td>';
print '<input type="text" class="flat minwidth200" name="BANKIMPORT_FINTS_BLZ" value="'.dol_escape_htmltag($fintsBLZ).'" placeholder="12345678" maxlength="8">';
print ' <span class="opacitymedium">'.$langs->trans("BLZHelp").'</span>';
print '</td>';
print '</tr>';
// Benutzerkennung
print '<tr class="oddeven">';
print '<td class="fieldrequired">'.$langs->trans("FinTSUsername").'</td>';
print '<td>';
print '<input type="text" class="flat minwidth300" name="BANKIMPORT_FINTS_USERNAME" value="'.dol_escape_htmltag($fintsUsername).'" placeholder="VR-NetKey / Alias">';
print '</td>';
print '</tr>';
// PIN (verschlüsselt)
print '<tr class="oddeven">';
print '<td class="fieldrequired">'.$langs->trans("FinTSPIN").'</td>';
print '<td>';
print '<input type="password" class="flat minwidth200" name="BANKIMPORT_FINTS_PIN" value="" placeholder="'.($pinIsSet ? '********' : '').'" autocomplete="new-password">';
if ($pinIsSet) {
print ' <span class="opacitymedium">'.img_picto('', 'tick', 'class="paddingleft"').' '.$langs->trans("PINAlreadySet").'</span>';
}
print '<br><span class="opacitymedium small">'.$langs->trans("PINHelp").'</span>';
print '</td>';
print '</tr>';
// Kontonummer/IBAN
print '<tr class="oddeven">';
print '<td class="fieldrequired">'.$langs->trans("AccountIBAN").'</td>';
print '<td>';
print '<input type="text" class="flat minwidth400" name="BANKIMPORT_FINTS_IBAN" value="'.dol_escape_htmltag($fintsIBAN).'" placeholder="DE89370400440532013000">';
print '</td>';
print '</tr>';
// FinTS Product ID (optional)
print '<tr class="oddeven">';
print '<td>'.$langs->trans("FinTSProductID").'</td>';
print '<td>';
print '<input type="text" class="flat minwidth300" name="BANKIMPORT_FINTS_PRODUCT_ID" value="'.dol_escape_htmltag($fintsProductId).'">';
print '<br><span class="opacitymedium small">'.$langs->trans("FinTSProductIDHelp").'</span>';
print '</td>';
print '</tr>';
print '</table>';
// PDF Upload Section
print '<br>';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td colspan="2">'.$langs->trans("PDFUploadSettings").'</td>';
print '</tr>';
// Default upload mode
$defaultUploadMode = getDolGlobalString('BANKIMPORT_UPLOAD_MODE') ?: 'auto';
print '<tr class="oddeven">';
print '<td class="titlefield">'.$langs->trans("DefaultUploadMode").'</td>';
print '<td>';
$uploadModes = array(
'auto' => $langs->trans("UploadModeAuto"),
'manual' => $langs->trans("UploadModeManual"),
);
print $form->selectarray('BANKIMPORT_UPLOAD_MODE', $uploadModes, $defaultUploadMode, 0, 0, 0, '', 0, 0, 0, '', 'minwidth200');
print ' <span class="opacitymedium small">'.$langs->trans("DefaultUploadModeHelp").'</span>';
print '</td>';
print '</tr>';
// Reminder when no statement uploaded
$reminderEnabled = getDolGlobalString('BANKIMPORT_REMINDER_ENABLED', '1');
print '<tr class="oddeven">';
print '<td class="titlefield">'.$langs->trans("ReminderEnabled").'</td>';
print '<td>';
print '<input type="checkbox" name="BANKIMPORT_REMINDER_ENABLED" value="1"'.($reminderEnabled ? ' checked' : '').'>';
print ' <span class="opacitymedium small">'.$langs->trans("ReminderEnabledHelp").'</span>';
print '</td>';
print '</tr>';
// Reminder months threshold
$reminderMonths = getDolGlobalInt('BANKIMPORT_REMINDER_MONTHS') ?: 3;
print '<tr class="oddeven">';
print '<td class="titlefield">'.$langs->trans("ReminderMonths").'</td>';
print '<td>';
$monthOptions = array(1 => '1', 2 => '2', 3 => '3', 4 => '4', 5 => '5', 6 => '6');
print $form->selectarray('BANKIMPORT_REMINDER_MONTHS', $monthOptions, $reminderMonths, 0, 0, 0, '', 0, 0, 0, '', 'minwidth75');
print ' <span class="opacitymedium small">'.$langs->trans("ReminderMonthsHelp").'</span>';
print '</td>';
print '</tr>';
print '</table>';
// Bank Account Mapping Section
print '<br>';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td colspan="2">'.$langs->trans("BankAccountMapping").'</td>';
print '</tr>';
// Bank Account Dropdown
$bankAccountId = getDolGlobalInt('BANKIMPORT_BANK_ACCOUNT_ID');
print '<tr class="oddeven">';
print '<td class="titlefield fieldrequired">'.$langs->trans("DolibarrBankAccount").'</td>';
print '<td>';
// Build select from llx_bank_account
$sql_ba = "SELECT rowid, label, iban_prefix FROM ".MAIN_DB_PREFIX."bank_account";
$sql_ba .= " WHERE entity = ".((int) $conf->entity);
$sql_ba .= " AND clos = 0";
$sql_ba .= " ORDER BY label ASC";
$bankAccounts = array('' => $langs->trans("SelectBankAccount"));
$resql_ba = $db->query($sql_ba);
if ($resql_ba) {
while ($obj_ba = $db->fetch_object($resql_ba)) {
$ibanDisplay = $obj_ba->iban_prefix ? ' ('.dol_trunc($obj_ba->iban_prefix, 20).')' : '';
$bankAccounts[$obj_ba->rowid] = $obj_ba->label.$ibanDisplay;
}
}
print $form->selectarray('BANKIMPORT_BANK_ACCOUNT_ID', $bankAccounts, $bankAccountId, 0, 0, 0, '', 0, 0, 0, '', 'minwidth300');
print '<br><span class="opacitymedium small">'.$langs->trans("DolibarrBankAccountHelp").'</span>';
print '</td>';
print '</tr>';
print '</table>';
// Automatic Import Section
print '<br>';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td colspan="2">'.$langs->trans("AutomaticImport").'</td>';
print '</tr>';
// Enable automatic import
$autoImportEnabled = getDolGlobalInt('BANKIMPORT_AUTO_ENABLED');
print '<tr class="oddeven">';
print '<td class="titlefield">'.$langs->trans("EnableAutoImport").'</td>';
print '<td>';
print $form->selectyesno('BANKIMPORT_AUTO_ENABLED', $autoImportEnabled, 1);
print ' <span class="opacitymedium small">'.$langs->trans("EnableAutoImportHelp").'</span>';
print '</td>';
print '</tr>';
// Import frequency
$autoFrequency = getDolGlobalString('BANKIMPORT_AUTO_FREQUENCY') ?: 'daily';
print '<tr class="oddeven">';
print '<td>'.$langs->trans("ImportFrequency").'</td>';
print '<td>';
$frequencies = array(
'daily' => $langs->trans("Daily"),
'weekly' => $langs->trans("Weekly"),
'twice_weekly' => $langs->trans("TwiceWeekly")
);
print $form->selectarray('BANKIMPORT_AUTO_FREQUENCY', $frequencies, $autoFrequency, 0, 0, 0, '', 0, 0, 0, '', 'minwidth150');
print '</td>';
print '</tr>';
// Days to fetch
$autoDays = getDolGlobalInt('BANKIMPORT_AUTO_DAYS') ?: 30;
print '<tr class="oddeven">';
print '<td>'.$langs->trans("DaysToFetch").'</td>';
print '<td>';
print '<input type="number" class="flat width75" name="BANKIMPORT_AUTO_DAYS" value="'.$autoDays.'" min="1" max="60">';
print ' <span class="opacitymedium">'.$langs->trans("DaysToFetchHelp").'</span>';
print '</td>';
print '</tr>';
// Last fetch info
$lastFetch = getDolGlobalInt('BANKIMPORT_LAST_FETCH');
$lastFetchCount = getDolGlobalInt('BANKIMPORT_LAST_FETCH_COUNT');
print '<tr class="oddeven">';
print '<td>'.$langs->trans("LastAutoFetch").'</td>';
print '<td>';
if ($lastFetch > 0) {
print dol_print_date($lastFetch, 'dayhour');
if ($lastFetchCount > 0) {
print ' <span class="badge badge-info">'.$lastFetchCount.' '.$langs->trans("Transactions").'</span>';
}
// Warning if more than 7 days since last fetch
if ((time() - $lastFetch) > 7 * 86400) {
print ' <span class="badge badge-warning">'.$langs->trans("MoreThan7Days").'</span>';
}
} else {
print '<span class="opacitymedium">'.$langs->trans("NeverFetched").'</span>';
}
print '</td>';
print '</tr>';
print '</table>';
print '<br>';
// Buttons
print '<div class="center">';
print '<input type="submit" class="button button-save" value="'.$langs->trans("Save").'">';
print '</div>';
print '</form>';
print '<br>';
// Test Connection Button
print '<div class="center">';
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'" style="display: inline-block; margin-right: 10px;">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="testconnection">';
print '<input type="submit" class="button" value="'.$langs->trans("TestConnection").'">';
print '</form>';
// Fetch Accounts Button
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'" style="display: inline-block;">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="fetchaccounts">';
print '<input type="submit" class="button" value="'.$langs->trans("FetchAvailableAccounts").'">';
print '</form>';
print '</div>';
// Display available accounts if fetched
if (!empty($availableAccounts)) {
print '<br><br>';
print '<div class="div-table-responsive">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>'.$langs->trans("IBAN").'</th>';
print '<th>'.$langs->trans("BIC").'</th>';
print '<th>'.$langs->trans("AccountNumber").'</th>';
print '<th>'.$langs->trans("BLZ").'</th>';
print '<th>'.$langs->trans("Action").'</th>';
print '</tr>';
foreach ($availableAccounts as $acc) {
$isSelected = ($acc['iban'] === $fintsIBAN);
print '<tr class="oddeven'.($isSelected ? ' highlight' : '').'">';
print '<td><strong>'.dol_escape_htmltag($acc['iban']).'</strong></td>';
print '<td>'.dol_escape_htmltag($acc['bic']).'</td>';
print '<td>'.dol_escape_htmltag($acc['accountNumber']).'</td>';
print '<td>'.dol_escape_htmltag($acc['blz']).'</td>';
print '<td>';
if ($isSelected) {
print '<span class="badge badge-status4">'.$langs->trans("Selected").'</span>';
} else {
print '<a class="button buttongen" href="'.$_SERVER["PHP_SELF"].'?action=selectiban&iban='.urlencode($acc['iban']).'&token='.newToken().'">'.$langs->trans("UseThisAccount").'</a>';
}
print '</td>';
print '</tr>';
}
print '</table>';
print '</div>';
}
// Info Box - VR Bank specific
print '<br>';
print '<div class="info">';
print '<strong>'.$langs->trans("VRBankInfo").'</strong><br>';
print $langs->trans("VRBankInfoText");
print '</div>';
// Security Info Box
print '<br>';
print '<div class="warning">';
print '<strong>'.$langs->trans("SecurityInfo").'</strong><br>';
print $langs->trans("SecurityInfoText");
print '</div>';
// Admin Tools Section
print '<br>';
print load_fiche_titre($langs->trans("AdminTools"), '', 'tools');
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>'.$langs->trans("Tool").'</th>';
print '<th>'.$langs->trans("Description").'</th>';
print '<th></th>';
print '</tr>';
print '<tr class="oddeven">';
print '<td>'.$langs->trans("RepairOrphanedTransactions").'</td>';
print '<td class="opacitymedium">'.$langs->trans("RepairOrphanedTransactionsDesc").'</td>';
print '<td class="right"><a class="butAction" href="'.dol_buildpath('/bankimport/repair.php', 1).'">'.$langs->trans("Open").'</a></td>';
print '</tr>';
print '</table>';
print '</div>';
// Page end
print dol_get_fiche_end();
llxFooter();
$db->close();