Bug 41918: Prevent a given librarian from running the same report multiple times simultaneously

Test Plan:
1) create a long running report such as:
   SELECT COUNT(*) FROM items i1 JOIN items i2 JOIN items i3 JOIN items i4 JOIN items i5 JOIN items i6
2) Run this report multiple times
3) Note the processes are running via SHOW FULL PROCESSLIST from koha-mysql
4) Kill those processes
5) Apply this patch
6) Restart all the things!
7) Try to run the report in two tabs, note the second tab opened says
   the report is already running!

Signed-off-by: Alex Carver [Acerock7] <alex@rcls.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
Kyle M Hall 2026-02-25 11:07:36 -05:00 committed by Lucas Gass
parent d0c5ceea3d
commit 7bd64b0f6f
No known key found for this signature in database
GPG Key ID: 60B447398B0D36CA
2 changed files with 21 additions and 1 deletions

View File

@ -1638,7 +1638,9 @@
<div class="alert alert-warning">
<strong>The following error was encountered:</strong><br />
[% FOREACH error IN errors %]
[% IF ( error.sqlerr ) %]
[% IF ( error.duplicate_running_report_ids ) %]
This report is already running. Please wait for it to finish before running it again.
[% ELSIF ( error.sqlerr ) %]
This report contains the SQL keyword <strong>[% error.sqlerr | html %]</strong>.<br />
Use of this keyword is not allowed in Koha reports due to security and data integrity risks. Only SELECT queries are allowed.<br />
Please return to the &quot;Saved Reports&quot; screen and delete this report or retry creating a new one.

View File

@ -824,6 +824,12 @@ if ( $op eq 'run' ) {
my $template_id = $input->param('template');
my $want_full_chart = $input->param('want_full_chart') || 0;
my @duplicate_running_report_ids;
if ( C4::Context->userenv ) {
my $user_id = C4::Context->userenv ? C4::Context->userenv->{number} : undef;
@duplicate_running_report_ids = Koha::Reports->running( { report_id => $report_id, user_id => $user_id } );
}
# offset algorithm
if ( $input->param('page') ) {
$offset = ( $input->param('page') - 1 ) * $limit;
@ -1009,6 +1015,18 @@ if ( $op eq 'run' ) {
'id' => $report_id,
'template_id' => $template_id,
);
} elsif (@duplicate_running_report_ids) {
$template->param(
'sql' => $sql,
'original_sql' => $original_sql,
'id' => $report_id,
'execute' => 1,
'name' => $name,
'notes' => $notes,
'errors' => [ { duplicate_running_report_ids => \@duplicate_running_report_ids } ],
'sql_params' => \@sql_params,
'param_names' => \@param_names,
);
} else {
my ( $sql, $header_types ) = $report->prep_report( \@param_names, \@sql_params );
$template->param( header_types => $header_types );