File Coverage

File:C4/ImportBatch.pm
Coverage:4.8%

linestmtbrancondsubtimecode
1package C4::ImportBatch;
2
3# Copyright (C) 2007 LibLime
4#
5# This file is part of Koha.
6#
7# Koha is free software; you can redistribute it and/or modify it under the
8# terms of the GNU General Public License as published by the Free Software
9# Foundation; either version 2 of the License, or (at your option) any later
10# version.
11#
12# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with Koha; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
6
6
6
41809
37
255
use strict;
21
6
6
6
49
33
261
use warnings;
22
23
6
6
6
376
51
306
use C4::Context;
24
6
6
6
382
37
2887
use C4::Koha;
25
6
6
6
429
28
2875
use C4::Biblio;
26
6
6
6
880
51
1524
use C4::Items;
27
6
6
6
73
42
501
use C4::Charset;
28
29
6
6
6
62
37
1100
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
30
31BEGIN {
32        # set the version for version checking
33
6
40
        $VERSION = 3.01;
34
6
69
        require Exporter;
35
6
340
        @ISA = qw(Exporter);
36
6
43289
        @EXPORT = qw(
37    GetZ3950BatchId
38    GetImportRecordMarc
39    AddImportBatch
40    GetImportBatch
41    AddBiblioToBatch
42    ModBiblioInBatch
43
44    BatchStageMarcRecords
45    BatchFindBibDuplicates
46    BatchCommitBibRecords
47    BatchRevertBibRecords
48    CleanBatch
49
50    GetAllImportBatches
51    GetImportBatchRangeDesc
52    GetNumberOfNonZ3950ImportBatches
53    GetImportBibliosRange
54        GetItemNumbersFromImportBatch
55
56    GetImportBatchStatus
57    SetImportBatchStatus
58    GetImportBatchOverlayAction
59    SetImportBatchOverlayAction
60    GetImportBatchNoMatchAction
61    SetImportBatchNoMatchAction
62    GetImportBatchItemAction
63    SetImportBatchItemAction
64    GetImportBatchMatcher
65    SetImportBatchMatcher
66    GetImportRecordOverlayStatus
67    SetImportRecordOverlayStatus
68    GetImportRecordStatus
69    SetImportRecordStatus
70    GetImportRecordMatches
71    SetImportRecordMatches
72        );
73}
74
75 - 93
=head1 NAME

C4::ImportBatch - manage batches of imported MARC records

=head1 SYNOPSIS

use C4::ImportBatch;

=head1 FUNCTIONS

=head2 GetZ3950BatchId

  my $batchid = GetZ3950BatchId($z3950server);

Retrieves the ID of the import batch for the Z39.50
reservoir for the given target.  If necessary,
creates the import batch.

