Bug 32394: (follow-up) Add param for Koha::BackgroundJob::StageMARCForImport->enqueue
[koha-ffzg.git] / Koha / BackgroundJob / BatchUpdateItem.pm
1 package Koha::BackgroundJob::BatchUpdateItem;
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18 use Modern::Perl;
19 use List::MoreUtils qw( uniq );
20 use Try::Tiny;
21
22 use MARC::Record;
23 use MARC::Field;
24
25 use C4::Biblio;
26 use C4::Items;
27
28 use Koha::DateUtils qw( dt_from_string );
29 use Koha::SearchEngine::Indexer;
30 use Koha::Items;
31 use Koha::UI::Table::Builder::Items;
32
33 use base 'Koha::BackgroundJob';
34
35 =head1 NAME
36
37 Koha::BackgroundJob::BatchUpdateItem - Background job derived class to process item modification in batch
38
39 =head1 API
40
41 =head2 Class methods
42
43 =head3 job_type
44
45 Define the job type of this job: batch_item_record_modification
46
47 =cut
48
49 sub job_type {
50     return 'batch_item_record_modification';
51 }
52
53 =head3 process
54
55     Koha::BackgroundJobs->find($id)->process(
56         {
57             record_ids => \@itemnumbers,
58             new_values => {
59                 itemnotes => $new_item_notes,
60                 k         => $k,
61             },
62             regex_mod => {
63                 itemnotes_nonpublic => {
64                     search => 'foo',
65                     replace => 'bar',
66                     modifiers => 'gi',
67                 },
68             },
69             exclude_from_local_holds_priority => 1|0
70         }
71     );
72
73 Process the modification.
74
75 new_values allows to set a new value for given fields.
76 The key can be one of the item's column name, or one subfieldcode of a MARC subfields not linked with a Koha field.
77
78 regex_mod allows to modify existing subfield's values using a regular expression.
79
80 =cut
81
82 sub process {
83     my ( $self, $args ) = @_;
84
85     if ( $self->status eq 'cancelled' ) {
86         return;
87     }
88
89     # FIXME If the job has already been started, but started again (worker has been restart for instance)
90     # Then we will start from scratch and so double process the same records
91
92     my $job_progress = 0;
93     $self->started_on(dt_from_string)->progress($job_progress)
94       ->status('started')->store;
95
96     my @record_ids = @{ $args->{record_ids} };
97     my $regex_mod  = $args->{regex_mod};
98     my $new_values = $args->{new_values};
99     my $exclude_from_local_holds_priority =
100       $args->{exclude_from_local_holds_priority};
101
102     my $report = {
103         total_records            => scalar @record_ids,
104         modified_fields          => 0,
105     };
106
107     try {
108         my ($results) =
109           Koha::Items->search( { itemnumber => \@record_ids } )
110           ->batch_update(
111             {
112                 regex_mod  => $regex_mod,
113                 new_values => $new_values,
114                 exclude_from_local_holds_priority =>
115                   $exclude_from_local_holds_priority,
116                 callback => sub {
117                     my ($progress) = @_;
118                     $self->progress($progress)->store;
119                 },
120             }
121           );
122         $report->{modified_itemnumbers} = $results->{modified_itemnumbers};
123         $report->{modified_fields}      = $results->{modified_fields};
124     }
125     catch {
126         warn $_;
127         die "Something terrible has happened!"
128           if ( $_ =~ /Rollback failed/ );    # Rollback failed
129     };
130
131     my $json = $self->json;
132     $self->discard_changes;
133     my $job_data = $json->decode($self->data);
134     $job_data->{report} = $report;
135
136     $self->ended_on(dt_from_string)->data($json->encode($job_data));
137     $self->status('finished') if $self->status ne 'cancelled';
138     $self->store;
139 }
140
141 =head3 enqueue
142
143 Enqueue the new job
144
145 =cut
146
147 sub enqueue {
148     my ( $self, $args ) = @_;
149
150     # TODO Raise exception instead
151     return unless exists $args->{record_ids};
152
153     my @record_ids = @{ $args->{record_ids} };
154
155     $self->SUPER::enqueue(
156         {
157             job_size  => scalar @record_ids,
158             job_args  => {%$args},
159             job_queue => 'long_tasks',
160         }
161     );
162 }
163
164 =head3 additional_report
165
166 Sent the infos to generate the table containing the details of the modified items.
167
168 =cut
169
170 sub additional_report {
171     my ( $self, $args ) = @_;
172
173     return unless $self->report->{modified_itemnumbers};
174
175     my $itemnumbers = $self->report->{modified_itemnumbers};
176     if ( scalar(@$itemnumbers) > C4::Context->preference('MaxItemsToDisplayForBatchMod') ) {
177         return { too_many_items_display => 1 };
178     } else {
179         my $items_table =
180           Koha::UI::Table::Builder::Items->new( { itemnumbers => $itemnumbers } )
181           ->build_table;
182
183         return {
184             items            => $items_table->{items},
185             item_header_loop => $items_table->{headers},
186         };
187     }
188 }
189
190 1;