Bugzilla – Attachment 190217 Details for
Bug 14962
Temp Shelving Location
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 14962: On Display code for BackgroundJobs
Bug-14962-On-Display-code-for-BackgroundJobs.patch (text/plain), 12.65 KB, created by
Jake Deery
on 2025-12-05 14:51:11 UTC
(
hide
)
Description:
Bug 14962: On Display code for BackgroundJobs
Filename:
MIME Type:
Creator:
Jake Deery
Created:
2025-12-05 14:51:11 UTC
Size:
12.65 KB
patch
obsolete
>From bf5da92ce5654d45dc26639d0c34cbffefe5bfc9 Mon Sep 17 00:00:00 2001 >From: Jake Deery <jake.deery@openfifth.co.uk> >Date: Mon, 1 Dec 2025 13:09:20 +0000 >Subject: [PATCH] Bug 14962: On Display code for BackgroundJobs > >This patch adds code required to make BackgroundJobs accept and process >batch addition and removal of items to and from displays. >Please see the test files commit for instructions on how to test this >bundle of patches. >--- > Koha/BackgroundJob.pm | 2 + > Koha/BackgroundJob/BatchAddDisplayItems.pm | 202 ++++++++++++++++++ > Koha/BackgroundJob/BatchDeleteDisplayItems.pm | 173 +++++++++++++++ > 3 files changed, 377 insertions(+) > create mode 100644 Koha/BackgroundJob/BatchAddDisplayItems.pm > create mode 100644 Koha/BackgroundJob/BatchDeleteDisplayItems.pm > >diff --git a/Koha/BackgroundJob.pm b/Koha/BackgroundJob.pm >index 0ff204281d6..6d8955bcf9b 100644 >--- a/Koha/BackgroundJob.pm >+++ b/Koha/BackgroundJob.pm >@@ -449,6 +449,8 @@ sub core_types_to_classes { > batch_biblio_record_modification => 'Koha::BackgroundJob::BatchUpdateBiblio', > batch_item_record_deletion => 'Koha::BackgroundJob::BatchDeleteItem', > batch_item_record_modification => 'Koha::BackgroundJob::BatchUpdateItem', >+ batch_add_display_items => 'Koha::BackgroundJob::BatchAddDisplayItems', >+ batch_delete_display_items => 'Koha::BackgroundJob::BatchDeleteDisplayItems', > erm_sushi_harvester => 'Koha::BackgroundJob::ErmSushiHarvester', > batch_hold_cancel => 'Koha::BackgroundJob::BatchCancelHold', > create_eholdings_from_biblios => 'Koha::BackgroundJob::CreateEHoldingsFromBiblios', >diff --git a/Koha/BackgroundJob/BatchAddDisplayItems.pm b/Koha/BackgroundJob/BatchAddDisplayItems.pm >new file mode 100644 >index 00000000000..c98b89b7cf6 >--- /dev/null >+++ b/Koha/BackgroundJob/BatchAddDisplayItems.pm >@@ -0,0 +1,202 @@ >+package Koha::BackgroundJob::BatchAddDisplayItems; >+ >+# This file is part of Koha. >+# >+# Koha 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. >+# >+# Koha 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 Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use Try::Tiny qw( catch try ); >+use DateTime; >+use C4::Context; >+ >+use Koha::DisplayItem; >+use Koha::DisplayItems; >+use Koha::Items; >+use Koha::Displays; >+ >+use base 'Koha::BackgroundJob'; >+ >+=head1 NAME >+ >+Koha::BackgroundJob::BatchAddDisplayItems - Background job to add multiple items to a display >+ >+=head1 API >+ >+=head2 Class methods >+ >+=head3 job_type >+ >+Return the job type 'batch_add_display_items'. >+ >+=cut >+ >+sub job_type { >+ return 'batch_add_display_items'; >+} >+ >+=head3 process >+ >+Process the batch addition of items to a display >+ >+=cut >+ >+sub process { >+ my ( $self, $args ) = @_; >+ >+ if ( $self->status eq 'cancelled' ) { >+ return; >+ } >+ >+ $self->start; >+ >+ my $display_id = $args->{display_id}; >+ my @item_ids = @{ $args->{item_ids} }; >+ my $date_remove = $args->{date_remove}; >+ >+ my $report = { >+ total_records => scalar @item_ids, >+ total_success => 0, >+ total_errors => 0, >+ }; >+ >+ my @messages; >+ my @added_items; >+ my @failed_items; >+ >+ # Validate display exists >+ my $display = Koha::Displays->find($display_id); >+ unless ($display) { >+ push @messages, { >+ type => 'error', >+ code => 'display_not_found', >+ display_id => $display_id, >+ }; >+ $self->finish( { messages => \@messages, report => $report } ); >+ return; >+ } >+ >+ # Calculate date_remove from display_days if not provided >+ unless ($date_remove) { >+ if ( $display->display_days ) { >+ my $dt = DateTime->now( time_zone => C4::Context->tz() ); >+ $dt->add( days => $display->display_days ); >+ $date_remove = $dt->ymd; >+ } >+ } >+ >+ try { >+ my $schema = Koha::Database->new->schema; >+ $schema->txn_do( >+ sub { >+ for my $item_id ( sort { $a <=> $b } @item_ids ) { >+ >+ last if $self->get_from_storage->status eq 'cancelled'; >+ >+ my $item = Koha::Items->find($item_id); >+ unless ($item) { >+ push @failed_items, { >+ itemnumber => $item_id, >+ error => 'Item not found' >+ }; >+ $report->{total_errors}++; >+ next; >+ } >+ >+ # Check if item is already in this display >+ my $existing = Koha::DisplayItems->search( >+ { >+ display_id => $display_id, >+ itemnumber => $item_id, >+ } >+ )->next; >+ >+ if ($existing) { >+ push @failed_items, { >+ itemnumber => $item_id, >+ error => 'Item already in display' >+ }; >+ $report->{total_errors}++; >+ next; >+ } >+ >+ # Create display item >+ my $display_item = Koha::DisplayItem->new( >+ { >+ display_id => $display_id, >+ itemnumber => $item_id, >+ biblionumber => $item->biblionumber, >+ date_remove => $date_remove, >+ } >+ )->store; >+ >+ push @added_items, { >+ display_item_id => $display_item->display_item_id, >+ itemnumber => $item_id, >+ biblionumber => $item->biblionumber, >+ }; >+ >+ $report->{total_success}++; >+ $self->step; >+ } >+ } >+ ); >+ } catch { >+ warn $_; >+ push @messages, { >+ type => 'error', >+ code => 'unknown', >+ error => $_, >+ }; >+ die "Something terrible has happened!" if ( $_ =~ /Rollback failed/ ); >+ }; >+ >+ $report->{added_items} = \@added_items; >+ $report->{failed_items} = \@failed_items; >+ >+ my $data = $self->decoded_data; >+ $data->{messages} = \@messages; >+ $data->{report} = $report; >+ >+ $self->finish($data); >+} >+ >+=head3 enqueue >+ >+Enqueue the job. >+ >+=cut >+ >+sub enqueue { >+ my ( $self, $args ) = @_; >+ >+ return unless exists $args->{item_ids} && exists $args->{display_id}; >+ >+ my @item_ids = @{ $args->{item_ids} }; >+ my $display_id = $args->{display_id}; >+ my $date_remove = $args->{date_remove}; >+ >+ $self->SUPER::enqueue( >+ { >+ job_size => scalar @item_ids, >+ job_args => { >+ display_id => $display_id, >+ item_ids => \@item_ids, >+ date_remove => $date_remove, >+ }, >+ job_queue => 'long_tasks', >+ } >+ ); >+} >+ >+1; >diff --git a/Koha/BackgroundJob/BatchDeleteDisplayItems.pm b/Koha/BackgroundJob/BatchDeleteDisplayItems.pm >new file mode 100644 >index 00000000000..606f9fabd36 >--- /dev/null >+++ b/Koha/BackgroundJob/BatchDeleteDisplayItems.pm >@@ -0,0 +1,173 @@ >+package Koha::BackgroundJob::BatchDeleteDisplayItems; >+ >+# This file is part of Koha. >+# >+# Koha 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. >+# >+# Koha 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 Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use Try::Tiny qw( catch try ); >+ >+use Koha::DisplayItem; >+use Koha::DisplayItems; >+use Koha::Items; >+ >+use base 'Koha::BackgroundJob'; >+ >+=head1 NAME >+ >+Koha::BackgroundJob::BatchDeleteDisplayItems - Background job to remove multiple items from displays >+ >+=head1 API >+ >+=head2 Class methods >+ >+=head3 job_type >+ >+Return the job type 'batch_delete_display_items'. >+ >+=cut >+ >+sub job_type { >+ return 'batch_delete_display_items'; >+} >+ >+=head3 process >+ >+Process the batch removal of items from displays >+ >+=cut >+ >+sub process { >+ my ( $self, $args ) = @_; >+ >+ if ( $self->status eq 'cancelled' ) { >+ return; >+ } >+ >+ $self->start; >+ >+ my @item_ids = @{ $args->{item_ids} }; >+ my $display_id = $args->{display_id}; # Optional: if specified, only remove from this display >+ >+ my $report = { >+ total_records => scalar @item_ids, >+ total_success => 0, >+ total_errors => 0, >+ }; >+ >+ my @messages; >+ my @deleted_items; >+ my @failed_items; >+ >+ try { >+ my $schema = Koha::Database->new->schema; >+ $schema->txn_do( >+ sub { >+ for my $item_id ( sort { $a <=> $b } @item_ids ) { >+ >+ last if $self->get_from_storage->status eq 'cancelled'; >+ >+ # Build search criteria >+ my $search_criteria = { itemnumber => $item_id }; >+ $search_criteria->{display_id} = $display_id if $display_id; >+ >+ my $display_items = Koha::DisplayItems->search($search_criteria); >+ >+ unless ($display_items->count) { >+ push @failed_items, { >+ itemnumber => $item_id, >+ error => $display_id ? 'Item not found in specified display' : 'Item not found in any display' >+ }; >+ $report->{total_errors}++; >+ next; >+ } >+ >+ my $deleted_count = 0; >+ my @deleted_from_displays; >+ >+ while (my $display_item = $display_items->next) { >+ push @deleted_from_displays, { >+ display_id => $display_item->display_id, >+ display_item_id => $display_item->display_item_id, >+ }; >+ $display_item->delete; >+ $deleted_count++; >+ } >+ >+ if ($deleted_count > 0) { >+ push @deleted_items, { >+ itemnumber => $item_id, >+ displays_removed_from => \@deleted_from_displays, >+ count => $deleted_count, >+ }; >+ $report->{total_success}++; >+ } else { >+ push @failed_items, { >+ itemnumber => $item_id, >+ error => 'No display items could be deleted' >+ }; >+ $report->{total_errors}++; >+ } >+ >+ $self->step; >+ } >+ } >+ ); >+ } catch { >+ warn $_; >+ push @messages, { >+ type => 'error', >+ code => 'unknown', >+ error => $_, >+ }; >+ die "Something terrible has happened!" if ( $_ =~ /Rollback failed/ ); >+ }; >+ >+ $report->{deleted_items} = \@deleted_items; >+ $report->{failed_items} = \@failed_items; >+ >+ my $data = $self->decoded_data; >+ $data->{messages} = \@messages; >+ $data->{report} = $report; >+ >+ $self->finish($data); >+} >+ >+=head3 enqueue >+ >+Enqueue the job. >+ >+=cut >+ >+sub enqueue { >+ my ( $self, $args ) = @_; >+ >+ return unless exists $args->{item_ids}; >+ >+ my @item_ids = @{ $args->{item_ids} }; >+ my $display_id = $args->{display_id}; # Optional >+ >+ $self->SUPER::enqueue( >+ { >+ job_size => scalar @item_ids, >+ job_args => { >+ item_ids => \@item_ids, >+ display_id => $display_id, >+ }, >+ job_queue => 'long_tasks', >+ } >+ ); >+} >+ >+1; >\ No newline at end of file >-- >2.50.1 (Apple Git-155)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 14962
:
190216
| 190217 |
190218
|
190219
|
190220
|
190221
|
190222
|
190223
|
190224
|
190225
|
190226
|
190227
|
190228
|
190229
|
190230
|
190231
|
190232