View | Details | Raw Unified | Return to bug 28745
Collapse All | Expand All

(-)a/tools/batchMod.pl (-178 / +171 lines)
Lines 59-65 my $biblionumber = $input->param('biblionumber'); Link Here
59
my $op           = $input->param('op');
59
my $op           = $input->param('op');
60
my $del          = $input->param('del');
60
my $del          = $input->param('del');
61
my $del_records  = $input->param('del_records');
61
my $del_records  = $input->param('del_records');
62
my $completedJobID = $input->param('completedJobID');
63
my $src          = $input->param('src');
62
my $src          = $input->param('src');
64
my $use_default_values = $input->param('use_default_values');
63
my $use_default_values = $input->param('use_default_values');
65
my $exclude_from_local_holds_priority = $input->param('exclude_from_local_holds_priority');
64
my $exclude_from_local_holds_priority = $input->param('exclude_from_local_holds_priority');
Lines 129-137 if ($op eq "action") { Link Here
129
128
130
    my $marcitem;
129
    my $marcitem;
131
130
131
    #initializing values for updates
132
    my (  $itemtagfield,   $itemtagsubfield) = &GetMarcFromKohaField( "items.itemnumber" );
133
    if ($values_to_modify){
134
        my $xml = TransformHtmlToXml(\@tags,\@subfields,\@values,\@indicator,\@ind_tag, 'ITEM');
135
        $marcitem = MARC::Record::new_from_xml($xml, 'UTF-8');
136
    }
137
    if ($values_to_blank){
138
        foreach my $disabledsubf (@disabled){
139
            if ($marcitem && $marcitem->field($itemtagfield)){
140
                $marcitem->field($itemtagfield)->update( $disabledsubf => "" );
141
            }
142
            else {
143
                $marcitem = MARC::Record->new();
144
                $marcitem->append_fields( MARC::Field->new( $itemtagfield, '', '', $disabledsubf => "" ) );
145
            }
146
        }
147
    }
148
149
    my $upd_biblionumbers;
150
    my $del_biblionumbers;
151
    try {
152
        my $schema = Koha::Database->new->schema;
153
        $schema->txn_do(
154
            sub {
155
                # For each item
156
                my $i = 1;
157
                foreach my $itemnumber (@itemnumbers) {
158
                    my $item = Koha::Items->find($itemnumber);
159
                    next
160
                      unless $item
161
                      ; # Should have been tested earlier, but just in case...
162
                    my $itemdata = $item->unblessed;
163
                    if ($del) {
164
                        my $return = $item->safe_delete;
165
                        if ( ref( $return ) ) {
166
                            $deleted_items++;
167
                            push @$upd_biblionumbers, $itemdata->{'biblionumber'};
168
                        }
169
                        else {
170
                            $not_deleted_items++;
171
                            push @not_deleted,
172
                              {
173
                                biblionumber => $itemdata->{'biblionumber'},
174
                                itemnumber   => $itemdata->{'itemnumber'},
175
                                barcode      => $itemdata->{'barcode'},
176
                                title        => $itemdata->{'title'},
177
                                reason       => $return,
178
                              };
179
                        }
180
181
                        # If there are no items left, delete the biblio
182
                        if ($del_records) {
183
                            my $itemscount = Koha::Biblios->find( $itemdata->{'biblionumber'} )->items->count;
184
                            if ( $itemscount == 0 ) {
185
                                my $error = DelBiblio( $itemdata->{'biblionumber'}, { skip_record_index => 1 } );
186
                                unless ($error) {
187
                                    $deleted_records++;
188
                                    push @$del_biblionumbers, $itemdata->{'biblionumber'};
189
                                    if ( $src eq 'CATALOGUING' ) {
190
                                        # We are coming catalogue/detail.pl, there were items from a single bib record
191
                                        $template->param( biblio_deleted => 1 );
192
                                    }
193
                                }
194
                            }
195
                        }
196
                    }
197
                    else {
198
                        my $modified_holds_priority = 0;
199
                        if ( defined $exclude_from_local_holds_priority && $exclude_from_local_holds_priority ne "" ) {
200
                            if(!defined $item->exclude_from_local_holds_priority || $item->exclude_from_local_holds_priority != $exclude_from_local_holds_priority) {
201
                            $item->exclude_from_local_holds_priority($exclude_from_local_holds_priority)->store;
202
                            $modified_holds_priority = 1;
203
                        }
204
                        }
205
                        my $modified = 0;
206
                        if ( $values_to_modify || $values_to_blank ) {
207
                            my $localmarcitem = Item2Marc($itemdata);
208
209
                            for ( my $i = 0 ; $i < @tags ; $i++ ) {
210
                                my $search = $searches[$i];
211
                                next unless $search;
212
213
                                my $tag = $tags[$i];
214
                                my $subfield = $subfields[$i];
215
                                my $replace = $replaces[$i];
216
217
                                my $value = $localmarcitem->field( $tag )->subfield( $subfield );
218
                                my $old_value = $value;
219
220
                                my @available_modifiers = qw( i g );
221
                                my $retained_modifiers = q||;
222
                                for my $modifier ( split //, $modifiers[$i] ) {
223
                                    $retained_modifiers .= $modifier
224
                                        if grep {/$modifier/} @available_modifiers;
225
                                }
226
                                if ( $retained_modifiers =~ m/^(ig|gi)$/ ) {
227
                                    $value =~ s/$search/$replace/ig;
228
                                }
229
                                elsif ( $retained_modifiers eq 'i' ) {
230
                                    $value =~ s/$search/$replace/i;
231
                                }
232
                                elsif ( $retained_modifiers eq 'g' ) {
233
                                    $value =~ s/$search/$replace/g;
234
                                }
235
                                else {
236
                                    $value =~ s/$search/$replace/;
237
                                }
238
239
                                my @fields_to = $localmarcitem->field($tag);
240
                                foreach my $field_to_update ( @fields_to ) {
241
                                    unless ( $old_value eq $value ) {
242
                                        $modified++;
243
                                        $field_to_update->update( $subfield => $value );
244
                                    }
245
                                }
246
                            }
247
248
                            $modified += UpdateMarcWith( $marcitem, $localmarcitem );
249
                            if ($modified) {
250
                                eval {
251
                                    if (
252
                                        my $item = ModItemFromMarc(
253
                                            $localmarcitem,
254
                                            $itemdata->{biblionumber},
255
                                            $itemnumber,
256
                                            { skip_record_index => 1 },
257
                                        )
258
                                      )
259
                                    {
260
                                        LostItem(
261
                                            $itemnumber,
262
                                            'batchmod',
263
                                            undef,
264
                                            { skip_record_index => 1 }
265
                                        ) if $item->{itemlost}
266
                                          and not $itemdata->{itemlost};
267
                                    }
268
                                };
269
                                push @$upd_biblionumbers, $itemdata->{'biblionumber'};
270
                            }
271
                        }
272
                        $modified_items++ if $modified || $modified_holds_priority;
273
                        $modified_fields += $modified + $modified_holds_priority;
274
                    }
275
                    $i++;
276
                }
277
                if (@not_deleted) {
278
                    Koha::Exceptions::Exception->throw(
279
                        'Some items have not been deleted, rolling back');
280
                }
281
            }
282
        );
283
    }
284
    catch {
285
        if ( $_->isa('Koha::Exceptions::Exception') ) {
286
            $template->param( deletion_failed => 1 );
287
        }
288
        die "Something terrible has happened!"
289
            if ($_ =~ /Rollback failed/); # Rollback failed
290
    };
291
    $upd_biblionumbers = [ uniq @$upd_biblionumbers ]; # Only update each bib once
292
293
    # Don't send specialUpdate for records we are going to delete
294
    my %del_bib_hash = map{ $_ => undef } @$del_biblionumbers;
295
    @$upd_biblionumbers = grep( ! exists( $del_bib_hash{$_} ), @$upd_biblionumbers );
296
297
    my $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX });
298
    $indexer->index_records( $upd_biblionumbers, 'specialUpdate', "biblioserver", undef ) if @$upd_biblionumbers;
299
    $indexer->index_records( $del_biblionumbers, 'recordDelete', "biblioserver", undef ) if @$del_biblionumbers;
300
132
    # Once the job is done
301
    # Once the job is done
133
    if ($completedJobID) {
302
    # If we have a reasonable amount of items, we display them
134
	# If we have a reasonable amount of items, we display them
135
    my $max_items = $del ? C4::Context->preference("MaxItemsToDisplayForBatchDel") : C4::Context->preference("MaxItemsToDisplayForBatchMod");
303
    my $max_items = $del ? C4::Context->preference("MaxItemsToDisplayForBatchDel") : C4::Context->preference("MaxItemsToDisplayForBatchMod");
136
    if (scalar(@itemnumbers) <= $max_items ){
304
    if (scalar(@itemnumbers) <= $max_items ){
137
        if (scalar(@itemnumbers) <= 1000 ) {
305
        if (scalar(@itemnumbers) <= 1000 ) {
Lines 154-333 if ($op eq "action") { Link Here
154
        $template->param( "job_completed" => 1 );
322
        $template->param( "job_completed" => 1 );
155
    }
323
    }
156
324
157
    } else {
158
    # While the job is getting done
159
160
	#initializing values for updates
161
    my (  $itemtagfield,   $itemtagsubfield) = &GetMarcFromKohaField( "items.itemnumber" );
162
	if ($values_to_modify){
163
	    my $xml = TransformHtmlToXml(\@tags,\@subfields,\@values,\@indicator,\@ind_tag, 'ITEM');
164
	    $marcitem = MARC::Record::new_from_xml($xml, 'UTF-8');
165
        }
166
        if ($values_to_blank){
167
	    foreach my $disabledsubf (@disabled){
168
		if ($marcitem && $marcitem->field($itemtagfield)){
169
		    $marcitem->field($itemtagfield)->update( $disabledsubf => "" );
170
		}
171
		else {
172
		    $marcitem = MARC::Record->new();
173
		    $marcitem->append_fields( MARC::Field->new( $itemtagfield, '', '', $disabledsubf => "" ) );
174
		}
175
	    }
176
        }
177
178
        my $upd_biblionumbers;
179
        my $del_biblionumbers;
180
        try {
181
            my $schema = Koha::Database->new->schema;
182
            $schema->txn_do(
183
                sub {
184
                    # For each item
185
                    my $i = 1;
186
                    foreach my $itemnumber (@itemnumbers) {
187
                        my $item = Koha::Items->find($itemnumber);
188
                        next
189
                          unless $item
190
                          ; # Should have been tested earlier, but just in case...
191
                        my $itemdata = $item->unblessed;
192
                        if ($del) {
193
                            my $return = $item->safe_delete;
194
                            if ( ref( $return ) ) {
195
                                $deleted_items++;
196
                                push @$upd_biblionumbers, $itemdata->{'biblionumber'};
197
                            }
198
                            else {
199
                                $not_deleted_items++;
200
                                push @not_deleted,
201
                                  {
202
                                    biblionumber => $itemdata->{'biblionumber'},
203
                                    itemnumber   => $itemdata->{'itemnumber'},
204
                                    barcode      => $itemdata->{'barcode'},
205
                                    title        => $itemdata->{'title'},
206
                                    reason       => $return,
207
                                  };
208
                            }
209
210
                            # If there are no items left, delete the biblio
211
                            if ($del_records) {
212
                                my $itemscount = Koha::Biblios->find( $itemdata->{'biblionumber'} )->items->count;
213
                                if ( $itemscount == 0 ) {
214
                                    my $error = DelBiblio( $itemdata->{'biblionumber'}, { skip_record_index => 1 } );
215
                                    unless ($error) {
216
                                        $deleted_records++;
217
                                        push @$del_biblionumbers, $itemdata->{'biblionumber'};
218
                                        if ( $src eq 'CATALOGUING' ) {
219
                                            # We are coming catalogue/detail.pl, there were items from a single bib record
220
                                            $template->param( biblio_deleted => 1 );
221
                                        }
222
                                    }
223
                                }
224
                            }
225
                        }
226
                        else {
227
                            my $modified_holds_priority = 0;
228
                            if ( defined $exclude_from_local_holds_priority && $exclude_from_local_holds_priority ne "" ) {
229
                                if(!defined $item->exclude_from_local_holds_priority || $item->exclude_from_local_holds_priority != $exclude_from_local_holds_priority) {
230
                                $item->exclude_from_local_holds_priority($exclude_from_local_holds_priority)->store;
231
                                $modified_holds_priority = 1;
232
                            }
233
                            }
234
                            my $modified = 0;
235
                            if ( $values_to_modify || $values_to_blank ) {
236
                                my $localmarcitem = Item2Marc($itemdata);
237
238
                                for ( my $i = 0 ; $i < @tags ; $i++ ) {
239
                                    my $search = $searches[$i];
240
                                    next unless $search;
241
242
                                    my $tag = $tags[$i];
243
                                    my $subfield = $subfields[$i];
244
                                    my $replace = $replaces[$i];
245
246
                                    my $value = $localmarcitem->field( $tag )->subfield( $subfield );
247
                                    my $old_value = $value;
248
249
                                    my @available_modifiers = qw( i g );
250
                                    my $retained_modifiers = q||;
251
                                    for my $modifier ( split //, $modifiers[$i] ) {
252
                                        $retained_modifiers .= $modifier
253
                                            if grep {/$modifier/} @available_modifiers;
254
                                    }
255
                                    if ( $retained_modifiers =~ m/^(ig|gi)$/ ) {
256
                                        $value =~ s/$search/$replace/ig;
257
                                    }
258
                                    elsif ( $retained_modifiers eq 'i' ) {
259
                                        $value =~ s/$search/$replace/i;
260
                                    }
261
                                    elsif ( $retained_modifiers eq 'g' ) {
262
                                        $value =~ s/$search/$replace/g;
263
                                    }
264
                                    else {
265
                                        $value =~ s/$search/$replace/;
266
                                    }
267
268
                                    my @fields_to = $localmarcitem->field($tag);
269
                                    foreach my $field_to_update ( @fields_to ) {
270
                                        unless ( $old_value eq $value ) {
271
                                            $modified++;
272
                                            $field_to_update->update( $subfield => $value );
273
                                        }
274
                                    }
275
                                }
276
277
                                $modified += UpdateMarcWith( $marcitem, $localmarcitem );
278
                                if ($modified) {
279
                                    eval {
280
                                        if (
281
                                            my $item = ModItemFromMarc(
282
                                                $localmarcitem,
283
                                                $itemdata->{biblionumber},
284
                                                $itemnumber,
285
                                                { skip_record_index => 1 },
286
                                            )
287
                                          )
288
                                        {
289
                                            LostItem(
290
                                                $itemnumber,
291
                                                'batchmod',
292
                                                undef,
293
                                                { skip_record_index => 1 }
294
                                            ) if $item->{itemlost}
295
                                              and not $itemdata->{itemlost};
296
                                        }
297
                                    };
298
                                    push @$upd_biblionumbers, $itemdata->{'biblionumber'};
299
                                }
300
                            }
301
                            $modified_items++ if $modified || $modified_holds_priority;
302
                            $modified_fields += $modified + $modified_holds_priority;
303
                        }
304
                        $i++;
305
                    }
306
                    if (@not_deleted) {
307
                        Koha::Exceptions::Exception->throw(
308
                            'Some items have not been deleted, rolling back');
309
                    }
310
                }
311
            );
312
        }
313
        catch {
314
            if ( $_->isa('Koha::Exceptions::Exception') ) {
315
                $template->param( deletion_failed => 1 );
316
            }
317
            die "Something terrible has happened!"
318
                if ($_ =~ /Rollback failed/); # Rollback failed
319
        };
320
        $upd_biblionumbers = [ uniq @$upd_biblionumbers ]; # Only update each bib once
321
322
        # Don't send specialUpdate for records we are going to delete
323
        my %del_bib_hash = map{ $_ => undef } @$del_biblionumbers;
324
        @$upd_biblionumbers = grep( ! exists( $del_bib_hash{$_} ), @$upd_biblionumbers );
325
326
        my $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX });
327
        $indexer->index_records( $upd_biblionumbers, 'specialUpdate', "biblioserver", undef ) if @$upd_biblionumbers;
328
        $indexer->index_records( $del_biblionumbers, 'recordDelete', "biblioserver", undef ) if @$del_biblionumbers;
329
    }
330
331
    # Calling the template
325
    # Calling the template
332
    $template->param(
326
    $template->param(
333
        modified_items => $modified_items,
327
        modified_items => $modified_items,
334
- 

Return to bug 28745