=cut
94
95sub GetZ3950BatchId {
96
0
    my ($z3950server) = @_;
97
98
0
    my $dbh = C4::Context->dbh;
99
0
    my $sth = $dbh->prepare("SELECT import_batch_id FROM import_batches
100                             WHERE batch_type = 'z3950'
101                             AND file_name = ?");
102
0
    $sth->execute($z3950server);
103
0
    my $rowref = $sth->fetchrow_arrayref();
104
0
    $sth->finish();
105
0
    if (defined $rowref) {
106
0
        return $rowref->[0];
107    } else {
108
0
        my $batch_id = AddImportBatch('create_new', 'staged', 'z3950', $z3950server, '');
109
0
        return $batch_id;
110    }
111
112}
113
114 - 118
=head2 GetImportRecordMarc

  my ($marcblob, $encoding) = GetImportRecordMarc($import_record_id);

=cut
119
120sub GetImportRecordMarc {
121
0
    my ($import_record_id) = @_;
122
123
0
    my $dbh = C4::Context->dbh;
124
0
    my $sth = $dbh->prepare("SELECT marc, encoding FROM import_records WHERE import_record_id = ?");
125
0
    $sth->execute($import_record_id);
126
0
    my ($marc, $encoding) = $sth->fetchrow();
127
0
    $sth->finish();
128
0
    return $marc, $encoding;
129
130}
131
132 - 137
=head2 AddImportBatch

  my $batch_id = AddImportBatch($overlay_action, $import_status, $type, 
                                $file_name, $comments);

=cut
138
139sub AddImportBatch {
140
0
    my ($overlay_action, $import_status, $type, $file_name, $comments) = @_;
141
142
0
    my $dbh = C4::Context->dbh;
143
0
    my $sth = $dbh->prepare("INSERT INTO import_batches (overlay_action, import_status, batch_type,
144                                                         file_name, comments)
145                                    VALUES (?, ?, ?, ?, ?)");
146
0
    $sth->execute($overlay_action, $import_status, $type, $file_name, $comments);
147
0
    my $batch_id = $dbh->{'mysql_insertid'};
148
0
    $sth->finish();
149
150
0
    return $batch_id;
151
152}
153
154 - 160
=head2 GetImportBatch 

  my $row = GetImportBatch($batch_id);

Retrieve a hashref of an import_batches row.

=cut
161
162sub GetImportBatch {
163
0
    my ($batch_id) = @_;
164
165
0
    my $dbh = C4::Context->dbh;
166
0
    my $sth = $dbh->prepare_cached("SELECT * FROM import_batches WHERE import_batch_id = ?");
167
0
    $sth->bind_param(1, $batch_id);
168
0
    $sth->execute();
169
0
    my $result = $sth->fetchrow_hashref;
170
0
    $sth->finish();
171
0
    return $result;
172
173}
174
175 - 180
=head2 AddBiblioToBatch 

  my $import_record_id = AddBiblioToBatch($batch_id, $record_sequence, 
                $marc_record, $encoding, $z3950random, $update_counts);

=cut
181
182sub AddBiblioToBatch {
183
0
    my $batch_id = shift;
184
0
    my $record_sequence = shift;
185
0
    my $marc_record = shift;
186
0
    my $encoding = shift;
187
0
    my $z3950random = shift;
188
0
    my $update_counts = @_ ? shift : 1;
189
190
0
    my $import_record_id = _create_import_record($batch_id, $record_sequence, $marc_record, 'biblio', $encoding, $z3950random);
191
0
    _add_biblio_fields($import_record_id, $marc_record);
192
0
    _update_batch_record_counts($batch_id) if $update_counts;
193
0
    return $import_record_id;
194}
195
196 - 200
=head2 ModBiblioInBatch

  ModBiblioInBatch($import_record_id, $marc_record);

=cut
201
202sub ModBiblioInBatch {
203
0
    my ($import_record_id, $marc_record) = @_;
204
205
0
    _update_import_record_marc($import_record_id, $marc_record);
206
0
    _update_biblio_fields($import_record_id, $marc_record);
207
208}
209
210 - 218
=head2 BatchStageMarcRecords

  ($batch_id, $num_records, $num_items, @invalid_records) = 
    BatchStageMarcRecords($encoding, $marc_records, $file_name, 
                          $comments, $branch_code, $parse_items,
                          $leave_as_staging, 
                          $progress_interval, $progress_callback);

=cut
219
220sub BatchStageMarcRecords {
221
0
    my $encoding = shift;
222
0
    my $marc_records = shift;
223
0
    my $file_name = shift;
224
0
    my $comments = shift;
225
0
    my $branch_code = shift;
226
0
    my $parse_items = shift;
227
0
    my $leave_as_staging = shift;
228
229    # optional callback to monitor status
230    # of job
231
0
    my $progress_interval = 0;
232
0
    my $progress_callback = undef;
233
0
    if ($#_ == 1) {
234
0
        $progress_interval = shift;
235
0
        $progress_callback = shift;
236
0
        $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
237
0
        $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
238    }
239
240
0
    my $batch_id = AddImportBatch('create_new', 'staging', 'batch', $file_name, $comments);
241
0
    if ($parse_items) {
242
0
        SetImportBatchItemAction($batch_id, 'always_add');
243    } else {
244
0
        SetImportBatchItemAction($batch_id, 'ignore');
245    }
246
247
0
    my @invalid_records = ();
248
0
    my $num_valid = 0;
249
0
    my $num_items = 0;
250    # FIXME - for now, we're dealing only with bibs
251
0
    my $rec_num = 0;
252
0
    foreach my $marc_blob (split(/\x1D/, $marc_records)) {
253
0
        $marc_blob =~ s/^\s+//g;
254
0
        $marc_blob =~ s/\s+$//g;
255
0
        next unless $marc_blob;
256
0
        $rec_num++;
257
0
        if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
258
0
            &$progress_callback($rec_num);
259        }
260
0
        my ($marc_record, $charset_guessed, $char_errors) =
261            MarcToUTF8Record($marc_blob, C4::Context->preference("marcflavour"), $encoding);
262
263
0
        $encoding = $charset_guessed unless $encoding;
264
265
0
        my $import_record_id;
266
0
        if (scalar($marc_record->fields()) == 0) {
267
0
            push @invalid_records, $marc_blob;
268        } else {
269
0
            $num_valid++;
270
0
            $import_record_id = AddBiblioToBatch($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0);
271
0
            if ($parse_items) {
272
0
                my @import_items_ids = AddItemsToImportBiblio($batch_id, $import_record_id, $marc_record, 0);
273
0
                $num_items += scalar(@import_items_ids);
274            }
275        }
276    }
277
0
    unless ($leave_as_staging) {
278
0
        SetImportBatchStatus($batch_id, 'staged');
279    }
280    # FIXME branch_code, number of bibs, number of items
281
0
    _update_batch_record_counts($batch_id);
282
0
    return ($batch_id, $num_valid, $num_items, @invalid_records);
283}
284
285 - 290
=head2 AddItemsToImportBiblio

  my @import_items_ids = AddItemsToImportBiblio($batch_id, 
                $import_record_id, $marc_record, $update_counts);

=cut
291
292sub AddItemsToImportBiblio {
293
0
    my $batch_id = shift;
294
0
    my $import_record_id = shift;
295
0
    my $marc_record = shift;
296
0
    my $update_counts = @_ ? shift : 0;
297
298
0
    my @import_items_ids = ();
299
300
0
    my $dbh = C4::Context->dbh;
301
0
    my ($item_tag,$item_subfield) = &GetMarcFromKohaField("items.itemnumber",'');
302
0
    foreach my $item_field ($marc_record->field($item_tag)) {
303
0
        my $item_marc = MARC::Record->new();
304
0
        $item_marc->leader("00000 a "); # must set Leader/09 to 'a'
305
0
        $item_marc->append_fields($item_field);
306
0
        $marc_record->delete_field($item_field);
307
0
        my $sth = $dbh->prepare_cached("INSERT INTO import_items (import_record_id, status, marcxml)
308                                        VALUES (?, ?, ?)");
309
0
        $sth->bind_param(1, $import_record_id);
310
0
        $sth->bind_param(2, 'staged');
311
0
        $sth->bind_param(3, $item_marc->as_xml());
312
0
        $sth->execute();
313
0
        push @import_items_ids, $dbh->{'mysql_insertid'};
314
0
        $sth->finish();
315    }
316
317
0
    if ($#import_items_ids > -1) {
318
0
        _update_batch_record_counts($batch_id) if $update_counts;
319
0
        _update_import_record_marc($import_record_id, $marc_record);
320    }
321
0
    return @import_items_ids;
322}
323
324 - 342
=head2 BatchFindBibDuplicates

  my $num_with_matches = BatchFindBibDuplicates($batch_id, $matcher, 
             $max_matches, $progress_interval, $progress_callback);

Goes through the records loaded in the batch and attempts to 
find duplicates for each one.  Sets the matching status 
of each record to "no_match" or "auto_match" as appropriate.

The $max_matches parameter is optional; if it is not supplied,
it defaults to 10.

The $progress_interval and $progress_callback parameters are 
optional; if both are supplied, the sub referred to by
$progress_callback will be invoked every $progress_interval
records using the number of records processed as the 
singular argument.

=cut
343
344sub BatchFindBibDuplicates {
345
0
    my $batch_id = shift;
346
0
    my $matcher = shift;
347
0
    my $max_matches = @_ ? shift : 10;
348
349    # optional callback to monitor status
350    # of job
351
0
    my $progress_interval = 0;
352
0
    my $progress_callback = undef;
353
0
    if ($#_ == 1) {
354
0
        $progress_interval = shift;
355
0
        $progress_callback = shift;
356
0
        $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
357
0
        $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
358    }
359
360
0
    my $dbh = C4::Context->dbh;
361
362
0
    my $sth = $dbh->prepare("SELECT import_record_id, marc
363                             FROM import_records
364                             JOIN import_biblios USING (import_record_id)
365                             WHERE import_batch_id = ?");
366
0
    $sth->execute($batch_id);
367
0
    my $num_with_matches = 0;
368
0
    my $rec_num = 0;
369
0
    while (my $rowref = $sth->fetchrow_hashref) {
370
0
        $rec_num++;
371
0
        if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
372
0
            &$progress_callback($rec_num);
373        }
374
0
        my $marc_record = MARC::Record->new_from_usmarc($rowref->{'marc'});
375
0
        my @matches = ();
376
0
        if (defined $matcher) {
377
0
            @matches = $matcher->get_matches($marc_record, $max_matches);
378        }
379
0
        if (scalar(@matches) > 0) {
380
0
            $num_with_matches++;
381
0
            SetImportRecordMatches($rowref->{'import_record_id'}, @matches);
382
0
            SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'auto_match');
383        } else {
384
0
            SetImportRecordMatches($rowref->{'import_record_id'}, ());
385
0
            SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'no_match');
386        }
387    }
388
0
    $sth->finish();
