Lines 45-50
use Koha::Items;
Link Here
|
45 |
use Koha::ItemTypes; |
45 |
use Koha::ItemTypes; |
46 |
use Koha::Patrons; |
46 |
use Koha::Patrons; |
47 |
use Koha::SearchEngine::Indexer; |
47 |
use Koha::SearchEngine::Indexer; |
|
|
48 |
use Koha::BackgroundJob::BatchDeleteItem; |
49 |
use Koha::BackgroundJob::BatchUpdateItem; |
48 |
|
50 |
|
49 |
my $input = CGI->new; |
51 |
my $input = CGI->new; |
50 |
my $dbh = C4::Context->dbh; |
52 |
my $dbh = C4::Context->dbh; |
Lines 102-175
my $modified_fields = 0; # Numbers of modified fields
Link Here
|
102 |
my %cookies = parse CGI::Cookie($cookie); |
104 |
my %cookies = parse CGI::Cookie($cookie); |
103 |
my $sessionID = $cookies{'CGISESSID'}->value; |
105 |
my $sessionID = $cookies{'CGISESSID'}->value; |
104 |
|
106 |
|
|
|
107 |
my @messages; |
105 |
|
108 |
|
106 |
#--- ---------------------------------------------------------------------------- |
109 |
#--- ---------------------------------------------------------------------------- |
107 |
if ($op eq "action") { |
110 |
if ($op eq "action") { |
108 |
#------------------------------------------------------------------------------- |
111 |
#------------------------------------------------------------------------------- |
109 |
my @tags = $input->multi_param('tag'); |
|
|
110 |
my @subfields = $input->multi_param('subfield'); |
111 |
my @values = $input->multi_param('field_value'); |
112 |
my @searches = $input->multi_param('regex_search'); |
113 |
my @replaces = $input->multi_param('regex_replace'); |
114 |
my @modifiers = $input->multi_param('regex_modifiers'); |
115 |
my @disabled = $input->multi_param('disable_input'); |
116 |
# build indicator hash. |
117 |
my @ind_tag = $input->multi_param('ind_tag'); |
118 |
my @indicator = $input->multi_param('indicator'); |
119 |
|
120 |
# Is there something to modify ? |
121 |
# TODO : We shall use this var to warn the user in case no modification was done to the items |
122 |
my $values_to_modify = scalar(grep {!/^$/} @values) || scalar(grep {!/^$/} @searches); |
123 |
my $values_to_blank = scalar(@disabled); |
124 |
|
125 |
my $marcitem; |
126 |
|
127 |
# Once the job is done |
128 |
if ($completedJobID) { |
129 |
# If we have a reasonable amount of items, we display them |
130 |
my $max_items = $del ? C4::Context->preference("MaxItemsToDisplayForBatchDel") : C4::Context->preference("MaxItemsToDisplayForBatchMod"); |
131 |
if (scalar(@itemnumbers) <= $max_items ){ |
132 |
if (scalar(@itemnumbers) <= 1000 ) { |
133 |
$items_display_hashref=BuildItemsData(@itemnumbers); |
134 |
} else { |
135 |
# Else, we only display the barcode |
136 |
my @simple_items_display = map { |
137 |
my $itemnumber = $_; |
138 |
my $item = Koha::Items->find($itemnumber); |
139 |
{ |
140 |
itemnumber => $itemnumber, |
141 |
barcode => $item ? ( $item->barcode // q{} ) : q{}, |
142 |
biblionumber => $item ? $item->biblio->biblionumber : q{}, |
143 |
}; |
144 |
} @itemnumbers; |
145 |
$template->param("simple_items_display" => \@simple_items_display); |
146 |
} |
147 |
} else { |
148 |
$template->param( "too_many_items_display" => scalar(@itemnumbers) ); |
149 |
$template->param( "job_completed" => 1 ); |
150 |
} |
151 |
|
152 |
} else { |
153 |
# While the job is getting done |
154 |
|
155 |
#initializing values for updates |
156 |
my ( $itemtagfield, $itemtagsubfield) = &GetMarcFromKohaField( "items.itemnumber" ); |
157 |
if ($values_to_modify){ |
158 |
my $xml = TransformHtmlToXml(\@tags,\@subfields,\@values,\@indicator,\@ind_tag, 'ITEM'); |
159 |
$marcitem = MARC::Record::new_from_xml($xml, 'UTF-8'); |
160 |
} |
161 |
if ($values_to_blank){ |
162 |
foreach my $disabledsubf (@disabled){ |
163 |
if ($marcitem && $marcitem->field($itemtagfield)){ |
164 |
$marcitem->field($itemtagfield)->update( $disabledsubf => "" ); |
165 |
} |
166 |
else { |
167 |
$marcitem = MARC::Record->new(); |
168 |
$marcitem->append_fields( MARC::Field->new( $itemtagfield, '', '', $disabledsubf => "" ) ); |
169 |
} |
170 |
} |
171 |
} |
172 |
|
112 |
|
|
|
113 |
if ( $del ) { |
173 |
my $upd_biblionumbers; |
114 |
my $upd_biblionumbers; |
174 |
my $del_biblionumbers; |
115 |
my $del_biblionumbers; |
175 |
try { |
116 |
try { |
Lines 218-301
if ($op eq "action") {
Link Here
|
218 |
} |
159 |
} |
219 |
} |
160 |
} |
220 |
} |
161 |
} |
221 |
else { |
|
|
222 |
my $modified_holds_priority = 0; |
223 |
if ( defined $exclude_from_local_holds_priority && $exclude_from_local_holds_priority ne "" ) { |
224 |
if(!defined $item->exclude_from_local_holds_priority || $item->exclude_from_local_holds_priority != $exclude_from_local_holds_priority) { |
225 |
$item->exclude_from_local_holds_priority($exclude_from_local_holds_priority)->store; |
226 |
$modified_holds_priority = 1; |
227 |
} |
228 |
} |
229 |
my $modified = 0; |
230 |
if ( $values_to_modify || $values_to_blank ) { |
231 |
my $localmarcitem = Item2Marc($itemdata); |
232 |
|
233 |
for ( my $i = 0 ; $i < @tags ; $i++ ) { |
234 |
my $search = $searches[$i]; |
235 |
next unless $search; |
236 |
|
237 |
my $tag = $tags[$i]; |
238 |
my $subfield = $subfields[$i]; |
239 |
my $replace = $replaces[$i]; |
240 |
|
241 |
my $value = $localmarcitem->field( $tag )->subfield( $subfield ); |
242 |
my $old_value = $value; |
243 |
|
244 |
my @available_modifiers = qw( i g ); |
245 |
my $retained_modifiers = q||; |
246 |
for my $modifier ( split //, $modifiers[$i] ) { |
247 |
$retained_modifiers .= $modifier |
248 |
if grep {/$modifier/} @available_modifiers; |
249 |
} |
250 |
if ( $retained_modifiers =~ m/^(ig|gi)$/ ) { |
251 |
$value =~ s/$search/$replace/ig; |
252 |
} |
253 |
elsif ( $retained_modifiers eq 'i' ) { |
254 |
$value =~ s/$search/$replace/i; |
255 |
} |
256 |
elsif ( $retained_modifiers eq 'g' ) { |
257 |
$value =~ s/$search/$replace/g; |
258 |
} |
259 |
else { |
260 |
$value =~ s/$search/$replace/; |
261 |
} |
262 |
|
263 |
my @fields_to = $localmarcitem->field($tag); |
264 |
foreach my $field_to_update ( @fields_to ) { |
265 |
unless ( $old_value eq $value ) { |
266 |
$modified++; |
267 |
$field_to_update->update( $subfield => $value ); |
268 |
} |
269 |
} |
270 |
} |
271 |
|
272 |
$modified += UpdateMarcWith( $marcitem, $localmarcitem ); |
273 |
if ($modified) { |
274 |
eval { |
275 |
if ( |
276 |
my $item = ModItemFromMarc( |
277 |
$localmarcitem, |
278 |
$itemdata->{biblionumber}, |
279 |
$itemnumber, |
280 |
{ skip_record_index => 1 }, |
281 |
) |
282 |
) |
283 |
{ |
284 |
LostItem( |
285 |
$itemnumber, |
286 |
'batchmod', |
287 |
undef, |
288 |
{ skip_record_index => 1 } |
289 |
) if $item->{itemlost} |
290 |
and not $itemdata->{itemlost}; |
291 |
} |
292 |
}; |
293 |
push @$upd_biblionumbers, $itemdata->{'biblionumber'}; |
294 |
} |
295 |
} |
296 |
$modified_items++ if $modified || $modified_holds_priority; |
297 |
$modified_fields += $modified + $modified_holds_priority; |
298 |
} |
299 |
$i++; |
162 |
$i++; |
300 |
} |
163 |
} |
301 |
if (@not_deleted) { |
164 |
if (@not_deleted) { |
Lines 321-335
if ($op eq "action") {
Link Here
|
321 |
my $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX }); |
184 |
my $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX }); |
322 |
$indexer->index_records( $upd_biblionumbers, 'specialUpdate', "biblioserver", undef ) if @$upd_biblionumbers; |
185 |
$indexer->index_records( $upd_biblionumbers, 'specialUpdate', "biblioserver", undef ) if @$upd_biblionumbers; |
323 |
$indexer->index_records( $del_biblionumbers, 'recordDelete', "biblioserver", undef ) if @$del_biblionumbers; |
186 |
$indexer->index_records( $del_biblionumbers, 'recordDelete', "biblioserver", undef ) if @$del_biblionumbers; |
|
|
187 |
} else { |
188 |
my $params = { |
189 |
tags => [ $input->multi_param('tag') ], |
190 |
subfields => [ $input->multi_param('subfield') ], |
191 |
values => [ $input->multi_param('field_value') ], |
192 |
searches => [ $input->multi_param('regex_search') ], |
193 |
replaces => [ $input->multi_param('regex_replace') ], |
194 |
modifiers => [ $input->multi_param('regex_modifiers') ], |
195 |
disabled => [ $input->multi_param('disable_input') ], |
196 |
ind_tag => [ $input->multi_param('ind_tag') ], |
197 |
indicator => [ $input->multi_param('indicator') ], |
198 |
record_ids => \@itemnumbers, |
199 |
}; |
200 |
try { |
201 |
my $job_id = Koha::BackgroundJob::BatchUpdateItem->new->enqueue($params); |
202 |
$nextop = 'enqueued'; |
203 |
$template->param( |
204 |
job_id => $job_id, |
205 |
); |
206 |
} catch { |
207 |
push @messages, { |
208 |
type => 'error', |
209 |
code => 'cannot_enqueue_job', |
210 |
error => $_, |
211 |
}; |
212 |
$template->param( view => 'errors' ); |
213 |
}; |
324 |
} |
214 |
} |
325 |
|
215 |
|
326 |
# Calling the template |
|
|
327 |
$template->param( |
328 |
modified_items => $modified_items, |
329 |
modified_fields => $modified_fields, |
330 |
); |
331 |
|
332 |
} |
216 |
} |
|
|
217 |
|
218 |
$template->param( |
219 |
messages => \@messages, |
220 |
); |
333 |
# |
221 |
# |
334 |
#------------------------------------------------------------------------------- |
222 |
#------------------------------------------------------------------------------- |
335 |
# build screen with existing items. and "new" one |
223 |
# build screen with existing items. and "new" one |
Lines 719-768
sub BuildItemsData{
Link Here
|
719 |
|
607 |
|
720 |
return { item_loop => \@item_value_loop, item_header_loop => \@header_loop }; |
608 |
return { item_loop => \@item_value_loop, item_header_loop => \@header_loop }; |
721 |
} |
609 |
} |
722 |
|
|
|
723 |
#BE WARN : it is not the general case |
724 |
# This function can be OK in the item marc record special case |
725 |
# Where subfield is not repeated |
726 |
# And where we are sure that field should correspond |
727 |
# And $tag>10 |
728 |
sub UpdateMarcWith { |
729 |
my ($marcfrom,$marcto)=@_; |
730 |
my ( $itemtag, $itemtagsubfield) = &GetMarcFromKohaField( "items.itemnumber" ); |
731 |
my $fieldfrom=$marcfrom->field($itemtag); |
732 |
my @fields_to=$marcto->field($itemtag); |
733 |
my $modified = 0; |
734 |
|
735 |
return $modified unless $fieldfrom; |
736 |
|
737 |
foreach my $subfield ( $fieldfrom->subfields() ) { |
738 |
foreach my $field_to_update ( @fields_to ) { |
739 |
if ( $subfield->[1] ) { |
740 |
unless ( $field_to_update->subfield($subfield->[0]) eq $subfield->[1] ) { |
741 |
$modified++; |
742 |
$field_to_update->update( $subfield->[0] => $subfield->[1] ); |
743 |
} |
744 |
} |
745 |
else { |
746 |
$modified++; |
747 |
$field_to_update->delete_subfield( code => $subfield->[0] ); |
748 |
} |
749 |
} |
750 |
} |
751 |
return $modified; |
752 |
} |
753 |
|
754 |
sub find_value { |
755 |
my ($tagfield,$insubfield,$record) = @_; |
756 |
my $result; |
757 |
my $indicator; |
758 |
foreach my $field ($record->field($tagfield)) { |
759 |
my @subfields = $field->subfields(); |
760 |
foreach my $subfield (@subfields) { |
761 |
if (@$subfield[0] eq $insubfield) { |
762 |
$result .= @$subfield[1]; |
763 |
$indicator = $field->indicator(1).$field->indicator(2); |
764 |
} |
765 |
} |
766 |
} |
767 |
return($indicator,$result); |
768 |
} |
769 |
- |