1 package C4::ImportBatch;
3 # Copyright (C) 2007 LibLime, 2012 C & P Bibliography Services
5 # This file is part of Koha.
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
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.
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.
28 use C4::AuthoritiesMarc;
29 use C4::MarcModificationTemplates;
31 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
34 # set the version for version checking
35 $VERSION = 3.07.00.049;
42 GetImportRecordMarcXML
47 AddItemsToImportBiblio
58 GetStagedWebserviceBatches
59 GetImportBatchRangeDesc
60 GetNumberOfNonZ3950ImportBatches
63 GetItemNumbersFromImportBatch
67 GetImportBatchOverlayAction
68 SetImportBatchOverlayAction
69 GetImportBatchNoMatchAction
70 SetImportBatchNoMatchAction
71 GetImportBatchItemAction
72 SetImportBatchItemAction
75 GetImportRecordOverlayStatus
76 SetImportRecordOverlayStatus
79 GetImportRecordMatches
80 SetImportRecordMatches
86 C4::ImportBatch - manage batches of imported MARC records
94 =head2 GetZ3950BatchId
96 my $batchid = GetZ3950BatchId($z3950server);
98 Retrieves the ID of the import batch for the Z39.50
99 reservoir for the given target. If necessary,
100 creates the import batch.
104 sub GetZ3950BatchId {
105 my ($z3950server) = @_;
107 my $dbh = C4::Context->dbh;
108 my $sth = $dbh->prepare("SELECT import_batch_id FROM import_batches
109 WHERE batch_type = 'z3950'
111 $sth->execute($z3950server);
112 my $rowref = $sth->fetchrow_arrayref();
114 if (defined $rowref) {
117 my $batch_id = AddImportBatch( {
118 overlay_action => 'create_new',
119 import_status => 'staged',
120 batch_type => 'z3950',
121 file_name => $z3950server,
128 =head2 GetWebserviceBatchId
130 my $batchid = GetWebserviceBatchId();
132 Retrieves the ID of the import batch for webservice.
133 If necessary, creates the import batch.
137 my $WEBSERVICE_BASE_QRY = <<EOQ;
138 SELECT import_batch_id FROM import_batches
139 WHERE batch_type = 'webservice'
140 AND import_status = 'staged'
142 sub GetWebserviceBatchId {
145 my $dbh = C4::Context->dbh;
146 my $sql = $WEBSERVICE_BASE_QRY;
148 foreach my $field (qw(matcher_id overlay_action nomatch_action item_action)) {
149 if (my $val = $params->{$field}) {
150 $sql .= " AND $field = ?";
154 my $id = $dbh->selectrow_array($sql, undef, @args);
157 $params->{batch_type} = 'webservice';
158 $params->{import_status} = 'staged';
159 return AddImportBatch($params);
162 =head2 GetImportRecordMarc
164 my ($marcblob, $encoding) = GetImportRecordMarc($import_record_id);
168 sub GetImportRecordMarc {
169 my ($import_record_id) = @_;
171 my $dbh = C4::Context->dbh;
172 my $sth = $dbh->prepare("SELECT marc, encoding FROM import_records WHERE import_record_id = ?");
173 $sth->execute($import_record_id);
174 my ($marc, $encoding) = $sth->fetchrow();
176 return $marc, $encoding;
180 =head2 GetImportRecordMarcXML
182 my $marcxml = GetImportRecordMarcXML($import_record_id);
186 sub GetImportRecordMarcXML {
187 my ($import_record_id) = @_;
189 my $dbh = C4::Context->dbh;
190 my $sth = $dbh->prepare("SELECT marcxml FROM import_records WHERE import_record_id = ?");
191 $sth->execute($import_record_id);
192 my ($marcxml) = $sth->fetchrow();
198 =head2 AddImportBatch
200 my $batch_id = AddImportBatch($params_hash);
208 foreach (qw( matcher_id template_id branchcode
209 overlay_action nomatch_action item_action
210 import_status batch_type file_name comments record_type )) {
211 if (exists $params->{$_}) {
213 push @vals, $params->{$_};
216 my $dbh = C4::Context->dbh;
217 $dbh->do("INSERT INTO import_batches (".join( ',', @fields).")
218 VALUES (".join( ',', map '?', @fields).")",
221 return $dbh->{'mysql_insertid'};
224 =head2 GetImportBatch
226 my $row = GetImportBatch($batch_id);
228 Retrieve a hashref of an import_batches row.
235 my $dbh = C4::Context->dbh;
236 my $sth = $dbh->prepare_cached("SELECT * FROM import_batches WHERE import_batch_id = ?");
237 $sth->bind_param(1, $batch_id);
239 my $result = $sth->fetchrow_hashref;
245 =head2 AddBiblioToBatch
247 my $import_record_id = AddBiblioToBatch($batch_id, $record_sequence,
248 $marc_record, $encoding, $z3950random, $update_counts);
252 sub AddBiblioToBatch {
253 my $batch_id = shift;
254 my $record_sequence = shift;
255 my $marc_record = shift;
256 my $encoding = shift;
257 my $z3950random = shift;
258 my $update_counts = @_ ? shift : 1;
260 my $import_record_id = _create_import_record($batch_id, $record_sequence, $marc_record, 'biblio', $encoding, $z3950random, C4::Context->preference('marcflavour'));
261 _add_biblio_fields($import_record_id, $marc_record);
262 _update_batch_record_counts($batch_id) if $update_counts;
263 return $import_record_id;
266 =head2 ModBiblioInBatch
268 ModBiblioInBatch($import_record_id, $marc_record);
272 sub ModBiblioInBatch {
273 my ($import_record_id, $marc_record) = @_;
275 _update_import_record_marc($import_record_id, $marc_record, C4::Context->preference('marcflavour'));
276 _update_biblio_fields($import_record_id, $marc_record);
280 =head2 AddAuthToBatch
282 my $import_record_id = AddAuthToBatch($batch_id, $record_sequence,
283 $marc_record, $encoding, $z3950random, $update_counts, [$marc_type]);
288 my $batch_id = shift;
289 my $record_sequence = shift;
290 my $marc_record = shift;
291 my $encoding = shift;
292 my $z3950random = shift;
293 my $update_counts = @_ ? shift : 1;
294 my $marc_type = shift || C4::Context->preference('marcflavour');
296 $marc_type = 'UNIMARCAUTH' if $marc_type eq 'UNIMARC';
298 my $import_record_id = _create_import_record($batch_id, $record_sequence, $marc_record, 'auth', $encoding, $z3950random, $marc_type);
299 _add_auth_fields($import_record_id, $marc_record);
300 _update_batch_record_counts($batch_id) if $update_counts;
301 return $import_record_id;
304 =head2 ModAuthInBatch
306 ModAuthInBatch($import_record_id, $marc_record);
311 my ($import_record_id, $marc_record) = @_;
313 my $marcflavour = C4::Context->preference('marcflavour');
314 _update_import_record_marc($import_record_id, $marc_record, $marcflavour eq 'UNIMARC' ? 'UNIMARCAUTH' : 'USMARC');
318 =head2 BatchStageMarcRecords
320 ($batch_id, $num_records, $num_items, @invalid_records) =
321 BatchStageMarcRecords($encoding, $marc_records, $file_name, $marc_modification_template,
322 $comments, $branch_code, $parse_items,
324 $progress_interval, $progress_callback);
328 sub BatchStageMarcRecords {
329 my $record_type = shift;
330 my $encoding = shift;
331 my $marc_records = shift;
332 my $file_name = shift;
333 my $marc_modification_template = shift;
334 my $comments = shift;
335 my $branch_code = shift;
336 my $parse_items = shift;
337 my $leave_as_staging = shift;
339 # optional callback to monitor status
341 my $progress_interval = 0;
342 my $progress_callback = undef;
344 $progress_interval = shift;
345 $progress_callback = shift;
346 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
347 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
350 my $batch_id = AddImportBatch( {
351 overlay_action => 'create_new',
352 import_status => 'staging',
353 batch_type => 'batch',
354 file_name => $file_name,
355 comments => $comments,
356 record_type => $record_type,
359 SetImportBatchItemAction($batch_id, 'always_add');
361 SetImportBatchItemAction($batch_id, 'ignore');
364 my $marc_type = C4::Context->preference('marcflavour');
365 $marc_type .= 'AUTH' if ($marc_type eq 'UNIMARC' && $record_type eq 'auth');
366 my @invalid_records = ();
369 # FIXME - for now, we're dealing only with bibs
371 foreach my $marc_blob (split(/\x1D/, $marc_records)) {
372 $marc_blob =~ s/^\s+//g;
373 $marc_blob =~ s/\s+$//g;
374 next unless $marc_blob;
376 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
377 &$progress_callback($rec_num);
379 my ($marc_record, $charset_guessed, $char_errors) =
380 MarcToUTF8Record($marc_blob, $marc_type, $encoding);
382 $encoding = $charset_guessed unless $encoding;
384 ModifyRecordWithTemplate( $marc_modification_template, $marc_record ) if ( $marc_modification_template );
386 my $import_record_id;
387 if (scalar($marc_record->fields()) == 0) {
388 push @invalid_records, $marc_blob;
391 # Normalize the record so it doesn't have separated diacritics
392 SetUTF8Flag($marc_record);
395 if ($record_type eq 'biblio') {
396 $import_record_id = AddBiblioToBatch($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0);
398 my @import_items_ids = AddItemsToImportBiblio($batch_id, $import_record_id, $marc_record, 0);
399 $num_items += scalar(@import_items_ids);
401 } elsif ($record_type eq 'auth') {
402 $import_record_id = AddAuthToBatch($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0, $marc_type);
406 unless ($leave_as_staging) {
407 SetImportBatchStatus($batch_id, 'staged');
409 # FIXME branch_code, number of bibs, number of items
410 _update_batch_record_counts($batch_id);
411 return ($batch_id, $num_valid, $num_items, @invalid_records);
414 =head2 AddItemsToImportBiblio
416 my @import_items_ids = AddItemsToImportBiblio($batch_id,
417 $import_record_id, $marc_record, $update_counts);
421 sub AddItemsToImportBiblio {
422 my $batch_id = shift;
423 my $import_record_id = shift;
424 my $marc_record = shift;
425 my $update_counts = @_ ? shift : 0;
427 my @import_items_ids = ();
429 my $dbh = C4::Context->dbh;
430 my ($item_tag,$item_subfield) = &GetMarcFromKohaField("items.itemnumber",'');
431 foreach my $item_field ($marc_record->field($item_tag)) {
432 my $item_marc = MARC::Record->new();
433 $item_marc->leader("00000 a "); # must set Leader/09 to 'a'
434 $item_marc->append_fields($item_field);
435 $marc_record->delete_field($item_field);
436 my $sth = $dbh->prepare_cached("INSERT INTO import_items (import_record_id, status, marcxml)
438 $sth->bind_param(1, $import_record_id);
439 $sth->bind_param(2, 'staged');
440 $sth->bind_param(3, $item_marc->as_xml());
442 push @import_items_ids, $dbh->{'mysql_insertid'};
446 if ($#import_items_ids > -1) {
447 _update_batch_record_counts($batch_id) if $update_counts;
448 _update_import_record_marc($import_record_id, $marc_record, C4::Context->preference('marcflavour'));
450 return @import_items_ids;
453 =head2 BatchFindDuplicates
455 my $num_with_matches = BatchFindDuplicates($batch_id, $matcher,
456 $max_matches, $progress_interval, $progress_callback);
458 Goes through the records loaded in the batch and attempts to
459 find duplicates for each one. Sets the matching status
460 of each record to "no_match" or "auto_match" as appropriate.
462 The $max_matches parameter is optional; if it is not supplied,
465 The $progress_interval and $progress_callback parameters are
466 optional; if both are supplied, the sub referred to by
467 $progress_callback will be invoked every $progress_interval
468 records using the number of records processed as the
473 sub BatchFindDuplicates {
474 my $batch_id = shift;
476 my $max_matches = @_ ? shift : 10;
478 # optional callback to monitor status
480 my $progress_interval = 0;
481 my $progress_callback = undef;
483 $progress_interval = shift;
484 $progress_callback = shift;
485 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
486 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
489 my $dbh = C4::Context->dbh;
491 my $sth = $dbh->prepare("SELECT import_record_id, record_type, marc
493 WHERE import_batch_id = ?");
494 $sth->execute($batch_id);
495 my $num_with_matches = 0;
497 while (my $rowref = $sth->fetchrow_hashref) {
499 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
500 &$progress_callback($rec_num);
502 my $marc_record = MARC::Record->new_from_usmarc($rowref->{'marc'});
504 if (defined $matcher) {
505 @matches = $matcher->get_matches($marc_record, $max_matches);
507 if (scalar(@matches) > 0) {
509 SetImportRecordMatches($rowref->{'import_record_id'}, @matches);
510 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'auto_match');
512 SetImportRecordMatches($rowref->{'import_record_id'}, ());
513 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'no_match');
517 return $num_with_matches;
520 =head2 BatchCommitRecords
522 my ($num_added, $num_updated, $num_items_added, $num_items_replaced, $num_items_errored, $num_ignored) =
523 BatchCommitRecords($batch_id, $framework,
524 $progress_interval, $progress_callback);
528 sub BatchCommitRecords {
529 my $batch_id = shift;
530 my $framework = shift;
532 # optional callback to monitor status
534 my $progress_interval = 0;
535 my $progress_callback = undef;
537 $progress_interval = shift;
538 $progress_callback = shift;
539 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
540 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
546 my $num_items_added = 0;
547 my $num_items_replaced = 0;
548 my $num_items_errored = 0;
550 # commit (i.e., save, all records in the batch)
551 SetImportBatchStatus('importing');
552 my $overlay_action = GetImportBatchOverlayAction($batch_id);
553 my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
554 my $item_action = GetImportBatchItemAction($batch_id);
557 my $dbh = C4::Context->dbh;
558 my $sth = $dbh->prepare("SELECT import_records.import_record_id, record_type, status, overlay_status, marc, encoding
560 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
561 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
562 WHERE import_batch_id = ?");
563 $sth->execute($batch_id);
564 my $marcflavour = C4::Context->preference('marcflavour');
566 while (my $rowref = $sth->fetchrow_hashref) {
567 $record_type = $rowref->{'record_type'};
569 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
570 &$progress_callback($rec_num);
572 if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'imported') {
578 if ($marcflavour eq 'UNIMARC' && $record_type eq 'auth') {
579 $marc_type = 'UNIMARCAUTH';
580 } elsif ($marcflavour eq 'UNIMARC') {
581 $marc_type = 'UNIMARC';
583 $marc_type = 'USMARC';
585 my $marc_record = MARC::Record->new_from_usmarc($rowref->{'marc'});
587 if ($record_type eq 'biblio') {
588 # remove any item tags - rely on BatchCommitItems
589 ($item_tag,$item_subfield) = &GetMarcFromKohaField("items.itemnumber",'');
590 foreach my $item_field ($marc_record->field($item_tag)) {
591 $marc_record->delete_field($item_field);
595 my ($record_result, $item_result, $record_match) =
596 _get_commit_action($overlay_action, $nomatch_action, $item_action,
597 $rowref->{'overlay_status'}, $rowref->{'import_record_id'}, $record_type);
601 if ($record_result eq 'create_new') {
603 if ($record_type eq 'biblio') {
604 my $biblioitemnumber;
605 ($recordid, $biblioitemnumber) = AddBiblio($marc_record, $framework);
606 $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?";
607 if ($item_result eq 'create_new' || $item_result eq 'replace') {
608 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result);
609 $num_items_added += $bib_items_added;
610 $num_items_replaced += $bib_items_replaced;
611 $num_items_errored += $bib_items_errored;
614 $recordid = AddAuthority($marc_record, undef, GuessAuthTypeCode($marc_record));
615 $query = "UPDATE import_auths SET matched_authid = ? WHERE import_record_id = ?";
617 my $sth = $dbh->prepare_cached($query);
618 $sth->execute($recordid, $rowref->{'import_record_id'});
620 SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
621 } elsif ($record_result eq 'replace') {
623 $recordid = $record_match;
625 if ($record_type eq 'biblio') {
626 my ($count, $oldbiblio) = GetBiblio($recordid);
627 $oldxml = GetXmlBiblio($recordid);
629 # remove item fields so that they don't get
630 # added again if record is reverted
631 # FIXME: GetXmlBiblio output should not contain item info any more! So the next foreach should not be needed. Does not hurt either; may remove old 952s that should not have been there anymore.
632 my $old_marc = MARC::Record->new_from_xml(StripNonXmlChars($oldxml), 'UTF-8', $rowref->{'encoding'}, $marc_type);
633 foreach my $item_field ($old_marc->field($item_tag)) {
634 $old_marc->delete_field($item_field);
636 $oldxml = $old_marc->as_xml($marc_type);
638 ModBiblio($marc_record, $recordid, $oldbiblio->{'frameworkcode'});
639 $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?";
641 if ($item_result eq 'create_new' || $item_result eq 'replace') {
642 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result);
643 $num_items_added += $bib_items_added;
644 $num_items_replaced += $bib_items_replaced;
645 $num_items_errored += $bib_items_errored;
648 $oldxml = GetAuthorityXML($recordid);
650 ModAuthority($recordid, $marc_record, GuessAuthTypeCode($marc_record));
651 $query = "UPDATE import_auths SET matched_authid = ? WHERE import_record_id = ?";
653 my $sth = $dbh->prepare_cached("UPDATE import_records SET marcxml_old = ? WHERE import_record_id = ?");
654 $sth->execute($oldxml, $rowref->{'import_record_id'});
656 my $sth2 = $dbh->prepare_cached($query);
657 $sth2->execute($recordid, $rowref->{'import_record_id'});
659 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
660 SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
661 } elsif ($record_result eq 'ignore') {
662 $recordid = $record_match;
664 $recordid = $record_match;
665 if ($record_type eq 'biblio' and defined $recordid and ( $item_result eq 'create_new' || $item_result eq 'replace' ) ) {
666 my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result);
667 $num_items_added += $bib_items_added;
668 $num_items_replaced += $bib_items_replaced;
669 $num_items_errored += $bib_items_errored;
670 # still need to record the matched biblionumber so that the
671 # items can be reverted
672 my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
673 $sth2->execute($recordid, $rowref->{'import_record_id'});
674 SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
676 SetImportRecordStatus($rowref->{'import_record_id'}, 'ignored');
680 SetImportBatchStatus($batch_id, 'imported');
681 return ($num_added, $num_updated, $num_items_added, $num_items_replaced, $num_items_errored, $num_ignored);
684 =head2 BatchCommitItems
686 ($num_items_added, $num_items_errored) =
687 BatchCommitItems($import_record_id, $biblionumber);
691 sub BatchCommitItems {
692 my ( $import_record_id, $biblionumber, $action ) = @_;
694 my $dbh = C4::Context->dbh;
696 my $num_items_added = 0;
697 my $num_items_errored = 0;
698 my $num_items_replaced = 0;
700 my $sth = $dbh->prepare( "
701 SELECT import_items_id, import_items.marcxml, encoding
703 JOIN import_records USING (import_record_id)
704 WHERE import_record_id = ?
705 ORDER BY import_items_id
707 $sth->bind_param( 1, $import_record_id );
710 while ( my $row = $sth->fetchrow_hashref() ) {
711 my $item_marc = MARC::Record->new_from_xml( StripNonXmlChars( $row->{'marcxml'} ), 'UTF-8', $row->{'encoding'} );
713 # Delete date_due subfield as to not accidentally delete item checkout due dates
714 my ( $MARCfield, $MARCsubfield ) = GetMarcFromKohaField( 'items.onloan', GetFrameworkCode($biblionumber) );
715 $item_marc->field($MARCfield)->delete_subfield( code => $MARCsubfield );
717 my $item = TransformMarcToKoha( $dbh, $item_marc );
719 my $duplicate_barcode = exists( $item->{'barcode'} ) && GetItemnumberFromBarcode( $item->{'barcode'} );
720 my $duplicate_itemnumber = exists( $item->{'itemnumber'} );
722 my $updsth = $dbh->prepare("UPDATE import_items SET status = ?, itemnumber = ? WHERE import_items_id = ?");
723 if ( $action eq "replace" && $duplicate_itemnumber ) {
724 # Duplicate itemnumbers have precedence, that way we can update barcodes by overlaying
725 ModItemFromMarc( $item_marc, $biblionumber, $item->{itemnumber} );
726 $updsth->bind_param( 1, 'imported' );
727 $updsth->bind_param( 2, $item->{itemnumber} );
728 $updsth->bind_param( 3, $row->{'import_items_id'} );
731 $num_items_replaced++;
732 } elsif ( $action eq "replace" && $duplicate_barcode ) {
733 my $itemnumber = GetItemnumberFromBarcode( $item->{'barcode'} );
734 ModItemFromMarc( $item_marc, $biblionumber, $itemnumber );
735 $updsth->bind_param( 1, 'imported' );
736 $updsth->bind_param( 2, $item->{itemnumber} );
737 $updsth->bind_param( 3, $row->{'import_items_id'} );
740 $num_items_replaced++;
741 } elsif ($duplicate_barcode) {
742 $updsth->bind_param( 1, 'error' );
743 $updsth->bind_param( 2, 'duplicate item barcode' );
744 $updsth->bind_param( 3, $row->{'import_items_id'} );
746 $num_items_errored++;
748 my ( $item_biblionumber, $biblioitemnumber, $itemnumber ) = AddItemFromMarc( $item_marc, $biblionumber );
749 $updsth->bind_param( 1, 'imported' );
750 $updsth->bind_param( 2, $itemnumber );
751 $updsth->bind_param( 3, $row->{'import_items_id'} );
758 return ( $num_items_added, $num_items_replaced, $num_items_errored );
761 =head2 BatchRevertRecords
763 my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted,
764 $num_ignored) = BatchRevertRecords($batch_id);
768 sub BatchRevertRecords {
769 my $batch_id = shift;
774 my $num_reverted = 0;
776 my $num_items_deleted = 0;
777 # commit (i.e., save, all records in the batch)
778 SetImportBatchStatus('reverting');
779 my $overlay_action = GetImportBatchOverlayAction($batch_id);
780 my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
781 my $dbh = C4::Context->dbh;
782 my $sth = $dbh->prepare("SELECT import_records.import_record_id, record_type, status, overlay_status, marcxml_old, encoding, matched_biblionumber, matched_authid
784 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
785 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
786 WHERE import_batch_id = ?");
787 $sth->execute($batch_id);
789 my $marcflavour = C4::Context->preference('marcflavour');
790 while (my $rowref = $sth->fetchrow_hashref) {
791 $record_type = $rowref->{'record_type'};
792 if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'reverted') {
796 if ($marcflavour eq 'UNIMARC' && $record_type eq 'auth') {
797 $marc_type = 'UNIMARCAUTH';
798 } elsif ($marcflavour eq 'UNIMARC') {
799 $marc_type = 'UNIMARC';
801 $marc_type = 'USMARC';
804 my $record_result = _get_revert_action($overlay_action, $rowref->{'overlay_status'}, $rowref->{'status'});
806 if ($record_result eq 'delete') {
808 if ($record_type eq 'biblio') {
809 $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
810 $error = DelBiblio($rowref->{'matched_biblionumber'});
812 my $deletedauthid = DelAuthority($rowref->{'matched_authid'});
814 if (defined $error) {
818 SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
820 } elsif ($record_result eq 'restore') {
822 my $old_record = MARC::Record->new_from_xml(StripNonXmlChars($rowref->{'marcxml_old'}), 'UTF-8', $rowref->{'encoding'}, $marc_type);
823 if ($record_type eq 'biblio') {
824 my $biblionumber = $rowref->{'matched_biblionumber'};
825 my ($count, $oldbiblio) = GetBiblio($biblionumber);
826 $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
827 ModBiblio($old_record, $biblionumber, $oldbiblio->{'frameworkcode'});
829 my $authid = $rowref->{'matched_authid'};
830 ModAuthority($authid, $old_record, GuessAuthTypeCode($old_record));
832 SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
833 } elsif ($record_result eq 'ignore') {
834 if ($record_type eq 'biblio') {
835 $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
837 SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
840 if ($record_type eq 'biblio') {
841 # remove matched_biblionumber only if there is no 'imported' item left
842 $query = "UPDATE import_biblios SET matched_biblionumber = NULL WHERE import_record_id = ?";
843 $query = "UPDATE import_biblios SET matched_biblionumber = NULL WHERE import_record_id = ? AND NOT EXISTS (SELECT * FROM import_items WHERE import_items.import_record_id=import_biblios.import_record_id and status='imported')";
845 $query = "UPDATE import_auths SET matched_authid = NULL WHERE import_record_id = ?";
847 my $sth2 = $dbh->prepare_cached($query);
848 $sth2->execute($rowref->{'import_record_id'});
852 SetImportBatchStatus($batch_id, 'reverted');
853 return ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, $num_ignored);
856 =head2 BatchRevertItems
858 my $num_items_deleted = BatchRevertItems($import_record_id, $biblionumber);
862 sub BatchRevertItems {
863 my ($import_record_id, $biblionumber) = @_;
865 my $dbh = C4::Context->dbh;
866 my $num_items_deleted = 0;
868 my $sth = $dbh->prepare_cached("SELECT import_items_id, itemnumber
870 JOIN items USING (itemnumber)
871 WHERE import_record_id = ?");
872 $sth->bind_param(1, $import_record_id);
874 while (my $row = $sth->fetchrow_hashref()) {
875 my $error = DelItemCheck($dbh, $biblionumber, $row->{'itemnumber'});
877 my $updsth = $dbh->prepare("UPDATE import_items SET status = ? WHERE import_items_id = ?");
878 $updsth->bind_param(1, 'reverted');
879 $updsth->bind_param(2, $row->{'import_items_id'});
882 $num_items_deleted++;
889 return $num_items_deleted;
894 CleanBatch($batch_id)
896 Deletes all staged records from the import batch
897 and sets the status of the batch to 'cleaned'. Note
898 that deleting a stage record does *not* affect
899 any record that has been committed to the database.
904 my $batch_id = shift;
905 return unless defined $batch_id;
907 C4::Context->dbh->do('DELETE FROM import_records WHERE import_batch_id = ?', {}, $batch_id);
908 SetImportBatchStatus($batch_id, 'cleaned');
911 =head2 GetAllImportBatches
913 my $results = GetAllImportBatches();
915 Returns a references to an array of hash references corresponding
916 to all import_batches rows (of batch_type 'batch'), sorted in
917 ascending order by import_batch_id.
921 sub GetAllImportBatches {
922 my $dbh = C4::Context->dbh;
923 my $sth = $dbh->prepare_cached("SELECT * FROM import_batches
924 WHERE batch_type IN ('batch', 'webservice')
925 ORDER BY import_batch_id ASC");
929 while (my $row = $sth->fetchrow_hashref) {
930 push @$results, $row;
936 =head2 GetStagedWebserviceBatches
938 my $batch_ids = GetStagedWebserviceBatches();
940 Returns a references to an array of batch id's
941 of batch_type 'webservice' that are not imported
945 my $PENDING_WEBSERVICE_BATCHES_QRY = <<EOQ;
946 SELECT import_batch_id FROM import_batches
947 WHERE batch_type = 'webservice'
948 AND import_status = 'staged'
950 sub GetStagedWebserviceBatches {
951 my $dbh = C4::Context->dbh;
952 return $dbh->selectcol_arrayref($PENDING_WEBSERVICE_BATCHES_QRY);
955 =head2 GetImportBatchRangeDesc
957 my $results = GetImportBatchRangeDesc($offset, $results_per_group);
959 Returns a reference to an array of hash references corresponding to
960 import_batches rows (sorted in descending order by import_batch_id)
961 start at the given offset.
965 sub GetImportBatchRangeDesc {
966 my ($offset, $results_per_group) = @_;
968 my $dbh = C4::Context->dbh;
969 my $query = "SELECT * FROM import_batches
970 WHERE batch_type IN ('batch', 'webservice')
971 ORDER BY import_batch_id DESC";
973 if ($results_per_group){
974 $query .= " LIMIT ?";
975 push(@params, $results_per_group);
978 $query .= " OFFSET ?";
979 push(@params, $offset);
981 my $sth = $dbh->prepare_cached($query);
982 $sth->execute(@params);
983 my $results = $sth->fetchall_arrayref({});
988 =head2 GetItemNumbersFromImportBatch
990 my @itemsnos = GetItemNumbersFromImportBatch($batch_id);
994 sub GetItemNumbersFromImportBatch {
996 my $dbh = C4::Context->dbh;
997 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=?");
998 $sth->execute($batch_id);
1000 while ( my ($itm) = $sth->fetchrow_array ) {
1006 =head2 GetNumberOfImportBatches
1008 my $count = GetNumberOfImportBatches();
1012 sub GetNumberOfNonZ3950ImportBatches {
1013 my $dbh = C4::Context->dbh;
1014 my $sth = $dbh->prepare("SELECT COUNT(*) FROM import_batches WHERE batch_type != 'z3950'");
1016 my ($count) = $sth->fetchrow_array();
1021 =head2 GetImportBiblios
1023 my $results = GetImportBiblios($importid);
1027 sub GetImportBiblios {
1028 my ($import_record_id) = @_;
1030 my $dbh = C4::Context->dbh;
1031 my $query = "SELECT * FROM import_biblios WHERE import_record_id = ?";
1032 return $dbh->selectall_arrayref(
1040 =head2 GetImportRecordsRange
1042 my $results = GetImportRecordsRange($batch_id, $offset, $results_per_group);
1044 Returns a reference to an array of hash references corresponding to
1045 import_biblios/import_auths/import_records rows for a given batch
1046 starting at the given offset.
1050 sub GetImportRecordsRange {
1051 my ( $batch_id, $offset, $results_per_group, $status, $parameters ) = @_;
1053 my $dbh = C4::Context->dbh;
1055 my $order_by = $parameters->{order_by} || 'import_record_id';
1056 ( $order_by ) = grep( /^$order_by$/, qw( import_record_id title status overlay_status ) ) ? $order_by : 'import_record_id';
1058 my $order_by_direction =
1059 uc( $parameters->{order_by_direction} ) eq 'DESC' ? 'DESC' : 'ASC';
1061 $order_by .= " $order_by_direction, authorized_heading" if $order_by eq 'title';
1063 my $query = "SELECT title, author, isbn, issn, authorized_heading, import_records.import_record_id,
1064 record_sequence, status, overlay_status,
1065 matched_biblionumber, matched_authid, record_type
1067 LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
1068 LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
1069 WHERE import_batch_id = ?";
1071 push(@params, $batch_id);
1073 $query .= " AND status=?";
1074 push(@params,$status);
1077 $query.=" ORDER BY $order_by $order_by_direction";
1079 if($results_per_group){
1080 $query .= " LIMIT ?";
1081 push(@params, $results_per_group);
1084 $query .= " OFFSET ?";
1085 push(@params, $offset);
1087 my $sth = $dbh->prepare_cached($query);
1088 $sth->execute(@params);
1089 my $results = $sth->fetchall_arrayref({});
1095 =head2 GetBestRecordMatch
1097 my $record_id = GetBestRecordMatch($import_record_id);
1101 sub GetBestRecordMatch {
1102 my ($import_record_id) = @_;
1104 my $dbh = C4::Context->dbh;
1105 my $sth = $dbh->prepare("SELECT candidate_match_id
1106 FROM import_record_matches
1107 JOIN import_records ON ( import_record_matches.import_record_id = import_records.import_record_id )
1108 LEFT JOIN biblio ON ( candidate_match_id = biblio.biblionumber )
1109 LEFT JOIN auth_header ON ( candidate_match_id = auth_header.authid )
1110 WHERE import_record_matches.import_record_id = ? AND
1111 ( (import_records.record_type = 'biblio' AND biblio.biblionumber IS NOT NULL) OR
1112 (import_records.record_type = 'auth' AND auth_header.authid IS NOT NULL) )
1113 ORDER BY score DESC, candidate_match_id DESC");
1114 $sth->execute($import_record_id);
1115 my ($record_id) = $sth->fetchrow_array();
1120 =head2 GetImportBatchStatus
1122 my $status = GetImportBatchStatus($batch_id);
1126 sub GetImportBatchStatus {
1127 my ($batch_id) = @_;
1129 my $dbh = C4::Context->dbh;
1130 my $sth = $dbh->prepare("SELECT import_status FROM import_batches WHERE import_batch_id = ?");
1131 $sth->execute($batch_id);
1132 my ($status) = $sth->fetchrow_array();
1138 =head2 SetImportBatchStatus
1140 SetImportBatchStatus($batch_id, $new_status);
1144 sub SetImportBatchStatus {
1145 my ($batch_id, $new_status) = @_;
1147 my $dbh = C4::Context->dbh;
1148 my $sth = $dbh->prepare("UPDATE import_batches SET import_status = ? WHERE import_batch_id = ?");
1149 $sth->execute($new_status, $batch_id);
1154 =head2 GetImportBatchOverlayAction
1156 my $overlay_action = GetImportBatchOverlayAction($batch_id);
1160 sub GetImportBatchOverlayAction {
1161 my ($batch_id) = @_;
1163 my $dbh = C4::Context->dbh;
1164 my $sth = $dbh->prepare("SELECT overlay_action FROM import_batches WHERE import_batch_id = ?");
1165 $sth->execute($batch_id);
1166 my ($overlay_action) = $sth->fetchrow_array();
1168 return $overlay_action;
1173 =head2 SetImportBatchOverlayAction
1175 SetImportBatchOverlayAction($batch_id, $new_overlay_action);
1179 sub SetImportBatchOverlayAction {
1180 my ($batch_id, $new_overlay_action) = @_;
1182 my $dbh = C4::Context->dbh;
1183 my $sth = $dbh->prepare("UPDATE import_batches SET overlay_action = ? WHERE import_batch_id = ?");
1184 $sth->execute($new_overlay_action, $batch_id);
1189 =head2 GetImportBatchNoMatchAction
1191 my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
1195 sub GetImportBatchNoMatchAction {
1196 my ($batch_id) = @_;
1198 my $dbh = C4::Context->dbh;
1199 my $sth = $dbh->prepare("SELECT nomatch_action FROM import_batches WHERE import_batch_id = ?");
1200 $sth->execute($batch_id);
1201 my ($nomatch_action) = $sth->fetchrow_array();
1203 return $nomatch_action;
1208 =head2 SetImportBatchNoMatchAction
1210 SetImportBatchNoMatchAction($batch_id, $new_nomatch_action);
1214 sub SetImportBatchNoMatchAction {
1215 my ($batch_id, $new_nomatch_action) = @_;
1217 my $dbh = C4::Context->dbh;
1218 my $sth = $dbh->prepare("UPDATE import_batches SET nomatch_action = ? WHERE import_batch_id = ?");
1219 $sth->execute($new_nomatch_action, $batch_id);
1224 =head2 GetImportBatchItemAction
1226 my $item_action = GetImportBatchItemAction($batch_id);
1230 sub GetImportBatchItemAction {
1231 my ($batch_id) = @_;
1233 my $dbh = C4::Context->dbh;
1234 my $sth = $dbh->prepare("SELECT item_action FROM import_batches WHERE import_batch_id = ?");
1235 $sth->execute($batch_id);
1236 my ($item_action) = $sth->fetchrow_array();
1238 return $item_action;
1243 =head2 SetImportBatchItemAction
1245 SetImportBatchItemAction($batch_id, $new_item_action);
1249 sub SetImportBatchItemAction {
1250 my ($batch_id, $new_item_action) = @_;
1252 my $dbh = C4::Context->dbh;
1253 my $sth = $dbh->prepare("UPDATE import_batches SET item_action = ? WHERE import_batch_id = ?");
1254 $sth->execute($new_item_action, $batch_id);
1259 =head2 GetImportBatchMatcher
1261 my $matcher_id = GetImportBatchMatcher($batch_id);
1265 sub GetImportBatchMatcher {
1266 my ($batch_id) = @_;
1268 my $dbh = C4::Context->dbh;
1269 my $sth = $dbh->prepare("SELECT matcher_id FROM import_batches WHERE import_batch_id = ?");
1270 $sth->execute($batch_id);
1271 my ($matcher_id) = $sth->fetchrow_array();
1278 =head2 SetImportBatchMatcher
1280 SetImportBatchMatcher($batch_id, $new_matcher_id);
1284 sub SetImportBatchMatcher {
1285 my ($batch_id, $new_matcher_id) = @_;
1287 my $dbh = C4::Context->dbh;
1288 my $sth = $dbh->prepare("UPDATE import_batches SET matcher_id = ? WHERE import_batch_id = ?");
1289 $sth->execute($new_matcher_id, $batch_id);
1294 =head2 GetImportRecordOverlayStatus
1296 my $overlay_status = GetImportRecordOverlayStatus($import_record_id);
1300 sub GetImportRecordOverlayStatus {
1301 my ($import_record_id) = @_;
1303 my $dbh = C4::Context->dbh;
1304 my $sth = $dbh->prepare("SELECT overlay_status FROM import_records WHERE import_record_id = ?");
1305 $sth->execute($import_record_id);
1306 my ($overlay_status) = $sth->fetchrow_array();
1308 return $overlay_status;
1313 =head2 SetImportRecordOverlayStatus
1315 SetImportRecordOverlayStatus($import_record_id, $new_overlay_status);
1319 sub SetImportRecordOverlayStatus {
1320 my ($import_record_id, $new_overlay_status) = @_;
1322 my $dbh = C4::Context->dbh;
1323 my $sth = $dbh->prepare("UPDATE import_records SET overlay_status = ? WHERE import_record_id = ?");
1324 $sth->execute($new_overlay_status, $import_record_id);
1329 =head2 GetImportRecordStatus
1331 my $status = GetImportRecordStatus($import_record_id);
1335 sub GetImportRecordStatus {
1336 my ($import_record_id) = @_;
1338 my $dbh = C4::Context->dbh;
1339 my $sth = $dbh->prepare("SELECT status FROM import_records WHERE import_record_id = ?");
1340 $sth->execute($import_record_id);
1341 my ($status) = $sth->fetchrow_array();
1348 =head2 SetImportRecordStatus
1350 SetImportRecordStatus($import_record_id, $new_status);
1354 sub SetImportRecordStatus {
1355 my ($import_record_id, $new_status) = @_;
1357 my $dbh = C4::Context->dbh;
1358 my $sth = $dbh->prepare("UPDATE import_records SET status = ? WHERE import_record_id = ?");
1359 $sth->execute($new_status, $import_record_id);
1364 =head2 GetImportRecordMatches
1366 my $results = GetImportRecordMatches($import_record_id, $best_only);
1370 sub GetImportRecordMatches {
1371 my $import_record_id = shift;
1372 my $best_only = @_ ? shift : 0;
1374 my $dbh = C4::Context->dbh;
1375 # FIXME currently biblio only
1376 my $sth = $dbh->prepare_cached("SELECT title, author, biblionumber,
1377 candidate_match_id, score, record_type
1379 JOIN import_record_matches USING (import_record_id)
1380 LEFT JOIN biblio ON (biblionumber = candidate_match_id)
1381 WHERE import_record_id = ?
1382 ORDER BY score DESC, biblionumber DESC");
1383 $sth->bind_param(1, $import_record_id);
1386 while (my $row = $sth->fetchrow_hashref) {
1387 if ($row->{'record_type'} eq 'auth') {
1388 $row->{'authorized_heading'} = C4::AuthoritiesMarc::GetAuthorizedHeading( { authid => $row->{'candidate_match_id'} } );
1390 next if ($row->{'record_type'} eq 'biblio' && not $row->{'biblionumber'});
1391 push @$results, $row;
1401 =head2 SetImportRecordMatches
1403 SetImportRecordMatches($import_record_id, @matches);
1407 sub SetImportRecordMatches {
1408 my $import_record_id = shift;
1411 my $dbh = C4::Context->dbh;
1412 my $delsth = $dbh->prepare("DELETE FROM import_record_matches WHERE import_record_id = ?");
1413 $delsth->execute($import_record_id);
1416 my $sth = $dbh->prepare("INSERT INTO import_record_matches (import_record_id, candidate_match_id, score)
1418 foreach my $match (@matches) {
1419 $sth->execute($import_record_id, $match->{'record_id'}, $match->{'score'});
1424 # internal functions
1426 sub _create_import_record {
1427 my ($batch_id, $record_sequence, $marc_record, $record_type, $encoding, $z3950random, $marc_type) = @_;
1429 my $dbh = C4::Context->dbh;
1430 my $sth = $dbh->prepare("INSERT INTO import_records (import_batch_id, record_sequence, marc, marcxml,
1431 record_type, encoding, z3950random)
1432 VALUES (?, ?, ?, ?, ?, ?, ?)");
1433 $sth->execute($batch_id, $record_sequence, $marc_record->as_usmarc(), $marc_record->as_xml($marc_type),
1434 $record_type, $encoding, $z3950random);
1435 my $import_record_id = $dbh->{'mysql_insertid'};
1437 return $import_record_id;
1440 sub _update_import_record_marc {
1441 my ($import_record_id, $marc_record, $marc_type) = @_;
1443 my $dbh = C4::Context->dbh;
1444 my $sth = $dbh->prepare("UPDATE import_records SET marc = ?, marcxml = ?
1445 WHERE import_record_id = ?");
1446 $sth->execute($marc_record->as_usmarc(), $marc_record->as_xml($marc_type), $import_record_id);
1450 sub _add_auth_fields {
1451 my ($import_record_id, $marc_record) = @_;
1454 if ($marc_record->field('001')) {
1455 $controlnumber = $marc_record->field('001')->data();
1457 my $authorized_heading = C4::AuthoritiesMarc::GetAuthorizedHeading({ record => $marc_record });
1458 my $dbh = C4::Context->dbh;
1459 my $sth = $dbh->prepare("INSERT INTO import_auths (import_record_id, control_number, authorized_heading) VALUES (?, ?, ?)");
1460 $sth->execute($import_record_id, $controlnumber, $authorized_heading);
1464 sub _add_biblio_fields {
1465 my ($import_record_id, $marc_record) = @_;
1467 my ($title, $author, $isbn, $issn) = _parse_biblio_fields($marc_record);
1468 my $dbh = C4::Context->dbh;
1469 # FIXME no controlnumber, originalsource
1470 $isbn = C4::Koha::GetNormalizedISBN($isbn);
1471 my $sth = $dbh->prepare("INSERT INTO import_biblios (import_record_id, title, author, isbn, issn) VALUES (?, ?, ?, ?, ?)");
1472 $sth->execute($import_record_id, $title, $author, $isbn, $issn);
1477 sub _update_biblio_fields {
1478 my ($import_record_id, $marc_record) = @_;
1480 my ($title, $author, $isbn, $issn) = _parse_biblio_fields($marc_record);
1481 my $dbh = C4::Context->dbh;
1482 # FIXME no controlnumber, originalsource
1483 # FIXME 2 - should regularize normalization of ISBN wherever it is done
1487 my $sth = $dbh->prepare("UPDATE import_biblios SET title = ?, author = ?, isbn = ?, issn = ?
1488 WHERE import_record_id = ?");
1489 $sth->execute($title, $author, $isbn, $issn, $import_record_id);
1493 sub _parse_biblio_fields {
1494 my ($marc_record) = @_;
1496 my $dbh = C4::Context->dbh;
1497 my $bibliofields = TransformMarcToKoha($dbh, $marc_record, '');
1498 return ($bibliofields->{'title'}, $bibliofields->{'author'}, $bibliofields->{'isbn'}, $bibliofields->{'issn'});
1502 sub _update_batch_record_counts {
1503 my ($batch_id) = @_;
1505 my $dbh = C4::Context->dbh;
1506 my $sth = $dbh->prepare_cached("UPDATE import_batches SET
1510 WHERE import_batch_id = import_batches.import_batch_id),
1514 JOIN import_items USING (import_record_id)
1515 WHERE import_batch_id = import_batches.import_batch_id
1516 AND record_type = 'biblio')
1517 WHERE import_batch_id = ?");
1518 $sth->bind_param(1, $batch_id);
1523 sub _get_commit_action {
1524 my ($overlay_action, $nomatch_action, $item_action, $overlay_status, $import_record_id, $record_type) = @_;
1526 if ($record_type eq 'biblio') {
1527 my ($bib_result, $bib_match, $item_result);
1529 if ($overlay_status ne 'no_match') {
1530 $bib_match = GetBestRecordMatch($import_record_id);
1531 if ($overlay_action eq 'replace') {
1532 $bib_result = defined($bib_match) ? 'replace' : 'create_new';
1533 } elsif ($overlay_action eq 'create_new') {
1534 $bib_result = 'create_new';
1535 } elsif ($overlay_action eq 'ignore') {
1536 $bib_result = 'ignore';
1538 if($item_action eq 'always_add' or $item_action eq 'add_only_for_matches'){
1539 $item_result = 'create_new';
1541 elsif($item_action eq 'replace'){
1542 $item_result = 'replace';
1545 $item_result = 'ignore';
1548 $bib_result = $nomatch_action;
1549 $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_new') ? 'create_new' : 'ignore';
1551 return ($bib_result, $item_result, $bib_match);
1552 } else { # must be auths
1553 my ($auth_result, $auth_match);
1555 if ($overlay_status ne 'no_match') {
1556 $auth_match = GetBestRecordMatch($import_record_id);
1557 if ($overlay_action eq 'replace') {
1558 $auth_result = defined($auth_match) ? 'replace' : 'create_new';
1559 } elsif ($overlay_action eq 'create_new') {
1560 $auth_result = 'create_new';
1561 } elsif ($overlay_action eq 'ignore') {
1562 $auth_result = 'ignore';
1565 $auth_result = $nomatch_action;
1568 return ($auth_result, undef, $auth_match);
1573 sub _get_revert_action {
1574 my ($overlay_action, $overlay_status, $status) = @_;
1578 if ($status eq 'ignored') {
1579 $bib_result = 'ignore';
1581 if ($overlay_action eq 'create_new') {
1582 $bib_result = 'delete';
1584 $bib_result = ($overlay_status eq 'match_applied') ? 'restore' : 'delete';
1595 Koha Development Team <http://koha-community.org/>
1597 Galen Charlton <galen.charlton@liblime.com>