389
0
    return $num_with_matches;
390}
391
392 - 398
=head2 BatchCommitBibRecords

  my ($num_added, $num_updated, $num_items_added, $num_items_errored, 
      $num_ignored) = BatchCommitBibRecords($batch_id, $framework,
                      $progress_interval, $progress_callback);

=cut
399
400sub BatchCommitBibRecords {
401
0
    my $batch_id = shift;
402
0
    my $framework = shift;
403
404    # optional callback to monitor status
405    # of job
406
0
    my $progress_interval = 0;
407
0
    my $progress_callback = undef;
408
0
    if ($#_ == 1) {
409
0
        $progress_interval = shift;
410
0
        $progress_callback = shift;
411
0
        $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
412
0
        $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
413    }
414
415
0
    my $num_added = 0;
416
0
    my $num_updated = 0;
417
0
    my $num_items_added = 0;
418
0
    my $num_items_errored = 0;
419
0
    my $num_ignored = 0;
420    # commit (i.e., save, all records in the batch)
421    # FIXME biblio only at the moment
422
0
    SetImportBatchStatus('importing');
423
0
    my $overlay_action = GetImportBatchOverlayAction($batch_id);
424
0
    my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
425
0
    my $item_action = GetImportBatchItemAction($batch_id);
426
0
    my $dbh = C4::Context->dbh;
427
0
    my $sth = $dbh->prepare("SELECT import_record_id, status, overlay_status, marc, encoding
428                             FROM import_records
429                             JOIN import_biblios USING (import_record_id)
430                             WHERE import_batch_id = ?");
431
0
    $sth->execute($batch_id);
432
0
    my $rec_num = 0;
433
0
    while (my $rowref = $sth->fetchrow_hashref) {
434
0
        $rec_num++;
435
0
        if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
436
0
            &$progress_callback($rec_num);
437        }
438
0
        if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'imported') {
439
0
            $num_ignored++;
440
0
            next;
441        }
442
443
0
        my $marc_record = MARC::Record->new_from_usmarc($rowref->{'marc'});
444
445        # remove any item tags - rely on BatchCommitItems
446
0
        my ($item_tag,$item_subfield) = &GetMarcFromKohaField("items.itemnumber",'');
447
0
        foreach my $item_field ($marc_record->field($item_tag)) {
448
0
            $marc_record->delete_field($item_field);
449        }
450
451        # decide what what to do with the bib and item records
452
0
        my ($bib_result, $item_result, $bib_match) =
453            _get_commit_action($overlay_action, $nomatch_action, $item_action,
454                               $rowref->{'overlay_status'}, $rowref->{'import_record_id'});
455
456
0
        if ($bib_result eq 'create_new') {
457
0
            $num_added++;
458
0
            my ($biblionumber, $biblioitemnumber) = AddBiblio($marc_record, $framework);
459
0
            my $sth = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
460
0
            $sth->execute($biblionumber, $rowref->{'import_record_id'});
461
0
            $sth->finish();
462
0
            if ($item_result eq 'create_new') {
463
0
                my ($bib_items_added, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $biblionumber);
464
0
                $num_items_added += $bib_items_added;
465
0
                $num_items_errored += $bib_items_errored;
466            }
467
0
            SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
468        } elsif ($bib_result eq 'replace') {
469
0
            $num_updated++;
470
0
            my $biblionumber = $bib_match;
471
0
            my ($count, $oldbiblio) = GetBiblio($biblionumber);
472
0
            my $oldxml = GetXmlBiblio($biblionumber);
473
474            # remove item fields so that they don't get
475            # added again if record is reverted
476
0
            my $old_marc = MARC::Record->new_from_xml(StripNonXmlChars($oldxml), 'UTF-8', $rowref->{'encoding'});
477
0
            foreach my $item_field ($old_marc->field($item_tag)) {
478
0
                $old_marc->delete_field($item_field);
479            }
480
481
0
            ModBiblio($marc_record, $biblionumber, $oldbiblio->{'frameworkcode'});
482
0
            my $sth = $dbh->prepare_cached("UPDATE import_records SET marcxml_old = ? WHERE import_record_id = ?");
483
0
            $sth->execute($old_marc->as_xml(), $rowref->{'import_record_id'});
484
0
            $sth->finish();
485
0
            my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
486
0
            $sth2->execute($biblionumber, $rowref->{'import_record_id'});
487
0
            $sth2->finish();
488
0
            if ($item_result eq 'create_new') {
489
0
                my ($bib_items_added, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $biblionumber);
490
0
                $num_items_added += $bib_items_added;
491
0
                $num_items_errored += $bib_items_errored;
492            }
493
0
            SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
494
0
            SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
495        } elsif ($bib_result eq 'ignore') {
496
0
            $num_ignored++;
497
0
            my $biblionumber = $bib_match;
498
0
            if (defined $biblionumber and $item_result eq 'create_new') {
499
0
                my ($bib_items_added, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $biblionumber);
500
0
                $num_items_added += $bib_items_added;
501
0
                $num_items_errored += $bib_items_errored;
502                # still need to record the matched biblionumber so that the
503                # items can be reverted
504
0
                my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
505
0
                $sth2->execute($biblionumber, $rowref->{'import_record_id'});
506
0
                SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
507            }
508
0
            SetImportRecordStatus($rowref->{'import_record_id'}, 'ignored');
509        }
510    }
511
0
    $sth->finish();
