- Add multi-invoice payment support (link one bank transaction to multiple invoices) - Add payment unlinking feature to correct wrong matches - Show linked payments, invoices and bank entries in transaction detail view - Allow linking already paid invoices to bank transactions - Update README with new features - Add CHANGELOG.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
102 lines
2.9 KiB
PHP
Executable file
102 lines
2.9 KiB
PHP
Executable file
<?php
|
|
/* 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.
|
|
*/
|
|
|
|
/**
|
|
* AJAX endpoint to check for pending bank transaction matches
|
|
* Used by browser notification system
|
|
*/
|
|
|
|
if (!defined('NOTOKENRENEWAL')) {
|
|
define('NOTOKENRENEWAL', '1');
|
|
}
|
|
if (!defined('NOREQUIREMENU')) {
|
|
define('NOREQUIREMENU', '1');
|
|
}
|
|
if (!defined('NOREQUIREHTML')) {
|
|
define('NOREQUIREHTML', '1');
|
|
}
|
|
if (!defined('NOREQUIREAJAX')) {
|
|
define('NOREQUIREAJAX', '1');
|
|
}
|
|
|
|
// 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");
|
|
}
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
// Security check
|
|
if (!$user->hasRight('bankimport', 'read')) {
|
|
echo json_encode(array('error' => 'access_denied'));
|
|
exit;
|
|
}
|
|
|
|
$bankAccountId = getDolGlobalInt('BANKIMPORT_BANK_ACCOUNT_ID');
|
|
if (empty($bankAccountId)) {
|
|
echo json_encode(array('pending' => 0, 'incoming' => 0));
|
|
exit;
|
|
}
|
|
|
|
// Count new unmatched transactions (incoming payments = positive amount)
|
|
$sqlIncoming = "SELECT COUNT(*) as cnt, COALESCE(SUM(amount), 0) as total";
|
|
$sqlIncoming .= " FROM ".MAIN_DB_PREFIX."bankimport_transaction";
|
|
$sqlIncoming .= " WHERE entity IN (".getEntity('banktransaction').")";
|
|
$sqlIncoming .= " AND status = 0 AND amount > 0";
|
|
$resIncoming = $db->query($sqlIncoming);
|
|
$incoming = 0;
|
|
$incomingTotal = 0;
|
|
if ($resIncoming) {
|
|
$obj = $db->fetch_object($resIncoming);
|
|
$incoming = (int) $obj->cnt;
|
|
$incomingTotal = (float) $obj->total;
|
|
}
|
|
|
|
// Count all new transactions
|
|
$sqlAll = "SELECT COUNT(*) as cnt FROM ".MAIN_DB_PREFIX."bankimport_transaction";
|
|
$sqlAll .= " WHERE entity IN (".getEntity('banktransaction').")";
|
|
$sqlAll .= " AND status = 0";
|
|
$resAll = $db->query($sqlAll);
|
|
$pending = 0;
|
|
if ($resAll) {
|
|
$obj = $db->fetch_object($resAll);
|
|
$pending = (int) $obj->cnt;
|
|
}
|
|
|
|
echo json_encode(array(
|
|
'pending' => $pending,
|
|
'incoming' => $incoming,
|
|
'incoming_total' => $incomingTotal,
|
|
));
|
|
|
|
$db->close();
|