* Copyright (C) 2024 Frédéric France * Copyright (C) 2026 Eduard Wisch * * 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 . */ /** * \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 = ''.$langs->trans("BackToModuleList").''; 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 ''.$langs->trans("BankImportSetupDescription").'

'; // 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 '
'; print ''; print ''; print ''; // FinTS Section Header print ''; print ''; print ''; // FinTS Server URL print ''; print ''; print ''; print ''; // BLZ (Bankleitzahl) print ''; print ''; print ''; print ''; // Benutzerkennung print ''; print ''; print ''; print ''; // PIN (verschlüsselt) print ''; print ''; print ''; print ''; // Kontonummer/IBAN print ''; print ''; print ''; print ''; // FinTS Product ID (optional) print ''; print ''; print ''; print ''; print '
'.$langs->trans("FinTSConfiguration").'
'.$langs->trans("FinTSServerURL").''; print ''; print '
'.$langs->trans("FinTSServerURLHelp").''; print '
'.$langs->trans("BLZ").''; print ''; print ' '.$langs->trans("BLZHelp").''; print '
'.$langs->trans("FinTSUsername").''; print ''; print '
'.$langs->trans("FinTSPIN").''; print ''; if ($pinIsSet) { print ' '.img_picto('', 'tick', 'class="paddingleft"').' '.$langs->trans("PINAlreadySet").''; } print '
'.$langs->trans("PINHelp").''; print '
'.$langs->trans("AccountIBAN").''; print ''; print '
'.$langs->trans("FinTSProductID").''; print ''; print '
'.$langs->trans("FinTSProductIDHelp").''; print '
'; // PDF Upload Section print '
'; print ''; print ''; print ''; print ''; // Default upload mode $defaultUploadMode = getDolGlobalString('BANKIMPORT_UPLOAD_MODE') ?: 'auto'; print ''; print ''; print ''; print ''; // Reminder when no statement uploaded $reminderEnabled = getDolGlobalString('BANKIMPORT_REMINDER_ENABLED', '1'); print ''; print ''; print ''; print ''; // Reminder months threshold $reminderMonths = getDolGlobalInt('BANKIMPORT_REMINDER_MONTHS') ?: 3; print ''; print ''; print ''; print ''; print '
'.$langs->trans("PDFUploadSettings").'
'.$langs->trans("DefaultUploadMode").''; $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 ' '.$langs->trans("DefaultUploadModeHelp").''; print '
'.$langs->trans("ReminderEnabled").''; print ''; print ' '.$langs->trans("ReminderEnabledHelp").''; print '
'.$langs->trans("ReminderMonths").''; $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 ' '.$langs->trans("ReminderMonthsHelp").''; print '
'; // Bank Account Mapping Section print '
'; print ''; print ''; print ''; print ''; // Bank Account Dropdown $bankAccountId = getDolGlobalInt('BANKIMPORT_BANK_ACCOUNT_ID'); print ''; print ''; print ''; print ''; print '
'.$langs->trans("BankAccountMapping").'
'.$langs->trans("DolibarrBankAccount").''; // 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 '
'.$langs->trans("DolibarrBankAccountHelp").''; print '
'; // Automatic Import Section print '
'; print ''; print ''; print ''; print ''; // Enable automatic import $autoImportEnabled = getDolGlobalInt('BANKIMPORT_AUTO_ENABLED'); print ''; print ''; print ''; print ''; // Import frequency $autoFrequency = getDolGlobalString('BANKIMPORT_AUTO_FREQUENCY') ?: 'daily'; print ''; print ''; print ''; print ''; // Days to fetch $autoDays = getDolGlobalInt('BANKIMPORT_AUTO_DAYS') ?: 30; print ''; print ''; print ''; print ''; // Last fetch info $lastFetch = getDolGlobalInt('BANKIMPORT_LAST_FETCH'); $lastFetchCount = getDolGlobalInt('BANKIMPORT_LAST_FETCH_COUNT'); print ''; print ''; print ''; print ''; print '
'.$langs->trans("AutomaticImport").'
'.$langs->trans("EnableAutoImport").''; print $form->selectyesno('BANKIMPORT_AUTO_ENABLED', $autoImportEnabled, 1); print ' '.$langs->trans("EnableAutoImportHelp").''; print '
'.$langs->trans("ImportFrequency").''; $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 '
'.$langs->trans("DaysToFetch").''; print ''; print ' '.$langs->trans("DaysToFetchHelp").''; print '
'.$langs->trans("LastAutoFetch").''; if ($lastFetch > 0) { print dol_print_date($lastFetch, 'dayhour'); if ($lastFetchCount > 0) { print ' '.$lastFetchCount.' '.$langs->trans("Transactions").''; } // Warning if more than 7 days since last fetch if ((time() - $lastFetch) > 7 * 86400) { print ' '.$langs->trans("MoreThan7Days").''; } } else { print ''.$langs->trans("NeverFetched").''; } print '
'; print '
'; // Buttons print '
'; print ''; print '
'; print '
'; print '
'; // Test Connection Button print '
'; print '
'; print ''; print ''; print ''; print '
'; // Fetch Accounts Button print '
'; print ''; print ''; print ''; print '
'; print '
'; // Display available accounts if fetched if (!empty($availableAccounts)) { print '

'; print '
'; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; foreach ($availableAccounts as $acc) { $isSelected = ($acc['iban'] === $fintsIBAN); print ''; print ''; print ''; print ''; print ''; print ''; print ''; } print '
'.$langs->trans("IBAN").''.$langs->trans("BIC").''.$langs->trans("AccountNumber").''.$langs->trans("BLZ").''.$langs->trans("Action").'
'.dol_escape_htmltag($acc['iban']).''.dol_escape_htmltag($acc['bic']).''.dol_escape_htmltag($acc['accountNumber']).''.dol_escape_htmltag($acc['blz']).''; if ($isSelected) { print ''.$langs->trans("Selected").''; } else { print ''.$langs->trans("UseThisAccount").''; } print '
'; print '
'; } // Info Box - VR Bank specific print '
'; print '
'; print ''.$langs->trans("VRBankInfo").'
'; print $langs->trans("VRBankInfoText"); print '
'; // Security Info Box print '
'; print '
'; print ''.$langs->trans("SecurityInfo").'
'; print $langs->trans("SecurityInfoText"); print '
'; // Admin Tools Section print '
'; print load_fiche_titre($langs->trans("AdminTools"), '', 'tools'); print '
'; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print '
'.$langs->trans("Tool").''.$langs->trans("Description").'
'.$langs->trans("RepairOrphanedTransactions").''.$langs->trans("RepairOrphanedTransactionsDesc").''.$langs->trans("Open").'
'; print '
'; // Page end print dol_get_fiche_end(); llxFooter(); $db->close();