512
0
    SetImportBatchStatus($batch_id, 'imported');
513
0
    return ($num_added, $num_updated, $num_items_added, $num_items_errored, $num_ignored);
514}
515
516 - 521
=head2 BatchCommitItems

  ($num_items_added, $num_items_errored) = 
         BatchCommitItems($import_record_id, $biblionumber);

=cut
522
523sub BatchCommitItems {
524
0
    my ($import_record_id, $biblionumber) = @_;
525
526
0
    my $dbh = C4::Context->dbh;
527
528
0
    my $num_items_added = 0;
529
0
    my $num_items_errored = 0;
530
0
    my $sth = $dbh->prepare("SELECT import_items_id, import_items.marcxml, encoding
531                             FROM import_items
532                             JOIN import_records USING (import_record_id)
533                             WHERE import_record_id = ?
534                             ORDER BY import_items_id");
535
0
    $sth->bind_param(1, $import_record_id);
536
0
    $sth->execute();
537
0
    while (my $row = $sth->fetchrow_hashref()) {
538
0
        my $item_marc = MARC::Record->new_from_xml(StripNonXmlChars($row->{'marcxml'}), 'UTF-8', $row->{'encoding'});
539        # FIXME - duplicate barcode check needs to become part of AddItemFromMarc()
540
0
        my $item = TransformMarcToKoha($dbh, $item_marc);
541
0
        my $duplicate_barcode = exists($item->{'barcode'}) && GetItemnumberFromBarcode($item->{'barcode'});
542
0
        if ($duplicate_barcode) {
543
0
            my $updsth = $dbh->prepare("UPDATE import_items SET status = ?, import_error = ? WHERE import_items_id = ?");
544
0
            $updsth->bind_param(1, 'error');
545
0
            $updsth->bind_param(2, 'duplicate item barcode');
546
0
            $updsth->bind_param(3, $row->{'import_items_id'});
547
0
            $updsth->execute();
548
0
            $num_items_errored++;
549        } else {
550
0
            my ($item_biblionumber, $biblioitemnumber, $itemnumber) = AddItemFromMarc($item_marc, $biblionumber);
551
0
            my $updsth = $dbh->prepare("UPDATE import_items SET status = ?, itemnumber = ? WHERE import_items_id = ?");
552
0
            $updsth->bind_param(1, 'imported');
553
0
            $updsth->bind_param(2, $itemnumber);
554
0
            $updsth->bind_param(3, $row->{'import_items_id'});
555
0
            $updsth->execute();
556
0
            $updsth->finish();
557
0
            $num_items_added++;
558        }
559    }
560
0
    $sth->finish();
561
0
    return ($num_items_added, $num_items_errored);
562}
563
564 - 569
=head2 BatchRevertBibRecords

  my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, 
      $num_ignored) = BatchRevertBibRecords($batch_id);

=cut
570
571sub BatchRevertBibRecords {
572
0
    my $batch_id = shift;
573
574
0
    my $num_deleted = 0;
575
0
    my $num_errors = 0;
576
0
    my $num_reverted = 0;
577
0
    my $num_items_deleted = 0;
578
0
    my $num_ignored = 0;
579    # commit (i.e., save, all records in the batch)
580    # FIXME biblio only at the moment
581
0
    SetImportBatchStatus('reverting');
582
0
    my $overlay_action = GetImportBatchOverlayAction($batch_id);
583
0
    my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
584
0
    my $dbh = C4::Context->dbh;
585
0
    my $sth = $dbh->prepare("SELECT import_record_id, status, overlay_status, marcxml_old, encoding, matched_biblionumber
586                             FROM import_records
587                             JOIN import_biblios USING (import_record_id)
588                             WHERE import_batch_id = ?");
589
0
    $sth->execute($batch_id);
590
0
    while (my $rowref = $sth->fetchrow_hashref) {
591
0
        if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'reverted') {
592
0
            $num_ignored++;
593
0
            next;
594        }
595
596
0
        my $bib_result = _get_revert_action($overlay_action, $rowref->{'overlay_status'}, $rowref->{'status'});
597
598
0
        if ($bib_result eq 'delete') {
599
0
            $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
600
0
            my $error = DelBiblio($rowref->{'matched_biblionumber'});
601
0
            if (defined $error) {
602
0
                $num_errors++;
603            } else {
604
0
                $num_deleted++;
605
0
                SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
606            }
607        } elsif ($bib_result eq 'restore') {
608
0
            $num_reverted++;
609
0
            my $old_record = MARC::Record->new_from_xml(StripNonXmlChars($rowref->{'marcxml_old'}), 'UTF-8', $rowref->{'encoding'});
610
0
            my $biblionumber = $rowref->{'matched_biblionumber'};
611
0
            my ($count, $oldbiblio) = GetBiblio($biblionumber);
612
0
            $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
613
0
            ModBiblio($old_record, $biblionumber, $oldbiblio->{'frameworkcode'});
614
0
            SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
615        } elsif ($bib_result eq 'ignore') {
616
0
            $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
617
0
            SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
618        }
619
0
        my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = NULL WHERE import_record_id = ?");
620
0
        $sth2->execute($rowref->{'import_record_id'});
621    }
622
623
0
    $sth->finish();
624
0
    SetImportBatchStatus($batch_id, 'reverted');
625
0
    return ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, $num_ignored);
626}
627
628 - 632
=head2 BatchRevertItems

  my $num_items_deleted = BatchRevertItems($import_record_id, $biblionumber);

=cut
633
634sub BatchRevertItems {
635
0
    my ($import_record_id, $biblionumber) = @_;
636
637
0
    my $dbh = C4::Context->dbh;
638
0
    my $num_items_deleted = 0;
639
640
0
    my $sth = $dbh->prepare_cached("SELECT import_items_id, itemnumber
641                                   FROM import_items
642                                   JOIN items USING (itemnumber)
643                                   WHERE import_record_id = ?");
644
0
    $sth->bind_param(1, $import_record_id);
645
0
    $sth->execute();
646
0
    while (my $row = $sth->fetchrow_hashref()) {
647
0
        DelItem($dbh, $biblionumber, $row->{'itemnumber'});
648
0
        my $updsth = $dbh->prepare("UPDATE import_items SET status = ? WHERE import_items_id = ?");
649
0
        $updsth->bind_param(1, 'reverted');
650
0
        $updsth->bind_param(2, $row->{'import_items_id'});
651
0
        $updsth->execute();
652
0
        $updsth->finish();
653
0
        $num_items_deleted++;
654    }
655
0
    $sth->finish();
656
0
    return $num_items_deleted;
657}
658
659 - 668
=head2 CleanBatch

  CleanBatch($batch_id)

Deletes all staged records from the import batch
and sets the status of the batch to 'cleaned'.  Note
that deleting a stage record does *not* affect
any record that has been committed to the database.

=cut
669
670sub CleanBatch {
671
0
    my $batch_id = shift;
672
0
    return unless defined $batch_id;
673
674
0
    C4::Context->dbh->do('DELETE FROM import_records WHERE import_batch_id = ?', {}, $batch_id);
675
0
    SetImportBatchStatus($batch_id, 'cleaned');
676}
677
678 - 686
=head2 GetAllImportBatches

  my $results = GetAllImportBatches();

Returns a references to an array of hash references corresponding
to all import_batches rows (of batch_type 'batch'), sorted in 
ascending order by import_batch_id.

=cut
687
688sub GetAllImportBatches {
689
0
    my $dbh = C4::Context->dbh;
690
0
    my $sth = $dbh->prepare_cached("SELECT * FROM import_batches
691                                    WHERE batch_type = 'batch'
692                                    ORDER BY import_batch_id ASC");
693
694
0
    my $results = [];
695
0
    $sth->execute();
696
0
    while (my $row = $sth->fetchrow_hashref) {
697
0
        push @$results, $row;
698    }
699
0
    $sth->finish();
700
0
    return $results;
701}
702
703 - 711
=head2 GetImportBatchRangeDesc

  my $results = GetImportBatchRangeDesc($offset, $results_per_group);

Returns a reference to an array of hash references corresponding to
import_batches rows (sorted in descending order by import_batch_id)
start at the given offset.

=cut
712
713sub GetImportBatchRangeDesc {
714
0
    my ($offset, $results_per_group) = @_;
715
716
0
    my $dbh = C4::Context->dbh;
717
0
    my $query = "SELECT * FROM import_batches
718                                    WHERE batch_type = 'batch'
719                                    ORDER BY import_batch_id DESC";
720
0
    my @params;
721
0
    if ($results_per_group){
722
0
        $query .= " LIMIT ?";
723
0
        push(@params, $results_per_group);
724    }
725
0
    if ($offset){
726
0
        $query .= " OFFSET ?";
727
0
        push(@params, $offset);
728    }
729
0
    my $sth = $dbh->prepare_cached($query);
730
0
    $sth->execute(@params);
731
0
    my $results = $sth->fetchall_arrayref({});
732
0
    $sth->finish();
733
0
    return $results;
734}
735
736 - 740
=head2 GetItemNumbersFromImportBatch

  my @itemsnos = GetItemNumbersFromImportBatch($batch_id);

=cut
741
742sub GetItemNumbersFromImportBatch {
743
0
        my ($batch_id) = @_;
744
0
  my $dbh = C4::Context->dbh;
745
0
        my $sth = $dbh->prepare("SELECT itemnumber FROM import_batches,import_records,import_items WHERE import_batches.import_batch_id=import_records.import_batch_id AND import_records.import_record_id=import_items.import_record_id AND import_batches.import_batch_id=?");
746
0
        $sth->execute($batch_id);
747
0
        my @items ;
748
0
        while ( my ($itm) = $sth->fetchrow_array ) {
749
0
                push @items, $itm;
750        }
751
0
        return @items;
752}
753
754 - 758
=head2 GetNumberOfImportBatches 

  my $count = GetNumberOfImportBatches();

=cut
759
760sub GetNumberOfNonZ3950ImportBatches {
761
0
    my $dbh = C4::Context->dbh;
762
0
    my $sth = $dbh->prepare("SELECT COUNT(*) FROM import_batches WHERE batch_type='batch'");
763
0
    $sth->execute();
764
0
    my ($count) = $sth->fetchrow_array();
765
0
    $sth->finish();
766
0
    return $count;
767}
768
769 - 777
=head2 GetImportBibliosRange

  my $results = GetImportBibliosRange($batch_id, $offset, $results_per_group);

Returns a reference to an array of hash references corresponding to
import_biblios/import_records rows for a given batch
starting at the given offset.

=cut
778
779sub GetImportBibliosRange {
780
0
    my ($batch_id, $offset, $results_per_group, $status) = @_;
781
782
0
    my $dbh = C4::Context->dbh;
783
0
    my $query = "SELECT title, author, isbn, issn, import_record_id, record_sequence,
784                                           status, overlay_status, matched_biblionumber
785                                    FROM import_records
786                                    JOIN import_biblios USING (import_record_id)
787                                    WHERE import_batch_id = ?";
788
0
    my @params;
789
0
    push(@params, $batch_id);
790
0
    if ($status) {
791
0
        $query .= " AND status=?";
792
0
        push(@params,$status);
793    }
794
0
    $query.=" ORDER BY import_record_id";
795
796
0
    if($results_per_group){
797
0
        $query .= " LIMIT ?";
798
0
        push(@params, $results_per_group);
799    }
800
0
    if($offset){
801
0
        $query .= " OFFSET ?";
802
0
        push(@params, $offset);
803    }
804
0
    my $sth = $dbh->prepare_cached($query);
805
0
    $sth->execute(@params);
806
0
    my $results = $sth->fetchall_arrayref({});
807
0
    $sth->finish();
808
0
    return $results;
809
810}
811
812 - 816
=head2 GetBestRecordMatch

  my $record_id = GetBestRecordMatch($import_record_id);

=cut
817
818sub GetBestRecordMatch {
819
0
    my ($import_record_id) = @_;
820
821
0
    my $dbh = C4::Context->dbh;
822
0
    my $sth = $dbh->prepare("SELECT candidate_match_id
823                             FROM import_record_matches
824                             WHERE import_record_id = ?
825                             ORDER BY score DESC, candidate_match_id DESC");
826
0
    $sth->execute($import_record_id);
827
0
    my ($record_id) = $sth->fetchrow_array();
828
0
    $sth->finish();
829
0
    return $record_id;
830}
831
832 - 836
=head2 GetImportBatchStatus

  my $status = GetImportBatchStatus($batch_id);

=cut
837
838sub GetImportBatchStatus {
839
0
    my ($batch_id) = @_;
840
841
0
    my $dbh = C4::Context->dbh;
842
0
    my $sth = $dbh->prepare("SELECT import_status FROM import_batches WHERE import_batch_id = ?");
843
0
    $sth->execute($batch_id);
844
0
    my ($status) = $sth->fetchrow_array();
845
0
    $sth->finish();
846
0
    return $status;
847
848}
849
850 - 854
=head2 SetImportBatchStatus

  SetImportBatchStatus($batch_id, $new_status);

=cut
855
856sub SetImportBatchStatus {
857
0
    my ($batch_id, $new_status) = @_;
858
859
0
    my $dbh = C4::Context->dbh;
860
0
    my $sth = $dbh->prepare("UPDATE import_batches SET import_status = ? WHERE import_batch_id = ?");
861
0
    $sth->execute($new_status, $batch_id);
862
0
    $sth->finish();
863
864}
865
866 - 870
=head2 GetImportBatchOverlayAction

  my $overlay_action = GetImportBatchOverlayAction($batch_id);

=cut
871
872sub GetImportBatchOverlayAction {
873
0
    my ($batch_id) = @_;
874
875
0
    my $dbh = C4::Context->dbh;
876
0
    my $sth = $dbh->prepare("SELECT overlay_action FROM import_batches WHERE import_batch_id = ?");
877
0
    $sth->execute($batch_id);
878
0
    my ($overlay_action) = $sth->fetchrow_array();
879
0
    $sth->finish();
880
0
    return $overlay_action;
881
882}
883
884
885 - 889
=head2 SetImportBatchOverlayAction

  SetImportBatchOverlayAction($batch_id, $new_overlay_action);

=cut
890
891sub SetImportBatchOverlayAction {
892
0
    my ($batch_id, $new_overlay_action) = @_;
893
894
0
    my $dbh = C4::Context->dbh;
895
0
    my $sth = $dbh->prepare("UPDATE import_batches SET overlay_action = ? WHERE import_batch_id = ?");
896
0
    $sth->execute($new_overlay_action, $batch_id);
897
0
    $sth->finish();
898
899}
900
901 - 905
=head2 GetImportBatchNoMatchAction

  my $nomatch_action = GetImportBatchNoMatchAction($batch_id);

=cut
906
907sub GetImportBatchNoMatchAction {
908
0
    my ($batch_id) = @_;
909
910
0
    my $dbh = C4::Context->dbh;
911
0
    my $sth = $dbh->prepare("SELECT nomatch_action FROM import_batches WHERE import_batch_id = ?");
912
0
    $sth->execute($batch_id);
913
0
    my ($nomatch_action) = $sth->fetchrow_array();
914
0
    $sth->finish();
915
0
    return $nomatch_action;
916
917}
918
919
920 - 924
=head2 SetImportBatchNoMatchAction

  SetImportBatchNoMatchAction($batch_id, $new_nomatch_action);

=cut
925
926sub SetImportBatchNoMatchAction {
927
0
    my ($batch_id, $new_nomatch_action) = @_;
928
929
0
    my $dbh = C4::Context->dbh;
930
0
    my $sth = $dbh->prepare("UPDATE import_batches SET nomatch_action = ? WHERE import_batch_id = ?");
931
0
    $sth->execute($new_nomatch_action, $batch_id);
932
0
    $sth->finish();
933
934}
935
936 - 940
=head2 GetImportBatchItemAction

  my $item_action = GetImportBatchItemAction($batch_id);

=cut
941
942sub GetImportBatchItemAction {
943
0
    my ($batch_id) = @_;
944
945
0
    my $dbh = C4::Context->dbh;
946
0
    my $sth = $dbh->prepare("SELECT item_action FROM import_batches WHERE import_batch_id = ?");
947
0
    $sth->execute($batch_id);
948
0
    my ($item_action) = $sth->fetchrow_array();
949
0
    $sth->finish();
950
0
    return $item_action;
951
952}
953
954
955 - 959
=head2 SetImportBatchItemAction

  SetImportBatchItemAction($batch_id, $new_item_action);

=cut
960
961sub SetImportBatchItemAction {
962
0
    my ($batch_id, $new_item_action) = @_;
963
964
0
    my $dbh = C4::Context->dbh;
965
0
    my $sth = $dbh->prepare("UPDATE import_batches SET item_action = ? WHERE import_batch_id = ?");
966
0
    $sth->execute($new_item_action, $batch_id);
967
0
    $sth->finish();
968
969}
970
971 - 975
=head2 GetImportBatchMatcher

  my $matcher_id = GetImportBatchMatcher($batch_id);

=cut
976
977sub GetImportBatchMatcher {
978
0
    my ($batch_id) = @_;
979
980
0
    my $dbh = C4::Context->dbh;
981
0
    my $sth = $dbh->prepare("SELECT matcher_id FROM import_batches WHERE import_batch_id = ?");
982
0
    $sth->execute($batch_id);
983
0
    my ($matcher_id) = $sth->fetchrow_array();
984
0
    $sth->finish();
985
0
    return $matcher_id;
986
987}
988
989
990 - 994
=head2 SetImportBatchMatcher

  SetImportBatchMatcher($batch_id, $new_matcher_id);

=cut
995
996sub SetImportBatchMatcher {
997
0
    my ($batch_id, $new_matcher_id) = @_;
998
999
0
    my $dbh = C4::Context->dbh;
1000
0
    my $sth = $dbh->prepare("UPDATE import_batches SET matcher_id = ? WHERE import_batch_id = ?");
1001
0
    $sth->execute($new_matcher_id, $batch_id);
1002
0
    $sth->finish();
1003
1004}
1005
1006 - 1010
=head2 GetImportRecordOverlayStatus

  my $overlay_status = GetImportRecordOverlayStatus($import_record_id);

=cut
1011
1012sub GetImportRecordOverlayStatus {
1013
0
    my ($import_record_id) = @_;
1014
1015
0
    my $dbh = C4::Context->dbh;
1016
0
    my $sth = $dbh->prepare("SELECT overlay_status FROM import_records WHERE import_record_id = ?");
1017
0
    $sth->execute($import_record_id);
1018
0
    my ($overlay_status) = $sth->fetchrow_array();
1019
0
    $sth->finish();
1020
0
    return $overlay_status;
1021
1022}
1023
1024
1025 - 1029
=head2 SetImportRecordOverlayStatus

  SetImportRecordOverlayStatus($import_record_id, $new_overlay_status);

=cut
1030
1031sub SetImportRecordOverlayStatus {
1032
0
    my ($import_record_id, $new_overlay_status) = @_;
1033
1034
0
    my $dbh = C4::Context->dbh;
1035
0
    my $sth = $dbh->prepare("UPDATE import_records SET overlay_status = ? WHERE import_record_id = ?");
1036
0
    $sth->execute($new_overlay_status, $import_record_id);
1037
0
    $sth->finish();
1038
1039}
1040
1041 - 1045
=head2 GetImportRecordStatus

  my $overlay_status = GetImportRecordStatus($import_record_id);

=cut
1046
1047sub GetImportRecordStatus {
1048
0
    my ($import_record_id) = @_;
1049
1050
0
    my $dbh = C4::Context->dbh;
1051
0
    my $sth = $dbh->prepare("SELECT status FROM import_records WHERE import_record_id = ?");
1052
0
    $sth->execute($import_record_id);
1053
0
    my ($overlay_status) = $sth->fetchrow_array();
1054
0
    $sth->finish();
1055
0
    return $overlay_status;
1056
1057}
1058
1059
1060 - 1064
=head2 SetImportRecordStatus

  SetImportRecordStatus($import_record_id, $new_overlay_status);

=cut
1065
1066sub SetImportRecordStatus {
1067
0
    my ($import_record_id, $new_overlay_status) = @_;
1068
1069
0
    my $dbh = C4::Context->dbh;
1070
0
    my $sth = $dbh->prepare("UPDATE import_records SET status = ? WHERE import_record_id = ?");
1071
0
    $sth->execute($new_overlay_status, $import_record_id);
1072
0
    $sth->finish();
1073
1074}
1075
1076 - 1080
=head2 GetImportRecordMatches

  my $results = GetImportRecordMatches($import_record_id, $best_only);

=cut
1081
1082sub GetImportRecordMatches {
1083
0
    my $import_record_id = shift;
1084
0
    my $best_only = @_ ? shift : 0;
1085
1086
0
    my $dbh = C4::Context->dbh;
1087    # FIXME currently biblio only
1088
0
    my $sth = $dbh->prepare_cached("SELECT title, author, biblionumber, score
1089                                    FROM import_records
1090                                    JOIN import_record_matches USING (import_record_id)
1091                                    JOIN biblio ON (biblionumber = candidate_match_id)
1092                                    WHERE import_record_id = ?
1093                                    ORDER BY score DESC, biblionumber DESC");
1094
0
    $sth->bind_param(1, $import_record_id);
1095
0
    my $results = [];
1096
0
    $sth->execute();
1097
0
    while (my $row = $sth->fetchrow_hashref) {
1098
0
        push @$results, $row;
1099
0
        last if $best_only;
1100    }
1101
0
    $sth->finish();
1102
1103
0
    return $results;
1104
1105}
1106
1107
1108 - 1112
=head2 SetImportRecordMatches

  SetImportRecordMatches($import_record_id, @matches);

=cut
1113
1114sub SetImportRecordMatches {
1115
0
    my $import_record_id = shift;
1116
0
    my @matches = @_;
1117
1118
0
    my $dbh = C4::Context->dbh;
1119
0
    my $delsth = $dbh->prepare("DELETE FROM import_record_matches WHERE import_record_id = ?");
1120
0
    $delsth->execute($import_record_id);
1121
0
    $delsth->finish();
1122
1123
0
    my $sth = $dbh->prepare("INSERT INTO import_record_matches (import_record_id, candidate_match_id, score)
1124                                    VALUES (?, ?, ?)");
1125
0
    foreach my $match (@matches) {
1126
0
        $sth->execute($import_record_id, $match->{'record_id'}, $match->{'score'});
1127    }
1128}
1129
1130
1131# internal functions
1132
1133sub _create_import_record {
1134
0
    my ($batch_id, $record_sequence, $marc_record, $record_type, $encoding, $z3950random) = @_;
1135
1136
0
    my $dbh = C4::Context->dbh;
1137
0
    my $sth = $dbh->prepare("INSERT INTO import_records (import_batch_id, record_sequence, marc, marcxml,
1138                                                         record_type, encoding, z3950random)
1139                                    VALUES (?, ?, ?, ?, ?, ?, ?)");
1140
0
    $sth->execute($batch_id, $record_sequence, $marc_record->as_usmarc(), $marc_record->as_xml(),
1141                  $record_type, $encoding, $z3950random);
1142
0
    my $import_record_id = $dbh->{'mysql_insertid'};
1143
0
    $sth->finish();
1144
0
    return $import_record_id;
1145}
1146
1147sub _update_import_record_marc {
1148
0
    my ($import_record_id, $marc_record) = @_;
1149
1150
0
    my $dbh = C4::Context->dbh;
1151
0
    my $sth = $dbh->prepare("UPDATE import_records SET marc = ?, marcxml = ?
1152                             WHERE import_record_id = ?");
1153
0
    $sth->execute($marc_record->as_usmarc(), $marc_record->as_xml(C4::Context->preference('marcflavour')), $import_record_id);
1154
0
    $sth->finish();
1155}
1156
1157sub _add_biblio_fields {
1158
0
    my ($import_record_id, $marc_record) = @_;
1159
1160
0
    my ($title, $author, $isbn, $issn) = _parse_biblio_fields($marc_record);
1161
0
    my $dbh = C4::Context->dbh;
1162    # FIXME no controlnumber, originalsource
1163
0
    $isbn = C4::Koha::_isbn_cleanup($isbn); # FIXME C4::Koha::_isbn_cleanup should be made public
1164
0
    my $sth = $dbh->prepare("INSERT INTO import_biblios (import_record_id, title, author, isbn, issn) VALUES (?, ?, ?, ?, ?)");
1165
0
    $sth->execute($import_record_id, $title, $author, $isbn, $issn);
1166
0
    $sth->finish();
1167
1168}
1169
1170sub _update_biblio_fields {
1171
0
    my ($import_record_id, $marc_record) = @_;
1172
1173
0
    my ($title, $author, $isbn, $issn) = _parse_biblio_fields($marc_record);
1174
0
    my $dbh = C4::Context->dbh;
1175    # FIXME no controlnumber, originalsource
1176    # FIXME 2 - should regularize normalization of ISBN wherever it is done
1177
0
    $isbn =~ s/\(.*$//;
1178
0
    $isbn =~ tr/ -_//;
1179
0
    $isbn = uc $isbn;
1180
0
    my $sth = $dbh->prepare("UPDATE import_biblios SET title = ?, author = ?, isbn = ?, issn = ?
1181                             WHERE import_record_id = ?");
1182
0
    $sth->execute($title, $author, $isbn, $issn, $import_record_id);
1183
0
    $sth->finish();
1184}
1185
1186sub _parse_biblio_fields {
1187
0
    my ($marc_record) = @_;
1188
1189
0
    my $dbh = C4::Context->dbh;
1190
0
    my $bibliofields = TransformMarcToKoha($dbh, $marc_record, '');
1191
0
    return ($bibliofields->{'title'}, $bibliofields->{'author'}, $bibliofields->{'isbn'}, $bibliofields->{'issn'});
1192
1193}
1194
1195sub _update_batch_record_counts {
1196
0
    my ($batch_id) = @_;
1197
1198
0
    my $dbh = C4::Context->dbh;
1199
0
    my $sth = $dbh->prepare_cached("UPDATE import_batches SET num_biblios = (
1200                                    SELECT COUNT(*)
1201                                    FROM import_records
1202                                    WHERE import_batch_id = import_batches.import_batch_id
1203                                    AND record_type = 'biblio')
1204                                    WHERE import_batch_id = ?");
1205
0
    $sth->bind_param(1, $batch_id);
1206
0
    $sth->execute();
1207
0
    $sth->finish();
1208
0
    $sth = $dbh->prepare_cached("UPDATE import_batches SET num_items = (
1209                                    SELECT COUNT(*)
1210                                    FROM import_records
1211                                    JOIN import_items USING (import_record_id)
1212                                    WHERE import_batch_id = import_batches.import_batch_id
1213                                    AND record_type = 'biblio')
1214                                    WHERE import_batch_id = ?");
1215
0
    $sth->bind_param(1, $batch_id);
1216
0
    $sth->execute();
1217
0
    $sth->finish();
1218
1219}
1220
1221sub _get_commit_action {
1222
0
    my ($overlay_action, $nomatch_action, $item_action, $overlay_status, $import_record_id) = @_;
1223
1224
0
    my ($bib_result, $bib_match, $item_result);
1225
1226
0
    if ($overlay_status ne 'no_match') {
1227
0
        $bib_match = GetBestRecordMatch($import_record_id);
1228
0
        if ($overlay_action eq 'replace') {
1229
0
            $bib_result = defined($bib_match) ? 'replace' : 'create_new';
1230        } elsif ($overlay_action eq 'create_new') {
1231
0
            $bib_result = 'create_new';
1232        } elsif ($overlay_action eq 'ignore') {
1233
0
            $bib_result = 'ignore';
1234        }
1235
0
        $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_matches') ? 'create_new' : 'ignore';
1236    } else {
1237
0
        $bib_result = $nomatch_action;
1238
0
        $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_new') ? 'create_new' : 'ignore';
1239    }
1240
1241
0
    return ($bib_result, $item_result, $bib_match);
1242}
1243
1244sub _get_revert_action {
1245
0
    my ($overlay_action, $overlay_status, $status) = @_;
1246
1247
0
    my $bib_result;
1248
1249
0
    if ($status eq 'ignored') {
1250
0
        $bib_result = 'ignore';
1251    } else {
1252
0
        if ($overlay_action eq 'create_new') {
1253
0
            $bib_result = 'delete';
1254        } else {
1255
0
            $bib_result = ($overlay_status eq 'match_applied') ? 'restore' : 'delete';
1256        }
1257    }
1258
0
    return $bib_result;
1259}
1260
12611;